Across the products we run, three different model families are doing the work. Claude on AWS Bedrock reads compliance filings for Entivault. Gemini and DeepSeek write replies for Microcrew. Gemini's live-audio model powers the interview partner in BlockJobs.
People occasionally read that as indecision. It's the opposite. It's the single most load-bearing architectural decision we make, and it's made once, at the start, before anyone has written a prompt.
The dependency you don't notice you're building
Nobody sets out to lock themselves to a vendor. It happens by accumulation.
You start with one model. You tune prompts against its particular behaviour — how it handles a system message, how it responds to being told to think step by step, its specific tendency to over-explain. You adopt its tool-calling format. You build around its context window. You write parsing that assumes its output habits. Six months in, you have a system that works, and every single one of those choices is an assumption about one vendor.
Then something changes. The price moves. A new version behaves differently on the cases you cared about. A client's procurement team asks where inference happens. A competitor's model gets dramatically better at your specific task, or dramatically cheaper.
And you find that "try a different model" is not an afternoon. It's a rewrite, with no way to tell whether the rewrite is better, because you never had a way to measure the original.
That's not a model problem. That's an architecture problem you gave yourself.
Different jobs genuinely want different models
Beyond the risk argument, there's a simpler one: the models aren't interchangeable in practice, and pretending they are costs you money.
Reading a dense filing and extracting structured data with citations is a long-context, high-stakes, accuracy-dominated task where being slow is fine and being wrong is expensive. Writing a WhatsApp reply in an operator's voice is a short, high-volume, latency-dominated task where being slow is being wrong, and where per-message cost matters because there are thousands of them. A live spoken conversation is a different problem again — one where the interaction modality dictates the choice almost entirely.
Forcing all three onto one model means overpaying for the cheap task or under-serving the hard one. Usually both.
The corollary: model selection is a per-workflow decision, exactly like autonomy level. Not a company-wide standard, not a religious position. A choice with a number attached.
What makes swapping actually possible
Saying "keep the model layer swappable" is easy. Three things make it true.
Evals, first and foremost. This is the whole game. Without a suite of real cases with assertions, "should we switch models?" is unanswerable, so the answer defaults to no. With one, it's an experiment: run the candidate against the suite, compare per-set scores, look at cost and latency, decide. An afternoon.
Every argument for model portability collapses into an argument for having evals. They are the same investment.
A boundary in the code. One place where model calls happen, with your own interface for messages, tools, and structured output. Provider quirks — retry semantics, rate-limit behaviour, tool-call formats, streaming differences — get absorbed there and nowhere else. If a provider SDK is imported in forty files, you don't have a boundary.
Prompts as versioned data. Not string literals scattered through the codebase. Prompts that can be paired with a model, versioned, and evaluated as a unit — because the honest truth is that a prompt tuned for one model is not automatically the right prompt for another. Portability doesn't mean the same prompt works everywhere. It means you can find the right prompt quickly and know when you have.
What we're not claiming
Two things this isn't.
It isn't a claim that all models are equal. They aren't, the gaps are real and they're often large, and choosing well matters a great deal. Portability is what lets you keep choosing well as the landscape moves — which, over a two-year engagement, it will, several times.
And it isn't an argument for a lowest-common-denominator abstraction that supports only the features every provider shares. That throws away the reason you picked a model. Use the provider-specific capability where it wins; just make sure that use is confined to one layer, and that you know from your evals what it's buying you.
The client-facing version
Most clients don't ask about this directly. What they ask is: what happens if this vendor changes their pricing, or gets acquired, or the model we depend on gets deprecated?
The answer we want to be able to give — and the only one worth giving — is: we run the eval suite against alternatives, we compare quality, latency and cost, and we switch if the numbers say so. Here's the last time we did it.
Anything vaguer than that is a way of saying you don't know.
Friday, and the last post in this series: what a 48-hour agent plan actually contains.
