Multi-Agent Orchestration
One agent has one context window, one tool list, one failure surface. Split it into many agents and you gain specialization, parallelism, and isolation — but the price is higher than most teams expect. The topology (supervisor, hierarchical, swarm) is only how you arrange the agents. The part that truly decides whether the system works is the handoff — the point where work passes from one agent to another. This is where context, and reliability, quietly get lost.
- hubMulti-agent is not a default — it's a tradeoff. You add agents to gain specialization, parallelism, or isolation. You pay in tokens, latency, and a brand-new failure surface. If a single agent with good tools works, use that.
- hubThree topologies, one spectrum of control. Supervisor/worker (a coordinator dispatches specialists — the ~70% production default), hierarchical (supervisors of supervisors), and swarm (peers hand off directly, no central control). More control vs. more autonomy.
- hubThe handoff is the real system. Most multi-agent failures are not caused by bad agents — they are caused by context lost at the handoff: the agent that receives the work does not get what the sending agent knew. Design the handoff data, not only the agents.
- hubAgents calling agents creates a large blast radius. Loops and uncontrolled fan-out spend your budget without warning. Depth limits, per-agent limits, and timeouts are not optional — they are what stops a swarm from spinning out of control.
- hubA2A is for crossing boundaries, not for your own graph. Inside one system, use your framework's handoffs. A2A earns its place when agents span vendors, clouds, or orgs and need a shared protocol to discover and delegate.
1Why split one agent into many at all
An agent is a model running in a loop with tools — it reasons, calls a tool, looks at the result, and repeats until the task is done. You can build a great deal with one such agent. So the first question, before any topology, is whether you need more than one agent at all. Many teams reach for multiple agents too early, and the extra cost is real.
A single agent has real limits. Give it forty tools and it chooses badly — too many options, unclear boundaries, wrong calls. Give it one large prompt covering billing and SSO debugging and refunds, and it does all three a little worse than three focused agents would. And everything runs in one context window and one sequential loop, so independent subtasks cannot run at the same time. Splitting into specialists fixes all three: each agent gets a small tool list, a focused prompt, its own context — and independent branches run in parallel.
But there is a cost demos rarely show: every new agent adds a failure surface, a context boundary, and more total cost. Each agent re-processes the shared context, so token usage grows quickly — a centralized multi-agent setup can cost several times more than a single agent for the same task. menu_book This is a real tradeoff, not a simple upgrade:
Adding an agent is like adding a team member: more capacity, but also more coordination work. Sometimes the right team size is one.
Start with a single agent. The best default is one well-scoped agent with a good set of tools. Move to multiple agents only when you reach a clear limit — too many tools, conflicting prompts, or a real need to run work in parallel. "It looks more advanced" is not a good reason. You pay the cost in tokens and reliability whether or not the split was needed.
2The three topologies, on one spectrum
Suppose you really need multiple agents. The next choice is how to connect them — and the field has settled on three arrangements. Treat them as points on one line, from centralized control to distributed autonomy, so you are choosing a position on a scale rather than learning three unrelated diagrams.
Supervisor / worker — the default
A central supervisor receives the task, decides which specialist handles each part, sends the work to workers, and collects their results. Workers talk only to the supervisor, never to each other. This is the most common production topology for a good reason: control is in one place and easy to follow, so routing is easy to debug, the stopping condition lives in one place, and you can understand the whole flow. The cost: the supervisor is a bottleneck and a single point of failure, and every step pays for a round-trip back to it. Start here.
Hierarchical — supervisors of supervisors
When one supervisor would have too many workers to route well, you add layers: a top-level supervisor coordinates middle-level supervisors, each owning a team of specialists — like a company org chart applied to agents. This scales the supervisor pattern to very large systems, because each coordinator manages only a few agents below it. The cost: extra latency (more layers to pass through) and more places where a handoff can lose context. Use it only when a single flat supervisor is clearly overloaded.
Swarm — peers, no boss
The swarm removes the supervisor. Agents hand off work directly to one another: each has handoff tools for the peers it can transfer to, and calling one passes control sideways. This is flexible and resilient — no central bottleneck, and the conversation can move wherever it needs to go. But no single component is in control, so the flow is harder to predict, harder to trace, and much easier to send into an endless loop. Powerful when used carefully, and the easiest topology to lose control of.
3The handoff is the real system
The topologies above show the agents and the lines between them. But the lines are where the real work happens, and they carry the main message of this article: the agents are the easy part; the handoffs are where multi-agent systems actually fail. This is what separates a system that works in a demo from one that survives in production.
When work passes from one agent to another, the receiving agent starts with a different context. The sending agent knew important things — the user's real goal, what it had already tried, the limits it found, its partly-finished reasoning. Unless you deliberately collect that and pass it along, it is lost. This is the most common failure in multi-agent systems, and it has a name: context loss at the handoff (the handoff is also called the "seam," the point where two agents meet). Each agent works correctly on its own; the system fails in the gap between them, because the handoff carried the task name but not the understanding behind it.
Most multi-agent bugs are not caused by a bad agent. They are caused by a good agent that received a task with none of the information needed to answer it.
The fix is to treat the handoff as data you design on purpose, not something added at the last moment. Everything the receiving agent needs to act — without working it out again — travels with the handoff: the original goal (not only the current subtask), relevant history, limits already found, and the structured arguments for the action. The interface between two agents is a contract, and a vague contract fails without warning. The tabs below show both handoff shapes, the supervisor-versus-swarm wiring, and the full supervisor graph assembled in one place:
# LOSSY: the handoff carries a bare instruction. The receiving agent
# has lost the goal, the history, and the constraints A discovered.
from langgraph.types import Command
def to_refund_agent(state):
return Command(
goto="refund_agent",
update={"task": "refund it"}, # <- that's all B gets
)
# B now re-asks the user or guesses the amount, the policy, the order…# STRUCTURED: a context packet travels with the handoff. B can act
# without re-deriving anything A already worked out.
from langgraph.types import Command
def to_refund_agent(state):
packet = {
"goal": state["user_goal"], # the ORIGINAL intent, not the subtask
"order_id": state["order_id"],
"amount": state["verified_amount"], # already computed & checked
"policy_ok": state["policy_checked"], # constraint A discovered
"history": state["summary"], # compacted, not the raw transcript
}
return Command(goto="refund_agent", update={"handoff": packet})
# B reads `handoff` and acts correctly on the first attempt.# SUPERVISOR: workers return to the coordinator, which routes next.
def supervisor(state):
nxt = pick_specialist(state) # the coordinator decides
return Command(goto=nxt) # control returns here after
# SWARM: agents hand off laterally to a PEER, no coordinator.
def billing_agent(state):
if needs_sso_help(state):
# goto a peer in the PARENT graph — control moves sideways, not up
return Command(goto="sso_agent", graph=Command.PARENT,
update={"handoff": build_packet(state)})
return {"messages": [answer(state)]}
# Same handoff discipline either way — the packet still has to be complete.# The whole supervisor topology in one place: state -> nodes -> router
# -> workers -> compile. Specialists are scoped; the supervisor routes.
from typing import Annotated, Literal
from typing_extensions import TypedDict
from langgraph.graph import StateGraph, START, END
from langgraph.graph.message import add_messages
class State(TypedDict):
messages: Annotated[list, add_messages]
next: str # which specialist runs next
def supervisor(state: State) -> dict:
# the coordinator decides who handles this; returns a routing label
return {"next": pick_specialist(state)} # "billing" | "sso" | "done"
def route(state: State) -> Literal["billing", "sso", "done"]:
return state["next"] # plain code — not the model — picks the edge
def billing(state: State) -> dict:
return {"messages": [run_billing(state)]} # tight tools, focused prompt
def sso(state: State) -> dict:
return {"messages": [run_sso(state)]}
builder = StateGraph(State)
builder.add_node("supervisor", supervisor)
builder.add_node("billing", billing)
builder.add_node("sso", sso)
builder.add_edge(START, "supervisor")
builder.add_conditional_edges("supervisor", route,
{"billing": "billing", "sso": "sso", "done": END})
builder.add_edge("billing", "supervisor") # workers report BACK to the supervisor
builder.add_edge("sso", "supervisor")
graph = builder.compile(checkpointer=checkpointer)
# Routing lives in `route` (code), not in a model's free-text — that's what
# keeps the topology deterministic and the flow traceable.Compact the handoff data — do not send the whole conversation. It is tempting to forward the entire raw conversation to the next agent, but this fills the receiving agent's context window. A model's context is a budget: a large amount of mostly-irrelevant history makes it slower and worse at finding what matters. Send a short structured summary plus the specific facts the next agent needs. The handoff is a context-window boundary, so treat it like one.
4Containing the blast radius
The handoff problem above is about correctness — work arriving complete. This section is about safety — what happens when the connections between agents form a loop or a flood. As soon as agents can call other agents, you create a failure a single agent never had, and it shows up directly as a large bill.
Single-agent systems call models and tools. Multi-agent systems add agents calling other agents — the traffic where cost can grow out of control. The main failure is not one bad decision but a large blast radius (the total damage one request can cause). Agent A hands work to B, B hands it back to A, and the loop spends tokens until something times out. Or a supervisor sends work to a dozen workers, each of those to a dozen more, and one request quietly creates hundreds of LLM calls. Swarms are especially at risk, because no central component is counting.
The defenses are operational, and not optional in production:
- Depth limits. Cap how many handoffs deep a request can go. Past the limit, stop and escalate instead of recursing forever.
- Per-agent budgets. Each agent gets a ceiling on calls (or tokens, or dollars) per request. When it's hit, the agent fails closed instead of fanning out further.
- Timeouts at every hop. A handoff that doesn't return in time is cancelled — no silent hangs waiting on a peer that looped away.
- Loop detection. Track the handoff path; if A→B→A→B repeats, break it — the same instinct that stops a single agent from calling one tool forever, applied to agents calling agents.
A swarm with no limits can spend your budget very fast. The flexibility that makes swarms attractive — any agent can hand work to any peer — is exactly what lets a request create endless repeated calls. If you choose the swarm topology, the depth limit, per-agent budget, and loop detector are part of the design from the start, not something added later. Centralized topologies are easier here, because the supervisor is a natural place to count.
5A2A: handoffs across boundaries
Everything so far assumed your agents live inside one system, sharing a framework and a graph. This section is about what changes when they do not — when a handoff has to cross between vendors, clouds, or organizations. That is a different problem with its own solution, and knowing when you actually need it keeps you from adding unnecessary complexity to the common case.
Inside one codebase, agents hand off through your framework's own mechanism (the Command handoffs above). But when an orchestrator on one platform must delegate to a specialist built by a different team, on a different cloud, in a different framework, there is no shared Command object between them. That is the gap A2A (Agent2Agent) fills: an open protocol, introduced by Google in April 2025 and now under Linux Foundation governance, that standardizes how independent agents discover, authenticate, and delegate to one another. menu_book
Two pieces matter. Agents publish an Agent Card — machine-readable metadata describing what an agent can do and how to reach it — so one agent can discover another's capabilities without a hardcoded integration. And the unit of work is a Task with a defined lifecycle, exchanged over standard web transports (JSON-RPC over HTTP, with streaming), which supports both quick calls and long-running, days-spanning delegations. Crucially, agents collaborate without sharing internal memory, tools, or implementation — the same structured handoff, now a protocol-level contract across an organizational boundary.
Do not use A2A inside your own graph. If all your agents run in one framework, A2A is extra complexity you do not need — use the framework's built-in handoffs. A2A is useful specifically at the boundary: between vendors, between clouds, between organizations. It is also still new as an enterprise pattern, so treat the protocol details as likely to change, and check the current specification before you build on them. [VERIFY: A2A governance, Agent Card schema, and transport details against the current specification before publishing.]
Securing this traffic is its own concern: A2A is agents calling agents across trust boundaries, so it carries every risk of letting one system act on another's behalf — authentication, least-privilege access, a governed boundary — now at the protocol layer. An open delegation protocol is also an open attack surface, governed by the same depth limits and gateways that contain blast radius.
6Choosing a topology
With the topologies, the handoff problem, the blast-radius controls, and A2A in hand, here is the decision itself — how to pick an arrangement for a real system. The right answer is rarely the most sophisticated one.
| If… | Use | Because |
|---|---|---|
| A single agent with good tools handles it | One agent | No handoff surface, no token tax. The right default. |
| A few specialists, one clear coordinator, you want it debuggable | Supervisor / worker | Central control is clear and easy to trace — the ~70% default. |
| Too many specialists for one supervisor to route well | Hierarchical | Nesting keeps each coordinator's fan-out manageable. |
| Dynamic, conversational flow where any specialist may need any other | Swarm (with limits) | Lateral handoffs fit fluid flows — but budget the blast radius. |
| Agents span vendors, clouds, or organizations | A2A at the seam | A shared protocol is the only way across a trust boundary. |
Notice the direction: the table starts at "one agent" and moves up, and every step adds cost. That is on purpose — use the smallest amount of orchestration that solves the problem, because each step up adds more handoffs, more latency, and more ways to fail. A more complex design is a cost, not a goal.
7The orchestration checklist
The pattern is complete; this section turns it into a pre-build gate. Each row distills one decision from the sections above into a single rule.
| Dimension | The rule |
|---|---|
| Default | One well-scoped agent first; split only at a specific ceiling |
| The tradeoff | Multi-agent buys specialization/parallelism/isolation; pays in tokens/latency/seams |
| Topology | Supervisor (default) → hierarchical (scale) → swarm (dynamic); pick the least |
| The handoff | Design the data you pass — goal, history, limits — not only the agents |
| Packet hygiene | Compact the context across the seam; don't ship the raw transcript |
| Blast radius | Depth limits, per-agent budgets, timeouts, loop detection — not optional |
| Swarms | Limits are part of the design, not a later hardening pass |
| A2A | Only at vendor/cloud/org boundaries; native handoffs inside one graph |
| Security | Agents calling agents carry every trust-boundary concern — authentication, least-privilege |
| Observability | Trace every handoff — "which agent did what" must be answerable |
| Economics | Multi-agent only when the task genuinely needs it; the token tax is real |
Conclusion: the handoffs, not the agents
Multi-agent orchestration looks like a problem about arranging agents — supervisor here, workers there, a swarm if you want something more advanced. But arranging the agents is the easy part. A single, well-scoped agent is still the best default; split it into many only when you reach a real limit: too many tools, conflicting prompts, or a true need to run work in parallel. When you do, you gain specialization and pay for it in tokens, latency, and a new failure surface.
And that failure surface is the handoff. The topology you choose — supervisor, hierarchical, swarm — is really a choice about where control lives, from one clear coordinator out to fully independent peers. But whichever you choose, the system succeeds or fails at the handoff: whether the receiving agent gets the goal, the history, and the limits, or only a task name with no meaning behind it. Design that handoff data, control the blast radius so agents calling agents cannot run away, and use A2A only when you cross a boundary your own framework cannot.
A single agent does the reasoning. Orchestration is how you combine many without losing what each one knew at the point where they connect. Get the handoff right, and the rest mostly takes care of itself.