Course
Give your AI a permanent memory of your business. A course for people who use ChatGPT or Claude daily.Compound Context
Aug 25, 2026Tutorials10 min read

How to Build a Multi-Agent System with LangGraph: A Step-by-Step Guide

NBNikolas Barwicki
Multi-Agent SystemsLangGraphLangChainPythonTutorial

You have built a single AI agent. Now split the work across a team of specialists that research, analyze, and write — all coordinated by a supervisor agent.

A single AI agent can handle a surprising amount of work. But push it far enough — give it too many tools, too many responsibilities, too broad a scope — and it starts to fall apart. Responses get slower, tool selection gets unreliable, and quality drops.

The fix isn't a better prompt. It's splitting the work across multiple specialized agents that collaborate on a shared goal. This is the same principle behind effective human teams: a researcher gathers information, an analyst makes sense of it, a writer turns it into something readable.

In this tutorial, you'll build exactly that — a multi-agent research assistant using LangGraph, LangChain's framework for orchestrating stateful agent workflows. If you've already followed our guide to building a single agent from scratch, this is the natural next step. And if you want the conceptual background on why multi-agent systems matter, start with our multi-agent systems overview.

Prerequisites

Before you start, make sure you have:

  • Python 3.10+ installed
  • An OpenAI API key (or swap in Anthropic, Google, etc.)
  • Basic familiarity with tool calling and the agent loop pattern

Install the required packages:

pip install langgraph langgraph-supervisor langchain-openai langchain-community tavily-python

Set your API keys:

export OPENAI_API_KEY="your-openai-key"
export TAVILY_API_KEY="your-tavily-key"

We're using Tavily for web search because it's built for LLM agents and has a generous free tier. You can substitute any search tool.

How LangGraph Models Multi-Agent Systems

If you've built agents with raw API calls, you know the core loop: prompt the LLM, check for tool calls, execute them, feed results back. LangGraph wraps that loop into a directed graph where each node does work and edges control the flow between them.

The key concepts:

  • StateGraph — the graph builder. You define a shared state schema (a Python TypedDict) and add nodes that read and update that state.
  • Nodes — Python functions that do the actual work: calling an LLM, running a tool, transforming data.
  • Edges — define transitions between nodes. Can be fixed ("always go from A to B") or conditional ("go to A or B depending on the state").
  • Checkpointer — saves state after each step, enabling memory, pause/resume, and debugging.

For multi-agent specifically, LangGraph supports three patterns:

PatternHow it worksBest for
SupervisorA central agent delegates to specialist workersStructured workflows with clear task routing
HierarchicalSupervisors managing other supervisors in a treeLarge systems with distinct team responsibilities
SwarmPeer agents hand off to each other dynamicallyFlexible, conversational collaboration

The langgraph-supervisor and langgraph-swarm libraries provide high-level helpers for the supervisor and swarm patterns respectively.

We'll use the supervisor pattern for this tutorial. It's the most intuitive starting point: one coordinator agent decides which specialist handles each part of the task.

What You'll Build

A research assistant with four agents:

         ┌─────────────┐
         │  Supervisor  │
         │ (routes work)│
         └──┬───┬───┬───┘
            │   │   │
    ┌───────┘   │   └───────┐
    ▼           ▼           ▼
┌─────────┐ ┌─────────┐ ┌─────────┐
│Researcher│ │ Analyst │ │  Writer │
│(web search)│(data    │ │(report  │
│          │ │ analysis)│ │drafting)│
└─────────┘ └─────────┘ └─────────┘

You send a research topic. The supervisor delegates to the researcher for data gathering, the analyst for extracting insights, and the writer for producing the final report.

Step 1: Define the Tools

Each specialist agent needs tools relevant to its role. The researcher gets web search. The analyst and writer get custom functions.

import json
from langchain_community.tools.tavily_search import TavilySearchResults
from langchain_core.tools import tool

# Researcher's tool — real web search
search_tool = TavilySearchResults(max_results=5)

# Analyst's tool
@tool
def analyze_findings(findings: str) -> str:
    """Analyze raw research findings and extract key insights, statistics, and trends."""
    # In production, this could call a specialized model or run data processing
    return f"Analysis complete. Key findings extracted from: {findings[:200]}..."

# Writer's tool
@tool
def write_report(topic: str, analysis: str) -> str:
    """Write a structured report based on analyzed research findings."""
    return f"Report draft on '{topic}' based on analysis: {analysis[:200]}..."

The @tool decorator from LangChain turns a regular Python function into a tool the LLM can call. The docstring becomes the tool description — make it clear so the LLM knows when to use it.

Step 2: Build the Specialist Agents

Each specialist is a ReAct agent — the same LLM + tools + loop pattern from the single-agent tutorial, wrapped in LangGraph's create_react_agent helper.

from langchain_openai import ChatOpenAI
from langgraph.prebuilt import create_react_agent

model = ChatOpenAI(model="gpt-4o")

# Agent 1: Researcher
researcher = create_react_agent(
    model=model,
    tools=[search_tool],
    name="researcher",
    prompt=(
        "You are a research specialist. When given a topic, search the web "
        "thoroughly and return detailed, factual findings. Include specific "
        "data points, quotes, and source references when available."
    ),
)

# Agent 2: Analyst
analyst = create_react_agent(
    model=model,
    tools=[analyze_findings],
    name="analyst",
    prompt=(
        "You are a data analyst. Take raw research findings and extract "
        "the key insights, identify patterns, highlight important statistics, "
        "and organize the information into a clear structure."
    ),
)

# Agent 3: Writer
writer = create_react_agent(
    model=model,
    tools=[write_report],
    name="writer",
    prompt=(
        "You are a technical writer. Take analyzed findings and produce "
        "a well-structured, readable report. Use clear headings, bullet "
        "points, and concise language."
    ),
)

Three things to notice:

  • Each agent has a name — this is how the supervisor refers to them when delegating.
  • Each agent has a focused prompt — keep it narrow. A specialist should only know about its role.
  • Each agent has only the tools it needs — the researcher doesn't need the writing tool, the writer doesn't need web search.

Step 3: Wire Up the Supervisor

The supervisor is the orchestrator. It receives the user's request, decides which specialist to call, reviews the results, and routes work until the task is complete.

from langgraph_supervisor import create_supervisor

workflow = create_supervisor(
    agents=[researcher, analyst, writer],
    model=model,
    prompt=(
        "You are a research team supervisor managing three specialists:\n"
        "- 'researcher': searches the web for information on a topic\n"
        "- 'analyst': analyzes raw findings and extracts key insights\n"
        "- 'writer': produces a polished report from analyzed data\n\n"
        "For any research request, follow this workflow:\n"
        "1. Send the topic to 'researcher' to gather information\n"
        "2. Send the research findings to 'analyst' for analysis\n"
        "3. Send the analysis to 'writer' for the final report\n\n"
        "Review each agent's output before passing it to the next. "
        "If the quality is insufficient, send the task back with feedback."
    ),
)

The create_supervisor function from the langgraph-supervisor package handles the routing logic. Under the hood, it creates a graph where the supervisor node uses the LLM to decide which agent to call next, and each agent's output flows back to the supervisor for review.

The supervisor prompt is critical. It defines the workflow sequence (research → analyze → write) and gives the supervisor permission to send work back if quality is lacking. This feedback loop is what makes multi-agent systems more reliable than a single monolithic agent.

Step 4: Add Persistence and Run It

Compile the graph with a checkpointer to enable state persistence, then run it.

from langgraph.checkpoint.memory import InMemorySaver

# Compile the workflow
checkpointer = InMemorySaver()
app = workflow.compile(checkpointer=checkpointer)

# Run it
config = {"configurable": {"thread_id": "research-001"}}

result = app.invoke(
    {
        "messages": [
            {
                "role": "user",
                "content": "Research the current state of quantum computing. "
                "What are the latest breakthroughs, who are the key players, "
                "and what's the realistic timeline for practical applications?",
            }
        ]
    },
    config=config,
)

# Print the final response
print(result["messages"][-1].content)

The thread_id in the config is what enables conversation memory. Every state change gets checkpointed. If you invoke the same thread again, the system remembers the entire conversation history.

What happens when you run this:

  1. The supervisor receives the query and delegates to researcher.
  2. The researcher calls TavilySearchResults multiple times to gather data on quantum computing.
  3. Results flow back to the supervisor, which forwards them to analyst.
  4. The analyst processes the raw findings and extracts key insights.
  5. Results flow back to the supervisor, which forwards them to writer.
  6. The writer produces a structured report.
  7. The supervisor reviews and returns the final output.

Each agent only handles what it's good at. The supervisor handles coordination.

Step 5: Visualize and Debug the Graph

LangGraph can render your agent graph as a Mermaid diagram, which is invaluable for understanding and debugging the flow.

# Print the graph as Mermaid markdown
print(app.get_graph().draw_mermaid())

This outputs a Mermaid diagram you can paste into any Mermaid renderer to see the full node and edge structure of your multi-agent system.

For deeper debugging, inspect the state history to see exactly what happened at each step:

# Walk through every state snapshot
for state in app.get_state_history(config):
    if state.metadata and "langgraph_node" in state.metadata:
        node = state.metadata["langgraph_node"]
        print(f"Node: {node}")
        print(f"  Messages: {len(state.values.get('messages', []))}")
        print()

This shows you which node executed at each step, what messages were in the state, and how the conversation evolved. When something goes wrong — an agent loops, picks the wrong tool, or produces poor output — this is how you diagnose it.

Going Further: Advanced Patterns

The supervisor pattern is just the starting point. Here are three directions to explore once you're comfortable with the basics.

Hierarchical Teams

For larger systems, create supervisors managing other supervisors. A top-level coordinator routes work to team leads, who route to their specialists:

research_team = create_supervisor(
    [search_agent, scraping_agent],
    model=model,
    supervisor_name="research_lead",
).compile(name="research_team")

writing_team = create_supervisor(
    [drafting_agent, editing_agent],
    model=model,
    supervisor_name="writing_lead",
).compile(name="writing_team")

top_level = create_supervisor(
    [research_team, writing_team],
    model=model,
    supervisor_name="project_manager",
).compile()

LangChain's hierarchical agent teams tutorial walks through this pattern in detail.

Swarm (Peer-to-Peer)

The langgraph-swarm library enables agents to hand off directly to each other without a central coordinator. Each agent gets a create_handoff_tool that lets it transfer control:

from langgraph_swarm import create_handoff_tool, create_swarm

alice = create_react_agent(
    model,
    tools=[search_tool, create_handoff_tool(agent_name="bob")],
    name="alice",
    prompt="You are a researcher. Hand off to Bob for writing.",
)

bob = create_react_agent(
    model,
    tools=[write_report, create_handoff_tool(agent_name="alice")],
    name="bob",
    prompt="You are a writer. Hand off to Alice for more research.",
)

swarm = create_swarm([alice, bob], default_active_agent="alice")
app = swarm.compile(checkpointer=InMemorySaver())

Human-in-the-Loop

LangGraph's interrupt() function lets you pause execution and wait for human approval before continuing. This is essential for production systems where agents take consequential actions.

Production Persistence

Replace InMemorySaver with PostgresSaver for production deployments where state needs to survive restarts:

pip install langgraph-checkpoint-postgres

Where to Go From Here

You've built a working multi-agent system. Here's how to keep going:

  • Add more agents. A fact-checker that verifies claims before the writer produces the final report. A critic that reviews output quality.
  • Connect agents to real data sources. Use MCP servers to expose databases, APIs, and file systems as tools your agents can use.
  • Test systematically. Multi-agent systems are harder to test than single agents. Our guide to evaluating AI agents covers strategies that apply here.
  • Try different LLMs per agent. The researcher might need GPT-4o for complex reasoning, but the writer could run fine on a smaller, faster model. LangGraph lets you assign different models to different agents.
  • Deploy to production. LangGraph Platform provides managed hosting with built-in persistence, streaming, and monitoring.

Conclusion

A multi-agent system doesn't have to be complex. At its core, it's the same agent loop you already know — an LLM, tools, and a cycle — replicated across specialists and wired together with a coordination layer.

LangGraph gives you that wiring. Define your state, build your agents, connect them with a supervisor, and you have a team of AIs that collaborate on tasks no single agent could handle well alone.

Start with the supervisor pattern shown here. Get it working, inspect the state history, and understand the flow. Then branch out into hierarchical teams, swarms, or human-in-the-loop patterns as your use case demands. The foundation is the same.

Reach 25,000+ AI enthusiasts every month

Promote your AI tool with featured placement, measurable visibility, and referral traffic.

Learn more →