How to Avoid Lock-In to One AI Provider
To avoid lock-in to one AI provider, fix the four things that actually bind you. Most teams insure against the cheapest one and miss the rest.
The usual advice on how to avoid lock-in to one AI provider is to put an abstraction layer in front of the SDK. That advice addresses the cheapest of the four things binding you to a provider, and ignores the most expensive.
Lock-in is not one thing. It is four, stacked, and each has a different escape cost. Knowing which layer you are actually stuck on tells you whether to spend a day or a quarter.
The four layers, by what they cost to leave
Layer | What binds you | Cost to escape |
|---|---|---|
The SDK | Client library and request shape | Hours |
The feature surface | Provider-specific capabilities you use | Days |
Operational knowledge | What you know about its behaviour | Weeks |
Tuned prompts and evals | Prompts shaped against one model | Weeks to months |
The ordering surprises people, because effort usually goes to the top row.
Layer 1: the SDK
The shallowest layer. Chat completion APIs across major providers converged years ago on a similar shape: messages with roles, a model name, temperature, a token cap, a tools array. Swapping one client for another is mostly mechanical.
This is genuinely cheap insurance, which is why it is worth doing, and it is worth doing in the smallest way that works: one module in your codebase that owns provider calls, rather than a framework that owns your architecture. A thin adapter you wrote is easier to leave than a heavy abstraction you adopted.
Layer 2: the feature surface
Deeper. Providers differentiate on capability, and the useful capabilities are the sticky ones: a specific caching mechanism, a structured output mode, a particular tool-calling behaviour, a context window nobody else matches, a built-in retrieval feature.
Every one of those you depend on is a thing the next provider may do differently or not at all. That is not an argument for refusing to use them, it is an argument for knowing the list. Write it down. A team that can name its six provider-specific dependencies is in a very different position from one that discovers them during a migration.
Prompt caching is the common example: it saves real money and it works differently across providers, so a cost model built on one provider's caching does not transfer.
Layer 3: operational knowledge
Rarely counted, consistently expensive. Your team knows this provider's rate limit behaviour, its error codes, its failure patterns, what its latency looks like at the tail, which of its models is best at your particular awkward task.
None of that is in your codebase. All of it is real, and all of it resets on a switch. This is the main reason migrations take longer than the estimate: the code change was a week and the relearning was a quarter.
Layer 4: tuned prompts and evaluations
The deepest layer and the one almost nobody plans for.
Prompts drift toward the model they were tested against. Every time someone adjusts wording because the output was not quite right, the prompt gets a little more shaped around one model's quirks. After a year of that, you do not have prompts, you have prompts tuned to a specific model, and they will underperform elsewhere for reasons nobody documented.
Worse, you often cannot tell. Without an evaluation set, switching models produces a vague sense that things got worse, with no way to confirm it or locate it.
The cheap insurance for each layer
**Layer 1:** one module owning provider calls. A day's work, done once, at the start.
**Layer 2:** a written list of provider-specific features you depend on, kept current. An hour a quarter.
**Layer 3:** nothing fully fixes this. Partial mitigation is sending a small share of non-critical traffic to a second provider, so somebody retains working knowledge of it.
**Layer 4:** an evaluation set. This is the one that matters.
An evaluation set is twenty to fifty real inputs from your product with outputs you have judged acceptable. It does not need a framework. A table and a scoring rubric is enough.
With one, switching providers becomes a measurement: run the set, compare, decide. Without one, it is a leap of faith followed by a month of complaints. Testing a new model before switching describes how to build one, and it is the highest-leverage hour in this entire article.
When lock-in is the right call
Being deliberate about this does not mean minimising it. Provider-specific features exist because they work, and refusing all of them to preserve a theoretical portability you will never exercise is a real cost paid for an imagined benefit.
The sensible position is to know your exposure and keep the measuring instrument. Use the good features. Keep the eval set. Then a provider change is a decision you can make on evidence rather than one you avoid out of fear.
Note that this is a different question from platform lock-in. If your concern is what you can take with you from an app builder rather than from a model API, AI app builder lock-in covers that layer instead, and the two problems have almost nothing in common beyond the word.
For the related operational question of what happens when your single provider has a bad day, what to do when your AI provider is down is the shorter and more urgent version of this article. The app building guide covers where this decision sits in a build.
Sources: the convergence of chat and tool-calling request shapes across providers is visible in public API references such as Anthropic's Messages API documentation.
How did this land?
About the author

Staff Engineer, Platform
Carlo works on the platform that turns prompts into running apps. He writes the engineering deep dives and the changelog notes worth reading.


