# Multi-provider as an architecture decision: why locking to one LLM is a reliability problem.

> Anthropic, OpenAI, Gemini, Ollama, claude-cli, gemini-cli — the provider abstraction in v1.0 and the manual-switch posture that keeps single-provider outages from breaking your workflow.

Published September 3, 2026 by CommitBrief (https://commitbrief.com)

Canonical URL: https://commitbrief.com/blog/provider-fallback-strategy/
Tags: providers, reliability, architecture

---

A single-provider code review tool is making a reliability bet whether it acknowledges it or not. The bet is that the chosen provider will be available, performant, and within budget every time you reach for the tool. The history of every cloud service ever tells you that bet loses eventually — the only question is how loudly it loses when it does.

CommitBrief talks to six providers because lock-in is a reliability problem, not a tooling problem. This post explains the architecture that makes that possible, what the abstraction deliberately gives up, and why the switchability — even when it's manual — materially changes the reliability calculus.

## The six providers

The currently supported set:

- **Anthropic.** Claude Opus 4.7, Sonnet 4.6, Haiku 4.5. Ephemeral prompt caching with a 5-minute TTL — re-runs on the same diff cost about an order of magnitude less than the first run.
- **OpenAI.** GPT-4o, GPT-4o-mini. Automatic prompt caching kicks in at ≥1024-token prefixes.
- **Google Gemini.** Gemini 2.5 Pro (2M context), 2.5 Flash, 1.5 Flash. The 2M context is what lets you review a 600-file PR in one call when you need to.
- **Ollama.** Any model you've `ollama pull`-ed. Local, no API key, no per-token cost. [The air-gapped post](/blog/air-gapped-with-ollama) covers when to reach for this one specifically.
- **`claude-cli`.** Subprocess wrapper around your locally-installed Claude Code (`claude`) binary. No second API key — your Claude Code subscription handles auth and billing.
- **`gemini-cli`.** Same idea, against Google's Gemini CLI.

You can change providers per run with `--provider <name>` (or the `--cli claude|gemini` shorthand for the subprocess ones), and per model with `--model`. The config files cascade — repo-local overrides user-global overrides embedded defaults — so a single repo can pin a specific provider while your other work uses your personal default.

## The interface that holds the abstraction together

Every provider lives in `internal/provider/<name>/` and implements the same `Provider` interface. The interface is narrow on purpose:

- A method to make a review call given a prompt and configuration
- A method to test the connection without spending inference time
- Metadata about supported models, context windows, and pricing

That's it. The interface intentionally doesn't try to expose every provider-specific feature. Anthropic's ephemeral cache, OpenAI's prompt-caching prefix optimization, Gemini's massive context window — these are all leveraged when you use those providers, but they're not exposed through a unified API. The CLI takes the lowest-common-denominator interface and lets each provider's implementation handle its own optimizations internally.

The narrow interface is what makes adding a seventh provider one new package and a single registration call. Mistral, Cohere, a self-hosted vLLM endpoint — any of these is a one-package change, not a refactor of the rest of the system. The two CLI-tool-backed providers (`claude-cli`, `gemini-cli`) are themselves proofs of the abstraction: they implement the same `Provider` interface as the HTTPS API providers, just with a subprocess transport instead of an SDK call.

## What the abstraction gives up

I want to be honest about the cost of this choice. A multi-provider design pays for its flexibility in two ways.

First: cross-provider feature parity. The same review on Anthropic and on OpenAI will produce slightly different output because the prompt templates have to be the lowest common denominator. The Anthropic-specific tricks that would extract more from Sonnet 4.6 aren't available because they wouldn't work on OpenAI or Ollama. The result is that a single-provider tool optimized end-to-end for one model would, in theory, produce marginally better output than CommitBrief on that one model.

Second: feature evolution speed. When a provider ships a new capability — say, structured outputs with strict JSON schema enforcement — a single-provider tool can adopt it the day it ships. CommitBrief has to either adopt it as the lowest common denominator (waiting until every provider has an equivalent) or expose it through an opt-in interface that complicates the CLI surface.

These are real costs. I think they're worth paying because the alternative — being locked to one provider's roadmap, pricing, and uptime — is a worse problem in the long run.

## Switching providers in v1.0 is manual, deliberately so

A natural follow-on question is: _does CommitBrief automatically fail over to a backup provider when the primary is down?_ The answer in v1.0 is no, and that's a considered choice, not an oversight. Three ways to switch in practice:

```sh
# Flip the active default. Touches only `provider:` in the config; every
# API key, model, and base URL is preserved across the switch.
commitbrief providers use openai

# Override for one invocation. Does NOT write to your config.
commitbrief --provider gemini --model gemini-2.5-flash --staged

# Drop to a local model entirely — air-gapped, zero per-token cost.
commitbrief --provider ollama --staged
```

`commitbrief providers list` shows every configured + registered provider with a masked API-key fingerprint, so it's a one-look check to see what you have set up before you switch. `commitbrief providers test <name>` pings the named provider's `TestConnection` and reports latency — useful when you're not sure whether your secondary is in working order before you actually need it.

The reason this is manual: silent fallback masks the signal. If Anthropic is down for an hour and your CLI quietly used OpenAI instead, you don't learn that Anthropic was down. The next time you reach for `commitbrief` you're back to defaulting to Anthropic — and if it's still down, you're surprised again. A manual switch makes the failure mode visible, which makes "should I move my default for the week?" a decision you can actually make.

The implication for your setup: have at least one secondary configured _before_ you need it. The five-minute investment of running `commitbrief setup` against a second provider buys you a single-command escape valve the day your primary has a regional outage.

## Per-run overrides for explicit choices

The same `--provider` mechanism that handles outages handles intentional choices:

```sh
# I know this is a big diff and I want Gemini's 2M context.
commitbrief --provider gemini --model gemini-2.5-pro --staged

# I'm working on the SOC2-bound repo today.
commitbrief --provider ollama --staged

# I want to compare what the two providers say about this PR.
commitbrief --provider anthropic --staged
commitbrief --provider openai --staged

# Reuse my Claude Code subscription instead of burning the API key.
commitbrief --cli claude --staged
```

These flags don't write to your config. They override for the single invocation. This is the right design for one-off experiments and for working across repos with different sensitivity levels.

## Reliability as a first-class concern

There's a quiet principle behind all of this: a tool that sits in your pre-commit workflow needs to be more reliable than the work it's reviewing. If `commitbrief` fails 2% of the time, you start treating it as an optional step, and the value of the pre-PR review pattern collapses.

The provider switchability, the local-cache hit on re-runs, the Ollama escape valve, the CLI-tool-backed providers that work even when your machine isn't authenticated against a cloud LLM — these are all in service of that reliability target. None of them are exciting features in isolation. Together they're what makes the tool worth wiring into your daily workflow.

## What this implies for your config

A few practical recommendations for setting up the multi-provider story for your own use:

- **Pick a primary based on quality, not cost.** Cost matters, but the provider-side prompt cache and CommitBrief's local response cache make per-call cost much lower than the sticker price suggests. Optimize for the review you want, not the bill you fear.
- **Configure at least one alternate** while everything is working. The day Anthropic has a regional outage is not the day you want to be running `commitbrief setup` for the first time against OpenAI.
- **Configure Ollama as the bottom of your switch list if you can run it.** It's the only provider that can't fail for cloud-provider reasons. The quality is lower; that's the trade-off; but "lower-quality review" is always better than "no review."
- **Treat the CLI-tool-backed providers as cost dampeners.** If you already pay for Claude Code or the Gemini CLI, `--cli claude` and `--cli gemini` reuse that auth and that bill — no second API key, no per-token surprise.

If you came in through [the CLI-vs-App post](/blog/cli-vs-github-app), this provider flexibility is the architectural payoff of the CLI choice. A GitHub App locks you to the App vendor's provider relationships; a CLI doesn't.

The final post in this series turns to something downstream of all this: how the JSON output and the cache-key design let you turn LLM reviews into something that can plug into a compliance evidence pipeline — and the careful framing that distinguishes "evidence" from "proof."