← Blog

Multi-agent systems: when one agent isn't enough

Orchestrator/worker patterns, specialization, and shared context, plus the failure modes (cost blowups, loops, compounding errors) and how to contain them.

A single agent with a clear task and a modest set of tools is a solved problem in most engineering teams. You define the capabilities, set a budget, add a confirmation gate or two, and ship. But a meaningful class of real work exceeds what a single context window, a single role, or a single execution thread can do well. That is when you reach for multiple agents, and where things get genuinely complex.

Multi-agent systems are not just “more agents.” They introduce coordination, shared state, inter-agent trust, and compounding failure surfaces that simply don’t exist in single-agent designs. Getting them right requires understanding both why they help and precisely where they tend to go wrong.

When multiple agents genuinely win

The core cases are well-defined.

Parallel decomposition. Some tasks are naturally divisible into independent subtasks with no shared state between them. A research workflow might simultaneously gather information from three different domains, each handled by a dedicated agent. A document-processing pipeline might spawn one agent per file. When subtasks are independent, parallelism cuts wall time proportionally, something no amount of prompt engineering on a single agent achieves.

Specialization. A general-purpose agent prompted to do everything tends to do everything adequately. A focused agent with a narrow capability scope, purpose-built context, and a targeted system prompt tends to do its one thing well. The software engineering analogy is exact: a code-review specialist, a test-generation specialist, and an architecture-critique specialist will outperform a single agent instructed to “do all three.”

Separation of concerns. Keeping orchestration logic separate from execution logic produces systems that are easier to reason about, easier to monitor, and easier to repair when something breaks. The orchestrator should know the plan; the workers should execute steps. Conflating the two in one agent produces a monolith that is hard to debug and harder to extend.

Three structural patterns

Orchestrator + workers is the most common shape. A thin orchestrating agent manages a plan, dispatches steps to workers, and accumulates results. Workers are scoped: each knows only what it needs, calls only the tools its role requires, and returns a typed result. The orchestrator never delegates the plan itself, that is its invariant.

Debate and review uses agents in adversarial roles. One agent produces a draft; a second agent critiques it; a third might adjudicate. This pattern is particularly effective for tasks where correctness matters more than speed: complex code generation, policy documents, high-stakes summaries. It is expensive by design, run it where the cost of a wrong output exceeds the cost of two extra inference calls.

Pipeline chains agents sequentially, where each stage transforms the output of the previous one. Pipelines are simple to reason about but fragile to errors early in the chain: a bad extraction at step one contaminates every downstream stage. Pipeline designs should add verification steps between stages wherever the downstream cost of bad input is high.

The failure modes

High Cost blowups. Multi-agent systems have no natural spending ceiling unless you build one. Orchestrators that spawn workers recursively, workers that retry failures aggressively, or debate agents that loop on unresolved disagreements will exhaust a token budget quickly. Without explicit per-agent budgets enforced at the capability layer, a swarm will expand to consume every resource available.

Critical Infinite loops. Agents calling other agents can produce cycles. An orchestrator routes a failed result back to a worker; the worker produces the same failure; the orchestrator re-routes. Without a maximum-retry count and a failure-state exit path, the loop runs until something external breaks it, usually a timeout or an emptied wallet.

High Compounding errors. Each agent introduces a probability of producing a subtly wrong output. In a five-stage pipeline, five independent error probabilities combine. Small inaccuracies, a misclassified entity, a truncated extraction, a hallucinated field, accumulate across stages until the final output is wrong in ways no single stage’s output suggested. The further downstream from the original data, the harder these errors are to detect.

Context loss between agents. Agents communicate through interfaces, not memory. Information that was obvious to the orchestrating agent may not be in the payload passed to a worker. If the interface is underspecified, a string rather than a typed schema, a summary rather than the source, critical context vanishes in transit. Agents then fill gaps by inference, introducing errors that look deliberate.

Containment strategies

The antidotes map directly to the failure modes.

Per-agent budgets, maximum tool calls, maximum wall time, maximum write operations, enforced at the capability layer, not just declared in a prompt. A budget that lives only in a system prompt can be reasoned around. A budget enforced by the infrastructure cannot.

Clear, typed interfaces between agents. Every hand-off should be a structured schema, not a free-text string. The schema defines what the downstream agent is allowed to assume. Anything outside the schema is not assumed.

Verification steps at pipeline junctions. Before a result from one agent becomes the input to the next, a lightweight check confirms structural correctness and catches obvious failure signals. This is cheap relative to the cost of propagating a bad result through three more stages.

Explicit loop-detection and failure exits. Every agent invocation path should have a countable depth and a defined exit when a retry budget is exhausted.

Controls that must live at the capability layer
  • per_agent.tool_call_limit maximum actions before forced yield High
  • per_agent.write_op_limit caps mutations regardless of role Critical
  • swarm.spawn_depth maximum orchestrator/worker nesting High
  • swarm.total_budget aggregate ceiling across all agents Medium
  • interface.schema_enforcement typed hand-offs, rejected on violation Medium

The MCP-first angle

There is a subtler point underneath the containment mechanics. In a multi-agent system, sub-agents are still agents, they can call tools, write to systems, trigger external actions. If each agent has its own independently configured capability scope, a compromised or misbehaving sub-agent can exceed what the system as a whole intended to permit. Coordination without a shared policy layer is not coordination; it is parallel autonomy.

The MCP-first architecture addresses this structurally: every agent in the swarm, orchestrator and workers alike, acts through the same permissioned, audited capability layer. A sub-agent cannot call a tool its role was never granted, even if the orchestrator can. A write-restricted worker cannot be instructed by the orchestrator to perform an irreversible action outside its scope. Policy is not per-agent configuration; it is a property of the capability layer itself.

This means the swarm as a whole is bounded by the same rules as a single agent. Adding more agents does not widen the blast radius. It just adds parallelism within an already-controlled envelope.

Explore the long-horizon agent patterns for how decomposition, checkpointing, and human gates apply once you have an orchestrator running a plan across multiple workers.

A swarm that shares a capability layer is no more dangerous than a single agent, and often far more capable.

Multi-agent architecture