LangGraph 03:持久化、Interrupt、恢复与时间旅行

2026-09-01
12515 分钟
...

1、本篇任务:让退款流程暂停一天后还能继续

审批可能几秒后完成,也可能第二天才处理。HTTP 请求不能一直挂着,所以图必须保存状态、结束当前请求,并在新请求中从相同 thread 恢复。

2、Checkpoint、Thread、Store 的关系

checkpointer 在每个 super-step 保存 state snapshot;thread ID 把一系列 checkpoint 组织成一次持续运行;store 保存跨 thread 的长期数据。业务订单和审计仍在自己的数据库,不应全部塞进 checkpoint。

from langgraph.checkpoint.memory import InMemorySaver

graph = builder.compile(checkpointer=InMemorySaver())
config = {"configurable": {"thread_id": "refund-task-42"}}

内存 saver 仅用于测试。生产数据库需要处理租户隔离、加密、备份、TTL 和 schema 迁移。

3、使用 interrupt 暂停审批

from langgraph.types import interrupt, Command

def approval_node(state: RefundState):
    decision = interrupt({
        "action_id": state["action_id"],
        "kind": "refund",
        "order_id": state["order_id"],
        "amount": state["refund_amount"],
        "expires_at": state["approval_expires_at"],
    })
    return {"decision": decision["decision"]}

# 第一次运行会暂停并保存 checkpoint
graph.invoke(initial_state, config=config)

# 后续请求使用同一个 thread 恢复
graph.invoke(Command(resume={"decision": "approve"}), config=config)

TypeScript 使用 interrupt(payload)new Command({ resume: decision })。payload 必须 JSON 可序列化;不要在 interrupt() 外包会吞掉中断的宽泛 try/except;不要在节点升级时随意改变多个 interrupt 的顺序。

4、为什么 interrupt 前的代码可能再次执行

恢复时节点会从头重新运行,直到 interrupt() 返回 resume 值。因此 interrupt 前的副作用必须幂等,最好把副作用放在批准之后的独立节点。

正确拆分:

draft_refund纯计算/保存草案
approval interrupt
validate_decision重新鉴权检查 hash/过期
submit_refundaction_id 幂等副作用

5、恢复 API 的权限合同

浏览器提交 action_id + decision。服务端根据登录态检查:action 属于当前用户/租户;thread 与 action 匹配;仍是 pending;未过期;批准的参数 hash 与草案一致。然后在事务内记录决定并恢复图。

thread ID、checkpoint ID、action ID 都是定位符,不是授权凭证。

6、故障恢复与 pending writes

并发 super-step 中一个节点失败时,已成功节点的 pending writes 可被保存,恢复时无需全部重跑。但外部服务是否重复调用仍由你的工具幂等保障。

重点测试故障窗口:退款服务已经成功,但 worker 在写完成状态前崩溃。恢复后 submit_refund(action_id) 必须返回同一退款记录,不产生第二条。

7、Time travel 是调试与分支,不是删除历史

checkpoint 历史可用于查看旧 state、从某个 snapshot fork 新分支、在隔离环境重放 bug。已经发生的退款、邮件或审计不能靠回到旧 checkpoint 撤销。回放时禁用真实副作用或复用原 action ID。

State schema 变化时为旧 checkpoint 写纯函数迁移,并保留 state_schema_version/graph_version。蓝绿部署期间可让旧 thread 固定由兼容 worker 完成。

8、本篇测试

暂停后进程退出再恢复;错误 thread/用户不能审批;过期和篡改参数被拒绝;重复 resume 不重复退款;interrupt 前节点重复执行仍无副作用;旧 checkpoint 可迁移或进入人工队列。

下一课学习如何把 state、消息、工具和自定义进度流式输出,并在生产环境定位图故障。

官方阅读:PersistenceInterrupts

如果您觉得这篇文章有帮助,请点个赞吧~

分享文章

相关文章

更多文章 →
AI2026-09-01
Deep Agents 01:何为 Agent Harness,以及如何开始
1、本篇任务:完成一份多步骤、带证据的技术调研 普通客服 Agent 的问题短、工具少、输出即时。技术调研或编码任务会持续很久,产生计划、搜索结果、文件和中间结论。Deep Agents 在 LangChain/LangGraph 之上预装规划、虚拟文件系统、上下文压缩和子 Agent,适合这类开放任务。 本课让 Agent 比较两种向量数据库,并交付一份可验证报告。 2、什么时候需要 Deep Agent 满足以下两项以上再考虑:任务...
学习
AI2026-09-01
Deep Agents 02:子 Agent、虚拟文件系统与长期记忆
1、本篇任务:让主管只看结论,让子 Agent 处理细节 技术调研会产生几十次搜索和大量文件。如果全部进入主管上下文,真正的目标会被噪音淹没。本课用两个子 Agent: 收集证据, 检查结论;主管负责计划与最终合成。 2、什么时候委派,什么时候直接调用工具 适合委派:子任务有多步;需要专门提示或工具;会产生大量中间结果;只需返回有限结论。不适合:一步查询;主管需要全部中间上下文;协调成本超过任务本身。 3、配置专门子 Agent Pyt...
学习
AI2026-09-01
Deep Agents 03:生产化、Sandbox、权限与上线验收
1、本篇任务:让 Deep Agent 在隔离环境中分析代码 只读研究 Agent 风险有限;编码 Agent 需要读写文件、安装依赖和执行测试。本课不讲如何让模型写更漂亮的代码,只讲执行环境、权限、恢复和上线验收。 2、先做威胁模型 资产包括源代码、用户文件、云凭证、生产网络和发布权限;攻击入口包括用户消息、仓库内容、网页、依赖包、MCP 返回和命令输出。 Prompt injection 不是靠一句 system prompt 解决...
学习
AI2026-09-01
LangChain 01:全景、原理与学习路线
1、本篇学完要得到什么 这一篇只解决三个问题:LangChain 到底负责什么;它与 LangGraph、Deep Agents、LangSmith 是什么关系;后面应按什么顺序学习。 贯穿整套课程的项目是“退款政策与订单助手”。它最终能够:回答知识库中的退款规则;查询当前用户的订单;生成结构化答复;对真正的退款操作进行人工审批;断线后恢复;通过评测后发布。 先记住一句话: 模型负责理解与生成,应用负责数据、权限、状态和副作用。 如果把...
学习
AI2026-09-01
LangChain 02:模型、消息与结构化输出
1、本篇任务:让模型输出成为程序可以依赖的合同 上一课只证明 Agent 能运行。本课暂时不接业务工具,只完成一个“客服分诊器”:输入用户问题,输出意图、紧急程度、是否需要人工和给用户的答复。 本课的核心不是学更多模型参数,而是理解三层合同:消息决定模型看到了什么;schema 决定程序期待什么;业务校验决定结果是否真的可用。 2、消息不是一段字符串,而是一条执行记录 一次工具型对话通常包含四种消息: | 类型 | 由谁产生 | 作用...
学习
AI2026-09-01
LangChain 03:工具与 Agent——从函数到可控行动
1、本篇任务:让 Agent 安全地读取订单 上一课得到结构化分诊结果,但模型不知道真实订单。本课增加一个只读工具 ,走通完整 Agent 循环,并把模型、工具包装和领域服务的责任分开。 完成后,用户问“我的 A100 发货了吗”,Agent 会选择工具;工具只按当前登录用户查询;模型基于工具结果回答。它仍然不能退款,因为我们没有提供写工具。 2、工具的本质是受 schema 约束的应用函数 一个好工具需要:稳定名称、清楚描述、窄输入...
学习

评论

请登录后发表评论

去登录
加载评论中...

目录