Skip to main content

What is multi-agent orchestration?

Multi-agent orchestration is the practice of coordinating multiple AI agents — each with its own tools, expertise, and scope — so they collaborate on a shared goal through structured handoffs and explicit control flow. Instead of one large agent doing everything, orchestration decomposes a complex task into sub-problems that specialized agents solve in parallel or sequence.

The key word is orchestration: who decides which agent handles what, when control passes from one agent to another, and how results are combined.

Why use multiple agents?

A single ReAct agent with unlimited tools has problems:

  • Context length: every tool result goes into the same context window
  • Focus: an agent trying to do everything often does nothing well
  • Parallelism: sequential tool calls are slow; specialized agents can run in parallel
  • Cost: a large reasoning model is expensive for simple subtasks

Multiple agents solve these by dividing responsibility: a supervisor decides what to do, specialists execute specific work, results are aggregated at the end.

Orchestration patterns

Supervisor + specialists

A supervisor agent receives the user's goal and routes to specialist agents:

User → Supervisor
├── Research agent (web search, summarize)
├── Code agent (write and run code)
└── Writing agent (draft final output)

The supervisor does not do the work — it decomposes and delegates.

Swarm (peer-to-peer handoffs)

Agents hand off to each other directly based on context:

User → Customer support agent
→ (escalate) Billing agent
→ (technical) Engineering agent

No central supervisor. Each agent decides when to hand off.

Parallel fan-out

A coordinator dispatches work to multiple agents simultaneously and aggregates results:

User query → Coordinator
├── Agent A (source 1) ─┐
├── Agent B (source 2) ─┤→ Aggregator → Final answer
└── Agent C (source 3) ─┘

Building multi-agent systems with AgentFlow

Supervisor pattern

from agentflow.prebuilt import ReactAgent, SupervisorTeamAgent
from agentflow.core.state import AgentState, Message

def search_web(query: str) -> str:
"""Search the web."""
return f"Search results for: {query}"

def run_python(code: str) -> str:
"""Execute Python code in a sandbox."""
return f"Output: (execution result)"

research_agent = ReactAgent(
name="researcher",
model="google/gemini-2.5-flash",
system_prompt=[{"role": "system", "content": "You are a research specialist. Search the web for information."}],
tools=[search_web],
)

code_agent = ReactAgent(
name="coder",
model="google/gemini-2.5-flash",
system_prompt=[{"role": "system", "content": "You are a coding specialist. Write and run Python code."}],
tools=[run_python],
)

team = SupervisorTeamAgent(
model="openai/gpt-4o",
agents=[research_agent, code_agent],
system_prompt=[{"role": "system", "content": "Route tasks to the right specialist agent."}],
)

app = team.compile()

Explicit handoff between agents

For precise control, use AgentFlow's Command and handoff tools:

from agentflow.core.graph import Agent, StateGraph
from agentflow.prebuilt.tools.handoff import create_handoff_tool
from agentflow.core.state import AgentState
from agentflow.utils import END

handoff_to_billing = create_handoff_tool(agent_name="billing")
handoff_to_support = create_handoff_tool(agent_name="support")

triage_agent = Agent(
model="google/gemini-2.5-flash",
tool_node="billing",
system_prompt=[{"role": "system", "content": "Triage support requests. Handoff billing questions to the billing agent."}],
)

billing_agent = Agent(
model="google/gemini-2.5-flash",
system_prompt=[{"role": "system", "content": "Handle billing questions."}],
)

graph = StateGraph(AgentState)
graph.add_node("triage", triage_agent)
graph.add_node("billing", billing_agent)
graph.add_conditional_edges("triage", lambda s: "billing" if s.next_agent == "billing" else END)
graph.add_edge("billing", END)
graph.set_entry_point("triage")

app = graph.compile()

Orchestration vs single agent

Single agentMulti-agent
Context windowShared by all tasksScoped per agent
Tool countUnlimited but noisyFocused per specialist
ParallelismSequential by defaultAgents can run in parallel
DebuggingOne tracePer-agent traces
CostSame model for all tasksCheap model for simple tasks

For most tasks under 10 tool calls, a single ReAct agent is simpler. Move to multi-agent when you hit context limits, need parallel execution, or specialists have meaningfully different capabilities.

Frequently asked questions

What is the difference between a supervisor agent and a swarm?
A supervisor agent has explicit control: it receives the task, decides which agent handles it, and aggregates results. A swarm uses peer-to-peer handoffs: each agent decides whether to handle the request or pass it to a more appropriate peer. Supervisors are easier to debug; swarms are more flexible for open-ended routing.
How do agents share state in a multi-agent system?
In AgentFlow, agents in the same graph share a single AgentState object that flows through the graph. Each agent reads from and writes to this shared state. For agents running in separate graphs, state is passed through the message payload at handoff time.
Can multi-agent systems run agents in parallel?
Yes. AgentFlow's StateGraph supports parallel branches: you can fan out to multiple agent nodes simultaneously and merge results. The graph engine handles concurrent execution via Python's async runtime.
Is multi-agent orchestration the same as LangGraph's multi-agent support?
Both LangGraph and AgentFlow support multi-agent orchestration using graph-based routing. AgentFlow includes the production stack (API server, TypeScript client) needed to deploy these systems without additional configuration. See the AgentFlow vs LangGraph comparison for a detailed breakdown.
When should I use a single agent vs multiple agents?
Use a single agent for tasks with fewer than 10–15 tool calls that fit in one context window. Use multiple agents when: the task decomposes naturally into specialist roles, some subtasks can run in parallel, different subtasks need different models (cheap vs powerful), or one agent's context gets too long to reason well.

Next steps