Most LLM applications begin with an llm call
response = client.chat.completions.create(
model="premium-model",
messages=messages,
)This is a reasonable approach for prototyping, but does not hold up in production.
Without intelligent routing, the same expensive model ends up handling everything : from diagnosing a production incident to glorified string manipulation such as
Convert this sentence to lowercaseUnsurprisingly, this kind of architectural misadventure irritates already-overstressed CFO, and is how the team lunch budget mysteriously disappears
This is the problem RouteWise is determined to solve
RouteWise is an OpenAI-compatible LLM gateway that sits between applications and multiple LLM providers.
It examines each request, identifies what it needs, filters unsuitable models, applies operational policies, and routes to an appropriate provider.
It also handles budgets, retries, fallbacks, circuit breakers, usage tracking, and routing visibility through an administrative dashboard.
Repository:
https://github.com/uncle-voh-max/routewiseWhy model routing matters
Every LLM request does not require the default capability.
Consider these prompts:
Extract the customer ID from this JSON.
Summarise this support request.
Analyse a production incident and propose likely causes.
Inspect this image and return structured findings.The first request needs reliable structured output.
The second request could be handled by a small, inexpensive model.
The third needs stronger reasoning and possibly a larger context window
The fourth requires vision support.
Sending every request to the strongest available model may produce good answers, but wastes money and capacity.
Similarly Sending everything to the cheapest model reduces cost but undermines quality
A good tradeoff is:
Selecting the least expensive model that serves the query reliably.
This is the essence of model routing.
cheap incorrect answers by app are not cost savings. They are incidents wearing discount codes.
RouteWise in the request path
With route wise applications call LLMs through an OpenAI-compatible gateway rather than directly integrating with Ollama, Azure, OpenAI, and other providers.
The query path becomes:

The important detail worth highlighting here is that filtering of llm models precedes actual scoring.
RouteWise first filter models that can perform the task. After that it compare models by cost, quality, latency, and faithfulness.
This avoids a common routing mistake:- allowing an unsuitable model to remain a contender merely because it is cheap.
Runtime conditions narrow the filter further
A model may be eligible for a request but could be currently unavailable. Such models are automatically excluded from the filter
RouteWise can exclude a candidate when it's
-
circuit breaker is open
-
cost budget has exhausted
-
predicted latency exceeds the request limit
-
quality is below the required threshold
-
Is explicitly excluded by the caller
Applications can express these constraints during instantiation of gateway
{
"gateway": {
"maximum_estimated_cost": 0.02,
"maximum_latency_ms": 2000,
"minimum_quality_score": 0.8,
"minimum_faithfulness_score": 0.75
}
}The application is effectively saying
Give me this level of quality,
within this latency,
and below this cost.RouteWise owns the decision about which models satisfies the given contract.
This is crispier than spreading specific model concerns throughout the application.
LLM landscape is highly uncertain. Model names could change, Pricing may evolve, Providers might deprecate older models and whatnot.
Applications should not request a release every time the model catalogue has a mood swing.
Routing policies precisely express intent
Once unsuitable models are filtered out RouteWise applies the selected policies and scores the remaining candidates .
The built-in policies represent common trade-offs
Balanced
{
"gateway": {
"routing_policy": "balanced"
}
}This is the default mode. It considers quality, cost, latency, and faithfulness in same manner, forbidding any one dimension to dominate.
It works well when the caller does not have any preference.
Cost optimized
{
"gateway": {
"routing_policy": "cost_optimized"
}
}Useful for:
Formatting
Routine classification
Internal automation
Development traffic
High-volume, low-risk requestsCost optimisation does not mean blindly selecting the cheapest model. Candidates must still satisfy capability and quality constraints.
Quality preferred
{
"gateway": {
"routing_policy": "quality_preferred"
}
}Useful for:
Complex reasoning
Code review
Important customer-facing reports
Incident investigation
High-value decisionsLatency optimized
{
"gateway": {
"routing_policy": "latency_optimized"
}
}Useful for:
Interactive assistants
Autocomplete
Real-time support
Interfaces where responsiveness matters more than marginal quality gains.Users rarely describe a slow answer as “high quality.” They normally describe the application as broken.
Configurable routing registry for all models
RouteWise stores model capabilities and operational characteristics in a registry.
A model registry looks like:
models:
- id: premium-reasoning-model
provider: openai_compat
provider_model: provider-model-name
tier: 1
enabled: true
capabilities:
tool_calling: true
structured_output: true
vision: true
streaming: true
context_window_tokens: 128000
max_output_tokens: 16384
input_cost_per_million_tokens: 2.50
output_cost_per_million_tokens: 10.00
quality_score: 0.97
faithfulness_score: 0.97
latency_score: 0.75This allows application to separate business code from model specific APIs
Complexity should influence route
A simple LLm task and a difficult task should not receive identical routing.
Formatting and rewriting
→ small local model
Structured extraction
→ inexpensive model with good schema support
Routine summarisation
→ mid-tier model
Complex reasoning
→ high-quality model
Long, expensive conversation
→ multi-model cascadeThis lets local models handle predictable workloads while higher tier models remain available for difficult tasks.
The idea is not new. Distributed systems have always placed work on resources appropriate for the workload.
LLMs simply add probabilistic behaviour and more entertaining invoices.
Cascades can split expensive work
Some requests are better handled via several stages.
For example:
Compact a long conversation
↓
Extract important facts
↓
Draft a response
↓
Finalise with a stronger modelRouteWise supports cascading where each stage can use a different tier.
complex_reasoning:
steps:
- name: compact
task: conversation_compaction
model_selector:
maximum_tier: 4
- name: extract
task: fact_extraction
model_selector:
maximum_tier: 3
- name: finalise
task: final_response
model_selector:
maximum_tier: 1
min_complexity: 3
max_direct_cost_multiplier: 1.5A smaller model can reduce or structure the input before a stronger model performs final reasoning.
This can lower cost, especially when the original context is large.
But cascading needs measurements or evals
Four inexpensive calls are not automatically cheaper or faster than one capable call.
Retries and fallbacks are part of routing
Providers fail. They time out, return rate limits, reject payloads, or become temporarily unhealthy.
RouteWise can retry retryable failures and automatically moves to the next eligible model.

Circuit breakers prevent repeated traffic being sent to a provider that is already failing.
This is an important reason to centralise routing.
Without a gateway, every application team eventually invents its own retry policy:
Team A retries everything
Team B retries nothing
Team C retries authentication failures ten times
Team D falls back directly to the most expensive modelCentralisation turns improvisation into an explicit operational policy
The dashboard makes routing visible
Dynamic model selection creates an obvious question
Why did this request use that model?RouteWise includes an administrative dashboard covering usage, cost, latency, models, health, circuit breakers, decisions, and audit events.
Overview

The overview helps answer:
-
How many requests are succeeding?
-
Which providers receive traffic?
-
How much are we spending?
-
Are fallbacks increasing?
-
Has latency changed?
-
Are circuit breakers open?
A gateway that reduces costs while hiding its behaviour eventually becomes an expensive mystery.
Model management

Models can be enabled or disabled at runtime.
This is useful during:
-
provider incidents
-
model deprecations
-
controlled rollouts
-
quality regressions
-
unexpected pricing changes
Every automated platform eventually needs a professionally labelled “absolutely not” switch.
Routing decisions

The decisions view records information such as
-
selected model
-
provider
-
active policy
-
latency
-
estimated cost
-
success or failure
-
fallback usage
When an answer is unexpectedly poor, engineers can identify which model handled the request and which policy influenced the decision.
A router without decision history is just a secretive oad balancer.
Evaluating routing quality
A router should not be evaluated merely by checking that requests return HTTP 200.
Compare metrics along several strategies:
Always use the strongest model
Always use the cheapest model
Balanced routing
Cost-optimised routing
Quality-preferred routingUse a representative request dataset (golden dataset) and record:
-
answer quality
-
selected model
-
token usage
-
cost
-
latency
-
failure rate
-
fallback count.
The most useful measurements are:
Quality retention
How close is routed quality to the strongest model?
Cost reduction
How much spend is saved without unacceptable quality loss?
Selection accuracy
Did the router forwarded tasks to suitable models?
Recovery effectiveness
Did retries and fallbacks recover successfully?
Routing stability
Does a small score adjustment unexpectedly move most traffic?
The North Star is not just cost reduction
A gateway that cuts model spend by 70% while doubling support escalations has merely moved the expense to another department.
Running RouteWise locally
RouteWise can be started with Docker Compose on local machine
The local stack uses PostgreSQL and Redis, Ollama for local inference.
Clone and configure
git clone https://github.com/uncle-voh-max/routewise.git
cd routewise
cp .env.example .envReview the environment file and add credentials for any hosted providers you intend to use.
Start with Docker Compose
docker compose up -dApply database migrations if required:
uv run alembic upgrade headCheck the service:
curl http://localhost:8000/healthRun the API directly
Install dependencies:
uv syncApply migrations:
uv run alembic upgrade headStart the server:
ROUTEWISE_ENV=local \
uv run uvicorn routewise.main:app --reloadA local Ollama installation commonly runs at:
http://localhost:11434Redis and PostgreSQL can be configured through REDIS_URL and DATABASE_URL.
Send the first routed request
curl http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"messages": [
{
"role": "user",
"content": "Explain circuit breakers in two paragraphs."
}
],
"gateway": {
"routing_policy": "cost_optimized",
"explain_routing": true
}
}'With routing explanation enabled, the response includes metadata describing the model that was selected and rational behind selection.
Open the dashboard at:
http://localhost:8000/admin/dashboard* * Use the configured admin API key, and change any development default before exposing the dashboard outside the local machine.
The senior-engineering perspective
RouteWise establishes a designated demarcation.
Applications express:
Required capabilities
Quality expectations
Latency tolerance
Cost limits
Routing policy
Tenant contextThe gateway owns:
Provider integrations
Model inventory
Pricing
Health
Budgets
Retries
Fallbacks
Circuit breakers
Usage tracking
Routing decisionsThis allows application teams to change models and providers without rewriting every integration.
It also creates one place to enforce organisational cost and reliability controls.
But centralisation carries the weight of bigger responsibilities
Model scores must be calibrated. Policies need owners. Dashboard access must be secured. Routing decisions must be evaluated continuously.
Intelligent routing should not make model choice mysterious. It should make model choice deliberate.
The best model is not always the largest or cheapest.
It is the model that satisfies the request, remains reliable under production load, and does not make finance reaching out to your manager.