The previous post ended with a claim: for complex workflows, break the work into specialized agents that communicate through structured handoffs. This post is the deep dive into what that actually looks like in production.
We've been running multi-agent systems in production for six months. Some of them work beautifully. Others failed in ways that were genuinely surprising. What follows is everything we learned: the architecture, the failure modes, and the patterns that survived contact with real users.
Why single-agent systems hit a ceiling
A single agent with 30 tools, a long system prompt, and a prayer is the default architecture most teams start with. It works for demos. It works for simple tasks. It stops working the moment complexity crosses a threshold.
The failure mode isn't dramatic. The agent doesn't crash or hallucinate wildly. It just gets mediocre. Tool selection accuracy drops. Plans become vague. The model spends its reasoning capacity managing its own complexity instead of solving the user's problem.
This is the same reason companies have departments. An engineer could theoretically also handle sales calls, write legal contracts, and manage payroll. In practice, specialization wins because depth beats breadth when quality matters.
The multi-agent architecture
The core idea is simple: instead of one agent doing everything, you have a coordinator that delegates to specialists. Each specialist has a narrow focus, a small tool set, and clear boundaries.
Interactive. Click each agent
The orchestrator never touches tools directly. It only does three things: decompose tasks, delegate to specialists, and merge results. This separation is critical. The orchestrator reasons about what needs to happen, while specialists reason about how to do it.
| 1 | |
| 2 | |
| 3 | |
| 4 | |
| 5 | |
| 6 | |
| 7 | |
| 8 | |
| 9 | |
| 10 | |
| 11 | |
| 12 | |
| 13 | |
| 14 | |
| 15 | |
| 16 | |
| 17 | |
| 18 | |
| 19 | |
| 20 | |
| 21 | |
| 22 | |
| 23 | |
| 24 | |
| 25 | |
| 26 | |
| 27 | |
| 28 | |
| 29 | |
| 30 | |
| 31 | |
| 32 | |
| 33 | |
| 34 | |
| 35 | |
| 36 | |
| 37 | |
| 38 | |
| 39 | |
| 40 | |
The handoff protocol
The most important design decision in a multi-agent system isn't which model to use or how many agents to deploy. It's how agents talk to each other.
If agents communicate through natural language, say "hey, can you look up the pricing for these three competitors?", you get the same ambiguity problems that plague human organizations. Instead, we use typed message envelopes with strict schemas.
Interactive. Toggle paths, click messages
Every handoff is a typed envelope. The TaskEnvelope has required fields: task type, constraints, deadline. The ResultEnvelope has status, confidence, and structured data. No prose. No ambiguity.
Failure recovery at scale
Single-agent systems have a simple failure model: the agent either succeeds or fails. Multi-agent systems have a much richer failure space. An agent can partially succeed. A downstream agent can fail because an upstream agent returned low-quality data. The orchestrator itself can make a bad delegation decision.
We handle this with a layered recovery strategy:
- Tool-level retry: transient failures (network timeouts, rate limits) are retried automatically by the tool layer. The agent never sees them.
- Agent-level fallback: if the primary strategy fails, the agent tries an alternative. Cache instead of live API. Heuristic instead of model call.
- Orchestrator-level rerouting: if an agent fails completely, the orchestrator can reassign the task or adjust the plan.
- Human escalation: when no automated recovery is possible, escalate with full context and a suggested action.
Interactive timeline. Click to expand
The goal isn't zero failures. It's zero surprises. Every failure should be caught, classified, and handled by the right layer.
State management across agents
Here's where most multi-agent tutorials lie to you: they show agents passing messages back and forth as if that's all the state you need. In production, you need three distinct state layers:
| 1 | |
| 2 | |
| 3 | |
| 4 | |
| 5 | |
| 6 | |
| 7 | |
| 8 | |
| 9 | |
| 10 | |
| 11 | |
| 12 | |
| 13 | |
| 14 | |
| 15 | |
| 16 | |
| 17 | |
| 18 | |
| 19 | |
| 20 | |
| 21 | |
| 22 | |
| 23 | |
| 24 | |
| 25 | |
| 26 | |
| 27 | |
| 28 | |
The critical distinction: conversation state is private to each agent. Agent A cannot read Agent B's message history. They communicate only through the structured handoff protocol. This isolation is a feature, not a limitation. It prevents context pollution and keeps each agent focused.
Evaluation and observability
You cannot run a multi-agent system in production without observability. Every handoff, every tool call, every decision point needs to be logged with enough context to reconstruct the full execution path after the fact.
We instrument at three levels:
- Trace-level: a unique trace ID follows a request through every agent it touches, similar to distributed tracing for microservices.
- Decision-level: every time an agent chooses an action over alternatives, we log the choice and the reasoning. This is where you find systematic biases.
- Outcome-level: did the final result actually solve the user's problem? This requires ground truth, which is hard to get at scale, but even partial outcome data is invaluable.
| 1 | |
| 2 | |
| 3 | |
| 4 | |
| 5 | |
| 6 | |
| 7 | |
| 8 | |
| 9 | |
| 10 | |
| 11 | |
| 12 | |
| 13 | |
| 14 | |
| 15 | |
| 16 | |
| 17 | |
| 18 | |
| 19 | |
| 20 | |
| 21 | |
| 22 | |
When not to use multi-agent
Not every problem needs this architecture. The overhead is significant: typed protocols, orchestration logic, and observability infrastructure all add up. Use multi-agent when:
- The task naturally decomposes into distinct phases (research → create → review)
- Different phases need different tool sets or model capabilities
- You need different failure/recovery strategies at different stages
- The quality bar requires specialized validation (compliance, factual accuracy)
For everything else, a well-designed single agent with constrained tools is simpler, faster, and easier to debug.
Architecture is the art of drawing lines. Multi-agent is powerful because the lines are explicit. Just make sure you only draw them where the complexity demands it.
Multi-agent systems aren't a silver bullet. They're a way of managing complexity by making it visible. Typed handoffs make communication explicit. Layered recovery makes failure handling predictable. Observability makes debugging possible. The agents themselves are the easy part. It's the space between them that determines whether the system works.