Multi-Agent Systems and Agent-to-Agent Protocols
Up to this point in Arc 10 we've been living inside one agent. One model, one context, one tool loop, one budget. That picture is enough for a huge fraction of real work. Most of what gets shipped as "an agent" in 2026 is a single model running a tool loop over a carefully chosen set of tools, and it's fine.
This post is about what happens when it isn't fine, and about the protocols that are starting to appear for when one agent needs to call another agent instead of a tool. A useful reframing: instead of asking "how do I build a multi-agent system," ask "when is a single agent the wrong shape, and in what direction does it fail?" Multi-agent is the answer to a few specific failure modes, not a general upgrade.
Here's the handle I want you to carry out of this post. Agents are subroutines with private memory. Calling another agent is cheaper than blowing up your own context, and more expensive than just trying again. Everything else is a consequence of that sentence.
Why reach for a second agent at all?
A single agent running a tool loop has three budgets, and every one of them can run out.
The first is context. The model has a finite window. If the task needs 30k tokens of research, 10k tokens of plan, and 5k tokens of output, a 128k-context model can swallow it in one shot. A longer task starts choking on the middle of its own transcript. Context engineering (see the context engineering post) buys you a lot of room, but not infinite room.
The second is role. A single system prompt has to be everything: a planner, a coder, a reviewer, a critic, a formatter. Models are genuinely worse at holding that many hats at once. Role-mixed prompts show up as sloppier outputs on each individual role, not as one beautifully balanced output.
The third is parallelism. If a task has three independent subtasks, a single agent runs them sequentially. Three tool calls, three waits, three observations, one after another. Wall-clock time stacks up even when the work is embarrassingly parallel.
Multi-agent is what you reach for when one of those three budgets is the thing failing. Context is too full. Role is too mixed. Work is too serial. If none of those three is biting you, you almost certainly don't need a second agent, and adding one is going to make things worse before it makes them better.
Prereqs
This post assumes the previous Arc 10 posts. If any of these aren't sitting in your head already, backtrack first.
- The agent loop — the generate / parse / execute / resume cycle that runs inside every agent.
- MCP — the model-to-tool protocol. We'll contrast it with A2A shortly.
- Tool use and function calling — because the simplest way to "call another agent" is to dress it up as a tool.
Arc 9 material (retrieval, context engineering) helps too but isn't strictly required.
Three topologies: supervisor, swarm, pipeline
There's no canonical taxonomy of multi-agent systems, but almost everything in the field can be described as one of three shapes or a combination of them. Each shape is the answer to a different symptom.
Three multi-agent topologies. Supervisor delegates to workers and integrates their results. Swarm is peer agents talking directly. Pipeline is a strict ordered handoff from stage to stage. Each shape answers a different symptom.
Supervisor is one agent delegating to workers. The supervisor holds the plan. The workers do the heavy context-chewing work and hand back summaries. This is the shape Anthropic's research orchestrator pattern uses, the one OpenAI's Agents SDK promotes through its "handoffs" primitive, and the one LangGraph nudges you toward with its subgraph model. It's the default for a reason. There's one place to audit the decision, one place to catch errors, and the failure modes are the easiest to reason about.
Swarm is peer agents talking directly to each other. No boss. This is the AutoGen and MetaGPT shape, and it's where debate, critique, and adversarial loops live. It's also where most of the academic multi-agent research lives, because emergent coordination is an interesting research question. In production systems it's rarer, for a reason we'll come back to in the misconceptions section.
Pipeline is sequential handoff. Stage 1 finishes, hands its artifact to stage 2, stage 2 finishes, hands to stage 3. This is the oldest shape in computing (Unix pipes are multi-process pipelines), and it's often what people actually want when they think they want a "multi-agent system." If your task is transcribe → summarize → translate, that's a pipeline, and pretending each stage is a peer agent with negotiation rights is overkill.
So: three shapes, three symptoms. Supervisor is the answer to "my single agent's context is bloating." Swarm is the answer to "I need genuinely adversarial roles." Pipeline is the answer to "my task has fixed, ordered stages."
A minimal formalism: agents as graph nodes, tasks as state
It's useful to hold a simple picture. An agent is a node. A message from one agent to another is an edge. A task is a state machine that moves across those edges over time.
Google's A2A protocol makes this explicit. Every task has a lifecycle: submitted → working → input-required (optional, if the agent needs to ask back) → completed / failed / canceled. Agents publish an agent card that describes what they can do, what inputs they accept, what outputs they produce, and how they authenticate. When agent X wants to use agent Y, it reads Y's card, opens a task, streams in inputs, and listens for status updates and artifacts.
You can think of an agent card as an OpenAPI spec for an autonomous service. The tool interface (MCP) describes "here's a function you can call." The agent interface (A2A) describes "here's a whole autonomous thing with its own goals, memory, and latency, and here's how to hand it a task." That difference shows up in the interaction model: a tool returns a value, and an agent opens a task whose status can be streamed, updated, or canceled over time. That's a genuinely different kind of interaction than a function call, and the wire format reflects it.
We don't need the full A2A wire format for the mental model. What we need is the picture: agents are autonomous services that speak a shared task-oriented protocol, and the topology of who-can-call-whom is a graph.
Runtime: what actually moves between agents
So a supervisor calls a worker. What actually happens?
In the simplest case, the supervisor treats the worker as a tool. The worker's "function signature" is a task description. The supervisor emits a tool call, the runtime dispatches it to the worker (either in-process, as a subroutine, or over the network via A2A), the worker runs its own agent loop in its own context, and returns a result. From the supervisor's perspective, one tool call happened. From the worker's perspective, a whole agent loop ran.
The load-bearing move here is context isolation. The worker doesn't see the supervisor's transcript. It sees a fresh context containing the task description and whatever state was explicitly passed. It runs its loop, accumulates tokens, uses tools, and eventually returns. The supervisor never sees any of that intermediate work, only whatever summary the worker chose to hand back.
A supervisor delegates to a worker. The worker spins up a fresh context, runs its own loop with its own tools, and returns a summary. The supervisor's transcript shows one handoff in and one summary out — none of the worker's intermediate work crosses the boundary.
That's what the handle from the opening is really pointing at. The supervisor's context stays small because the heavy lifting happens in someone else's context, which is allowed to blow up because it's going to get thrown away in a second anyway. You've traded a single giant context for a bunch of small ones, and you've paid for the trade with whatever was lost in the summarization at the boundary.
The loss at the boundary is real. The supervisor never sees the worker's full reasoning, only the summary the worker chose to emit. If the worker made a subtle mistake in step 3 and still produced a plausible-looking summary at step 7, the supervisor has no way to catch it without re-examining the work. Handoffs are lossy by design, and designing the handoff (what gets summarized, what gets kept, what gets discarded) is most of the engineering work in a multi-agent system.
A2A vs MCP: orthogonal, not overlapping
Before we go further, let me nail down a point that's easy to conflate. MCP and A2A are not competing protocols. They operate on different axes.
MCP is the protocol a model uses to talk to tools. Read files, query databases, hit APIs. The thing on the other end of an MCP call is passive: it does what it's told and returns. There's no "state" to the tool beyond whatever the tool's own backend has. A filesystem server doesn't have a context window. A Postgres server doesn't have goals.
A2A is the protocol an agent uses to talk to other agents. The thing on the other end of an A2A call is another full LLM-powered thing with its own context, its own tools (likely including its own MCP clients), its own running loop. The caller doesn't know, and doesn't need to know, how the callee gets its job done. It just opens a task and waits.
The two compose cleanly. A supervisor agent can speak MCP to its filesystem and A2A to its researcher worker, in the same loop, at the same time. The researcher worker can, in turn, speak MCP to its web-search tool and A2A to a third-party fact-check agent. MCP gives a model its hands. A2A gives an agent its peers.
The coordination tax is real
None of this is free. Every multi-agent system pays a tax that a single agent doesn't, and the tax comes in three forms.
The coordination tax: tokens spent on scaffolding, latency added by handoffs, and information lost across summarization boundaries. The bars compare a single agent against two-, three-, and five-agent setups on the same task.
Token tax: every handoff means re-prompting. The supervisor's prompt is re-emitted to every worker call. The worker's summary is re-emitted back. The more agents, the more round trips, the more tokens spent on scaffolding relative to useful output. A five-agent swarm can easily spend 4× the tokens of a single agent on the same task, with most of those tokens going to "hi, here's your sub-task" and "here's my summary of my sub-task."
Latency tax: every handoff is a round trip. Even if the work is parallelized, the orchestration overhead (wait for all workers, reconcile results, possibly re-delegate) adds wall-clock time. In a pipeline, latency stacks strictly. In a supervisor pattern with parallel workers, latency is bounded by the slowest worker plus orchestration overhead. In a swarm, latency is bounded by however long it takes the peers to stop arguing.
Handoff loss: every summary is lossy. The receiving agent rarely has full provenance into the upstream agent's reasoning. It sees an artifact and a claim about that artifact, and it has to decide whether to trust it. Errors in early stages cascade, because late-stage agents have no way to catch them without redoing the work.
Cognition wrote a blog post in June 2025 called "Don't Build Multi-Agents" that made the strongest form of this argument: most tasks people throw at multi-agent systems would be better served by a single agent with better context management. The argument resonated immediately. A lot of 2024 multi-agent demos would have been outperformed by a single strong model running a longer loop. The thing that shifted in 2025 was honest telemetry: when Anthropic and others published their research-orchestrator results, they were careful to measure against a strong single-agent baseline, and the supervisor pattern did win, but only on genuinely decomposable tasks and only with careful handoff design. The Cognition critique and the Anthropic pattern are both right, at different ends of the task spectrum.
Worked example
Let's do the thing. Task: "Write a short blog post about the vLLM paper's key contributions, with a working Python snippet showing the PagedAttention idea."
A single agent on a 128k context can almost do this. It will fetch the paper, read it, draft prose, write a snippet, and usually produce something decent. But the paper is long, the code needs care, and the two roles (literary critic and systems programmer) pull in different directions. Role bleed shows up as prose that sounds like a code comment, or code that reads like it was written by someone hedging against reviewers.
A two-agent supervisor pattern decomposes this cleanly.
- Supervisor: holds the plan. Has a short system prompt: "You are a writing supervisor. Delegate research and coding subtasks. Integrate results. Output one blog post."
- Researcher: long context, strong reading. System prompt: "You extract key claims from technical papers. You return a bulleted summary with citations."
- Coder: short context, strong code discipline. System prompt: "You write small, correct, self-contained Python snippets. You never hand-wave."
The supervisor emits two delegations: delegate(researcher, "summarize 2309.06180") and, once the summary returns, delegate(coder, "implement a minimal PagedAttention block from this summary"). It then drafts prose around the two artifacts and returns one post.
What did we buy with the extra agents? The researcher's context gets to fill up with the paper without dragging the supervisor's context along, the coder runs with a clean systems-programming persona and no literary noise, and if the researcher and the coder could run in parallel (they can't here, because the coder needs the summary, but in general) we'd get a latency win too.
What did we pay? The supervisor's handoffs are lossy. The coder only sees the researcher's summary, not the full paper, so if the summary omits a subtle detail the code needs, the code will silently get it wrong. Debugging is also harder, because when the final post has a bug in its snippet, it isn't obvious whether to blame the coder, the summary it worked from, or the researcher's reading of the paper.
That tradeoff, "decomposed work, lossy boundaries", is the whole story of multi-agent engineering.
Implementation sketch
Here's the worked example, wired up. I'm using the OpenAI Agents SDK's handoff primitive because it's the cleanest public-facing shape for supervisor/worker in 2026, but the pattern is identical in LangGraph or a raw loop. The point is how little code it takes.
from agents import Agent, Runner, handoff
# Two specialists. Each has a narrow system prompt and owns a fresh context.
researcher = Agent(
name="researcher",
instructions=(
"You extract key claims from technical papers. "
"Return a bulleted summary with section citations. "
"Be terse. Facts over flourish."
),
tools=[web_search, read_url], # MCP-backed tools, defined elsewhere
)
coder = Agent(
name="coder",
instructions=(
"You write small, correct, self-contained Python. "
"No pseudocode, no TODOs. If you can't do it cleanly, say so."
),
tools=[run_python],
)
# The supervisor delegates by handing off. From its POV, each worker
# looks like a tool that accepts a task and returns a result.
supervisor = Agent(
name="supervisor",
instructions=(
"You coordinate a researcher and a coder to produce one blog post. "
"Delegate, integrate, return one coherent piece."
),
handoffs=[handoff(researcher), handoff(coder)],
)
# Run it. The SDK manages the context-isolated worker loops for you.
result = Runner.run_sync(
supervisor,
"Write a short post on vLLM's PagedAttention, with a working Python snippet.",
)
print(result.final_output)A few things worth noticing. The worker loops don't appear in this file. The SDK handles context isolation: when the supervisor invokes handoff(researcher), a separate agent loop runs in its own context, with its own tool budget, and returns only its final output to the supervisor. The supervisor's transcript shows one handoff in and one summary out. It does not show the researcher's 40 tool calls.
The shape of this code is why this pattern keeps winning in production. There's one obvious place to tune each worker (its instructions, its tools), one obvious place to audit the plan (the supervisor's instructions), and one obvious boundary where information is lost (the handoff return value). Debugging is a matter of checking which boundary the information stopped flowing across. A five-way peer swarm usually doesn't give you that clarity.
Misconceptions
"Multi-agent always beats single-agent." No. Cognition's critique from 2025 still holds: most tasks are better served by a single strong agent with better context management. The coordination tax is real, and the handoff loss is real, and both of them show up as a quality regression on anything the single agent could have done in one shot. Reach for multi-agent when a specific budget (context, role, parallelism) is the thing failing. Don't reach for it because it sounds more sophisticated.
"A2A and MCP overlap, and one of them will win." They don't overlap, and they won't displace each other. MCP is model-to-tool. A2A is agent-to-agent. They live on different layers of the stack and compose cleanly. An agent speaks MCP down to its tools and A2A across to its peers in the same loop. The Google A2A announcement was careful about this and explicitly positioned A2A as complementary to MCP rather than competing with it. Expect both to stick around.
"Swarm is the most powerful pattern because it's the most general." Peer coordination is the hardest pattern to debug, not the most effective one in practice. When three peers disagree, who wins? When one peer stalls, who breaks the tie? Most swarm designs end up adding a coordinator anyway, at which point they're a supervisor pattern with extra steps. Supervisor wins more often than swarm does, and the reason is boring: there's one place to look when something goes wrong.
"Context can be safely passed at the handoff boundary." No, it can't, not completely. Summaries are lossy and order-sensitive, and the receiving agent rarely has full provenance into the sending agent's reasoning. If you design a multi-agent system as if handoffs were zero-cost, you'll be surprised by silent quality regressions where stage N made a decision based on a summary that stage N-1 didn't know was load-bearing. The engineering move is to be explicit about what information crosses the boundary, and to treat the boundary as a thing that can fail, not as a transparent wall.
What's next
That closes Arc 10. The next arc steps back from the loop and looks at the provider ecosystems practitioners actually build against. The next post covers OpenAI's API: from Chat Completions to Responses, walking through the four generations of OpenAI's API and what each one shipped that mattered.
Additional reading (and watching)
-
OpenAI. (2025). OpenAI Agents SDK documentation: Handoffs. Reference for the handoff primitive used in the worked example.
-
Wu, Q., et al. (2023). AutoGen: Enabling Next-Gen LLM Applications via Multi-Agent Conversation. arXiv:2308.08155. The canonical peer-agent conversation framework and one of the main academic references for multi-agent patterns.
-
Hong, S., et al. (2023). MetaGPT: Meta Programming for a Multi-Agent Collaborative Framework. arXiv:2308.00352. Role-specialized agents (PM, architect, engineer) collaborating on software tasks; a clear example of the swarm-with-roles shape.
-
Google. (2025). Agent2Agent (A2A) Protocol and its specification. Canonical reference for agent cards, the task lifecycle, and streaming updates.
-
Cognition. (2025). Don't Build Multi-Agents. Influential June 2025 blog post arguing that most multi-agent systems underperform a well-engineered single agent. Cited for the coordination-tax critique.
-
Anthropic. (2025). How we built our multi-agent research system. Internals of the Claude-based research orchestrator, including why parallel workers and careful handoff design were both load-bearing.
-
OpenAI. (2025). OpenAI Agents SDK — Handoffs reference. Detailed documentation for the handoff primitive, including how the context-isolated worker loop is spawned and how tracing spans the boundary.
-
CrewAI. (2024–2026). CrewAI Documentation. One of the main frameworks around role-specialized multi-agent orchestration; a concrete point of reference for supervisor and pipeline patterns.
-
LangChain. (2024–2026). LangGraph Documentation. Graph-oriented multi-agent orchestration with explicit subgraphs, the cleanest public expression of the "agents as graph nodes" formalism.