Skip to main content
Semantic routing directs queries to the most appropriate handler, model, or pipeline based on content understanding. Think of it as a smart receptionist at a hospital: instead of sending every patient to the same doctor, they assess symptoms and route to the right specialist. Sending “what’s 2+2?” to GPT-4o is like sending a paper cut patient to the ER — expensive and wasteful. Semantic routing fixes this. The payoff is significant: teams that implement intelligent routing typically see 40-70% cost reductions with no quality loss on simple queries, because the cheap model handles them just fine.

Intent Classification

Embedding-Based Classification

LLM-Based Classification

Query Routing

Multi-Model Router

The core insight: not every query needs your most expensive model. “What’s 2+2?” doesn’t need GPT-4o, but “Design a distributed system for…” does. Routing by complexity can cut your API bill by 50-70% with negligible quality loss on the queries that get routed down. Route queries to the most appropriate model based on complexity:

Topic-Based Routing

Routing Approach Comparison

Decision framework for choosing your routing approach:
  • Under 10 intents with clear boundaries (billing, support, sales): Embedding-based. Fast, cheap, and the centroid approach handles it well.
  • Overlapping intents or nuanced classification (“is this a complaint or a feature request?”): LLM-based. The model’s reasoning catches subtlety that cosine similarity misses.
  • Cost-sensitive at high volume (10K+ queries/day): Hybrid. Use regex/keyword rules to catch 60-70% of queries instantly, then route the ambiguous remainder through embeddings.
  • Multi-model routing (choosing between GPT-4o-mini, GPT-4o, Claude): Two-stage. First classify complexity with a fast model, then route based on the classification. The routing call should never cost more than the cheapest model in your fleet.

Cost-Optimized Routing

In production, you’re optimizing three variables simultaneously: cost, latency, and quality. This router makes those trade-offs explicit and configurable rather than using one model for everything and hoping for the best.

Hybrid Routing

Combine multiple routing strategies:
Routing Best Practices
  • Use fast models for routing decisions themselves — if your router uses GPT-4o to decide which model to call, the routing overhead defeats the purpose. Use GPT-4o-mini or embeddings.
  • Cache routing decisions — similar queries should route the same way. Hash the query and cache for 5-10 minutes.
  • Monitor routing accuracy — track cases where the cheap model produced bad answers. This is your “mis-routing” rate.
  • Implement fallbacks — if the fast model returns low confidence, automatically escalate to the powerful model. Don’t make users retry.
  • Track cost savings — measure actual cost with routing vs. what it would have been with the powerful model for everything. This justifies the engineering investment.
  • Pitfall to avoid: Don’t over-engineer routing for small scale. If you’re under $100/month in API costs, just use one good model. Routing ROI kicks in at scale.

Practice Exercise

Build a production routing system that:
  1. Classifies queries by intent and complexity
  2. Routes to appropriate models based on requirements
  3. Optimizes for cost while meeting quality thresholds
  4. Tracks routing decisions and outcomes
  5. Adapts routing rules based on feedback
Focus on:
  • Low-latency routing decisions
  • Graceful degradation on failures
  • A/B testing different routing strategies
  • Cost and quality monitoring

Interview Deep-Dive

Strong Answer:
  • First, I would instrument every request to capture the query text, the model used, the latency, the token count, and a quality signal — either explicit user feedback (thumbs up/down) or an automated LLM-as-judge evaluation on a sampled subset. You cannot optimize what you do not measure, and without a quality baseline, any cost reduction is a gamble.
  • The routing layer itself has two stages. Stage one is a fast classifier — either an embedding-based centroid approach or a fine-tuned small model — that buckets queries into complexity tiers: simple, moderate, and complex. The classifier must run on something cheap like text-embedding-3-small or gpt-4o-mini, never on the expensive model you are trying to avoid. If the classifier itself costs significant tokens, you have defeated the purpose.
  • Stage two maps tiers to models: simple queries go to gpt-4o-mini (or an even cheaper model), moderate to gpt-4o, and complex to the most capable model available. The key insight is that 50-70% of production queries in most customer-facing products are simple — greetings, FAQ-type questions, single-fact lookups — and the cheap model handles them indistinguishably from the expensive one.
  • I would deploy this with a shadow mode first: route all queries to both the current model and the proposed cheaper model, then compare outputs using an automated eval. This gives you a real mis-routing rate before you flip any traffic. A mis-routing rate above 5% means your classifier needs more training examples or a different threshold.
  • The fallback mechanism is critical. If the cheap model returns low confidence or the user re-asks the same question, automatically escalate to the powerful model. This catch-net prevents the worst user experiences while still capturing the cost savings on the majority of traffic.
Follow-up: How do you handle the cold-start problem — when you have no historical data to train the classifier on?Start with a rule-based heuristic as a bootstrap: queries under 20 tokens with no technical jargon go to the cheap model, everything else goes to the expensive one. Log everything. After a week of production traffic, you have enough labeled data to train an embedding-based classifier. The heuristic is intentionally conservative — it routes more to the expensive model than necessary, which means quality stays high while you gather data. Once the classifier is trained, A/B test it against the heuristic and compare both cost and quality metrics. In my experience, even the crude heuristic captures 20-30% savings because so many production queries are genuinely simple.
Strong Answer:
  • The most insidious failure mode is latency amplification. If you use gpt-4o-mini to classify before routing, you have added 200-400ms of latency to every single request. For a chat application where perceived responsiveness matters, this overhead can negate the UX benefit of streaming. The fix is to use embeddings for classification instead — a single embedding call is 50ms and does not require a full LLM inference pass.
  • Second failure mode: the classifier and the router create a circular dependency. The LLM-based classifier is itself an API call that can fail, rate-limit, or time out. If your routing layer goes down, all queries stall. You need a fast fallback — if classification fails, default to the middle-tier model. Never default to the cheapest model on failure, because that degrades quality silently without any signal.
  • Third: confidence miscalibration. LLMs are notoriously overconfident when asked to self-rate. If you ask gpt-4o-mini “how complex is this query?” and it says 0.95 confidence that it is simple, that 0.95 is not a real probability. It is a language pattern. You cannot trust model-generated confidence scores for routing thresholds without calibrating them against actual outcomes.
  • The architecture fundamentally breaks down when query complexity is not predictable from the query text alone. For instance, “Tell me about the Johnson account” looks simple, but the answer might require reasoning across five documents in a RAG system. Complexity is often a function of the retrieval results, not the query. In these cases, you need a two-phase approach: do a cheap retrieval first, assess the complexity of the retrieved context, then route.
  • Finally, adversarial or ambiguous inputs — sarcasm, multi-intent queries (“book me a flight and also explain quantum physics”), or queries in mixed languages — tend to confuse simple classifiers. These edge cases get mis-routed to the cheap model and produce visibly bad outputs.
Follow-up: You mentioned embedding-based classification as faster than LLM-based. What is the practical accuracy trade-off, and when would you accept LLM-based classification despite the latency?In my experience, embedding centroids with 5-10 examples per intent achieve 85-90% accuracy on well-separated intents like “billing vs. technical support vs. product info.” LLM-based classification gets you to 95%+ because it can reason about nuance — but at 5-10x the latency cost. I would use LLM-based classification only for high-stakes routing decisions where a mis-route has significant consequences, like routing a compliance question to a model that hallucinates, versus routing a casual greeting to a slightly less capable model. For most consumer applications, the embedding approach is the right trade-off. You can also run LLM classification asynchronously as a quality check — route immediately using embeddings, but log the LLM classification result for monitoring and retraining the embedding classifier over time.
Strong Answer:
  • The core metric is the “routing accuracy rate” — the percentage of queries where the routed model produced an answer of equivalent or better quality compared to always using the most expensive model. You measure this by running an offline evaluation: take a random sample of routed queries (say 500 per week), re-run them through the expensive model, and compare outputs using an LLM-as-judge or human eval. If the cheap-model answers are rated equally good 95%+ of the time for queries routed to the cheap tier, your router is working.
  • Second, track the “escalation rate” — queries where the user re-asked the same question, gave a thumbs-down, or where a downstream quality check flagged the response. A rising escalation rate for the cheap tier is the earliest signal of router degradation. I would set up an alert if the weekly escalation rate for any tier increases by more than 2 percentage points.
  • Third, build a routing distribution dashboard that shows: what percentage of queries go to each tier, the average cost per query per tier, the p50/p95 latency per tier, and the total monthly cost. If the distribution shifts suddenly (e.g., 80% going to the cheap model when it was 60% last week), something changed — either user behavior shifted or the classifier drifted.
  • Fourth, log every routing decision with the classifier’s confidence score and the actual model used. This lets you build confusion matrices: for queries the classifier labeled “simple” that users rated poorly, what were the common patterns? These misclassified queries become new training examples for the next version of the classifier.
  • Finally, run a continuous A/B test where 5% of traffic bypasses the router and goes to the expensive model regardless. This control group gives you a live quality benchmark to compare against routed traffic. If the control group’s quality metrics are significantly better, the router is losing value somewhere.
Follow-up: The A/B test shows routed traffic has 3% worse quality ratings than the control group. Is that acceptable, and how do you decide?It depends entirely on the cost savings and the domain. If routing saves $20K/month and the 3% quality gap is on non-critical queries (casual chat, simple lookups), most businesses would accept that trade-off happily. But if the 3% gap concentrates in high-value interactions — enterprise customer queries, medical advice, legal analysis — even 1% degradation can be unacceptable because the cost of a bad answer far exceeds the API savings. I would segment the quality gap by query type and user tier. If premium users see any degradation, tighten their routing to always use the powerful model. If free-tier users see a 3% gap on casual queries, that is likely acceptable. The decision is a product call, not an engineering call — but engineering’s job is to provide the segmented data so the product team can make an informed decision.
Strong Answer:
  • Embedding-based classification computes a vector for the query and compares it against pre-computed intent centroids using cosine similarity. It is fast (one embedding API call, ~50ms), cheap (embedding models cost 10-100x less than chat models), and deterministic given the same model version. The trade-off is that it cannot reason about context, negation, or multi-intent queries. “I do NOT want to cancel my subscription” has high cosine similarity to “cancel my subscription” because the embedding captures topic proximity, not logical negation.
  • LLM-based classification sends the query to a chat model with a prompt listing the available intents and asks it to classify. It handles nuance, negation, and ambiguity well because it reasons about the full meaning. But it is 5-10x more expensive, 3-5x slower, and non-deterministic — the same query can get different classifications on different runs if temperature is above zero.
  • I would choose embeddings for high-throughput, low-stakes routing — a customer support bot handling thousands of queries per hour where 90% of queries cleanly fall into one of five categories. The 5-10% edge cases that get misclassified can be caught by a confidence threshold and escalated to a human or a more expensive model.
  • I would choose LLM-based classification for low-throughput, high-stakes decisions — routing a medical triage question to the right specialist pipeline, or classifying a compliance query where misclassification has regulatory consequences. Here, the extra 300ms and $0.001 per classification is trivial compared to the cost of getting it wrong.
  • The hybrid approach is often best in production: use embeddings as the fast path for clear-cut queries (confidence above 0.85), and fall back to LLM classification only for ambiguous queries (confidence between 0.5 and 0.85). This gives you the speed of embeddings for the 80% easy case and the accuracy of LLMs for the 20% hard case.
Follow-up: You mentioned embedding models cannot handle negation well. What other semantic nuances do embeddings consistently miss, and how would you build test cases to catch these gaps?Beyond negation, embeddings struggle with: sarcasm (“Oh great, another meeting” classifies as positive), conditional intent (“I would cancel IF the price goes up” classifies as cancellation), comparative queries (“Is Plan A better than Plan B” is ambiguous about which plan the user cares about), and code-switched language where the user mixes English and another language mid-sentence. I would build an adversarial test set specifically targeting these categories — 10-20 examples per failure mode. Run the embedding classifier against this set monthly. If accuracy on the adversarial set drops below 70%, it is time to either add more training examples for those edge cases or implement the hybrid approach with LLM fallback. The adversarial set is your canary — it catches classifier drift before your users notice it.