At 3 p.m. the model I'd been pairing with all day started rate-limiting. Instead of losing the thread, I typed /models, picked a different provider, and kept going — same open files, same task history, same terminal. The switch cost me one keystroke and roughly four seconds. A year earlier, that same interruption would have meant closing one tool, opening another, and re-explaining my whole repository to a stranger.
That small moment is the whole argument for model-agnostic coding agents. The model you start the year on is almost never the one you finish it on. What you shouldn't have to change, every time the leaderboard shuffles, is your tool.
The harness is the product
Strip a terminal coding agent down and you find two separable parts. One is the model: the thing that reads your prompt and predicts tokens. The other is everything around it — the part I'll call the harness. The harness runs the agent loop, decides which files to read, applies edits, executes shell commands and feeds back their output, talks to your language server for real symbol information, manages what fits in the context window, and keeps the whole conversation coherent across dozens of tool calls.
Almost all of the engineering that makes an agent feel good lives in the harness, not the model. The vendor CLIs — Claude Code, OpenAI's Codex CLI, Google's Gemini CLI — bolt a very good harness to exactly one provider's models. That's a fine deal until the day you want a cheaper model for a boilerplate refactor, a larger-context model for a sprawling migration, or a local model for code you can't send over the wire. Then the coupling is the problem.
Model-agnostic tools cut the harness loose. Aider is an open-source, git-native pair programmer that works with Claude, GPT, Gemini, and Grok interchangeably. OpenCode ships with LSP integration and support for 75+ providers out of the box. Cline works across 30+ providers plus local Ollama and LM Studio. Their pitch is the same: the model is a pluggable dependency, not the product.
How the decoupling actually works
You don't get provider-agnosticism for free — every vendor's API is shaped a little differently. Three layers do the reconciling.
An OpenAI-compatible surface. The /chat/completions request shape became the de facto interface, and nearly every provider now speaks it or offers an adapter that does. OpenCode, for instance, routes any custom endpoint through @ai-sdk/openai-compatible, which is how a local Ollama server drops in next to a hosted frontier model.
A translation layer. Under many of these tools sits LiteLLM, which normalizes provider quirks behind a single provider/model naming convention — gemini/…, openai/…, anthropic/…, openrouter/…. You name the model; the layer picks the right endpoint, auth header, and payload dialect.
A gateway, optionally. A router like OpenRouter puts many providers behind one API key and one base URL, so switching from Anthropic to Google to DeepSeek is a change of model string, not a change of credentials.
The upshot is that "which LLM am I using" collapses to one line of config.
Configuring it
Here's the shape in OpenCode. The model key sets the default; anything listed under provider becomes switchable at runtime:
{
"$schema": "https://opencode.ai/config.json",
"model": "anthropic/claude-sonnet-4-20250514",
"provider": {
"openrouter": {
"models": {
"google/gemini-2.5-pro": {},
"openai/gpt-5": {}
}
},
"ollama": {
"npm": "@ai-sdk/openai-compatible",
"name": "Ollama (local)",
"options": { "baseURL": "http://localhost:11434/v1" },
"models": { "qwen2.5-coder": {} }
}
}
}
Keys stay out of the file — {env:OPENAI_API_KEY} reads from the environment, and browser auth lands in a separate auth.json. Mid-session, /models swaps the active model and the context carries over; the session you're in wins over the file default, so switching doesn't rewrite your config.
Aider is even terser — the provider prefix lives right in the flag:
# .env
ANTHROPIC_API_KEY=...
OPENROUTER_API_KEY=...
aider --model anthropic/claude-sonnet-4-5
aider --model gemini/gemini-2.5-pro
aider --model openrouter/deepseek/deepseek-chat
Same repo, same git integration, same edit format — three different brains behind it.
Why you'd actually switch
Flexibility for its own sake is a weak reason. The real ones are operational:
- Cost routing. Send a mechanical rename or a test scaffold to a cheap, fast model; reserve the expensive reasoning model for the gnarly design work. Paying frontier prices for boilerplate is pure waste.
- Outage and rate-limit failover. Providers have bad afternoons. A second configured model turns a hard stop into a keystroke.
- Task fit. Huge diffs want a large context window; a subtle concurrency bug wants the strongest reasoner; a quick docstring wants whatever's cheapest. No single model is best at all three.
- Privacy and locality. Some code can't leave your network. A local model behind an OpenAI-compatible endpoint sits in the same picker as the hosted ones.
- No lock-in. When a better model ships next quarter, you edit a string. You don't relearn a tool or migrate your workflow.
Choosing your agent and choosing your model become two independent decisions. That separation is the entire point — and it's what the vendor CLIs quietly take away.
The part that doesn't transfer
Model-agnostic is not model-equal, and pretending otherwise will burn you. Prompts tuned for one model can underperform on another. Tool-calling reliability varies sharply — some models fumble multi-step edits that another sails through. Context windows differ by an order of magnitude, so a task that fits one model overflows the next. Benchmarks are always a harness-plus-model pairing, never a model alone; the same model scores differently under different agents.
So treat the switch as cheap but not invisible. Keep one or two models you actually trust for the hard work, a cheap one for the grunt work, and a local fallback for the sensitive stuff — and know which is which. The goal isn't to use every model. It's to owe loyalty to none of them.
The takeaway
Pick your coding agent for its harness — the edit loop, the git and LSP integration, the context management, the terminal ergonomics you'll live inside all day. Treat the model as a config line you can change in seconds. Wire up at least two providers plus a local fallback before you need them, not during an outage. Do that, and the next model launch stops being a migration and becomes a one-line diff.
Sources: OpenCode — Providers, OpenCode — Models, Aider — API Keys, LiteLLM — OpenAI-Compatible Endpoints, OpenRouter — Use OpenRouter with any coding agent