The typical AI application shipped in 2024 has a provider name hard-coded somewhere near its core. A base URL, an SDK, a key format, a response shape, all of it assuming one lab, chosen once, forever. That decision was reasonable when it was made. It is now the single most common source of avoidable cost and risk we see.
The frontier flattened
Two years ago the quality gap between the leading model and the next-best alternative was wide enough that most teams could ignore everything below the top. That is no longer true. On the workloads teams actually run (extraction, classification, code generation, summarisation) the top five or six models are frequently indistinguishable in quality and separated by 5–10x in price.
The best model for a task is the cheapest one that clears your quality bar reliably. When several models clear it, the choice is economic, not technical.
When several providers can do the job, pinning yourself to one means overpaying for capability you could have had elsewhere, and carrying the outage risk of a single vendor for no offsetting benefit.
What "multi-model" actually requires
It is tempting to think you can add a second provider later, when you need it. In practice, "later" means a rewrite, because the assumptions leak everywhere:
- Authentication: each provider has its own key format and header convention.
- Request shape: system instructions, tool definitions and multimodal content blocks differ between providers in ways that are annoying rather than hard.
- Response shape: streaming event formats diverge, and usage accounting means different things across vendors.
- Failure modes: a mid-stream failure on one provider is a different event from a rate limit on another.
Absorbing those differences at call sites, one if at a time, is how a clean codebase becomes an unmaintainable one.
The gateway pattern
The alternative is to make the difference somebody else's problem. A gateway sits between your application and every provider, exposes one request shape, one key format and one response format, and translates. Your application names a model as a string; switching from one to another is a config change, not an integration.
{
"model": "deepseek/deepseek-v3.2",
"messages": [{ "role": "user", "content": "Summarise this report" }],
"provider": { "strategy": "balanced" }
}Change "deepseek/deepseek-v3.2" to "anthropic/claude-sonnet-4.5" and nothing else moves. That property (that a model name is a value rather than a commitment) is the whole point. It is what lets you evaluate a new release the week it ships instead of the quarter you get around to it.
Where to start
You do not have to route everything everywhere on day one. Start by pinning exact models explicitly, get one fallback in place for your highest-volume path, and measure. Automatic routing is only trustworthy once there is real quality and latency data behind it. Adopt it deliberately, not by default.
The teams moving fastest right now are not the ones who picked the best model. They are the ones who built so that the question "which model?" stays cheap to answer.