Module 10: Multi-Agent Systems
Introduction: From One Agent to Many
Overview
Your AI Research Assistant is supervised. It has retry with backoff, parallel search, persistent memory, time-travel debugging, long-term memory, multi-user support, and human approvals before expensive actions. You built it across Modules 6-9. It's a production agent.
But it does everything.
It searches for information. It analyzes the results. It generates the report. It picks the format. It selects the sources. It handles errors. A single agent with an 1800-token system prompt, 10 tools, and the hope that the LLM picks correctly every single time.
Picture this scenario: you ask it to "research the impact of AI on finance, analyze the data, and generate an executive report." Your agent has to be a good researcher, a good analyst, AND a good writer. With one system prompt. With one model.
Now picture this instead: a researcher agent that's an expert at finding sources (3 search tools, a cheap and fast model). An analyst agent that's an expert at finding patterns (1 analysis tool, a powerful model). A writer agent that's an expert at executive prose (no tools, a creative model). And a supervisor that coordinates who works when.
Same problem. Better result. Easier to debug. Cheaper to run.
That's multi-agent: splitting a complex task across specialized agents that each do their part better than a generalist would.
But — and this is critical — multi-agent isn't always better. A single agent with good tools is simpler, faster, and easier to maintain. Multi-agent is justified only when the complexity calls for it. This module gives you the judgment to decide when to use it and when not to.
Where are we in the guide?
This is Module 10 of LangChain & LangGraph: From Chains to Agents. It's the last module of Block 3 (Advanced LangGraph).
Block 1: LangChain Core (Modules 1-4) ✅ Done
Block 2: LangGraph Fundamentals (Modules 5-7) ✅ Done
Block 3: Advanced LangGraph (Modules 8-10) ← YOU ARE HERE (Module 10)
Block 4: Production (Modules 11-12)
Your progress:
Block 1 — LangChain Core ✅ Done
│
│ Module 1: Models and Providers ✅
│ Module 2: Tools and Tool Calling ✅
│ Module 3: Agents (create_agent) ✅
│ Module 4: Middleware and Customization ✅
│
▼
Block 2 — LangGraph Fundamentals ✅ Done
│
│ Module 5: Introduction to LangGraph ✅
│ Module 6: Functional API ✅
│ Module 7: Advanced Flows ✅
│
▼
Block 3 — Advanced LangGraph
│
│ Module 8: Memory and Persistence ✅ Done
│ Module 9: Human-in-the-Loop ✅ Done
│ Module 10: Multi-Agent Systems ← YOU ARE HERE
│
▼
Block 4 — Production 🔒
│
│ Module 11: Deep Agents 🔒
│ Module 12: LangSmith and Production 🔒
This module closes Block 3. After this, you understand the three levels of abstraction for building agents: create_agent (a simple agent), LangGraph (an agent with a custom workflow), and multi-agent (multiple coordinated agents). Block 4 adds production: Deep Agents (M11) and LangSmith (M12).
The bridge from Module 9
What you already have
Your Research Agent v4 is a supervised system:
- ✅ Retry with exponential backoff and graceful degradation
- ✅ Parallel search across multiple sources
- ✅ Checkpointing, crash recovery, and time-travel debugging
- ✅ Long-term memory and multi-user support with thread_id
- ✅ Approval gates before expensive actions
- ✅ Review of the research plan before executing
- ✅ Feedback to redirect the research mid-flight
- ✅ State edit to fix data before the final report
The question that's still open
Your agent is capable, robust, persistent, and supervised. But it does everything with one system prompt and one model.
Your Research Agent v4 receives: "Research AI in finance, analyze trends, generate a report"
A single agent does EVERYTHING:
→ Searches 3 sources (needs to be a good searcher)
→ Analyzes the results (needs to be a good analyst)
→ Generates the report (needs to be a good writer)
→ Picks the format (needs to understand presentation)
Problem:
❌ The system prompt tries to cover 4 different roles
❌ 10+ tools — the agent gets confused about which one to use
❌ One model for everything (gpt-4.1 for search is expensive and unnecessary)
❌ If the report comes out wrong, was it the search, the analysis, or the writing?
The fix isn't a smarter agent. It's splitting up the work.
When ONE agent isn't enough
Not every problem needs multi-agent. These are the concrete signals that your single agent is hitting its ceiling:
Signal 1: The system prompt goes past 2000 tokens
If your prompt is trying to cover search, analysis, writing, formatting, and error handling — it's trying to be everything. A prompt that's everything is nothing.
Signal 2: More than 8 tools
Once an agent has 10-15 tools, it starts getting confused about which one to reach for. A researcher with web_search, arxiv_search, and scholar_search is clear. An agent with those 3 plus analyze_data, create_chart, write_report, send_email, format_table, translate, and summarize has too many options.
Signal 3: Different tasks need different models
Searching the web is a simple task — gpt-4.1-mini is enough and costs 10x less. Analyzing complex patterns needs gpt-4.1. Generating creative text works better with certain models. A single agent uses a single model for all of it.
Signal 4: Debugging is hard because you can't isolate the problem
"The report came out wrong." Was it because the search found bad sources? Did the analysis misread the data? Was the writing weak? With one agent, you can't isolate which part failed.
Signal 5: You want real parallelism
One agent works sequentially. With multi-agent, you can search 3 sources in parallel while another agent prepares the report template.
The benefits of multi-agent
Specialization
Each agent is an expert at ONE thing. A researcher with 3 search tools produces better results than a generalist agent with 15 tools. It's the Single Responsibility Principle applied to agents.
Parallelization
Agents can work at the same time. The researcher searches while the analyst sets up its analysis framework.
Separation of concerns
If the report comes out wrong, you know exactly which agent failed. You can improve the researcher without touching the analyst. You can test each agent independently.
Model optimization
Use the right (and cheaper) model for each task:
Researcher: gpt-4.1-mini → $0.40/M input (searching is simple)
Analyst: gpt-4.1 → $2.00/M input (analyzing is complex)
Writer: gpt-4.1-mini → $0.40/M input (writing with a good prompt is simple)
vs.
Single agent: gpt-4.1 → $2.00/M input for EVERYTHING (simple search included)
The 4 multi-agent patterns
There are four main architectures. You'll see each one in detail in the technical capsules:
1. Supervisor
A central agent receives the query, decides which agent should work, delegates, receives results, and decides the next steps. It's the most common pattern.
┌──────────┐
│Supervisor│
└────┬─────┘
┌───────┼───────┐
▼ ▼ ▼
┌────────┐┌───────┐┌──────┐
│Research││Analyst││Writer│
└────────┘└───────┘└──────┘
2. Handoffs
An agent transfers control directly to another agent. There's no central supervisor — the agents pass the work between themselves like a relay race.
┌────────┐ ┌───────┐ ┌──────┐
│Research│ ──▶│Analyst│ ──▶│Writer│
└────────┘ └───────┘ └──────┘
3. Subagents (hierarchical)
One agent calls others as "subcontractors." The main agent keeps full control — the subagents are like tools that happen to be full agents.
┌──────────────────┐
│ Main Agent │
│ ┌──────┐ │
│ │Sub A │ │
│ └──────┘ │
│ ┌──────┐ │
│ │Sub B │ │
│ └──────┘ │
└──────────────────┘
4. Router
A lightweight component (an LLM or simple rules) classifies the incoming query and sends it to the right agent. Only one agent handles each query.
┌──────┐ ┌────────┐
│Router│ ──▶ │Agent A │ (if it's search)
│ │ ──▶ │Agent B │ (if it's analysis)
│ │ ──▶ │Agent C │ (if it's writing)
└──────┘ └────────┘
The microservices analogy
If you come from software engineering, the analogy is direct:
| Monolith → Microservices | Single agent → Multi-agent |
|---|---|
| One application does everything | One agent does everything |
| Each service has one responsibility | Each agent has one specialty |
| Services talk through APIs | Agents talk through shared state |
| An API gateway routes requests | A supervisor routes tasks |
| Each service scales independently | Each agent uses its optimal model |
| Debugging: logs per service | Debugging: tracing per agent |
The same rule applies: don't break a monolith that works well into microservices. Only split when the complexity justifies it.
When NOT to use multi-agent
This matters as much as knowing when to use it:
Simple Q&A → a single agent
If your agent answers questions using 2-3 tools, multi-agent is over-engineering. create_agent with a good prompt is enough.
Linear pipeline with no branching → a single agent or the Functional API
If the flow is always "search → analyze → write" with no variations, you don't need a supervisor deciding anything. A linear StateGraph or @entrypoint + @task does the same with less complexity.
Tight budget → fewer agents = fewer API calls
Every extra agent is at least one extra LLM call. A supervisor with 3 workers can generate 5-10 LLM calls per query. If cost matters, a single well-designed agent is more efficient.
Latency-critical → fewer agents = less overhead
Every handoff between agents adds latency. For applications that need a response in under 2 seconds, multi-agent may be too slow.
The golden rule
Start with a single agent. Only scale to multi-agent when the signals from the previous section are clear. "Premature multi-agent is the root of all evil" — the same rule that applies to microservices applies here.
Module map
| # | Capsule | What you'll learn | Type |
|---|---|---|---|
| 01 | Introduction (this one) | When and why to use multi-agent, the 4 patterns, when NOT to use it | Intro |
| 02 | Pattern Supervisor | The supervisor as coordinator, specialized workers, create_supervisor | Technical |
| 03 | Pattern Handoffs | Direct transfer between agents, handoff tools, flow without a supervisor | Technical |
| 04 | Pattern Subagents | Agents in isolated context, subagent as a tool, parallel execution | Technical |
| 05 | Pattern Router | Classify and delegate in a single decision, deterministic vs LLM routers | Technical |
| 06 | Shared vs isolated state | State design in multi-agent, shared vs isolated, contracts between agents | Technical |
| 07 | Advanced orchestration | Combining patterns, hierarchies, parallelism, consensus, HITL and debugging | Technical |
| 08 | Project: Research Team | Research Agent v5: researcher + analyst + writer + supervisor | Project |
Learning flow
You start with the Supervisor pattern (capsule 02) — the most common architecture and the natural starting point. Then you learn Handoffs (capsule 03) — direct transfer between agents with no central supervisor. Capsule 04 (Subagents) introduces context isolation: each agent works in its own space and returns only the result. Capsule 05 (Router) closes out the four patterns with the simplest of them all: a single classification decision. With all four under your belt, you take on shared vs isolated state (capsule 06) — the hardest design problem in multi-agent: what each agent sees and how conflicts get prevented. Capsule 07 (advanced orchestration) combines patterns, adds hierarchies and parallelism, and teaches you HITL and debugging at the system level — essential for production. Finally, you pull it all together in Research Agent v5 (capsule 08).
The progression is: supervisor → handoffs → subagents → router → state → orchestration → project.
Connection to the project
Research Agent v5: the research team
Your Research Agent becomes a multi-agent system with real specialization:
v1 (Module 6): Working but fragile
↓
v2 (Module 7): Robust (retry, branching, error handling)
↓
v3 (Module 8): Persistent (checkpointing, memory, multi-user)
↓
v4 (Module 9): Supervised (approval gates, review, feedback, state edit)
↓
v5 (This module): Multi-agent
│
│ 🔍 Research Agent: searches multiple sources (web, papers, docs)
│ 📊 Analysis Agent: analyzes, synthesizes, spots patterns
│ ✍️ Writer Agent: generates the final report
│ 🎯 Supervisor: coordinates the flow between the three
│
▼
v6 (Module 11): + Deep Agent (automatic planning, virtual filesystem)
The shift is natural: what used to be one agent doing everything is now 3 specialized agents + 1 supervisor. The payoff: higher-quality reports, faster processing (parallelism), cost optimization (a different model per agent), and a system that's easier to debug.
The proof it worked: you run a complex piece of research, and you can see in the log which agent did what, how much each one cost, and whether any of them failed — without the rest of the system being affected.
Connection to Module 11: Deep Agents
Module 10 teaches you to build multi-agent by hand: you design the agents, define the handoffs, and configure the supervisor. Module 11 introduces the "batteries-included" layer: automatic planning with write_todos, a virtual filesystem, subagent spawning, and long-term memory with pluggable backends. You'll rebuild the Research Assistant as a Deep Agent to see how the framework gives you out of the box what you built by hand.
Connection to Module 12: LangSmith and Production
When you have 4 agents generating 10+ LLM calls per query, observability becomes critical. LangSmith gives you end-to-end tracing of the flow between agents, cost per agent, latency per step, and quality metrics. What you learn about debugging in capsule 07 gets professionalized with LangSmith in M12.
What this module does NOT cover
- ❌ Deep Agents — Automatic planning, virtual filesystem, and subagent spawning belong to Module 11. Here you build multi-agent from the primitives
- ❌ LangSmith tracing — Professional observability with LangSmith belongs to Module 12. Here you implement basic per-agent logging and debugging
- ❌ Deploying multi-agent — How to ship a multi-agent system with LangGraph Cloud belongs to Module 12
- ❌ Multi-agent RAG — We don't build a RAG system with multiple agents. The focus is the Research Assistant
- ❌ Agent-to-agent communication protocols — Protocols like Google's A2A (Agent-to-Agent) or MCP are interoperability topics that go beyond the scope of this module
Technical setup
Prerequisites
- ✅ Module 9 completed — you have a Research Agent v4 with HITL
- ✅ Python 3.11+ installed
- ✅ At least one API key from a provider (OpenAI recommended)
- ✅ A working checkpointer — you've been using MemorySaver since M8
Installation
One new package for the Supervisor pattern:
pip install langgraph langchain-openai python-dotenv langgraph-supervisor
Check the imports:
from langchain.agents import create_agent
from langgraph_supervisor import create_supervisor
from langgraph.graph import StateGraph, MessagesState, START, END
from langgraph.checkpoint.memory import MemorySaver
print("create_agent available")
print("create_supervisor available")
print("StateGraph available")
# Expected output:
# create_agent available
# create_supervisor available
# StateGraph available
Environment variables
Your .env from Module 9 still works:
# .env
OPENAI_API_KEY=sk-...
Quick check: basic multi-agent
Run this script to confirm the supervisor pattern works. It uses a manual supervisor (no LLM) so you don't need an API key yet:
from langgraph.graph import StateGraph, START, END
from typing import TypedDict
class TeamState(TypedDict):
query: str
research: str
analysis: str
current_agent: str
step: int
def supervisor(state: TeamState) -> dict:
step = state.get("step", 0)
if step == 0:
return {"current_agent": "researcher", "step": 1}
elif step == 1:
return {"current_agent": "analyst", "step": 2}
return {"current_agent": "done", "step": 3}
def researcher(state: TeamState) -> dict:
return {"research": f"5 sources found for: '{state['query']}'"}
def analyst(state: TeamState) -> dict:
return {"analysis": f"3 patterns in: {state['research'][:40]}..."}
def route(state: TeamState) -> str:
return state["current_agent"]
builder = StateGraph(TeamState)
builder.add_node("supervisor", supervisor)
builder.add_node("researcher", researcher)
builder.add_node("analyst", analyst)
builder.add_edge(START, "supervisor")
builder.add_conditional_edges("supervisor", route, {
"researcher": "researcher",
"analyst": "analyst",
"done": END,
})
builder.add_edge("researcher", "supervisor")
builder.add_edge("analyst", "supervisor")
graph = builder.compile()
result = graph.invoke({
"query": "State of the art in RAG 2025",
"research": "", "analysis": "",
"current_agent": "", "step": 0,
})
print(f"Research: {result['research']}")
print(f"Analysis: {result['analysis']}")
print(f"Steps: {result['step']}")
# Expected output:
# Research: 5 sources found for: 'State of the art in RAG 2025'
# Analysis: 3 patterns in: 5 sources found for: 'State of the ...
# Steps: 3
If you see the research and the analysis filled in, and 3 steps, the supervisor pattern works: the supervisor delegated to the researcher, got the result, delegated to the analyst, got the result, and finished.
Evidence of success
By the end of this module, you'll know it worked if:
- ✅ You can design a multi-agent system with the Supervisor pattern using
create_supervisor - ✅ You implement handoffs between agents — one agent delegates work to another and gets the result back
- ✅ You create specialized agents with their own tools, prompts, and models
- ✅ You handle shared vs isolated state between agents
- ✅ You know how to decide when a single agent is enough vs when you need multi-agent
- ✅ Your Research Agent v5 has 3 specialized agents + 1 supervisor and produces better results than v4
Self-assessment
If you can answer these, you're on track:
- When is a single agent with good tools better than multi-agent?
- What's the difference between the Supervisor pattern and the Handoffs pattern?
- If your supervisor uses
gpt-4.1to decide who to delegate to, is that necessary? What's a cheaper alternative? - How do you decide whether two agents should share state or have isolated state?
- If your system has 8 specialized agents, is that a good design? Why?
Summary
- Your Research Agent v4 is capable but does everything with a single agent: search, analysis, writing. When the system prompt goes past 2000 tokens, you have more than 8 tools, or you need different models per task — it's time to consider multi-agent
- Multi-agent isn't always better. A single agent with good tools is simpler, faster, and easier to debug. Multi-agent is justified when there's real specialization, prompts that got too long, different models per subtask, or a need to separate concerns
- Four patterns: Supervisor (central coordinator), Handoffs (direct transfer), Subagents (hierarchical), Router (classification). The Supervisor is the most common and the natural starting point
- The microservices analogy is direct: don't split a monolith that works well. Start simple, scale when you need to
- 3-4 agents is the sweet spot. The Research Agent becomes: researcher (search), analyst (analysis), writer (writing), supervisor (coordination)
- Specialization produces better results than a generalist. A researcher with 3 search tools searches better than an agent with 15 tools that does a bit of everything. Single Responsibility Principle applied to agents
Further reading
- LangGraph — Multi-Agent Systems — Official docs on multi-agent patterns: supervisor, handoffs, subagents
- LangGraph Supervisor — Official repo for the
langgraph-supervisorpackage, with examples and an API reference - How to build a multi-agent supervisor — A practical step-by-step guide to implementing the supervisor pattern
- How to implement handoffs — Guide to direct control transfer between agents
- Multi-Agent Architectures — LangChain Blog — Analysis of multi-agent patterns with comparisons and trade-offs
- Microservices Pattern — Martin Fowler — The analogy we use in this module: when to split a monolith and when not to
Module 10 — LangChain & LangGraph: From Chains to Agents
Next capsule: Pattern Supervisor — you'll learn how a supervisor agent coordinates specialized workers, the difference between simple routing and LLM routing, and how to use create_supervisor to build your first multi-agent system.