Once you've grasped the concept of "coordinating multiple AIs" in What is a multi-agent system?, the next question is how to actually build one. This article walks through a 5-step practical process for beginners, using the 2026 de facto standard: the supervisor pattern.

Before getting into frameworks, here is the most important principle: "build with a single agent first, and add agents minimally only after you hit a limit." Starting with a crowd is usually over-engineering. The second half shows minimal, readable code that follows the official Claude Agent SDK and OpenAI Agents SDK documentation, plus how to split roles and the failures people actually run into. The same thinking applies if you connect tools through MCP.

HOW TO BUILD MULTI-AGENT · 5 STEPS

Build small, measure, then add

— The supervisor pattern, from a minimal setup

1Decompose the task
2Define workers (up to 3-5)
3Design the supervisor
4Decide handoff & context sharing
5Measure and run with caps

Note: the code follows the official Claude Agent SDK and OpenAI Agents SDK documentation (checked October 4, 2026). These SDKs change quickly, so confirm parameter names in each official doc before running anything. Every figure in this article names its source.

1. Before you build: do you really need multi?

The first gate isn't technical — it's a judgment call. Multi-agent is powerful, but it doesn't help every job. If none of the following apply, build with a single agent first.

3 signs you should go multi

  • Specialization split: the knowledge won't fit in one prompt (domains span research, legal, code, etc.)
  • Parallelism: doing several tasks at once is clearly faster
  • Decision separation: quality improves when you split "doer" and "verifier"

As noted in the previous article, using multi-agent on a one-track process costs you. In a Google Research study (published January 2026, comparing 180 configurations), every multi-agent variant tested did 39–70% worse than a single agent on a task requiring strict sequential reasoning (PlanCraft). Costs rise too: in its write-up of its own research agent, Anthropic reports that agents use about 4× the tokens of a chat, and multi-agent systems about 15×. Start from the premise that more agents do not mean more intelligence.

2. The base shape: the supervisor pattern

If you're unsure which pattern to use, starting with the supervisor pattern is the safe choice. The major SDKs document it as a core pattern. In the Claude Agent SDK, the main agent calls subagents through the Agent tool; in the OpenAI Agents SDK, the equivalent is "agents as tools," where a manager agent calls specialist agents as tools.

One owner of the final answer

The supervisor keeps control of the conversation and combines the workers' results into one answer. OpenAI's docs recommend this shape when you want one agent to own the final answer.

Errors spread less

In the same Google Research study, agents running in parallel without talking amplified errors 17.2×, while setups with an orchestrator kept it to 4.4×.

Easy to audit

Who was asked to do what, and what came back, stays in the supervisor's history. Because each worker gets its own tool set, you can also bound the damage.

The mechanics are simple. The supervisor receives the overall task, breaks it into subtasks, delegates them to specialist workers, and aggregates the results. The supervisor needn't know how a worker does its job — only which worker to call and in what output format. The expertise lives in the workers.

Note that in the OpenAI Agents SDK, a handoff means something narrower than the general passing of work in Step 4: a triage agent passes the conversation itself to a specialist, who then answers the user directly. No supervisor remains, so treat it as a different pattern from the supervisor (Section 6 covers when to use which).

3. Build it in 5 steps

Assemble a minimal supervisor setup in five steps. The rule of thumb: start with 2-3 workers, then add more only as measurement justifies it.

STEP 1. Decompose the task

Write down the "end goal" and the "specialist roles" needed. Example: for a market research report, "1) gather info → 2) analyze → 3) write → 4) fact-check." Decompose clearly up front — vagueness here collapses the whole thing.

STEP 2. Define workers (up to 3-5)

Give each worker one role, the tools it needs, and an output format. Don't be greedy at first — 3-5 max. Each worker is independent and holds only its own tools (search, code execution, etc.).

STEP 3. Design the supervisor

In the supervisor's prompt, explicitly list the worker names it may call (a hard cap). The trick: spend more time on the supervisor than on any individual worker. This determines overall quality.

STEP 4. Decide handoff & context sharing

Define what is passed between workers, and in what format. Passing the full context to everyone bloats tokens, so pass only the needed information. The standard protocol for agent-to-agent coordination is A2A.

STEP 5. Measure and run with caps

Instrument every handoff before adding agents (observability is not optional). Set caps on iterations, tokens, and cost. Set up evals and guardrails at the same time.

4. Minimal code ①: Claude Agent SDK (Python)

First, build one supervisor plus two workers (a researcher and a reviewer) with Anthropic's Claude Agent SDK. Setup is just pip install claude-agent-sdk and the ANTHROPIC_API_KEY environment variable (official quickstart; the SDK doesn't load .env files automatically). The code follows the official Subagents page. For the SDK as a whole, see our Claude Agent SDK guide.

import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions, AgentDefinition, ResultMessage

options = ClaudeAgentOptions(
    model="claude-opus-5-5",  # the supervisor (main agent)
    system_prompt=(
        "You coordinate a research report. Delegate research to researcher and fact-checking "
        "to reviewer, and write the final text yourself. When delegating, always state the "
        "goal, the output format, and the scope."
    ),
    allowed_tools=["Agent", "WebSearch", "WebFetch"],  # tools that run without a prompt
    agents={
        "researcher": AgentDefinition(
            description="Gathers primary sources. Use when facts or figures are needed.",
            prompt="Find primary sources for the question and return bullet points with source URLs. Never fill gaps with guesses.",
            tools=["WebSearch", "WebFetch"],  # the only tools this role has
            model="sonnet",
            maxTurns=15,
        ),
        "reviewer": AgentDefinition(
            description="Fact-checks drafts. Always use before finalizing text.",
            prompt="Check each claim in the draft against its source and list every sentence that lacks support.",
            tools=["WebFetch"],
            model="sonnet",
            maxTurns=10,
        ),
    },
    max_turns=30,         # cap on round trips for the whole run
    max_budget_usd=5.0,   # spend cap (the SDK's estimate)
    env={"CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH": "1"},  # workers can't spawn their own
)


async def main():
    try:
        async for message in query(
            prompt="Find three official statistics on workplace use of generative AI and write a short report",
            options=options,
        ):
            if isinstance(message, ResultMessage):
                print(message.subtype, message.total_cost_usd)
                print(message.result)
    except Exception as error:
        print(f"Stopped early: {error}")  # hitting a cap also lands here


asyncio.run(main())

Five things to notice:

  • Workers go in agents as AgentDefinition entries. The supervisor reads each worker's description to decide whom to call and when, so describe concretely what the role does and when to use it.
  • Listing tools means the role gets only those tools. That's why the reviewer has no write tools. allowed_tools, by contrast, lists tools that run without a permission prompt; it doesn't restrict anything (official Python reference).
  • Put caps in three places. A per-role maxTurns, an overall max_turns, and a spend cap with max_budget_usd. When an overall cap is hit, the result subtype becomes error_max_turns or error_max_budget_usd and the run stops (agent loop docs).
  • Stop the nesting. Subagents can spawn subagents of their own. Setting the CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH environment variable to 1 makes workers do the work themselves. CLAUDE_CODE_MAX_CONCURRENT_SUBAGENTS (default 20) limits how many run at once.
  • AgentDefinition fields are camelCase. Writing max_turns instead of maxTurns raises a TypeError at construction time (an official note). The supervisor uses the current claude-opus-5-5; the workers use the alias "sonnet", so the code keeps working when a new version ships.

The official docs point out that Opus 5 delegates to subagents more readily than earlier models, and recommend setting depth, concurrency, and spend limits in addition to prompt instructions. An instruction only changes how Claude asks for help; only the limits reliably stop a run.

5. Minimal code ②: OpenAI Agents SDK (Python)

In OpenAI's Agents SDK, the same shape turns specialist agents into tools with as_tool() and passes them to the supervisor's tools (official "agents as tools"). Setup is pip install openai-agents plus the OPENAI_API_KEY environment variable (official quickstart). If you omit model, the SDK's default model is used; that default changes between SDK versions, so check the Models page.

import asyncio
from agents import Agent, Runner, WebSearchTool

researcher = Agent(
    name="Researcher",
    instructions="Find primary sources for the question and return bullet points with source URLs. Never fill gaps with guesses.",
    tools=[WebSearchTool()],
)
reviewer = Agent(
    name="Reviewer",
    instructions="Check each claim in the draft you receive against its source and list every sentence that lacks support.",
)

manager = Agent(
    name="Manager",
    instructions=(
        "You coordinate a research report. Delegate research to research and fact-checking "
        "to review, and write the final text yourself."
    ),
    tools=[
        researcher.as_tool(
            tool_name="research",
            tool_description="Gather primary sources with citations",
            max_turns=10,  # cap on this role's round trips
        ),
        reviewer.as_tool(
            tool_name="review",
            tool_description="Fact-check a draft",
        ),
    ],
)


async def main():
    result = await Runner.run(
        manager,
        input="Find three official statistics on workplace use of generative AI and write a short report",
        max_turns=10,  # exceeding it raises MaxTurnsExceeded
    )
    print(result.final_output)


asyncio.run(main())

What the two SDKs share, and where they differ:

  • Workers don't know the parent's conversation. An agent called through as_tool() doesn't automatically inherit the parent run's conversation state (official docs). The Claude Agent SDK works the same way: the only thing a subagent receives from the parent is the Agent tool's prompt. Put file paths, error messages, and decisions into the request itself.
  • The cap is Runner.run(..., max_turns=). Exceeding it raises MaxTurnsExceeded. Passing error_handlers={"max_turns": ...} lets you return a controlled answer instead of an exception (Running agents).
  • With handoffs you'd write Agent(..., handoffs=[billing_agent, refund_agent]). The receiving agent takes over the conversation and, by default, sees the entire previous conversation history. If there's information it shouldn't get, narrow it with an input_filter.

6. Splitting roles: good and bad splits

The split is harder than the code. Anthropic writes that each subagent needs an objective, an output format, guidance on the tools and sources to use, and clear task boundaries (same write-up). Here are splits that meet those four conditions and splits that don't.

Split Verdict Why
By expertise and tools (research, writing, fact-checking) Good Each role gets only the tools and permissions it needs. The reviewer can be read-only.
By independent target (research three vendors' products, one each) Good They run in parallel without waiting on each other, and the supervisor compares at the end.
Chopping a one-track pipeline into roles (summarize → format → translate) Avoid Each step just waits for the previous one, so nothing runs in parallel, and context is lost at every handoff. A single agent is enough.
Handing the same question to several roles without scoping it Avoid In Anthropic's early version, on a semiconductor-shortage query, one subagent explored the 2021 automotive chip crisis while two others duplicated work on 2025 supply chains.
Merging the doer and the checker into one role Avoid The role ends up checking its own output, which defeats the point of a separate check.

The same write-up gives a guide to how many agents to use. Anthropic embedded scaling rules in its research supervisor's prompt: simple fact-finding needs one agent with 3–10 tool calls, direct comparisons 2–4 subagents with 10–15 calls each, and complex research might use more than 10 subagents. Those numbers are for research work, so in your own job start at the small end and add only after measuring.

For supervisor versus handoff, OpenAI's docs give a clear rule. If you want one agent to own the final answer or to combine several specialists' outputs, use the supervisor (agents as tools). If routing is itself the job and the chosen specialist should answer the user directly (triaging support requests, for example), use a handoff. You can combine the two.

7. Common failures and fixes

Where people stumble is predictable. Below are failures Anthropic says actually happened with its research agent, plus the points both SDKs' official docs warn about.

Failure Fix
Spawning a crowd for an easy question (Anthropic's early version spawned 50 subagents for simple queries) Write scaling rules into the supervisor's prompt, and cap concurrency and spend.
Searching endlessly for sources that don't exist (another early failure) Cut it off with a per-role maxTurns and an overall max_turns.
Workers duplicating each other's work State the goal, output format, and scope (including what not to do) in every request.
A worker answers off-target because it lacks context The parent's conversation isn't passed on. Write the facts it needs into the request.
The supervisor does the work itself instead of delegating Make each description concrete, or name the worker in the prompt (the Claude Agent SDK's official troubleshooting).
Token bloat (multi-agent uses about 15× the tokens of a chat) Pass only what's needed, not the full context. Use cheaper models for workers.
Accuracy drops on sequential tasks (a study measured 39–70% worse) If the work is one-track, go back to a single agent.
You can't tell where it failed Log every call. In the Claude Agent SDK, tool_use blocks named Agent and the parent_tool_use_id field tell you which role produced each message.

The shared lesson: "prompts, tool design, and the eval harness decide success more than the framework does." OpenAI's docs likewise list investing in good prompts, monitoring and iterating, specialized agents, and evals. Over a flashy architecture, the discipline of building small, measuring, and adding only when it pays off is what's fastest in the end.

Summary

Building a multi-agent system isn't scary if you start with the supervisor pattern from a minimal setup. Let's recap.

Key takeaways

  • 🚦 Start single. On sequential tasks, one study found every multi-agent setup 39–70% worse.
  • 🧠 The base shape is the supervisor. Subagents in the Claude Agent SDK, agents as tools in the OpenAI Agents SDK.
  • 🔢 5 steps: decompose → define workers → design the supervisor → handoffs → measure.
  • 🧩 Splitting: by expertise, tools, or independent targets. Don't chop a one-track pipeline into pieces.
  • ⚠️ Caps in three places (per role, overall, spend). Give every worker a goal, a format, and a scope.

"Build small, measure, then add." Keep that discipline and a multi-agent system becomes a powerful partner for complex work. For the concept, see What is a multi-agent system?; for building a single one, How to build an AI agent.

FAQ

Q. Which pattern should I build first?

A. The supervisor pattern, no question. Major frameworks support it, its failure mode is known, and reference implementations are the most abundant. Explore other patterns once you're comfortable.

Q. How many workers should I start with?

A. Start with 2-3, and keep it to 3-5 at most. The more you add, the more unstable it gets and the more tokens balloon. The norm is to add more only once measurement proves the need.

Q. Do I need a framework (SDK)?

A. No. OpenAI's docs also describe orchestrating via code, such as using structured outputs to classify a task and pick the next agent, or looping a task agent with an evaluator agent, and note that this is more predictable in speed, cost, and performance. That approach suits work whose order is fixed. If you'd rather not write session storage, tool permissions, and caps yourself, an SDK is the shortcut.

Q. How do I prevent cost blowups?

A. Four things work: ① cap round trips overall and per role, ② cap spend (max_budget_usd in the Claude Agent SDK), ③ pass only what's needed instead of the full context, and ④ use cheaper models for workers. Anthropic found multi-agent systems used about 15× the tokens of a chat, so put the caps in from day one.