Single-agent systems have predictable failure modes. The agent calls a tool, the tool fails, the agent receives an error and decides what to do next. The failure is contained to the single agent’s context and decision loop. Debugging is straightforward because the entire execution path is visible in a single trace.
Multi-agent systems introduce failure modes that do not exist in single-agent architectures. The failure of one agent can cascade through the system in ways that are difficult to predict and harder to debug. When agent A calls agent B to complete a subtask, agent A’s correctness now depends on agent B’s correctness, which may depend on agent C’s correctness. A failure at any point in this chain propagates upward.
The failure may be obvious: agent B returns an error. Or it may be subtle: agent B returns a plausible but incorrect result that agent A incorporates into its reasoning without detecting the error. The subtle failures are the dangerous ones because they produce confident, wrong outputs that propagate through the system as verified facts.
Cascading Hallucination
The most dangerous multi-agent failure mode is cascading hallucination. Agent B hallucinates a fact. Agent A receives the hallucinated fact, treats it as ground truth because it came from another agent, and builds further reasoning on top of it. The hallucination is now embedded in agent A’s context and will be presented to the user with the confidence of a verified fact.
This is worse than single-agent hallucination for two reasons. First, the user may trust multi-agent output more than single-agent output. The assumption is that multiple agents checking each other’s work should reduce errors. In practice, without explicit verification mechanisms, multiple agents can amplify errors rather than catching them. Second, the hallucination is harder to trace. In a single-agent system, you can see the hallucination in the agent’s output. In a multi-agent system, the hallucination is buried in an intermediate agent’s response that was consumed by the calling agent and is not directly visible in the final output.
A Concrete Scenario
Consider a customer support system with three agents. Agent A is the orchestrator that receives the customer query. Agent B is a knowledge agent that searches documentation and returns facts. Agent C is a policy agent that checks company policies and returns guidance.
A customer asks about their refund eligibility. Agent A delegates to Agent B to find the refund policy. Agent B searches its knowledge base and hallucinates that the policy was updated last week to extend the refund window from 30 to 60 days. This is wrong. The policy has not changed. But Agent B presents it confidently with a plausible-sounding effective date.
Agent A receives this information and delegates to Agent C to check whether this customer qualifies under the 60-day window. Agent C confirms that the customer qualifies because they are within 45 days of purchase. Agent A tells the customer they are eligible for a refund under the extended 60-day policy.
The customer contacts the company expecting a refund under a policy that does not exist. The hallucination traveled through three agents, each of which trusted the previous agent’s output, and emerged as a confident, specific, wrong answer.
Mitigation: Inter-Agent Verification
The mitigation is inter-agent verification. When agent A receives a result from agent B, it should not trust it blindly. Agent A can verify agent B’s result by checking it against known facts, running a separate retrieval to confirm the information, or invoking a third agent specifically to verify the claim.
The verification does not need to be exhaustive. Focus verification on factual claims that are critical to the final output. If agent B reports a customer’s account balance, verify it against the source system. If agent B summarizes a document, spot-check a few key claims. Full verification of every sub-agent output is too expensive. Targeted verification of critical claims is practical.
Another mitigation is confidence scoring. Each agent should return a confidence score with its results. Low-confidence results should trigger verification by the calling agent. High-confidence results can proceed without verification, with the understanding that occasional high-confidence errors are an acceptable trade-off for reduced latency and cost.
Context Window Exhaustion
Each agent in a multi-agent system has its own context window. When agent A calls agent B, agent A must pass enough context for agent B to do its work. If agent B then calls agent C, the context must be further compressed or truncated. By the time you reach three or four levels of delegation, the context available to the deepest agent may be insufficient for accurate work.
Consider a scenario where agent A is orchestrating a complex research task. It has accumulated 80,000 tokens of context from previous steps. It delegates to agent B to analyze a specific document. Agent B receives the document (20,000 tokens) plus a summary of agent A’s context (10,000 tokens). Agent B then delegates to agent C to extract key entities from a section of the document. Agent C receives a compressed version of the document section (5,000 tokens) plus a summary of agent B’s reasoning (3,000 tokens).
Agent C misses entities that were in the full document but not in the compressed version. Agent B’s analysis is incomplete because it was based on agent C’s incomplete extraction. Agent A’s final output is wrong, but the error originated three levels deep in the delegation chain, in a context compression step that is not visible in the final trace.
Mitigation: Context Management Discipline
Each agent should pass the minimum context needed for the sub-agent to do its work, not the entire conversation history. Critical context like specific constraints, quality requirements, and known facts should be explicitly included. Background context that is nice to have but not essential should be omitted to preserve context window space.
Hierarchical summarization helps. Agent A provides agent B with a summary of the relevant context plus the specific task. Agent B provides agent C with an even more focused summary. Each level of delegation adds its own context compression. The compression may lose information, but it is better than truncation, which loses information without any attempt at preservation.
Context pinning is another technique. Identify the most critical pieces of context (the user’s original request, key constraints, known facts) and pin them at every level of delegation. Pinned context is always included, even if it means reducing other context. This ensures that the most important information survives the delegation chain.
Monitoring Context Degradation
Measure context completeness at each delegation level. After each agent completes its task, compare the information it used against the information available in the full context. If the agent used only 40% of the relevant context because the rest was compressed away, the delegation is losing information at an unacceptable rate.
This measurement is hard to automate perfectly, but even rough estimates help. Track the token count of context passed at each level. If the token count drops by 60% at each delegation level, you can estimate that information loss is accumulating at a predictable rate. Set a threshold: if the estimated information loss exceeds a threshold, reduce the delegation depth or improve the context compression.
Dead Loops and Infinite Delegation
Multi-agent systems can enter loops where agent A calls agent B, agent B calls agent C, and agent C calls agent A. Without loop detection, the agents keep delegating to each other indefinitely, consuming tokens and adding latency without making progress.
Explicit loops are easy to detect with a delegation stack. Each agent tracks the delegation chain. If an agent is asked to handle a task that is already in the delegation stack, it rejects the delegation and forces the calling agent to handle the task directly. This breaks the loop.
The harder problem is implicit loops or infinite delegation behavior. Agent A is unsure about a decision and delegates to agent B for a second opinion. Agent B is also unsure and delegates to agent C. Agent C is also unsure and delegates back to agent A, not because of a circular dependency but because all three agents have the same uncertainty threshold and none of them can resolve the uncertainty.
Mitigation: Delegation Depth Limits
Set a maximum depth for the delegation chain. When an agent reaches the maximum depth, it must produce an answer rather than delegating further. The answer may be uncertain or incomplete, but it breaks the loop and returns control to the user.
Delegation depth limits should be small. A maximum depth of two or three levels is sufficient for most multi-agent architectures. If your system needs deeper delegation, the task decomposition is probably wrong. Break the task into smaller pieces that can be handled within the depth limit.
Uncertainty thresholds are another mitigation. If an agent is above its uncertainty threshold (it is confident in its answer), it returns the answer. If it is below the threshold (it is unsure), it delegates. But if the delegated agent is also below its threshold, the original agent should degrade gracefully rather than delegating again. Return an answer with an explicit uncertainty marker and let the calling agent decide how to handle it.
Loop Detection at the Orchestration Layer
The orchestrator agent should track delegation patterns and detect loops before they consume significant resources. If the orchestrator sees that agent B has been called three times in the last ten seconds with similar tasks, it should stop delegating to agent B and handle the task differently. This is rate-limiting applied to delegation.
The orchestrator should also monitor token consumption per task. If a task has consumed more tokens than expected without producing a result, it should abort the delegation chain and return a partial result with an explanation. Token-based abort prevents runaway delegation from generating unexpected costs.
Inconsistent State
When multiple agents operate on shared state, they can create inconsistent state. Agent A reads a customer record, decides to update the address, and sends the update. Agent B reads the same customer record before agent A’s update is applied, decides to update the phone number, and sends its update. Depending on the update mechanism, one update may overwrite the other.
This is the classic concurrent modification problem from distributed systems. It applies to multi-agent systems whenever agents share state through external systems like databases or APIs. The problem is worse in multi-agent systems because agents may not be aware that other agents are operating on the same state.
Mitigation: Optimistic Concurrency Control
Each agent reads the state with a version identifier (a timestamp, a sequence number, or an ETag). When updating, the agent includes the version identifier. If the state has changed since the agent read it, the update is rejected, and the agent must re-read and retry. This prevents silent overwrites.
The retry logic adds complexity to the agent. The agent must detect the rejection, re-read the current state, re-evaluate its decision based on the updated state, and retry the update. If the state has changed significantly, the agent’s original decision may no longer be valid. The agent must handle this gracefully rather than blindly retrying.
State Ownership
Another mitigation is to designate a single agent as the owner of each piece of state. If agent A owns customer records and agent B needs to update a customer, agent B delegates the update to agent A rather than performing it directly. This serializes access through the owning agent.
State ownership prevents concurrent modification but may create bottlenecks. If agent A is the sole owner of customer records and ten agents need to update customers simultaneously, agent A becomes a serialization point. The throughput is limited by agent A’s processing speed.
The trade-off depends on your concurrency requirements. If concurrent modifications are rare, optimistic concurrency control is simpler and higher-throughput. If concurrent modifications are common, state ownership provides stronger consistency guarantees at the cost of throughput.
Idempotent Operations
Design tool operations to be idempotent. If agent A sends the same update twice (because it retried after a timeout), the second update should have no effect. Idempotency requires the tool to detect duplicate requests, usually through a request ID or idempotency key.
Idempotency is essential for reliable multi-agent systems because agents will retry failed operations. Without idempotency, a retry can create duplicate records, send duplicate emails, or apply duplicate charges. The tool layer must handle idempotency, not the agent layer, because the agent does not know whether the tool received the first request.
Cascading Latency
Each agent call adds latency. Agent A waits for agent B, which waits for agent C. The total latency is the sum of all agent call latencies plus network overhead. In a chain of four agents, each taking two seconds, the total latency is eight seconds before the user receives a response.
Latency compounds non-linearly in practice because each agent may make multiple tool calls, and the tool calls add their own latency. A multi-agent system where each agent makes two tool calls at 500ms each, in a chain of three agents, produces a total latency of at least three seconds from tool calls alone, plus model inference time at each level.
Parallel Execution
The primary mitigation is parallel execution of independent subtasks. If agent A needs results from both agent B and agent C, and B and C are independent, call them in parallel rather than sequentially. This reduces the total latency to the maximum of the individual latencies rather than their sum.
Parallel execution requires the orchestrator to identify independence. If agent B’s task depends on agent C’s output, they cannot be parallelized. If they are independent, parallelization cuts latency roughly in half for two parallel calls, in thirds for three, and so on.
Timeout Enforcement
Each agent call should have a timeout. If the sub-agent does not respond within the timeout, the calling agent should handle the timeout gracefully. Three options exist. Retry the call (appropriate for transient failures). Use a degraded fallback like a cached result or a simplified heuristic (appropriate when some answer is better than no answer). Return an incomplete result with a clear explanation that some subtasks timed out.
The timeout should be set based on the expected latency of the sub-agent’s task plus a buffer for variance. A simple retrieval task might have a five-second timeout. A complex analysis task might have a thirty-second timeout. Do not set a single global timeout for all agent calls because different tasks have different latency profiles.
Circuit Breaking
If a sub-agent consistently fails or times out, stop calling it. The circuit-breaker pattern applies to multi-agent delegation: if agent B fails three times in a row, open the circuit and stop delegating to agent B. Route around the failure by using a fallback or reducing the scope of the task.
The circuit breaker should have a half-open state where it periodically retries the failed agent to see if it has recovered. If the retry succeeds, close the circuit and resume normal delegation. If it fails, keep the circuit open.
Failure Mode Summary
Cascading hallucination requires inter-agent verification and confidence scoring. Context window exhaustion requires context management discipline, hierarchical summarization, and context pinning. Dead loops require delegation depth limits, uncertainty thresholds, and loop detection. Inconsistent state requires optimistic concurrency control, state ownership, or idempotent operations. Cascading latency requires parallel execution, timeout enforcement, and circuit breaking.
The common thread is that multi-agent systems need the same distributed-systems patterns that microservices need: circuit breakers, timeouts, retries, idempotency, and eventual consistency. The models are non-deterministic, which adds a layer of complexity that deterministic microservices do not have. But the architectural patterns for handling failure, latency, and consistency are the same patterns that distributed systems engineers have been applying for decades.
Start with a single agent and add multi-agent delegation only when the task genuinely requires it. Every level of delegation adds failure modes, latency, and debugging complexity. The question is not whether multi-agent architectures are possible but whether the delegation justifies the operational overhead for your specific use case. For most production systems, one well-designed agent with good tool access outperforms three mediocre agents delegating to each other.
Ship it safely
If you’re hardening multi-agent failure modes for real users, our Multi-User Agent Hardening Sprint covers it end to end. For a fast baseline across the seven control layers, take the AI Production Scorecard.