Skip to content

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 ​

python
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 ​

  1. Resume with a JSON dictionary including comments and validate its fields.
  2. Log before the interrupt and observe whether it repeats on resume.
  3. Design timeout rejection without automatic approval.

Official references ​

Verified on: 2026-09-17.