Business

Routing Requests by Cost and Quality: Rules You Can Audit

Antonio Evans9 min read

A diagram showing a request entering a router that reads its cost and quality tags, then directs it to one of three model lanes (cheap, balanced, strong).
Key points

Key points

  1. 1Attach a task type and a quality tier to every request, then let a written rule pick the model.
  2. 2Compute the maximum acceptable cost per request from token counts and the published price before you route anything.
  3. 3Always define a fallback to a stronger model when the cheap route fails validation or returns low confidence.
  4. 4Log the tags, chosen model, tokens, computed cost and outcome for every request so the savings claim survives review.

Why routing needs a cost tag before it needs a model

A router is only as good as the number it optimizes against. If you cannot say what one request of a given task should cost, you are not routing, you are guessing with extra steps. The finance-side literature is blunt about this: AI cost tracking has to start at the request level, because invoice totals cannot tell you which feature or workflow produced the spend the cost tracking guide from Mavvrik. DoiT's survey of 500 finance leaders found only 15 percent could calculate AI ROI without significant bottlenecks, and the recurring cause was attribution, not patience DoiT's ROI measurement writeup.

That is the core insight this article builds on: routing is downstream of measurement. A routing table that maps "summarization, low quality" to a cheap model is elegant, but if you never computed the expected cost of a summarization request, you cannot tell whether the cheap route saved 60 percent or 6 percent.

So the order of work is: define task types, tag requests, compute expected cost per request per route, write the rules, then log and audit. Skipping the third step is the most common failure.

There is a second reason to be careful. RAND interviewed 65 experienced data scientists and engineers and found that a leading cause of AI project failure is deploying models optimized for the wrong metric, or ones that do not fit the surrounding workflow RAND's root cause analysis. A router that minimizes cost while quietly increasing rework is exactly that anti-pattern. Your routing metric has to be cost per accepted outcome, not cost per call.

Step 1: Define task types and quality tiers

Two tags are enough to start. More than two invites a rule explosion nobody can audit.

The task type names the work: classification, extraction, summarization, drafting, code generation, retrieval-augmented question answering, and so on. Task type matters because the input/output token ratio and the tolerance for error differ enormously between them. A classification call might be 800 input tokens and 5 output tokens; a draft generation call might be 1,000 input and 4,000 output. The same model can be cheap for one and expensive for the other.

The quality tier names the consequence of being wrong: low, medium, high. Define each tier with a testable condition rather than a feeling.

TierTest for assigning itDefault route behavior
LowError is caught by a deterministic check or a human reviewer before it reaches a customerCheapest model that passes the offline eval
MediumError reaches a user but is recoverable (a wrong summary, a rejected draft)Mid-tier model, sample audit at 5 percent
HighError reaches a customer, a contract, or production code with no review stepStrongest approved model, no cost ceiling

The important discipline is that the tier is assigned by the caller, not inferred by the router. The caller knows whether the output goes to a customer or into a scratch file. Inworld's routing guidance makes the same point: conditions should have a product reason and an observable outcome, and you should avoid rules that encode assumptions you never measured, such as "long prompt means expensive model" Inworld's routing strategies.

A useful convention is to make the tier part of the span attributes from the first day, so you can slice cost by tier later without a migration.

Step 2: Compute the cost ceiling per request

Before writing any rule, calculate what a request of each task type should cost on each candidate model. The arithmetic is simple but easy to get wrong by a factor of ten, usually through unit errors or forgotten retries.

The base formula for an uncached request is:

cost = (input_tokens / 1_000_000) × input_rate
     + (output_tokens / 1_000_000) × output_rate

Then multiply by billed attempts, not user-visible jobs. A document pipeline that makes three model calls per document has three charges before any retry, and a retry is another billable attempt unless the provider says otherwise BenchLM's token pricing guide.

Token counts also vary by provider. The same text can tokenize differently across vendors, so a prompt measured on one model is an estimate, not a measurement, on another Silicon Data's cost per token guide. Measure with the target model's own tokenizer before you commit to a ceiling.

Here is a worked example using the synthetic workloads and dated list rates from BenchLM's calculator, which is a useful template even if your own rates differ:

Workload (monthly)Calls per unitInputOutputMonthly token volume
Retrieval and summarization, 100,000 requests18,000800800M in / 80M out
Draft generation, 10,000 drafts11,0004,00010M in / 40M out
Structured extraction, 10,000 documents31,50015045M in / 4.5M out

Plug your own published rates into the formula for each row and you get a per-workload budget. BenchLM's own comparison, computed from rates it read on a stated date, put the same retrieval workload at $168 to $2,560 per month depending on the model and, for one provider, the time of day BenchLM's dated rate table. That spread is your routing headroom. If your ceiling for a low-tier summarization request is set below the cheapest option's computed cost, your rule is broken before it ships.

LiteLLM ships a pricing calculator that does this arithmetic interactively, showing per-request, daily and monthly cost from input tokens, output tokens and request volume LiteLLM's pricing calculator docs. Whatever tool you use, write the resulting ceiling into the rule, not into a spreadsheet nobody opens.

Step 3: Write rules with explicit thresholds and fallbacks

A routing rule should be readable by someone who is not the author. The cleanest form is a table with a default and a small number of overrides.

routes:
  - match: {task: classification, tier: low}
    model: cheap-fast
    max_cost_usd_per_request: 0.00012
    validate: {schema: label_enum, confidence_min: 0.6}
    fallback: mid-tier

  - match: {task: summarization, tier: medium}
    model: mid-tier
    max_cost_usd_per_request: 0.0040
    validate: {schema: summary_length, sampling: 0.05}
    fallback: strong-tier

  - match: {task: code_generation, tier: high}
    model: strong-tier
    max_cost_usd_per_request: null   # no ceiling, quality wins
    validate: {tests: must_pass}
    fallback: none

Three design choices in that block matter more than the syntax.

First, every cheap route has a validation step. Validation is what turns a cost decision into a quality decision. For classification, it is a schema check and a confidence floor. For summarization, it is a length bound plus a sample audit. For code, it is the test suite.

Second, every route with a fallback has a bound on how many attempts it can make. Inworld separates error fallback (move after an explicit failure) from latency fallback (move when the model has not started responding within a threshold), and warns that the latter can create simultaneous or sequential spend Inworld's failover guidance. Record total time and total cost across attempts, not just the winning attempt.

Third, the high tier has no cost ceiling. Writing max_cost_usd_per_request: null is a deliberate act of documentation. It tells an auditor that the absence of a cap is a decision, not an oversight.

A comparison of the three common routing patterns helps when you are choosing:

PatternDecision inputMain riskWhere it fits
Static ruleTask and tier tagsStale thresholdsMost teams, most of the time
Automatic selectionPrice, latency or benchmarkOptimizes a proxy, not your outcomeBroad, low-risk, well-instrumented workloads
Traffic splitWeighted or sticky assignmentUnmeasured quality driftValidating a rule change before rollout

For a first deployment, the static rule wins on auditability. Inworld's own conclusion is that a transparent static rule often beats a complex selector the team cannot explain.

Step 4: Instrument every request

Routing without logs is unprovable. The OpenTelemetry GenAI semantic conventions give you a vendor-neutral shape for this, and the SRE guidance is to track attributes such as model, token counts, latency and cost per call, because LLM billing is per token rather than per request OpenTelemetry for LLMs from OpenObserve. PostHog's documentation on calculating LLM costs shows the same mechanics at the product-analytics layer PostHog's cost calculation docs.

At minimum, emit one event per request with these fields:

  • task_type and quality_tier (the tags the caller set)
  • route_matched and model_selected
  • input_tokens, output_tokens, cached_input_tokens
  • computed_cost_usd, calculated in your code from the rate table you stored
  • validation_result and fallback_used (true or false, plus the reason)
  • accepted (the outcome that actually matters)

Storing the rate table alongside the event is the trick most teams miss. If you only store the computed cost, a rate change months later makes your history unauditable. If you store the rate you applied, anyone can recompute the number.

Mavvrik's three-layer model is a good mental checklist for what comes next: a usage layer (what happened inside the system), an ownership layer (team, product, feature, customer) and a finance layer (allocation rule, budget, cost-to-serve) Mavvrik's cost tracking guide. Routing gives you the usage layer almost for free. The ownership layer is what lets you say "the support classifier saved this much and the drafting tool did not."

One warning from the same source is worth repeating: AI cost tracking starts with usage events and expands outward into infrastructure, so model costs are not the whole bill. A route that is cheap on tokens but triggers a long vector retrieval is not cheap.

Step 5: Review savings against quality, not against spend alone

The review meeting should compare three numbers per route, and refuse to discuss any of them alone.

Cost per accepted outcome. Total route cost divided by the count of outputs that passed validation or were accepted downstream. This is the number that matters, and it is the one DoiT argues is missing from most ROI conversations DoiT.

Acceptance rate, and rework rate. If the cheap route's acceptance rate drops enough, savings evaporate. The concrete trap is documented in AI ROI guidance: if AI produces a draft in 20 minutes instead of 60 but you spend 25 minutes fixing errors, the saving is 15 minutes, not 40 the AI ROI metrics rundown from Naitive. Apply the identical logic to routing. Compare cost per accepted output, not cost per call.

Fallback rate. The share of requests that fell back to the stronger model. A high fallback rate means the cheap route is a toll you pay on the way to the expensive one, and you should either fix its validation or delete it.

Waydev's coding-tool ROI framework offers a useful unit metric you can borrow: cost per merged pull request. Their worked example divides total AI spend by merged PRs to get a single number that finance and engineering can both read Waydev's AI coding ROI guide. The routing analog is cost per accepted task, and the same caution applies: if cost per accepted task falls while cycle time rises, you have moved the work, not removed it.

A simple review table, filled monthly, keeps the conversation honest:

RouteRequestsCostCost per acceptedAcceptanceFallback rateVerdict
classification / low412,000$41$0.0001297.8%1.1%keep
summarization / medium61,000$198$0.004191.2%8.4%tighten validation
drafting / medium9,400$74$0.011884.0%21.0%delete or re-tier

That last row is the decision rule this whole article is built around. A route with a high fallback rate and a weak acceptance rate is not a saving. It is a second bill with extra latency. Delete it, or move the task to a higher tier and stop pretending the cheap route works.

If the numbers are new to your team and the exercise needs a second pair of eyes before you commit engineering time, a free 30 minute AI discovery call is a low-commitment way to pressure-test the plan against your own workloads Quanta Consulting.

What to do when you run more than one model

The rules above assume you can call several models from one place and see one bill. That is the operational prerequisite, and it is where a lot of teams stall: three vendors, three SDKs, three rate tables to keep in sync. A single OpenAI-compatible endpoint that covers text, image, audio and embedding models, with prepaid pricing in US dollars, removes the integration work and leaves you with the routing logic itself Quanta Inference. Keep the rate table in your own code regardless of the gateway, because the audit depends on you storing the rate you applied.

For teams that want the routing policy reviewed against a specific line of business rather than as a general exercise, Quanta's domain experts read your context and return finished deliverables, which is a reasonable way to get a second opinion on thresholds without a long consulting engagement Quanta Experts.

FAQ

FAQ

Do I need a router to save money, or are tags enough?

Tags alone do not save anything; the rule that maps a tag to a model does. But tags are the prerequisite, because without them every request looks the same and your only lever is a global default. Start with tags and a two-row rule table, and add routing complexity only when the logs show a route whose cost per accepted outcome justifies the maintenance.

How do I pick the cost ceiling for a route?

Compute the expected request cost on each candidate model using the formula in step 2, measured with that model's tokenizer, then set the ceiling slightly above the cheapest candidate that passes your offline eval. If the ceiling is below the computed cost of every candidate, the rule is wrong, not the model.

What should happen when the cheap model fails validation?

It should fall back to the next tier up, and the request should be logged with fallback_used: true and a reason code. Cap the number of attempts so a bad route cannot spend without limit, and include the fallback cost in the route's total when you review savings. A route with a high fallback rate is a candidate for deletion, not tuning.

How many models should a routing table reference?

Two or three per task type is usually enough: a cheap default, a mid tier and a strong tier. Every additional model multiplies your rate table, your eval coverage and your failure modes. Inworld's guidance is to restrict the eligible set for any workload where tool behavior or data policy is strict Inworld.

How often should the rules be reviewed?

Monthly for the first quarter, then quarterly. The review should compare cost per accepted outcome, acceptance rate and fallback rate against the prior period, and any threshold change should go through a traffic split before it applies to all traffic. Rate changes and tokenizer changes are the two events most likely to make an old rule quietly wrong.

Sources

Sources

  1. How to Track AI Costs in 2026: Usage Logs to Cost-to-Serve
  2. How to Measure AI ROI When You Can't See Where Tokens ...
  3. The Root Causes of Failure for Artificial Intelligence Projects and ...
  4. LLM Routing Strategies: Conditional Routing, Failover, and ...
  5. How LLM Token Pricing Works: A Complete Guide to API ...
  6. Understanding LLM Cost Per Token: A 2026 Practical Guide
  7. Pricing Calculator (Cost Estimation)
  8. OpenTelemetry for LLMs: Complete SRE Guide for 2026
  9. Calculating LLM costs - Docs
  10. AI ROI Metrics: Top 10 KPIs to Track
  11. How to measure the ROI of AI coding tools - Waydev
About the author

About the author

Antonio Evans
Antonio Evans

Antonio Evans is the founder of Quanta Intelligence and a fractional CTO who builds HIPAA-ready AI systems for health and life-science companies. Before that he was technical co-founder of FriendsEAT for twenty years, CEO of Socialdraft, and a data engineer at IBM. Antonio lives with his dog Santino in Lisbon, Portugal.

All articles