在LangGraph架构中,interrupt机制是实现“人工介入”与“流程暂停/恢复”的核心功能。它允许正在运行的Agent工作流在特定节点主动暂停,将当前状态与上下文完全暴露,等待外部输入后再从暂停点继续执行。

你可以将其类比为:
- 调试器中的断点
- 工作流引擎里的人工审批节点
- 操作系统中的sleep后resume
- 分布式任务中的checkpoint加recovery
1. 为什么需要 interrupt?
传统的Agent工作流是一条直线:用户请求 → LLM → 调用工具 → 返回结果。问题在于,一旦Agent做出危险操作(如直接删除数据库),根本来不及人工干预。
举个例子:
用户: 帮我删除 AWS 上所有测试服务器
Agent: 调用 delete_server() 执行完成
可以看到,没有机会让人确认。
引入interrupt后,流程变为:
用户请求 → Agent推理 → 准备调用delete_server() → interrupt() → 暂停 → 人工确认“是否真的删除?” → 继续执行 → delete_server()
这才是关键:在危险操作前,提供了一个“踩刹车”的入口。
2. interrupt 的基本使用
在代码层面,用法非常直接:
from langgraph.types import interrupt
def approval_node(state):
answer = interrupt(
{
"question": "是否允许执行删除操作?",
"action": "delete_user"
}
)
if answer["approved"]:
return {"result": "执行删除"}
return {"result": "取消删除"}
当执行到interrupt(...)时,整个流程即刻暂停。它会返回一个数据结构:
{
"question":"是否允许执行删除操作?",
"action":"delete_user"
}
外部系统接收到这个结构后,可以展示一个界面:
是否允许执行删除操作? [允许] [拒绝]
用户点击“允许”,传回:
{"approved":true}
随后流程恢复,继续执行后续任务。
3. interrupt 和普通 return 有什么区别?
普通return的节点,其生命周期为:
node → return → 结束
一次性执行,完成即终止。
而interrupt的节点,生命周期分为两段:
第一次:
node → interrupt → 保存状态 → 暂停
第二次(恢复后):
恢复 → value = 用户输入 → 继续执行
这是本质区别:普通return代表“结束”,interrupt则是“暂停,等待后续操作”。
4. interrupt 的设计原理
核心思想可以用一句话概括:“可持久化的暂停点”。
LangGraph本质上是一个图执行引擎,大致结构如下:
+-------+
| start |
+---+---+
|
v
+----+----+
| Agent |
+----+----+
|
v
+----+----+
| Tool |
+----+----+
|
v
END
每个节点执行的操作是:State → Node → New State。状态不断变化,例如:
{
"messages":["用户请求删除服务器"],
"current_step":"tool_call"
}
当执行interrupt()时,LangGraph内部会完成以下几件事:
1. 保存当前 state
类似于:
checkpoint:{
state:{
messages:[...],
current_node:"approval"
}
}
2. 保存执行位置
记录当前停在哪一个节点,以及下一步是什么:
graph position:node = approval_node
next_step = after_interrupt
3. 抛出特殊异常
内部实际上相当于触发了GraphInterrupt(),但这并非普通异常,而是专门用于暂停的机制。
4. 等待 resume
外部通过调用:
Command(
resume={"approved":True}
)
来唤醒工作流。
5. 恢复执行
从checkpoint恢复 → 回到approval_node → interrupt返回用户输入 → 继续执行后续逻辑
5. interrupt 为什么需要 checkpoint?
因为Agent可能运行很长时间。例如:
Agent:搜索网页 → 分析数据 → 调用数据库 → 生成报告 → 等待审批 → 发送邮件
审批可能发生在5分钟后、1天后,甚至一个月后。不能让服务一直空等,因为:
- 服务可能重启
- 机器可能宕机
- 内存数据会丢失
因此LangGraph使用checkpoint storage来持久化数据:
State + 执行位置 + 线程ID
例如:
thread_id=abc123
checkpoint:{
node:"approval",
state:{
order_id:10001,
amount:50000
}
}
6. interrupt 和消息队列有什么区别?
不少人容易将这两个概念混淆。
消息队列(MQ)解决的是“异步通信”和“削峰填谷”问题,比如Kafka、RabbitMQ。其重点在于解耦生产者和消费者,确保消息不丢失。
而interrupt解决的是“有状态暂停与恢复”。它关注的是整个工作流的执行状态,尤其是中间状态(state)的保存和恢复。例如:
订单流程:创建订单 → 付款 → interrupt → 人工审核 → 发货
这里interrupt之后,整个订单的状态都需要保留,等待审核结果回来再继续,这远不是MQ单向传递所能做到的。
7. interrupt 在 Agent 中的典型场景
① 人工审批
这是最常见的场景:AI生成合同 → interrupt → 律师审核 → 继续签署。
② 高风险工具调用
AI准备执行“DELETE DATABASE”时,interrupt等待确认,给运维人员一个紧急刹车的机会。
③ 信息补充
AI表示“我要帮你订机票”,但缺少“出发城市”信息,于是通过interrupt向用户提问:“请输入出发城市”。
④ 多 Agent 协作
Planner Agent → Research Agent → interrupt(专家审核) → Writer Agent。这里interrupt充当了不同角色之间的“交接点”。
8. interrupt 的核心设计理念
可以总结为四点:
① 图执行模型
不是传统的函数调用链,而是状态机(State Machine)。
② 可恢复计算
类似于数据库事务:begin → 执行 → checkpoint → commit。每一步都可以从中间状态恢复。
③ 长生命周期 Agent
普通LLM调用是秒级完成,而LangGraph的Agent可以跨越小时、天甚至月。
④ 人机协同
不是“AI替代人”,而是“AI执行80%的常规工作,人只在关键节点做决策”。这才是实际落地中最现实、最有价值的模式。
9. 和 LangChain Agent 的区别
传统的LangChain Agent是一个循环:
while True:
思考 → action → observation
状态主要存在于内存中,运行结束后即消失。
而LangGraph的Agent是:
State Graph Node → Checkpoint → Interrupt → Resume
这种设计更适合企业级应用:工作流自动化、审批流程、数据处理Pipeline。说到底,它是为“真正需要人工兜底”的复杂场景而生的。
