A router lelke egyetlen kérdés: melyik modellre küldjem ezt a kérést? A motorban erre három különböző szabályverzió volt élesben az elmúlt tizenegy hónapban, és mindhárom rossz volt. A negyedik már nem rossz, de még nem tökéletes — ez egy poszt arról, miért.
v1 — pick_cheapest_first
Az első szabály egyszerű volt: válaszd a legolcsóbb modellt, ami elvileg meg tudja oldani a feladatot. A „elvileg” itt egy statikus capability mátrixot jelentett, amit egy táblázatból olvastunk be Postgres-ből (eng_model_capabilities). A logika tetszett: olcsóság előbb, minőség később, ha kell, fallback chain elviszi. Két hét után derült ki, hogy a használók 28%-a a fallback miatt szenvedett: az olcsó modell elszúrta a kérést, retry-elt a következőre, és a végül szállított válasz medián latenciája 2.4 másodperc volt egy 600ms SLO mellett. A „takarítás” nem érte meg a sebesség-veszteséget. A retry-arány önmagában 18% volt a két leghasználtabb tenantnél.
A tanulság: a költségoptimalizáció rossz default, mert a fallback-aktiválás drágább, mint a kezdetből jó modell-választás. Nem a tokenárban — a kérés végső latenciájában, az SRE oncall-jában, és a felhasználói türelemben.
v2 — pick_fastest_first
A második verzió ennek az inverze volt. Vedd a leggyorsabb modellt elérhető providerre, ne foglalkozz az árral, mert a felhasználó türelme drágább, mint a token. Ez működött is — a medián latencia 340ms-re esett. A számla viszont megduplázódott három hét alatt. A pénzügy nem volt boldog. A CFO levele („srácok, mi történt április első hetében?”) a Slack #engineering csatornán kezdődött és a tervezőbizottság elé jutott. A „leggyorsabb” itt szinte mindig gpt-4o-t jelentett, akkor is, amikor a kérés egy 80-tokenes klasszifikáció volt, amit egy nano-modell háromtizede pénzen lefuttat. A „túl drága, mert nem mérted, mihez képest drága” érvelés ekkor szilárdult bennünk.
v3 — first_to_meet_slo
A harmadik verzió egy per-tenant SLO sorra épül (eng_tenant_slo), ami három mezőt tárol: latency_p95_ms, cost_ceiling_per_request_eur, quality_floor. A router végigmegy a candidate model listán (capability filter szerint), és az ELSŐ olyat választja, ami mindhárom feltételt teljesíti az utolsó 30 perces telemetriai ablakban. Ez működött — pénzügyileg, latenciában, és a támogatási ticketek számában. Nyolc hónapig.
Kétszer ment félre. Az első egy ritka kombináció: egy tenant SLO-ja olyan szigorú volt (latency_p95 < 200ms ÉS cost < 0.001 EUR), hogy semelyik modell sem ment át. A router kihullott egy NoEligibleModel exceptionre, ami a hívóoldalon 500-as választ adott. A javítás: ha egyetlen modell sem teljesít minden feltételt, válaszd azt, amelyik a legkevesebbet sérti, és emelj egy slo.degraded countert. A második hiba szubtilisebb volt: a telemetriai ablak 30 perc, de friss tenant aktivációkor ez üres. A v3 ilyenkor az utolsó ismert globális mediánt használta proxynak, ami egy lassú modellnél kifejezetten gyorsnak tűnt. A javítás: warm-up periódus alatt használj „pessimistic estimate”-et — a candidate model legrosszabb publikált latenciáját.
A metrika, ami végül lezárta a vitát
Nem a latency, nem a cost, és nem a routing accuracy. Egyetlen szám: resolved-request-cost — a tenantnek számlázott ár osztva azzal, hány kérést kezelt sikeresen (nem retry, nem fallback, egyetlen kör). Ez a szám egy szám, és ez a szám most a router-szabály egyetlen célfüggvénye. A v3 ezt 32%-kal javította a v2-höz képest, és 47%-kal a v1-hez képest. A v4 (amit most fejlesztünk) ennek a számnak a tenant-szintű elmozdulására figyel napi szinten, és ha drift van, automatikusan újrakalibrálja a candidate listát anélkül, hogy ember belenyúlna.
A tanulság nem az, hogy a router nehéz. Az, hogy a célfüggvényt sokkal nehezebb megválasztani, mint az algoritmust megírni.
Egy következmény a csapat-szervezésre
Az első verzió után megpróbáltuk egyetlen mérnököt felelőssé tenni a router-szabályért. Ez nem működött, mert a routerről hozott döntések érintik a pénzügyet, a SRE-t, a product-ot és a support-ot. A negyedik verzió óta a router-szabály változtatás egy két-PR ritmus: az első PR a logikát változtatja egy feature flag mögött; a második a flag-et kapcsolja, a feature flag bekapcsolása heti meetingen történik, ahol a négy érintett terület képviselője ott van. Lassúbb, de a v1/v2/v3 idejében visszahozzott regressziók egyike sem ment volna át rajta. A „sebesség a változásban” drága lehet, amikor a változás a teljes ügyfél-élményt érinti.