Routing and variants
See Variants and progressive rollout → for the conceptual model. This page is the field-level reference for the Decider, the Router element’s routing rules, canary, and the variant catalogue itself.
Decider
The Decider block routes a request across candidate upstreams based on content, rather than a fixed provider. Routing becomes a runtime decision instead of a fixed wire: a surface can send a coding question to one model and a creative-writing question to another, or fan a request out to several models at once for comparison, all without the caller knowing which upstream actually answered.
Set it with the Mode dropdown on the LLM node’s sidebar. Any choice other than LLM Direct adds a routing node to the canvas, labelled Decider, Comparer, or Summariser to match the mode, and the LLM node’s sidebar then shows Open decider…. Configure the routing node with Configure Decider, which opens the Decider Configuration editor.
- Decide LLM based on content gives a single best-fit answer: a small, fast router LLM inspects the request and picks one candidate to actually serve it.
- Compare output from multiple LLMs and Summarise output from multiple LLMs send every candidate the same request. Summarise merges the results into one answer, while Compare hands a person every answer to compare. Every candidate is billed, and a streaming request gets a buffered response.
- In Decide LLM based on content mode, keep the candidate list to a handful of clearly distinct options (e.g. “fast/cheap model” vs. “high-reasoning model”). More candidates give the router finer-grained choices, but also more room to misclassify a request.
- Order candidates with the option you’d want as a safe fallback listed first, since the first candidate is the fallback while Default candidate (fallback) is left at First candidate.
| Mode option | Canvas node | Behaviour |
|---|---|---|
| LLM Direct (default) | None | The surface sends each request straight to the LLM node’s provider. |
| Decide LLM based on content | Decider | The router LLM reads the request and picks one candidate, whose provider serves it. |
| Compare output from multiple LLMs | Comparer | Every candidate is called at once, and every answer is returned, each labelled with its candidate, with no merger and no Jury. |
| Summarise output from multiple LLMs | Summariser | Every candidate is called at once, then the Merger LLM consolidates the answers into one, which continues through the Jury and response guardrails as normal. |
Decider fields:
| Field | What it does | Default |
|---|---|---|
| Router LLM | The router LLM that makes the routing decision (typically small and fast), with the same provider, endpoint, model, and API key controls as other targets. Shown in Decide LLM based on content mode only, and required there. | Not set |
| Routing instructions | System prompt steering the routing decision. The candidate menu (id, name, description) is appended automatically. Reset to default restores the built-in prompt. | A built-in routing prompt |
| Disable thinking | Disable chain-of-thought for a reasoning router model, as a toggle. | Off |
| Candidates | Candidate upstreams, shown as the Candidates (N) list on the routing node’s sidebar with an Add candidate button. At least one is needed. In Compare and Summarise mode, Add candidate is disabled at 10 candidates. | One candidate, Candidate 1 |
| Default candidate (fallback) | Candidate used when the router’s choice is unknown or empty. Shown in Decide LLM based on content mode only. | First candidate |
Each candidate:
| Field | What it does | Default |
|---|---|---|
| Candidate id | Stable identifier the router returns to select this candidate; must be unique and non-empty. | candidate-N |
| Name | Human-readable name, shown in the router menu. | Candidate N |
| Description | Fed into the router menu so the model can reason about which upstream to pick. | Not set |
| LLM Configuration | Provider/model/endpoint for the main call when this candidate wins. | Not set |
Merger LLM
Shown in Summarise output from multiple LLMs mode. The merger produces one clean answer that continues through the normal Jury and guardrail pipeline.
| Field | What it does | Default |
|---|---|---|
| Merger LLM | The LLM that synthesises candidate answers into one. Required in Summarise mode. | Not set |
| Merge instructions | System prompt steering the merge. When empty, a built-in synthesis instruction is used. Candidate answers are appended automatically. | Empty |
| Disable thinking | Disable chain-of-thought for a reasoning merger model, as a toggle. | Off |
Validation: an enabled Decider needs at least one candidate with a unique, non-empty candidate id; a selected default candidate must be one of the candidates; Decide LLM based on content needs a Router LLM; Summarise output from multiple LLMs needs a Merger LLM.
Routing rules
Routing rules send a request to a variant by matching a request header, a top-level body field, or an attachment type. They live on the Router element, which you drag from the Inputs palette group onto the edge after the Access Point. The variant is chosen before authentication, policy, and guardrails run, so the chosen variant’s own model, Inputs elements, and guardrails govern the rest of the request.
Select the Router element to see its Enforce routing switch and a count of its rules, and use Configure routing rules… to open the full-page editor, where Add routing rule adds a row. Rules apply while Enforce routing is on, and are kept when you turn it off. Routing rules belong to the base surface, not to a variant.
- Header is the most explicit signal, usable when the caller (or a proxy in front of them) can set a custom header.
- Body field keys off something already present in the request body, like a caller-supplied tag.
- Attachment type gives deterministic, LLM-free routing to a variant whose model accepts that input: for example, sending any request carrying an image straight to a variant with a vision-capable model and an Image File element.
| Field | What it does | Default |
|---|---|---|
| Enforce routing | Switch on the Router element’s sidebar. Turns rule-based routing on or off. | On when the element is added |
| Kind | The first dropdown on each rule row: Header, Body field, or Attachment type. | Header |
| Name and value | For Header and Body field, the header name or field name, and the value it must equal. | Not set |
| Attachment type | For Attachment type, one of Image file, Audio file, Document file, or Realtime voice (WebSocket). Plain text has no rule of its own and falls through like any unmatched request. | Image file |
| → variant | The variant a matching request goes to. The list opens on Base surface: choose a named variant on every rule, because the surface saves with Enforce routing on only when each rule names one. | Base surface |
Match kinds:
| Kind | Matches when |
|---|---|
| Header | The named request header equals the value. The header name matches regardless of case. |
| Body field | A top-level request-body string field equals the value. |
| Attachment type | The request carries that kind of attachment, detected from the request body. Realtime voice (WebSocket) matches a realtime session on the /v1/realtime path. |
How a chat request picks its variant:
- An explicit
$aliasin the route wins first. - Otherwise, the first matching rule wins and sends the request to its variant.
- A request that matches no rule falls through to the canary split, and then to the surface’s default: the base surface, or the variant promoted to default.
A realtime session uses the first Realtime voice (WebSocket) rule that names a variant. Otherwise it goes to the surface’s default.
Validation: while Enforce routing is on, every rule must name a variant that exists on the surface, and a Header or Body field rule needs both a name and a value.
Canary
Canary implements an A/B traffic split across a surface’s variants, letting you prove a new model or variant is safe with real traffic before committing to it fully. Instead of an all-or-nothing cutover, a small percentage of requests see the new option while the rest keep hitting your known-good baseline. It’s set in the Canary / A-B traffic split section of the Surface Configuration editor, and belongs to the base surface, not to a variant.
- Start small (5–10% is a reasonable first split) and watch the Monitoring tab’s error rate, latency, and cost for that variant against the baseline.
- Once its telemetry looks comparable or better, increase the split in steps rather than jumping straight to an even or majority share, so a regression only ever affects a small slice of traffic before you notice it.
| Field | What it does | Default |
|---|---|---|
| Enable canary split | Master switch. When on, a request that no $alias or routing rule has already placed is sent to a target by weight. | Off |
| Splits | One row per target, labelled Base surface or with the variant’s alias, each with a percentage input. Entering a value rebalances the others so they always total 100%. With no variants yet, the section reads “Add variants to split traffic.” | Base surface 100%, each variant 0% |
Turning the canary split off keeps the stored percentages, so turning it back on restores the previous split.
Validation: an enabled canary needs a positive total weight, and every named variant must exist on the surface.
Variants
Each surface carries a catalogue of named variants, edited on the Variants panel. A variant is addressed at {route}$alias/.... The base surface is the default until you select Default on a variant, which promotes that variant to receive every request that no $alias, routing rule, or canary split has placed.
Each variant:
| Field | What it does | Default |
|---|---|---|
| Alias | URL-safe alias used in {route}$alias/.... Must be lowercase letters, digits, and dashes, 1–32 characters. | aliasN |
| Name | Human-readable name shown in the dashboard. | aliasN |
| Description | Free-text description. | Not set |
| Enabled | Toggle. A request that selects a disabled variant gets HTTP 503. The default variant stays enabled; to disable it, make another variant the default first. | On |
| Default | Makes this variant the surface’s default. | Off |
Edit a variant’s own settings by switching to it with the variant switcher on the canvas and editing its own copies of the surface’s elements. A variant keeps its own copy of the settings it covers, so a later change to the base surface doesn’t flow into it. Its identity and routing fields (id, name, listener, route, metrics and log settings, and integrations) stay those of the base surface, so a variant is reachable at the same base route and follows the same metrics and log settings.
A variant keeps its own copy of these settings:
| Setting | What it covers |
|---|---|
| LLM | The upstream: provider, model, endpoint, and API key. |
| Parameter override policy | The model and parameter override policies, including the reasoning effort level. |
| Upstream headers | The extra request headers sent to the provider, each value read from a secret. See Upstream headers. |
| Prompt Guard, Judge, Jury | The corresponding guardrail block. |
| OPA Policy | The surface’s Rego policy attachment. |
| Rate Limit | The request rate limit. |
| Cost tracking | The cost-tracking state and any price override, in USD per 1K tokens, set in the surface’s Config JSON view. |
| Audio File, Audio Stream, Image File, Document File | The variant’s own Inputs elements, so one variant can accept realtime voice or images while its siblings stay chat-only. |
| Canvas | The variant’s own canvas layout. |
Related
- Guardrails: The provider/model/endpoint target shape shared by Decider candidates, Judge, and Jury.
- Resilience and caching: Failover and load-balancing targets, which also use that shape.
- Variants and progressive rollout: The conceptual model for routing rules, canary, and variants.
- Inputs and modalities: How the Router sends each attachment type to a variant whose model accepts it.
- LLM drift detection: How a replay evaluation’s target surface or variant compares to routing rules and canary as a way to evaluate a change.
Glad to hear it! Please tell us how we can improve more.
Sorry to hear that. Please tell us how we can improve.
Thank you for sharing your feedback so we can improve your experience.