Chapter 6 · Human approval, interrupts, and resume
Build an approval flow that never sends real email. Display a draft, collect an explicit decision, and record the outcome. A model cannot approve on the human’s behalf.
Mechanics and design choices
interrupt() pauses execution and saves resumable state, requiring a checkpointer and thread ID. Resume the same thread with Command(resume=...). The interrupted node starts again from the beginning, not the next Python line. Side effects before the interrupt may repeat; place writes after approval and protect them with business idempotency keys.
Example
from typing import TypedDict
from langgraph.graph import StateGraph, START, END
from langgraph.checkpoint.memory import InMemorySaver
from langgraph.types import interrupt, Command
class State(TypedDict):
draft: str
status: str
def review(state: State):
approved = interrupt({"draft": state["draft"], "question": "Approve this draft?"})
return {"status": "approved" if approved is True else "rejected"}
builder = StateGraph(State)
builder.add_node("review", review)
builder.add_edge(START, "review")
builder.add_edge("review", END)
graph = builder.compile(checkpointer=InMemorySaver())
config = {"configurable": {"thread_id": "draft-001"}}
paused = graph.invoke({"draft": "Welcome to the course!", "status": "pending"}, config)
print(paused["__interrupt__"][0].value)
answer = input("Type APPROVE to approve; anything else rejects: ")
result = graph.invoke(Command(resume=answer == "APPROVE"), config)
assert result["status"] in {"approved", "rejected"}
print(result["status"])Run and verify
Run twice: enter APPROVE once and another value once. Both paths must end. This example uses the default interrupt return format. With explicit version="v2", use result.interrupts and result.value instead; do not mix formats.
Pitfalls
Do not swallow interrupt control flow in broad exception handlers or treat the first invoke as completion. A new thread ID cannot resume the original pause.
🧪 随堂测验
点击你认为正确的选项。答错时会展示正确答案与原因解析。
1. Which thread should resume use?
2. Where does the node restart?
3. What enables pause and resume?
4. Should timeout imply approval?
Hands-on exercises
- Resume with a JSON dictionary including comments and validate its fields.
- Log before the interrupt and observe whether it repeats on resume.
- Design timeout rejection without automatic approval.
Official references
Verified on: 2026-09-17.