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.
That's the series
Between these five guides, you've now got the full 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. From here, the fastest way to get better at it is the same as with any framework - build something small, real, and slightly annoying, and let the parts of LangGraph you actually need reveal themselves.