09. Multi-Agent Teams
A multi-agent team in LangGraph is a supervisor node that dispatches tasks to specialized worker nodes, each of which may itself be a compiled sub-graph. The pattern has three layers: a team state shared by all agents, a supervisor that routes work to idle workers, and worker nodes that perform domain-specific tasks and write results back to shared state.
class TeamState(TypedDict):
task: str
assignments: Annotated[list[str], add]
results: dict[str, str]
next_worker: Literal["researcher", "coder", "done"]
The supervisor node implements the routing logic. Rather than branching via conditional edges alone, the supervisor returns a next_worker string that a conditional edge uses:
def supervisor(state: TeamState) -> TeamState:
task = state["task"]
pending = [w for w in ["researcher", "coder"] if w not in state["assignments"]]
if not pending:
return {"next_worker": "done"}
chosen = pending[0]
return {"next_worker": chosen, "assignments": [chosen]}
The conditional edge maps next_worker to actual node names:
builder.add_conditional_edges(
"supervisor",
lambda s: s["next_worker"],
{"researcher": "researcher", "coder": "coder", "done": END}
)
Workers write their outputs into the shared results dict keyed by their agent name. The supervisor reads this dict after each worker completes to synthesize or decide the next step. This pattern cleanly separates concerns: the supervisor handles orchestration logic; workers handle domain execution.
Local verification checkpoint
Run the smallest example from this chapter in a local workspace and record the package version, runtime, data path, and observed output. If the result depends on model size, vector count, CPU/GPU backend, or available memory, note that constraint beside the exercise so the lesson remains reproducible.
Build a two-worker team (researcher and coder) with a supervisor. Add a summarizer node that the supervisor calls after both workers complete. Use conditional routing to confirm the summarizer only runs after both workers have reported.