LangGraphLangGraph 1.2 · Python 3.10+
0%
1
Curious builder0 XP earned · 300 to level 2
0 daysFinish a lesson to begin
Badge collection0 of 6 unlocked
38 small wins to finish your pathNext lesson →

Multi-agent: a supervisor routing to workers

A multi-agent graph splits a job across specialised agents: a supervisor reads the request and routes it, with Command(goto=...), to the worker that handles it.

Last updated: 27 Sep, 2026 · LangGraph 1.2

One agent that does everything grows tangled. Splitting the work, one agent per job, keeps each one small, and a supervisor decides which one runs.

The supervisor that routes

The supervisor is a node that returns a Command naming the worker to run next, based on the request.

python
def supervisor(s) -> Command:
    dest = "refunds" if "refund" in s["request"].lower() else "orders"
    return Command(goto=dest)   # hand the run to that worker

The workers that finish

Each worker handles its own job and returns Command(goto=END) with its answer, so control does not bounce back to the supervisor.

python
def orders(s) -> Command:
    return Command(goto=END, update={"answer": "Order A17 shipped on 3 March."})

def refunds(s) -> Command:
    return Command(goto=END, update={"answer": "Refund started for A17."})

A supervisor routing a refund end to end

The whole graph in one file.

Example
from typing_extensions import TypedDict
from langgraph.graph import StateGraph, START, END
from langgraph.types import Command

class State(TypedDict):
    request: str
    answer: str

def supervisor(s) -> Command:
    dest = "refunds" if "refund" in s["request"].lower() else "orders"
    return Command(goto=dest)                       # route to a worker

def orders(s) -> Command:
    return Command(goto=END, update={"answer": "Order A17 shipped on 3 March."})

def refunds(s) -> Command:
    return Command(goto=END, update={"answer": "Refund started for A17."})

b = StateGraph(State)
b.add_node("supervisor", supervisor)
b.add_node("orders", orders)
b.add_node("refunds", refunds)
b.add_edge(START, "supervisor")
graph = b.compile()

print(graph.invoke({"request": "I want a refund", "answer": ""})["answer"])

How the request was routed

  • The supervisor read the request and returned Command(goto="refunds").
  • The refunds worker ran, wrote the answer, and returned Command(goto=END).
  • The orders worker never ran, because the supervisor did not route to it.

One agent vs a supervisor

One agentSupervisor and workers
Each partHandles every jobHandles one job
RoutingInside one promptAn explicit supervisor node
Growing itThe prompt gets longerAdd another worker

When to split into agents

  • A job with clearly separate tasks, such as orders, refunds and fraud.
  • You want the transcript to show which agent handled each request.
  • Different workers need different tools or models.
Watch out. A worker that returns Command(goto="supervisor") instead of END sends the run back up; without a stop condition that is an infinite loop, capped by the recursion limit.
Try it yourself
  • Add a third worker, fraud, and route to it on the word "charge".
  • Make the supervisor fall through to orders when nothing matches.
  • Have a worker route back to the supervisor and watch the recursion limit stop it.

Little by little, you're building something great.