
OrcaRouter Routing-infrastruktur: sessionsmedveten routing och frontier-eskalering
- obsidianNYQwen3.8 27B Uncensored (Aggressive)2026-08-15$0.40 / $4.21 per 1M tokens · 22 tok/s
- qwenNYQwen: Qwen3.8 27B (free)2026-08-1343 tok/s
- deepseekNYDeepSeek: DeepSeek V4 Pro 08132026-08-1253Intelligens69Kodning
- grokNYSpaceXAI: Grok 4.62026-08-1261Intelligens77Kodning
- metaNYMeta: Muse Spark 1.22026-08-0557Intelligens72Kodning
- qwenQwen: Qwen3.8 Max2026-08-0358Intelligens72Kodning
- deepseekDeepSeek: DeepSeek V4 Flash 07312026-07-3152Intelligens69Kodning
- minimaxMiniMax: MiniMax-H32026-07-31minimax/minimax-h3
- qwenQwen: Qwen3.7 Flash2026-07-27$0.03 / $0.13 per 1M tokens · 273 tok/s
- orcaOrcaDub: OrcaDub 1.02026-07-27orca/dub
- anthropicAnthropic: Claude Opus 52026-07-2463Intelligens78Kodning
- googleGoogle: Gemini 3.6 Flash2026-07-2152Intelligens69Kodning
- googleGoogle: Gemini 3.5 Flash-Lite2026-07-2137Intelligens49Kodning
- metaMeta: Muse Spark 1.12026-07-1653Intelligens71Kodning
- kimiMoonshotAI: Kimi K32026-07-1560Intelligens76Kodning
- openaiOpenAI: GPT-5.6 Luna2026-07-0952Intelligens71Kodning
- openaiOpenAI: GPT-5.6 Terra2026-07-0957Intelligens77Kodning
- openaiOpenAI: GPT-5.6 Sol2026-07-0961Intelligens77Kodning
- grokxAI: Grok 4.52026-07-0856Intelligens72Kodning
- tencentTencent: Hy32026-07-0642Intelligens59Kodning
ORCAROUTER · RUTTNINGSARKITEKTUR
Varje LLM-gateway som cachar prompts måste låsa en konversation till en enda modell. Varje gateway som låser en konversation fattar sitt routningsbeslut baserat på den minst informativa turen i den konversationen. Detta är en rapport om den avvägningen, och om den nivåindelade stickighetsmekanism som OrcaRouter levererar för att undkomma den.
Ämne: OrcaRouter LLM-gateway (Go / Gin / Redis) · Komponent: session affinity + Frontier Escalation-motor · Metod: uppspelning av 400 sessioner mot produktionsbeslutskoden · Datum: 14 augusti 2026
SAMMANFATTNING — Routing av LLM på begäranivå — att poängsätta varje begäran oberoende och skicka den till den billigaste tillräckliga modellen — är den ansats som nästan all publicerad routerforskning behandlar. Det är också fel ansats för den trafik som nu dominerar gatewayvolymen: flervarviga agentsessioner, där prompten till 90 % består av överförd kontext och leverantörens promptcache betalar för kontinuiteten. Att byta modell mitt i en konversation förlorar 10× rabatten på det delade prefixet, så gateways låser fast sessioner. Men en låsning som görs vid varv 1 är en låsning som görs vid det varv som har minst belägg, och den kvarstår under hela konversationens livstid.
100 / 100 — latent-svåra sessioner vars tur-1-poäng inte går att skilja från en trivial sådan
+16% — svårighetspoängsdrift enbart från transkriptlängd, vid identisk uppgiftssvårighet
45% — av always-frontier-kostnaden, för 67 % av dess hard-turn-täckning
0.019 — marginalen mellan den levererade gate:n och taket för realistiska poäng
1 Två routingregimer
En LLM-gateway som ligger framför många leverantörer måste besvara en fråga per förfrågan: vilken modell betjänar detta? Det finns två strukturellt olika sätt att besvara den, och litteraturen och produktionsverkligheten har glidit isär när det gäller vilket som spelar roll.
Routing på begäranivå behandlar varje förfrågan som oberoende. En scorer uppskattar frågans svårighet eller förväntad svarskvalitet, och förfrågan skickas till den billigaste modell som förväntas klara av den. Detta är metoden bakom i stort sett allt publicerat routerarbete: RouteLLM tränar routrar på preferensdata som når 95 % av GPT-4:s kvalitet med 14 % anrop till starka modellersup>[1]/sup>; FrugalGPT kaskaderar från billiga till dyra modeller med en acceptera/avvisa-kontroll och rapporterar upp till 98 % kostnadsminskningsup>[2]/sup>; RouterArena bygger ett benchmark med 8 400 frågor för att jämföra routrar på exakt denna axelsup>[3]/sup>. Analysenheten är frågan.
Anledningen till att sessionsmedveten routing finns är inte elegans. Det är aritmetik.
2 Cacheekonomin som gör stickiness obligatorisk
I en flervarvsagentsession, varv n:s prompt är varv n−1:s prompt plus ett delta. Vid varv 10 är det överförda prefixet den övervägande majoriteten av indatatokenen. Varje större leverantör prissätter nu det prefixet olika beroende på om det är en cacheträff:
Tabell 1.Prompt-cache-semantik per leverantör. Cachen nycklas på ett exakt prefix och på serveringsnyckeln — ett modellbyte eller en nyckelrotation är en kall läsning till fullt pris.
OrcaRouter kodar exakt dessa livslängder som pin-TTL:er: en karta per kanaltyp över providercachefönster — 5 minuter för OpenAI, Anthropic och Gemini, 60 minuter för DeepSeek — med en standard på 5 minuter för ommappade providers. Kanal+nyckel-pinnen upphör med det fönstret, eftersom ett inaktuellt nyckelindex inte har något cachevärde och bara snedvrider lastbalanseringen. modellpinnen, på en Redis-understödd driftsättning och för en session-id som är berättigad till lång pin, kvarstår i 30 dagar — inte för cachevärde, som sedan länge är borta, utan för kontinuitet i förfrågningsformat. Ett byte av modell mitt i en konversation tvingar fram en konvertering av förfrågningsformat som kan vara datainkompatibel: tankeblock och verktygsanrops-ID:n överlever inte nödvändigtvis översättning mellan providerscheman.
DEN UNDERSKATTADE DETALJEN
Promptcachar är nycklade per API-nyckel, inte per modell. En gateway som låser modellen men lastbalanserar över tre nycklar på samma kanal får fortfarande kalläsningar i två av tre anrop. Det är därför OrcaRouters kanallås lagrar {ChannelID, KeyIndex} i stället för ett kanal-ID, och varför låset släpps när det registrerade nyckelindexet inte längre matchar en aktiverad nyckel — en boostad men roterad nyckel skulle gynna en kall cache samtidigt som den kringgår lastbalanseringen, vilket är det värsta av båda världar.
Stiften är mjuka genomgående: ett oupplösbart sessions-ID är en no-op, en inaktiverad eller ohälsosam pinnad kanal degraderas till normal balanserad selektion, och ett stift till en vikt-noll-kanal i en blandad pool ignoreras så att en administratör som dränerar en kanal inte besegras av stickiness. De orsakar aldrig att en begäran misslyckas.
3 Fällan: stickiness inaktiverar routern
Here is the failure mode. In OrcaRouter's pre-escalation code path, for a session-aware router on any non-DSL strategy, the session→model pin returned
Det skulle vara tolerabelt om tur 1 vore representativ. Det är systematiskt inte fallet, av två skäl som förstärker varandra.
3.1 Tur 1 är den minst informativa turen.
Svårighetsskalären (service/model_router_difficulty.go) är en viktad linjär kombination över sex lexikala egenskaper:
LogPromptTokens × 0,20, tak: log(8001) ≈ 8,99
ReasoningCueCount × 0.15, tak 5
SystemPromptLogLen × 0,10 tak log(2001) ≈ 7,60
CodeKeywordDensity × 0.20 cap 5.0 (träffar per 100 tecken)
HasTools × 0.15 redan 0/1
MathMarkerCount × 0,20 tak 5
En kort öppnare utan historik får låga poäng nästan per konstruktion: den 0.20-viktade tokentermen är nära sitt golv, och resonemangs- och matematiktermerna aktiveras på ordförråd som användaren ännu inte haft anledning att använda. Sessioner förbinder sig därför till en svag-pool-modell i det ögonblick då informationen är som minst — och med en Redis-stödd 30-dagars modellpinning är det åtagandet långvarigt.
Figur 1. Genomsnittlig svårighet för den senaste turen per konversationstur, över 100 latent-svåra sessioner och 200 genuint lätta sådana, poängsatta av produktionsscorern. Vid tur 1 — den tur där den självhäftande lappen skrivs — är de två populationerna omöjliga att skilja åt (0,210 mot 0,208). Den svåra populationen passerar gränsen vid tur 5. Under en pin-only-policy hamnar alla 100 latent-svåra sessioner i den billiga poolen innan något sådant bevis finns.
3.2 Längd maskerar sig som svårighet
Det andra problemet är mer subtilt och det underminerar den uppenbara lösningen. Om du helt enkelt kör svårighetsgrinden igen varje tur, kör du den på ett resultat som beräknats utifrån hela den sammanlagda transkriptionen. Det resultatet har en inbyggd uppåtdrift: LogPromptTokens-termen med vikt 0,20 stiger monotont med konversationens längd, och för varje agentsession är HasTools-termen (0,15) och SystemPromptLogLen-termen (0,10) i praktiken konstanta golv. En lång, tråkig session ser progressivt svårare ut.

Figur 2. Längdbiasartefakten, uppmätt på 60 sessioner som helt består av triviala redigeringar (”byt namn på den här variabeln”, ”lägg till en nil-kontroll”). Hela transkriptets poäng förskjuts +16 % över 25 vändor vid konstant uppgiftssvårighet; den senaste vändans (delta) poäng är platt. En naiv omvärdering av hela transkriptets poäng varje vända skulle eskalera sessioner för att de är långa.
The fix OrcaRouter ships is a separate delta extractor (service/model_router_delta.go) that scores only the latest turn — the new user text plus any tool results attached after the last assistant message — reusing the same weights and caps but deliberately zeroing SystemPromptLogLen, which is not part of the delta. Figure 2's flat blue line is that extractor.
4 Design: nivåbaserad vidhäftning
Den naiva flykten från turn-1-inlåsning är att omdirigera varje tur — vilket bara är routning på request-nivå och går miste om cachen. Den naiva lösningen i andra riktningen är att göra pinnen till minnet av "den här sessionen blev svår" — vilket inte kan uttrycka de-eskalering och inte kan begränsas. OrcaRouters design avvisar båda.
Omformuleringen: en session är bunden till en modell inom en nivå, och en liten Redis nivåstatus är det enda eskaleringsminnet. Modellkopplingen är aldrig minnet.
Nivåpooler. Den starka nivån är den fastställda eskaleringspoolen (escalation_pool, som standard routerns strong_pool). Basnivån är AllowedModels \ den starka nivåns pool; en modell som finns i båda tillhör den starka nivån. Inom basnivån fortsätter gated_adaptives klassificering i svaga/mellan/starka svårighetsband att fungera precis som tidigare.
Tier-scoped pins. The strong tier's model-pin key gets a :t:strong suffix; the base tier keeps the legacy key unchanged. Escalation therefore preserves the base pin, so a de-escalated session — or one resumed after the tier state expires — lands back on the exact model it started on, not an arbitrary re-pick. Strong pins are written with the short provider-window TTL only: a 30-day strong pin would outlive the 4-hour tier state that justified it.
The gate runs first. In selectByStrategy (service/model_router.go:1374) the tier is resolved up front, the candidate set is narrowed to the tier's pool, and only then is the sticky pin consulted — within that tier. This is the structural fix for §3: the difficulty computation and the escalation triggers run every turn, before the pin can short-circuit them.
4.1 Three trigger classes, ranked by trust
Table 2. Escalation triggers. No fuzzy signal ever ratchets alone; only an explicit client ask commits at n=1, and even it obeys the caps.
Three hygiene invariants are load-bearing. Strikes are deduplicated by request id through a ring buffer, so interleaved client retries cannot double-count. Infrastructure failure is never capability failure — 429s, 5xxs and channel fallbacks never strike; only post-success quality signals count. And a “turn” is defined as a completed, billed-success request that ran strike evaluation, so failed requests advance neither strike decay nor the clean-turn counter.
4.2 Resolve is pure; commit is deferred
The engine's most consequential structural property is that ResolveEscalation writes nothing. It returns a decision plus a list of pending intents. The distributor applies those intents in its post-success block, onto a fresh read inside a Redis WATCH transaction. This matters because the resolver runs on paths that must never mutate state: speculative fallback-chain resolutions, the read-only diagnostic endpoints, and requests that later 403 or fail upstream. Re-applying intents onto fresh state also means a stale concurrent writer cannot clobber a committed escalation, and two racing identical escalations merge idempotently.
4.3 Caps, and why they bind everything
A false-positive escalation costs (strong − base) price × remaining warm-episode tokens, and it costs it silently — nothing fails. The blast radius is bounded by caps that apply to every class:
escalation_max_per_session (default 1). De-escalation and client resets do not refund it, which closes the reset-loop gaming path.
A per-router escalated-share cap (default 20 %) over a trailing 24–48 h window of Redis day-buckets, plus a workspace-wide cross-router cap. At the cap, all escalation routing is suppressed — including explicit asks and once boosts.
De-escalation only at cache-cold boundaries, so a false positive is bounded to one warm episode.
The reason Class A obeys the caps is a threat-model conclusion, not a policy preference: on an API gateway, whoever holds the workspace token controls the headers. A cap-exempt “the client asked for it” path is an unmetered spend channel. §7 measures what happens when every client abuses it.
4.4 De-escalation is asymmetric by design
Escalate on corroborated evidence; de-escalate only when it is free. A strong session returns to base only when all of: the session is cache-cold (idle past the provider window recorded at escalation), it has accumulated ≥3 strike-free evaluated turns, and the latest delta difficulty is below T1. Inside the warm window, a switch pays a full-price cold re-read — flapping is the one guaranteed way to make escalation cost-negative.
5 Method
We measured the mechanism by replaying a synthetic session corpus through the actual production decision code. The harness is a Go test in the service package that calls ResolveEscalation and CommitEscalationDecision per turn against a miniredis-backed tier store, with the real difficulty scorers, the real request-side strike producers, and the real share-cap machinery. Nothing about the decision path is reimplemented or mocked except the audit-event sink.
WHAT IS REAL AND WHAT IS NOT
Real: every routing decision, difficulty score, strike detection, streak rule, cap evaluation and Redis state transition — these are the shipped functions. Synthetic: the traffic. The corpus is generated, not sampled from production logs. Its archetype mix (50 % hard) is a stress mix chosen to exercise the mechanism, not an estimate of real traffic; §6.4 reports the sensitivity to that choice, and it is large. The clean precision numbers below reflect a corpus whose classes are separable by construction, and should be read as “the mechanism fires where it was designed to”, not as a production precision estimate.
5.1 Corpus
400 sessions, 3,968 turns, seeded and deterministic. Each turn is a full chat-completions request body carrying the cumulative history, a two-tool definition array, and a realistic system prompt — the shape a coding agent actually sends. Five archetypes, each carrying a ground-truth label:
Table 3. Corpus composition. “Needs strong” is the ground truth used for the precision and coverage scores.
Hard turns carry a pasted goroutine dump or source excerpt of 3–8 KB in addition to the prose, because that is what a real hard debugging turn contains. This detail turned out to matter enormously — see §6.2.
5.2 Cost model
Costs are computed from published list prices with per-provider cache semantics; the model is stated in full so it can be disagreed with.
Table 4. Cost model parameters. Prices are $ per 1M tokens, August 2026 list.
A warm turn costs 0.1·p_in·prefix + write·p_in·delta; a cold turn costs write·p_in·prompt. Turn 1 is always a full cache write. The tier-switch turn under the escalation policy is explicitly charged as cold, so the mechanism pays for its own cache invalidation.
Quality is reported as hard-turn coverage — the fraction of ground-truth-hard turns actually served by the strong model — rather than as an accuracy figure. We did not run upstream inference, so we decline to invent accuracy numbers.
6 Results
6.1 The mechanism fires where it was designed to
Table 5. Escalation outcomes by archetype, auto mode, canary 100 %, T2 = 0.70 (shipped default).
Zero false positives on the 200 easy sessions, including the 60 long ones that a full-transcript scorer would have drifted into the hard band. The trigger classes specialise cleanly and without overlap: difficulty catches reasoning-heavy work, strikes catch failure loops. Note that failure_loop's peak difficulty score is 0.262 — the difficulty gate never sees those sessions at all. An agent stuck in a compile-error loop is not producing reasoning-cue-dense prose; it is producing the same short prompt with a different stack trace. Without Class C strikes, every one of those 60 sessions would grind on the cheap model indefinitely.

Figure 3. When sessions escalate, split by trigger. Strike-driven escalations are sharply concentrated (turn 4, the first turn at which two strikes can have accumulated inside the decay window); difficulty-driven escalations spread across turns 2–11 following the corpus's onset distribution. The two-consecutive-turn streak rule means the earliest possible difficulty escalation is turn 2.
6.2 Finding: the shipped gate sits on a cliff edge
Our first corpus produced zero difficulty-driven escalations. The hard turns — loaded with race conditions, invariants, complexity analysis and proof vocabulary — peaked at 0.658 against a 0.70 gate. Adding the pasted stack traces that real debugging turns actually carry pushed them to 0.719. The gate is passed by a margin of 0.019.

Figure 4. Where the difficulty budget actually goes, averaged over 855 hard and 3,113 easy turns. A realistic hard turn reaches 0.719 of a theoretical 0.90 delta maximum. The CodeKeywordDensity term contributes 0.069 of its 0.20 budget — measured density is 1.72 matches per 100 characters against a saturation cap of 5.0 — and SystemPromptLogLen's 0.10 is structurally zero in the delta extractor. Roughly a third of the score's nominal range is unreachable by realistic text.
The threshold sweep confirms this is a cliff, not a slope. Across T2 from 0.35 to 0.65 the outcome is identical — 200 of 400 sessions escalate, with zero misses. At the shipped 0.70 the classifier starts losing sessions; at 0.75 difficulty-driven escalation collapses from 122 sessions to 23.

Figure 5. Threshold sensitivity. The whole 0.35–0.65 range is behaviourally identical because no realistic delta text lands in it — the score distribution is bimodal, with easy turns clustered near 0.23 and hard turns near 0.72, and nothing in between. The shipped default sits at the top edge of the upper mode.
ENGINEERING IMPLICATION
T2 is calibrated for the full-transcript distribution the gated_adaptive bands were tuned on, and it is being reused as the delta extractor's threshold. The design document flags that the delta extractor “needs its own tuning”; this measurement quantifies how much. Either the delta gate needs a lower T2 of its own — anywhere in 0.45–0.60 buys identical behaviour with real margin — or the percentile-based threshold already scheduled for Phase 3 (“top X % of this router's recent traffic”) should land, which makes the escalation rate the operator's knob and sidesteps absolute calibration entirely.
6.3 Cost and coverage

Figure 6. Five policies over the same 400 sessions. Left: cost per 1,000 sessions (log scale). Right: fraction of genuinely hard turns served by the strong model.
Table 6. Policy comparison. Cost per 1,000 sessions under the Table 4 model.
Two results are worth separating. First, session affinity alone saves 24 % at identical model choice (16.64 → 12.63) and 35 % on the frontier pair (290.93 → 188.30). That is pure cache economics — same models, same everything, only the key stickiness differs. The saving is larger on the frontier pair because Anthropic's 1.25× write premium makes cold turns disproportionately expensive.
Second, escalation lands where a rescue mechanism should: 45 % of always-frontier cost for 67 % of its hard-turn coverage, serving the strong model on only 21.4 % of turns.
The missing third of coverage is not a defect; it is the ratchet's price. The corroboration rules that give zero false positives also mean the mechanism cannot act on turn one of a problem:
Table 7. Escalation latency — hard turns served on the cheap model before the ratchet fires.
Two turns is exactly what the two-consecutive-turn streak rule specifies, and one turn is exactly what two-strikes-to-ratchet specifies. The latency is the design, and it is the same property that produced zero false positives. Anyone who wants faster rescue has the Class A header, which acts at n=1 — that is precisely why the manual escape hatch shipped first.
6.4 The headline ratio depends entirely on your traffic
The corpus is 50 % hard by construction. Real router traffic is not, and the cost comparison is extremely sensitive to that. Re-weighting the measured per-archetype costs across a range of hard-session prevalences:

Figure 7. Cost per 1,000 sessions as a function of how much of your traffic genuinely needs the strong model. Within-class behaviour is held at the measured values; only the mix changes.
Tabell 8. Prevalenskänslighet, $ per 1 000 sessioner.
Vid designdokumentets egen mål-eskaleringstakt på ≤5 % av sessionerna kostar eskaleringen 1,6× cheap-pool-räkningen och 12 % av frontier-räkningen. Vid stressblandningen 50 % kostar det 6,7× cheap-pool-räkningen. Båda är sanna; de svarar på olika frågor. Den operativt relevanta är den första, och det är därför andelsstaket som standard är 20 % i stället för ”av” — staket, inte triggerns precision, är vad som faktiskt begränsar räkningen.
6.5 The caps hold under adversarial abuse
We re-ran the corpus with the real share-cap machinery — no stub, real Redis day-buckets — under the §8 threat model: every client sends X-OrcaRouter-Tier: strong on every single turn.

Figure 8. Adversarial header abuse against the 20 % escalated-share cap. The first 20 requests are unconstrained by design — the warm-up floor prevents “1 escalation out of 2” reading as 50 % and locking the feature on a fresh router — after which the share converges and holds. Final state: 296 of 1,439 requests served strong (20.6 %), with 1,143 explicit asks denied and audited as denied_cap events.
The residual 0.6 % overshoot is the intended behaviour of a strictly-greater comparison on an approximate trailing counter, and the per-session cap of 1 keeps individual sessions from consuming the budget. Every denial is visible to the client in the X-Orca-Session-Tier: base; reason=denied:share_cap response header and to the operator in the audit table — a suppressed escalation is never silent.
7 What we would change
Give the delta extractor its own threshold. Reusing the full-transcript T2 leaves a 0.019 margin (§6.2). A delta-specific T2 in 0.45–0.60 is behaviourally identical on this corpus with two orders of magnitude more headroom. The percentile-threshold work already scheduled subsumes this and is the better fix.
Do not let the code-density term stay decorative. It contributes 0.069 of its 0.20 budget on the densest realistic text we could construct, because its saturation cap of 5 matches per 100 characters implies roughly one code keyword every twenty characters. Either re-cap it against a measured production distribution or reallocate its weight.
Klass C är arbetshästen för agenttrafik, och den är minst utvecklad. failure_loop-populationen är osynlig för svårighetsgrinden (topp 0,262) och fångas helt av strikes. Agentsessioner misslyckas genom att loopa, inte genom att bli lexikalt svårare. De återstående producenterna på responssidan — och den native-Gemini-hooken för strömningsfångst som fortfarande saknas — är värda mer än ytterligare svårighetsjustering.
Publicera eskaleringslatensen. Två omgångar hårt arbete som serveras på den billiga modellen är den ärliga kostnaden för en bekräftande spärr, och operatörer bör se den i analyspanelen bredvid precision, inte upptäcka den.
8 Begränsningar
Korpusen är syntetisk. Den konstruerades för att ge ren separation, så resultatet med noll falska positiva kännetecknar mekanismens specificitet på separerbar indata, inte dess precision på produktionstrafik. Det verkliga precisionsvärdet kan bara komma från det märkningsjobb i skuggläge som designen specificerar — full triggerpipeline igång, utan att dirigera något, beslut märkta retroaktivt — med en go-live-grind på ≥70 % märkt precision.
Kostnadsmodellen förutsätter ett fast antal på 500 utmatade tokens per tur, vilket undertrycker en verklig effekt: frontier-modeller genererar fler resonemangstokens, så den verkliga frontierpremien underskattas. Den modellerar också cache-värme på begäranivå som en enhetlig 1/N över nyckelslots; en viktad pool skulle använda Herfindahl-index Σw², och en enkelnyckelkanal skulle inte visa någon cache-fördel för sessionstillhörighet alls på kanallagret – även om modelllagrets pin fortfarande spelar roll för adaptiva strategier.
Vi körde inte uppströmsinferens, så inga anspråk på noggrannhet eller uppgiftsframgång görs. Hard-turn-täckning är en proxy för kvalitet och förutsätter att den starka modellen faktiskt är bättre på de turerna — rimligt för de konstruerade arketyperna, men inte verifierat här.
Slutligen mäter detta en gateways implementering. Turn-1-inlåsningsfelfunktionen bör generalisera till alla cache-medvetna routrar som låser fast sessioner, men de specifika siffrorna är egenskaper hos dessa tröskelvärden, dessa vikter och dessa priser.
9 Relaterat arbete
Routning på förfrågningsnivå är väl utforskat. FrugalGPTsup>[2]/sup> introducerade LLM-kaskaden — fråga den billiga modellen, poängsätt svaret, eskalera vid låg konfidens — och rapporterade upp till 98 % kostnadsminskning vid bibehållen noggrannhet. RouteLLMsup>[1]/sup> tränar routrar på preferensdata från Chatbot Arena och rapporterar 95 % av GPT-4-kvaliteten med 14 % anrop till starka modeller, med routrar som kan överföras mellan modellpar utan omträning. RouterArenasup>[3]/sup> tillhandahåller den saknade utvärderingsgrunden: 8 400 frågor över domäner och svårighetsnivåer, utvärderade med avseende på noggrannhet, kostnad, routingoptimalitet, robusthet och routeroverhead.
Det som ingen av dessa tar upp är konversationen som routingenhet. En kaskad eskalerar en förfrågan och glömmer bort; nästa tur kör återigen samma billiga modell på samma uppgift som nu är känd som svår. En preferenstränad router poängsätter en fråga, inte en trajektoria. Det gap som den här rapporten tar upp är vad en router bör komma ihåg mellan turer, hur länge, och vad som ska få ändra dess uppfattning — en fråga som bara blir brådskande när promptcachning gör det kostsamt att glömma.
OrcaRouter medföljer en in-tree RouterArena-testmiljö (eval/) som benchmarkar dess fem request-level-strategier — cheapest, quality, balanced, linucb, gated_adaptive — mot den öppna datamängden utan att modifiera det uppströms repositoryt. Den session-level-mekanism som beskrivs här är ortogonal mot och komponerbar med alla fem.
10 Slutsats
Prompt caching förändrade ekonomin för LLM-routning på ett sätt som routinglitteraturen inte har hunnit ikapp. När kontinuitet väl är värd en 10×-rabatt på merparten av dina inmatningstokens, måste en router låsa — och i samma ögonblick som den låser, fattar den sitt beslut vid den tur där den vet minst, och lever med det beslutet under resten av konversationen. Routning på begäranivå har inte det här problemet och betalar för det i form av cachemissar; naiv omvärdering per tur återinför missarna och lägger dessutom till en längdbiasartefakt.
Tiered stickiness resolves it by separating two things that look like one: which model serves this session (the pin, stable within a tier) and which tier this session belongs to (a small, capped, corroborated, expiring piece of state). In our replay that separation recovers 87 % of sessions whose difficulty is undetectable at turn 1, with zero false positives on 200 easy sessions, at 45 % of always-frontier cost — and holds a 20 % spend cap against clients actively trying to defeat it.
Mekanismens ärliga svagheter handlar om kalibrering, inte arkitektur: en svårighetströskel som återanvänds från en distribution den inte var inställd för, en feature-term som inte kan nå sin budget, och två steg av oundviklig räddningslatens. Det är hanterbart. Det arkitektoniska påståendet — att eskalationsminnet måste vara åtskilt från pinnen, att ingen oskarp signal får stegras ensam, och att tak måste binda klientens egen uttryckliga begäran eftersom klienten innehar token — är den del vi skulle behålla.
11 Källor
1. LMSYS Org. RouteLLM: An Open-Source Framework for Cost-Effective LLM Routing. a href="https://www.lmsys.org/blog/2024-07-01-routellm/">u>lmsys.org/blog/2024-07-01-routellm//u>/a> · code: a href="https://github.com/lm-sys/RouteLLM">u>github.com/lm-sys/RouteLLM/u>/a>
2. Chen, Zaharia & Zou. FrugalGPT: How to Use Large Language Models While Reducing Cost and Improving Performance. arXiv:2305.05176. a href="https://arxiv.org/abs/2305.05176">u>arxiv.org/abs/2305.05176/u>/a>
3. Lu, Liu, Yuan, Cui, Zhang, Liu & Xing. RouterArena: An Open Platform for Comprehensive Comparison of LLM Routers. arXiv:2510.00202. a href="https://arxiv.org/abs/2510.00202">u>arxiv.org/abs/2510.00202/u>/a>
4. OpenAI. Prompt Caching i API:et. a href="https://openai.com/index/api-prompt-caching/">u>openai.com/index/api-prompt-caching//u>/a> — automatisk cachelagring, prefix på minst 1 024 tokens i steg om 128 tokens, rensning efter 5–10 minuters inaktivitet, ≤1 timme; rabatt på cachelagrad indata efter modellnivå. Prissättning: a href="https://openai.com/api/pricing/">u>openai.com/api/pricing//u>/a>
5. Anthropic. Cachning av prompter. a href="https://platform.claude.com/docs/en/build-with-claude/prompt-caching">u>platform.claude.com/docs/en/build-with-claude/prompt-caching/u>/a> — cacheläsningar 0,1× basinmatning, skrivningar 1,25× (5 minuters TTL) eller 2× (1 timmes TTL), uppdateras vid användning. Prissättning: a href="https://www.anthropic.com/pricing">u>anthropic.com/pricing/u>/a>
6. DeepSeek. DeepSeek API introduces Context Caching on Disk. a href="https://api-docs.deepseek.com/news/news0802/">u>api-docs.deepseek.com/news/news0802//u>/a> — automatic, billed on actual cache hits, order-of-magnitude reduction on hit.
7. Google. Gemini API context caching. a href="https://ai.google.dev/gemini-api/docs/caching">u>ai.google.dev/gemini-api/docs/caching/u>/a> — implicit and explicit caching with storage-priced TTL.
8. OrcaRouter-källkod, detta repo: service/session_affinity.go (pins, TTL:er, tier-scoped nycklar) · service/session_escalation.go (motorn) · service/model_router.go:1374 (selectByStrategy: tier-avsmalning före pin-läsningen) · service/model_router_difficulty.go (vikter och tak) · service/model_router_delta.go (deltaextraherare) · service/escalation_strikes.go (producenter på requestsidan) · service/escalation_caps.go (andelstak) · docs/features/frontier-escalation.md (design, granskningsomgångar 1–4).
Reproducerbarhet. Mätuppställningen är ett Go-test i servicepaketet som kör ResolveEscalation / CommitEscalationDecision mot miniredis, plus en Python-pipeline för analys och figurer. Korpusgenereringen är seedad (rand.NewSource(20260814)) och hela körningen är deterministisk: 400 sessioner, 3 968 turer, tre experiment (huvudreplay, adversarial cap-körning, 9-punkters tröskelsvepning). Figurerna använder en CVD-validerad kategorisk palett; varje figur åtföljs av sin underliggande tabell. Inga produktionsdata nåddes, och ingen del av denna analys har committats till repositoryt.
Jämförda i den här artikeln1
Identifierat från den här artikeln · Benchmarks: Artificial Analysis · uppdateras dagligen
