前言
上一篇的 interrupt() 是动态人机协同:停在哪儿由代码运行时决定。
还有一类静态断点:编译图时声明「进入某节点前 / 离开某节点后」一律暂停,适合调试或固定审批闸门。
本文只讲 interrupt_before / interrupt_after 与 invoke(None) 分步恢复。
bind_tools、ToolNode 与工具循环见 《LangGraph 06:工具调用》。
下文需要 Python 3.12+,依赖用 uv 管理。
依赖
建议使用 Python 3.12 及以上。
1 2 3 4
| uv init langgraph-static-interrupt cd langgraph-static-interrupt uv venv --python 3.12 uv add "langgraph>=1.0,<2.0" rich
|
静态断点同样需要 checkpointer 与稳定的 thread_id。
本篇示例不调 LLM,无需配置模型密钥。
静态断点
在 compile 时传入节点名列表。
首次 invoke 会在第一个断点停下;之后用 invoke(None, config=...) 推进到下一闸门,直到跑完。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| from typing import TypedDict
from langgraph.checkpoint.memory import InMemorySaver from langgraph.graph import END, START, StateGraph from rich import print as rprint
class OverAllState(TypedDict): final_res: str
def node_a(state: OverAllState) -> OverAllState: return {"final_res": "node_a"}
def node_b(state: OverAllState) -> OverAllState: return {"final_res": "node_b"}
def node_c(state: OverAllState) -> OverAllState: return {"final_res": "node_c"}
builder = StateGraph(state_schema=OverAllState) builder.add_node("node_a", node_a) builder.add_node("node_b", node_b) builder.add_node("node_c", node_c) builder.add_edge(START, "node_a") builder.add_edge("node_a", "node_b") builder.add_edge("node_b", "node_c") builder.add_edge("node_c", END)
graph = builder.compile( checkpointer=InMemorySaver(), interrupt_before=["node_a", "node_b"], interrupt_after=["node_a", "node_b"], ) config = {"configurable": {"thread_id": "static-1"}}
rprint(graph.invoke({}, config=config)) rprint(graph.invoke(None, config=config)) rprint(graph.invoke(None, config=config)) rprint(graph.invoke(None, config=config))
|
也可在单次 invoke(..., interrupt_before=..., interrupt_after=...) 里临时指定断点,不必写进 compile。
注意:临时列表与编译期配置混用时,某次调用若省略断点参数,后续行为可能与预期不一致;联调时固定一种写法更稳妥。
并行图上声明多个静态断点时,各分支会各自卡在闸门,恢复顺序仍按 invoke(None) 逐步推进。
总结
- 静态断点:
interrupt_before / interrupt_after + checkpointer;恢复用 invoke(None, config=...)。
- 动态
interrupt() 适合业务审批;静态断点适合固定闸门与调试。
- 工具调用(
bind_tools、ToolNode、并行与包装)见 《LangGraph 06:工具调用》。