Multi-Agent Systems Explained

A multi-agent system is more than one LLM-driven agent, each with its own instructions and tools, coordinating to finish a task that a single agent would struggle with alone. That "would struggle with alone" clause is the whole game. Most teams reach for multiple agents far too early, then spend weeks debugging a distributed system they never actually needed.

Start single. Really. #

Before you draw any org chart of agents, build one agent with a good tool set and a clear prompt. A single agent with retrieval, a code interpreter, and a few APIs handles a surprising amount. It is easier to reason about, cheaper to run, and trivial to trace when something breaks.

You go multi-agent when the task genuinely splits along one of these seams:

Distinct skills or prompts: A researcher, a writer, and a fact-checker each need different instructions and tools that would bloat one prompt into an unfocused mess.

Context isolation: One agent's working context would pollute another's. A code-review agent and a customer-reply agent should not share the same scratch memory.

Parallelism: You have five independent subtasks and want them running at once instead of serially.

Bounded responsibility: You want to constrain what each unit can do for safety or cost reasons, so a narrow specialist beats a do-everything generalist.

If your reason is "it feels more sophisticated," stop.

The main orchestration patterns #

Supervisor / orchestrator-worker: A router agent receives the request, decides which specialist should handle it, delegates, and collects results. The supervisor owns control flow; workers just do their job and report back. This is the most common and most reliable starting pattern.

Role-based teams (CrewAI style): You define agents by role, goal, and backstory, then hand the crew a task. Agents collaborate according to a process you pick (sequential or hierarchical). Good when the work maps cleanly onto human-team roles.

Sequential pipeline: Output of agent A becomes input to agent B to C. Think extract, then transform, then summarize. Simple and predictable, but a bad early stage poisons everything downstream.

Hierarchical: Supervisors of supervisors. A top orchestrator delegates to mid-level managers who delegate to workers. Powerful for large tasks, but every layer adds latency and places for context to drift.

Network / hand-off: Peer agents pass control to each other with no central boss. A triage agent hands a conversation to a billing agent, which can hand it to a refunds agent. Flexible, but the hardest to keep from looping.

A supervisor in text #

Here is the supervisor pattern boiled down to pseudocode:

python.python

def supervisor(request, agents):
state = {"task": request, "history": []}
while not done(state):
# Supervisor decides who acts next, or that we're finished
decision = route(state) # LLM call: "researcher" | "writer" | "STOP"
if decision == "STOP":
break
worker = agents[decision]
result = worker.run(state) # specialist does its slice
state["history"].append((decision, result))
return synthesize(state)

The routing call is the heart of it. Everything hard about multi-agent systems lives in route: picking the right worker, knowing when to stop, and not calling the same worker forever.

Shared vs isolated state #

Two agents can share one memory object (a common scratchpad and message log) or keep private state and exchange only messages. Shared state is convenient and keeps everyone informed, but it dilutes context: agent B now reads a pile of agent A's intermediate noise. Isolated state keeps each agent focused, at the cost of explicit hand-off payloads. A good default is a shared high-level task record plus private working memory per agent.

Communication #

Agents coordinate through message passing (structured messages appended to a shared log) or hand-offs (one agent transfers control and a compact summary to another). What matters most is what you put in the hand-off. Passing the entire raw transcript forward dilutes context; passing a tight summary of "what's decided and what's needed next" keeps systems coherent.

Failure modes to design against #

Error propagation: A wrong fact in step one becomes a confident wrong conclusion in step five. Add validation between stages, not just at the end.

Infinite loops: Two agents hand control back and forth, or a supervisor keeps re-dispatching the same worker. Always cap total steps and detect repeated states.

Cost blow-up: Every hand-off is more tokens, and hierarchies multiply calls fast. A three-layer system can cost 10x a single agent for a marginal quality gain. Budget token spend per request and alarm on it.

Context dilution: As shared history grows, each agent's signal-to-noise ratio drops and quality quietly degrades. Summarize aggressively and prune what a given agent doesn't need.

Evaluation #

Evaluate the system end to end on real tasks, not each agent in isolation. Track task success rate, step count, token cost, and latency together, because improving one usually worsens another. Log every routing decision and hand-off so a failed run traces back to the exact agent and message where things went sideways. Without that trace, a multi-agent failure is nearly impossible to diagnose.

How frameworks implement this #

LangGraph models the system as a graph of nodes and edges with explicit shared state. Its supervisor pattern is a router node whose edges point to worker nodes; you get fine control over state and transitions, at the cost of more wiring.

CrewAI leans into role-based crews. You declare agents and tasks, choose a sequential or hierarchical process, and the framework runs the collaboration. Fast to stand up, less granular control.

Microsoft Agent Framework brings orchestration and workflow primitives with an enterprise bent, supporting sequential, concurrent, and hand-off coordination with a focus on observability and governance.

For a deeper comparison, see our best AI agent frameworks write-up, and for single-agent structure, the AI agent design patterns guide.

When to use multi-agent: a decision section #

Ask these in order:

Have you shipped a single agent with tools and hit a real wall? If no, build that first.

Does the task split into clearly separable responsibilities with different prompts or tools? If no, stay single.

Do you need context isolation or parallelism that one agent cannot give? If no, stay single.

Can you afford the extra tokens, latency, and the tracing infrastructure to debug it? If no, stay single.

If you answered yes to 1 through 4, start with the supervisor pattern. It gives you most of the benefit with the least coordination risk.

The call we'd make #

Default to a single agent with strong tools. Move to multi-agent only when the task genuinely splits and you have observability in place. When you do go multi, start with a supervisor over two or three specialists, cap the step count, budget tokens per request, and keep hand-offs tight. Reach for hierarchical or network topologies only after the simple supervisor proves the split is real. Most teams that "need multi-agent" actually need a better single agent first.

For the full arc from first agent to production, start with our building AI agents guide.