This is the last guide in the series, and it covers the two ideas that tend to come up right when a LangGraph project starts getting real: how do you make an agent stop and ask before doing something risky, and how do you split one overloaded agent into several that each do one thing well?
Part 1: pausing for a human with interrupt()
Some actions shouldn't happen fully autonomously - issuing a refund above a certain amount, sending an email to a customer, deleting a record. LangGraph handles this with a function called interrupt(): call it inside a node, and the graph stops exactly there, saves its state (this is why persistence from the previous guide is a prerequisite, not optional), and waits - indefinitely, if needed - for someone to respond.
The graph genuinely stops at interrupt() - nothing runs again until a human's decision comes back in.
Resuming is just another call to the graph, using the same thread ID, with the human's decision attached:
from langgraph.types import Command
# ... graph pauses inside the "review" node when interrupt() is called
# later, once a person has decided:
app.invoke(Command(resume={"approved": True}), config)
Whatever value you pass into Command(resume=...) is exactly what interrupt() returns inside the node, so your node code reads almost like a normal function call that just happens to take a while to return - the pausing and state-saving is handled for you underneath.
Part 2: splitting one agent into several
A single agent with a dozen tools and a sprawling system prompt tends to get worse, not better, as you add to it - instructions start contradicting each other, and the model has a harder time picking the right tool. The fix is usually to split the work: instead of one generalist agent, you build several focused ones, each with its own narrow set of tools and instructions, and a supervisor that decides which one should handle the current step.
Each worker hands control back to the supervisor when it's done, so the supervisor always decides what happens next.
Mechanically, a worker hands control back to the supervisor (or to another worker directly, in what's usually called a "swarm" pattern) using a Command object - the same building block that powers conditional routing elsewhere in LangGraph, just used across agents instead of within one:
from langgraph.types import Command
def researcher_node(state):
findings = do_research(state["task"])
return Command(
goto="supervisor",
update={"research": findings},
)
goto tells LangGraph which node to hand off to next, and update merges new information into the shared state on the way - so the supervisor sees exactly what the researcher found when it decides where to route next.
The foundations are in place
Between these five guides, you've now got the core shape of LangGraph: what it is and when to use it, the four building blocks everything is made from, a working agent loop you built yourself, how to make that loop survive a crash, and how to add a human checkpoint or split it into a coordinated team. The next four guides build on this directly: naming the patterns your agent already resembles, streaming its output, deploying it, and debugging it once it's live.