|
| 1 | +--- |
| 2 | +title: "Reduce LLM Spend With Semantic Routing You Can Measure" |
| 3 | +category: "Deep Dive" |
| 4 | +toc: false |
| 5 | +publishDate: 2026-07-10 |
| 6 | +author: "Daneyon Hansen" |
| 7 | +description: "Use agentgateway, vLLM Semantic Router, and catalog-priced telemetry to reduce routine coding-model spend without routing every request to the cheapest model." |
| 8 | +--- |
| 9 | + |
| 10 | +I spend a lot of time in Go and Rust, where a quick "one more thing" in a |
| 11 | +long coding chat can turn a tidy refactor into an hour of debugging. I do not |
| 12 | +always remember to step down from the strongest model after the hard part is |
| 13 | +over. A few routine tests, configuration edits, and follow-up questions later, |
| 14 | +I have spent premium-model credits on work that did not need them. |
| 15 | + |
| 16 | +Sending every request to a cheaper model is not the answer either. The |
| 17 | +distributed-systems design, correctness work, and difficult debugging that |
| 18 | +show up in those same conversations are exactly where I want more capable help. |
| 19 | +I want the client to stay simple while the routing policy makes that choice. |
| 20 | + |
| 21 | +This example combines [vLLM Semantic Router (vSR)](https://vllm-semantic-router.com/) |
| 22 | +with [agentgateway](https://agentgateway.dev/) to send routine Go and Rust |
| 23 | +coding tasks to `gpt-5.4-nano` and escalate more complex correctness, |
| 24 | +distributed-systems, and deep-debugging work to `gpt-5.5`. I am not trying to |
| 25 | +claim perfect routing accuracy. I want a reproducible way to show lower spend |
| 26 | +without quietly routing every request to the cheapest tier. |
| 27 | + |
| 28 | +## Make the Decision Observable |
| 29 | + |
| 30 | +{{< reuse-image src="img/blog/cost-based-semantic-routing/semantic-routing-flow.svg" alt="Flow diagram: a coding agent sends model auto to agentgateway, vLLM Semantic Router selects either GPT-5.4 nano for routine coding or GPT-5.5 for complex coding, and agentgateway records catalog-priced telemetry" caption="One model name in, the appropriate model tier out - with the routing decision and realized cost visible at the gateway" >}} |
| 31 | + |
| 32 | +I keep the client side boring: it sends an OpenAI-compatible request with |
| 33 | +`model: "auto"`. An agentgateway policy sends the full request body to vSR. |
| 34 | +vSR evaluates semantic, complexity, keyword, context, and structure signals, |
| 35 | +then returns the selected model. Agentgateway forwards the request and records |
| 36 | +what happened. |
| 37 | + |
| 38 | +I do not ask vSR to use historic request cost as a classifier input. Cost is an |
| 39 | +outcome that agentgateway measures after the request. That keeps the policy |
| 40 | +explainable: the routing configuration says which work merits the stronger |
| 41 | +model, while the gateway shows what that decision actually cost. |
| 42 | + |
| 43 | +## Price the Outcome at the Gateway |
| 44 | + |
| 45 | +Token counts are useful, but my company needs prices to make a budget decision. |
| 46 | +Agentgateway loads a model cost catalog, calculates realized request cost, and |
| 47 | +exposes the data in metrics, logs, and traces. The [model cost catalog |
| 48 | +guide](https://agentgateway.dev/docs/kubernetes/latest/llm/cost-controls/costs/) explains how |
| 49 | +to generate and load the catalog with `agctl`. |
| 50 | + |
| 51 | +For this evaluation, I use the integrated [OpenTelemetry stack](https://agentgateway.dev/docs/kubernetes/main/observability/otel-stack/). |
| 52 | +It adds Prometheus, Loki, Tempo, the OpenTelemetry Collector, and Grafana so |
| 53 | +engineering and finance can inspect the same model-selection event: |
| 54 | + |
| 55 | +- Prometheus carries token, duration, catalog-lookup, and cost signals. |
| 56 | +- Logs and traces retain the selected model, request ID, latency, and cost. |
| 57 | +- Grafana puts spend next to the signals needed to explain a routing decision. |
| 58 | + |
| 59 | +## A Small, Reproducible Evaluation |
| 60 | + |
| 61 | +I built the [cost-based semantic routing demo](https://github.com/danehans/agentgateway-demos/tree/main/cost-based-semantic-routing) |
| 62 | +around a compact 24-prompt Go and Rust dataset. Half of the prompts are routine |
| 63 | +implementation or test work; the other half involve correctness or |
| 64 | +distributed-systems problems. I send every prompt through two lanes: |
| 65 | + |
| 66 | +| Lane | Purpose | |
| 67 | +|---|---| |
| 68 | +| `routed` | vSR selects `gpt-5.4-nano` or `gpt-5.5`. | |
| 69 | +| `always_expensive` | Every request uses `gpt-5.5`; the cost baseline. | |
| 70 | + |
| 71 | +Each evaluation run has an ID attached to every request. The runner uses it in |
| 72 | +its cost queries, which keeps unrelated traffic in the cluster out of the |
| 73 | +result. |
| 74 | + |
| 75 | +I deliberately leave out a forced-cheap lane. It would make the comparison |
| 76 | +larger, but it would not answer the question I care about: does routing save |
| 77 | +money while still escalating the work that deserves the expensive model? |
| 78 | + |
| 79 | +In a clean run on July 13, 2026, all 48 primary requests completed with exact |
| 80 | +model-catalog lookups. vSR selected `gpt-5.4-nano` for 16 requests and |
| 81 | +`gpt-5.5` for 8. Catalog-priced agentgateway metrics reported `$0.231896` for |
| 82 | +the routed lane versus `$0.405800` for the always-expensive lane, a **42.9% |
| 83 | +cost reduction**. Routed p50 latency was **3.96 seconds**, compared with |
| 84 | +**11.02 seconds** for the always-expensive lane. P95 was similar at 19.48 and |
| 85 | +20.12 seconds because the requests that still use GPT-5.5 naturally determine |
| 86 | +the tail. |
| 87 | + |
| 88 | + |
| 89 | + |
| 90 | +The chart gives me the guardrail I need. It reached 83.3% tier agreement on the |
| 91 | +checked-in coding sample and sent 8 of the 12 prompts labelled complex to |
| 92 | +GPT-5.5. This is not a claim of perfect model selection. I read it as |
| 93 | +evidence that the savings did not come from a blanket downgrade: one-third of |
| 94 | +the routed requests still used the expensive model, including most of the |
| 95 | +complex sample. |
| 96 | + |
| 97 | +That is the useful scope for this example. It keeps higher-risk work on a more |
| 98 | +capable model by policy and makes the exceptions visible. It is not a general |
| 99 | +answer-quality benchmark or a substitute for an application's own task-success |
| 100 | +and user-feedback measures. |
| 101 | + |
| 102 | +## Try It |
| 103 | + |
| 104 | +I made the demo do the setup work that I would otherwise forget or repeat by |
| 105 | +hand. Behind the scenes, it uses the merged [agentgateway semantic-routing |
| 106 | +example](https://github.com/agentgateway/agentgateway/tree/main/examples/llm-semantic-routing), |
| 107 | +creates or reuses a kind cluster, and installs agentgateway, vSR, a model cost |
| 108 | +catalog, and the OpenTelemetry stack. Before the primary requests run, it |
| 109 | +checks readiness, routing, catalog-priced metrics, logs, and traces. |
| 110 | + |
| 111 | +```bash |
| 112 | +git clone https://github.com/danehans/agentgateway-demos.git |
| 113 | +cd agentgateway-demos/cost-based-semantic-routing |
| 114 | + |
| 115 | +export OPENAI_API_KEY='sk-...' |
| 116 | +./demo.sh all --yes |
| 117 | +``` |
| 118 | + |
| 119 | +The default run sends 54 billable requests: two routing probes, four smoke-test |
| 120 | +requests, and 48 primary requests. It writes request-level JSONL, an |
| 121 | +evaluation-scoped Prometheus report, and an SVG chart under `results/`. |
| 122 | + |
| 123 | +When I want to change the policy, I edit the fetched vSR values, redeploy with |
| 124 | +`./demo.sh router`, and run `./demo.sh eval --yes` again. |
| 125 | + |
| 126 | +## From Example to Rollout |
| 127 | + |
| 128 | +I would not treat semantic routing as a magic cost switch. I would start with |
| 129 | +an explainable policy and compare it against sending every request to the |
| 130 | +expensive model. Then I would confirm that the policy uses both tiers and |
| 131 | +protects complex work, and tune it against the signals that matter to the |
| 132 | +application: task completion, feedback, retries, and escalation rates. |
| 133 | + |
| 134 | +Agentgateway gives me the accounting and observability plane; vSR makes the |
| 135 | +semantic decision. Together, they let me cut routine-model spend without |
| 136 | +hiding a blanket downgrade behind an attractive cost chart. |
| 137 | + |
| 138 | +## What's Next |
| 139 | + |
| 140 | +I see cost-based semantic routing as one part of an LLM cost-management |
| 141 | +practice. After validating a tiering policy, I can use |
| 142 | +[agentgateway cost controls](https://agentgateway.dev/docs/kubernetes/main/llm/cost-controls/) |
| 143 | +to attribute usage with virtual keys, observe realized spend by model and |
| 144 | +consumer, and enforce budget or spend limits where I need them. That turns a |
| 145 | +routing result into an operating model for keeping AI spend visible and under |
| 146 | +control. |
| 147 | + |
| 148 | +The agentgateway community is continuing to improve cost-based routing and the |
| 149 | +tools around it. Future work will make it easier to tune, operate, and measure |
| 150 | +model-tier decisions as real application traffic evolves. |
0 commit comments