Add Fallback Path is an AI refactoring for LLM systems, in the Safety and reliability group. Define what happens when the model, the tool, or the provider fails.
At 2pm, the primary model provider starts returning 503. A bank’s voice bot has no second path. Every call falls into silence after four seconds. The call center fills up. When the model, a tool, or the provider fails or slows down, the whole product stops with it, and nobody defined what should happen. This is the Single Provider Dependency smell.
Solution
Define, for each dependency, what happens when it fails: a short timeout, an already evaluated alternative path (another model, another provider, a fixed answer, a queue, a person), and a circuit breaker that stops hammering a service that is down.
Before and after
-def answer(call):- reply = client.messages.create(model=PRIMARY, messages=call.messages)- return speak(reply)+def answer(call):+ if breaker.is_open("primary"): # breaker open: do not even try+ return fallback(call)+ try:+ reply = client.with_options(timeout=2.5, max_retries=0).messages.create(+ model=PRIMARY, messages=call.messages, max_tokens=400)+ breaker.record_success("primary")+ return speak(reply)+ except (APITimeoutError, APIConnectionError, InternalServerError, RateLimitError):+ breaker.record_failure("primary")+ return fallback(call)++def fallback(call):+ reply = backup_client.create(model=BACKUP, prompt=BACKUP_PROMPT, ...) # evaluated in the eval+ if reply is None:+ return speak_fixed("I will transfer you to an agent.") or transfer(call)+ return speak(reply)
Before: a single path.
flowchart LR
C(["1. Call"]):::io --> P(["2. Primary model"]):::llm
P -->|"failure or slowness"| X(["3. Silence and a dropped call"]):::io
After: a timeout, a circuit breaker, and fallback tiers.
flowchart LR
C(["1. Call"]):::io --> B{"2. Breaker open?"}
B -->|no| P(["3. Primary model, short timeout"]):::llm
B -->|yes| F(["4. Backup model"]):::llm
P -->|"error or timeout"| F
F -->|"also failed"| H((("5. Human agent"))):::human
P --> OUT(["Answer"]):::io
F --> OUT
The request arrives.
If the primary service failed several times recently, the breaker is open and no attempt is made.
The primary model has a timeout that fits the product (seconds, not minutes).
The backup has already been evaluated with its own prompt.
If everything fails, there is a defined path that does not depend on a model.
Why it works
Provider failures are rare, but certain. Major providers’ status pages record public incidents with some regularity. Without a plan, every failure becomes a manual decision, made late and under pressure. With a plan in code, the switch happens in seconds and the same way every time.
The three parts complement each other. A short timeout stops hanging requests from consuming every resource. The circuit breaker avoids hammering a service that is down, which worsens the outage and delays recovery. The evaluated fallback guarantees the alternative path works before you need it.
Worked example: voice with a 3-second ceiling
Product: a bank IVR on the phone. The pause a customer will tolerate is about 3 seconds. The SDK default waits 10 minutes and retries twice. Leave that alone, and a provider slowdown holds 200 concurrent calls until timeout.
Configuration: timeout=2.5, max_retries=0. Breaker opens after 5 failures in 30 seconds. Fallback: a model at another provider, with its own prompt. Suppose the eval shows the backup about 4 points below the primary on intent classification. Third tier: a fixed sentence and transfer to a human agent.
At 2pm the primary returns 503. The first 5 calls fail in 2.5s and fall to the backup. The breaker opens. Later calls do not even try the primary. The call center only gets what the backup also could not cover. Without the plan, every call went to silence.
Safe mechanics
Measure. Gather the model’s p95 and p99 latency, the error rate, and what happens today on a failure (simulate it in staging).
Set timeouts from the experience the product can accept, not from the library default.
Choose each dependency’s fallback: another model, another region, another provider, a fixed answer, a queue, or a person. A nightly job does not need the same tier as live voice.
Evaluate the fallback with the eval, with its own prompt if needed. Know how much quality drops. Without that, the backup is a surprise on the worst day.
Implement the circuit breaker with a failure threshold, an open period, and a recovery probe (half-open: one probe, not a flood).
Record on the trace which path served each request.
Rehearse the failure: take the primary down in staging and confirm the fallback takes over.
Measure again availability and quality on the alternative path.
Trap: two models at the same provider
gpt-4o and gpt-4o-mini fail together when that provider’s API, in that region, is down. Diversify provider or region when the product cannot stop. If you cannot, the last tier cannot be a model: a fixed sentence, a queue, a person.
Another trap: a fallback nobody ran through the eval. Different format, different tone, a tool with an old name. The outage day is the first time that prompt sees production.
Risks
A never-tested fallback. A backup model nobody evaluated may answer worse or in another format. The backup’s eval is mandatory.
A fallback that also falls. Two models at the same provider and region fail together. Diversify when the product requires it.
Flapping. A badly configured breaker opens and closes constantly. Tune the threshold and window. One probe in half-open, not 100% of traffic back at once.
Unexpected cost. The backup may be more expensive. Monitor cost while it is in use.
Challenge
A nightly report generator uses a model to summarize sales. If the provider goes down, the report does not go out. Which fallback makes sense here?
Show solution
For an asynchronous task, the simplest fallback is time: retry with growing backoff for a few hours, only on transient errors, with an alert if it has not finished by a deadline. If the report must go out no matter what, a second tier can produce a version without the summary (only the tables computed in code), marked as incomplete. A backup model only if the eval shows it summarizes well.
Add Fallback Path is an AI refactoring for LLM systems, in the Safety and reliability group. Define what happens when the model, the tool, or the provider fails.