Escalation-Router Routing
Escalation-Router Routing
Escalation-router routing starts each conversation on a cheaper weak model.
An LLM judge watches how the work progresses and moves the conversation to a
more capable strong model when it detects sustained, recoverable trouble.
After escalation, the conversation stays on the strong tier for the rest of
the task.
Use it for multi-turn agent workloads where a weak model can handle routine work but may need rescue after repeated errors, loops, drift, false progress, or premature completion. Unlike LLM Classifier Routing, which predicts how difficult a request looks, escalation routing judges whether the run is actually going well.
How it works
The router keeps one state value per conversation: whether that conversation has escalated. Conversations are identified from the stable system prompt and first user message, using the same bounded in-memory store described in Sticky Routing.
For each turn, Switchyard:
- Checks the conversation latch. A latched conversation routes to
strongwithout calling the judge again. - Routes an unlatched conversation to
weak. Beforejudge.min_turn(default3), it skips the judge because there is too little trajectory to assess. - Gives the judge a bounded summary containing the system and first-user anchors, recent messages, and a coverage note for omitted history.
- Parses the judge’s structured
escalatedecision. When the configured confirmation policy is satisfied, Switchyard pins the conversation tostrongand uses the strong model for the current turn. - Fails open to
weakwhen the judge times out, errors, or returns invalid output. A judge failure never creates a strong-tier pin.
The routing decision for one turn is:
Confirmation policy
judge.confirmations controls how many positive verdicts are required before
the strong-tier latch fires:
confirmations: 1is the default and escalates on the first positive verdict.confirmations: 2withconfirmation_window: 1requires positive verdicts on consecutive judged turns.- A larger
confirmation_windowallows recurring trouble to confirm even when negative verdicts occur between positive ones. A positive verdict remains live across at mostconfirmation_window - 1intervening negative verdicts.
A judge failure provides no evidence either way: it routes the turn to weak without clearing an existing confirmation streak.
Configure an escalation route
Configure escalation routing in the routes: bundle loaded by
--routing-profiles.
Run the route as a standalone proxy:
The route ID (agent-escalation) is the model ID clients select to use the
router. The strong and weak model IDs are also registered as direct
passthrough choices. The judge is internal to the route and is not exposed as
a client-selectable model.
If the selected tier exceeds its context window, Switchyard retries once on
fallback_target_on_evict, which must match one of the configured tier ids
(strong / weak unless the targets set their own id). See
Context-Window Handling.
Useful options
Observability
Read the standard routing stats endpoint:
The snapshot reports per-model calls, tokens, latency, and cost for the strong and weak tiers. Judge calls are recorded in the classifier stats bucket so their token cost, latency, and errors remain visible as routing overhead.
With judge.dump_verdicts: true (off by default), each judged turn also
writes an escalation_verdict={...} JSON line to server stderr. The record
includes the decision, reason, turn, confirmation state, and judge latency.
After the latch fires, later turns skip the judge and report the pinned
routing source in request metadata.
Repeated benchmark trials
By default, the session key is derived from the system prompt and first user message. Repeated trials of the same task against one long-lived server can therefore share a latch: if the first trial escalates, later trials may start on strong.
Use one of these isolation strategies:
- Start a fresh Switchyard process for each trial set.
- Set
session_key_depth: Nto extend the key with the firstNmessages after the initial user message. This only separates trials when those early trajectories differ, so it requires nonzero sampling temperature.
Keep session_key_depth: 0 for normal traffic. Context compaction or other
mid-session prefix rewrites can change a deep key and lose the existing latch.
When not to use escalation routing
- One-shot requests. There is no trajectory to judge. Use LLM Classifier Routing when the initial request should determine the tier.
- Fixed traffic experiments. Use Random Routing for A/B splits and gradual traffic ramps.
- Per-turn stage optimization. Use Stage-Router Routing when tool-result signals should move individual turns in both directions.
- Latency-critical traffic. Eligible unlatched turns wait for the judge before the selected backend call.
- Long-range failure cycles. The judge only sees a bounded recent window; cycles longer than that window may be missed.
Related
- Routing Overview: compare all supported routing strategies.
- Sticky Routing: session-key derivation and affinity behavior.
- Architecture: the end-to-end request lifecycle and system boundaries.