LangGraph isn't just for single agents — it's the most powerful framework for multi-agent orchestration. Multiple specialized agents work together in coordination, controlled by a state graph.
The most common multi-agent pattern: A supervisor agent decides which worker becomes active next:
from langgraph.graph import StateGraph, END
def supervisor_node(state: AgentState) -> dict:
# LLM decides which agent goes next
response = supervisor_llm.invoke(
f"Current task: {state['task']}\n"
f"Results so far: {state['results']}\n"
f"Available agents: researcher, analyst, writer\n"
f"Which agent should work next? (or FINISH)"
)
return {"next_agent": response.content}
graph = StateGraph(AgentState)
graph.add_node("supervisor", supervisor_node)
graph.add_node("researcher", researcher_node)
graph.add_node("analyst", analyst_node)
graph.add_node("writer", writer_node)
graph.add_conditional_edges("supervisor", route_to_agent, {
"researcher": "researcher",
"analyst": "analyst",
"writer": "writer",
"FINISH": END
})
# Every worker goes back to the supervisor
for worker in ["researcher", "analyst", "writer"]:
graph.add_edge(worker, "supervisor")
With handoffs, an agent transfers control directly to another without a supervisor:
| Pattern | Description | Use Case |
|---|---|---|
| Supervisor | Central control | Complex workflows |
| Handoff | Direct transfer | Specialized chains |
| Broadcast | To all simultaneously | Parallel analysis |
| Voting | Majority decision | Quality assurance |
All agents share a common state. Important design decisions:
class MultiAgentState(TypedDict):
messages: Annotated[list, add_messages]
task: str
research_data: list[dict]
analysis: dict
draft: str
next_agent: str
iteration_count: int
Agents can delegate tools to other agents:
def researcher_node(state: MultiAgentState) -> dict:
tools = [web_search, arxiv_search, database_query]
agent = create_react_agent(llm, tools)
result = agent.invoke({"messages": state["messages"]})
return {"research_data": extract_data(result)}
LangGraph supports parallel execution via fan-out nodes:
graph.add_node("parallel_research", parallel_research_node)
# Multiple agents work simultaneously
# Results are merged in the state
Practical tip: Limit iteration depth (e.g., max 5 cycles). Without a limit, a multi-agent system can loop forever — with corresponding costs. Define clear exit conditions.