Route

A calibrated cascade across model backends — a cheap or self-hosted model first, escalating to a stronger or more expensive one only when needed — with either a cost guarantee or an accuracy guarantee, instead of a static “always call the expensive model” or “always call the cheap one” rule.

Request

from cli_sdk import CLIClient, OpenAIBackend, Route, VLLMBackend
 
with CLIClient() as client:
    result = client.evaluate(
        context={"query": user_query},
        queries={
            "answer": Route(
                cascade=[
                    {"backend": VLLMBackend(model="meta-llama/Llama-3.3-70B-Instruct",
                                            base_url="http://internal-vllm:8000")},
                    {"backend": OpenAIBackend(model="gpt-4.1-2025-04-14")},
                ],
                calibration_profile="cost-routing-v1",
                guarantee="cost_budget",
                target_cents=0.4,
                alpha=0.10,
            ),
        },
    )
 
answer = result.answers["answer"]
print(answer.output)
print(answer.served_by, answer.escalated, answer.cost_cents)

Route does not need a backend argument: its backends come from cascade. The same holds for a Judge that declares a cascade. A request whose queries all declare their own cascade can omit backend; any other query in the same request still needs one.

Response

{
  "answer": {
    "type": "route",
    "output": "You can export invoices from Settings, then Billing.",
    "served_by": { "provider": "vllm", "model": "meta-llama/Llama-3.3-70B-Instruct" },
    "escalated": false,
    "cost_cents": 0.03,
    "guarantee": {
      "type": "cost_budget",
      "target_cents": 0.4,
      "alpha": 0.10,
      "method": "calibrated-cascade",
      "calibration_profile": "cost-routing-v1",
      "calibration_n": 900
    }
  }
}

Guarantee modes

guaranteeStatementCard
"cost_budget"P(cost per request≤target_cents)≥1−αP(\text{cost per request} \le \text{target\_cents}) \ge 1-\alphatype: "cost_budget" with target_cents and alpha
"accuracy"P(served answer is wrong)≤αP(\text{served answer is wrong}) \le \alpha, escalating whenever the cheap stage’s Venn-Abers interval is too wide to support that boundtype: "risk" with target equal to α\alpha

Both are marginal over requests exchangeable with the calibration set. A cost budget does not cap the cost of any single request: up to an α\alpha fraction of requests can exceed target_cents.

Calibrating a cascade

A Route profile is built from historical queries with every stage’s output and the correct answer recorded, so CLI can learn a calibrated per-query escalation rule rather than a single global confidence threshold. Add examples the same way as any other profile:

client.calibration_profiles.add_examples(
    "cost-routing-v1",
    examples=[
        {
            "context": {"query": q},
            "tier_outputs": {"cheap": cheap_out, "strong": strong_out},
            "label": gold_answer,
        }
        for q, cheap_out, strong_out, gold_answer in historical_data
    ],
)

See the cost routing guide for an end-to-end setup, including a spend monitor.

Answer attributes

AttributeTypeMeaning
outputAnyThe answer from the stage that served the request
served_bydictProvider and model of that stage
escalatedboolWhether the request moved past the first stage
cost_centsfloat | NoneCost of this request
guarantee, is_heuristicThe guarantee card, and whether it is heuristic

Parameters

ParameterTypeDescription
cascadelist[dict]Required, at least one stage. Each stage is {"backend": ...}, cheapest first.
calibration_profilestrRequired.
guarantee"cost_budget" | "accuracy"Default "cost_budget".
target_centsfloatRequired for "cost_budget". Per-request cost target.
alphafloat, optionalAllowed violation rate.