Multi-agent fallback chains: stopping infinite handoff loops

Multi-agent fallback chains work by running routing strategies in sequence and stopping delegation when a confidence threshold is missed or a failure counter trips. The patterns that prevent infinite loops are a max-turn limit and a circuit breaker, and both require deliberate design before a system handles real traffic.
The five routing patterns and where each one breaks
Understanding where each pattern fails is as important as knowing when to use it. You will almost certainly need more than one.
Rule-based routing
The simplest pattern: an if/elif tree that maps task properties to agent names. It is fast, auditable, and free of model latency. It breaks the moment a task falls between two rules or matches more than one. When that happens with no tiebreaker, agents pass the task to each other indefinitely.
Semantic routing
A classifier, usually a small embedding model, maps the input to the nearest category in a pre-built intent space. It handles natural-language variation better than rules. It fails on out-of-distribution inputs, returning a confident-looking score to an intent that is only loosely correct. If the receiving agent cannot complete the task, there is no built-in signal to try a different path.
LLM-based routing
A prompt asks a language model to decide which agent should handle the task. It handles ambiguous inputs well and can reason about context accumulated across turns. It adds 200 to 800 milliseconds of latency per routing decision and introduces non-determinism. Two identical inputs can produce two different routing decisions, making loops difficult to reproduce in staging. Uber’s engineering team documented a 27% relative increase in acceptable answers and a 60% relative reduction in incorrect advice after moving their internal on-call copilot to an agentic architecture, but that improvement came with careful prompt constraints on the routing step, not open-ended delegation.
Hierarchical routing
An orchestrator agent owns all routing decisions and delegates to specialist agents. Specialists never route to each other directly. This eliminates peer-to-peer ping-pong entirely. The cost is a single point of failure: if the orchestrator’s context window fills or its routing prompt degrades, every task in flight is affected simultaneously.
Hybrid routing
Rules handle the high-confidence majority, semantic classification covers moderate-confidence cases, and LLM-based routing handles only the ambiguous tail. This is the pattern that survives production. HCLTech’s dynamic handoff system routes based on context that emerges mid-conversation, for example when a billing question reveals an underlying technical fault, and attributes 40% faster case resolution to this approach. The overhead is complexity: each layer needs its own confidence threshold and a clear handoff contract to the next layer.
Building the fallback chain
A fallback chain runs routing strategies in order. If a strategy returns below its confidence threshold, control passes to the next strategy. The chain terminates when a strategy succeeds or when a typed error is returned.
flowchart TD
A[Incoming task] --> B{Rule match?}
B -- Yes --> C[Route to agent]
B -- No --> D{Semantic score >= 0.75?}
D -- Yes --> C
D -- No --> E{LLM classification confident?}
E -- Yes --> C
E -- No --> F[Human escalation queue]
C --> G{Agent completes task?}
G -- Yes --> H[Done]
G -- No --> I{Turn count < max?}
I -- Yes --> B
I -- No --> J[Circuit breaker fires]
J --> F
The key decision at each node is confidence, not just category. A semantic router that returns 0.62 when your threshold is 0.75 should not route; it should yield. Build that yield condition into every strategy, not as an afterthought.
The two mechanisms that stop loops
Max-turn limits
Every task thread carries a shared counter. Each agent-to-agent handoff increments it. When the counter reaches your limit (start at ten, adjust after observing production traces), the orchestrator stops routing and raises a MaxTurnsExceeded error rather than handing off again.
MAX_TURNS = 10
class TaskContext:
def __init__(self, task_id: str, payload: dict):
self.task_id = task_id
self.payload = payload
self.turn_count = 0
def increment(self):
self.turn_count += 1
if self.turn_count > MAX_TURNS:
raise MaxTurnsExceeded(
task_id=self.task_id,
turn_count=self.turn_count,
)
Circuit breakers
A circuit breaker tracks failure counts per routing path over a rolling window. When failures on a given path exceed a threshold (for example, five failures in sixty seconds), the breaker opens and stops routing to that path for a fixed cool-down period. This prevents a degraded agent from consuming all retries before the fallback chain can try an alternative.
from collections import defaultdict
import time
class CircuitBreaker:
def __init__(self, threshold: int = 5, window_s: int = 60, cooldown_s: int = 120):
self.threshold = threshold
self.window_s = window_s
self.cooldown_s = cooldown_s
self._failures: dict[str, list[float]] = defaultdict(list)
self._open_until: dict[str, float] = {}
def record_failure(self, path: str):
now = time.time()
self._failures[path] = [
t for t in self._failures[path] if now - t < self.window_s
]
self._failures[path].append(now)
if len(self._failures[path]) >= self.threshold:
self._open_until[path] = now + self.cooldown_s
def is_open(self, path: str) -> bool:
return time.time() < self._open_until.get(path, 0)
Pair this with a typed error schema. An agent that cannot handle a task should return CapabilityMismatch, not a generic failure. An agent that failed due to a downstream timeout should return TransientError. The router uses the error type to decide whether to try the next strategy or escalate immediately.
What production looks like with this in place
Warp routes routine code fixes to cheaper models and security-sensitive changes to stronger models, with each routing decision logged for audit. That auditability is only possible because the routing layer emits structured events at every decision point, including which strategy fired, what confidence score it returned, and what the turn count was. Without that, you are debugging loops from inference.
OpenTable reached 70% autonomous resolution of diner inquiries within weeks of deployment, partly because ambiguous cases had a clear escalation path rather than cycling between agents. The routing layer needs to know what it cannot handle as precisely as it knows what it can.
For teams working on LangGraph deployments, the turn counter maps naturally onto LangGraph’s state object. For CrewAI setups, the circuit breaker fits at the crew orchestration layer before tasks are delegated to individual agents. The pattern is framework-agnostic; the implementation varies by one layer.
Tools like Prefactor give you a managed layer for routing observability if you want that instrumentation without building it yourself, though the circuit breaker and max-turn logic still live in your orchestration code regardless of what sits on top.
For a deeper look at the observability side, see the guide on how to implement agent observability and the overview of agentic AI orchestration patterns. If you are deciding between framework options before building this out, the LangGraph vs CrewAI comparison covers the trade-offs in detail. The broader context on multi-agent system architecture is useful if you are still deciding how many agents your system actually needs. And if governance and audit trails are a concern for your organisation, the guide on AI agent governance covers the policy layer that sits above the routing layer described here.
78% of multi-agent systems never reach production. The routing layer is where most of them stall. A fallback chain with a max-turn limit and a circuit breaker is the difference between a system that degrades gracefully and one that loops until you pull it.
Where to start
Run your current routing logic against the five patterns above and identify which one you are relying on exclusively. Then take the agent readiness assessment to find out which gaps in your coordination layer are most likely to block a production deployment.