16d · 用 LangGraph 恢复一次真正中断的任务
⏱ 按步骤实践 | 从框架概念走到进程退出后继续
🎯 一句话
框架保存“运行到了哪里”,业务系统决定“现在还有没有权执行”。 用同一个工单流程验证这两层,不需要先下载大模型。
🔗 概念见框架这层皮,业务状态见12b。完整实现 framework.py;安装见17b。命令均在仓库根目录运行。
🔬 一、先暂停,再换进程恢复
python examples/knowledge-assistant/framework.py --db output/graph-business.db --checkpoints output/graph-checkpoints.db --thread interview-001
第一次输出含 __interrupt__,展示草稿与指纹后进程已经退出,没有工单副作用。现在用另一个命令进程恢复:
python examples/knowledge-assistant/framework.py --db output/graph-business.db --checkpoints output/graph-checkpoints.db --thread interview-001 --resume yes
预期 result 为 created。再次使用相同线程发起新任务会被拒绝,避免把旧状态当新会话。要做新的演示,换 --thread interview-002;拒绝审批用 --resume no。
--resume yes 是本地操作者夹具:命令行代表另一个有审批权的操作者,先写业务审批,再恢复图。产品中应换成已认证用户查看动作预览后的操作接口。不能把这个开关交给模型,也不能让前端任意 user_id 获得审批身份。
二、逐个概念对到代码
| 框架概念 | 本项目里是什么 | 需要观察 |
|---|---|---|
| StateGraph / State | 准备、审批、执行的状态字段 | 字段类型与节点只返回更新项 |
| 节点与边 | prepare → approval → commit | 业务先后关系,不靠模型猜步骤 |
| interrupt | 返回需要人看的动作预览 | 节点恢复时会重跑,之前不能放非幂等副作用 |
| checkpointer | 单独 SQLite checkpoint 文件 | 重启进程仍有 thread 状态 |
| thread_id | 稳定工作流实例 ID | 不是登录会话,也不是授权凭证 |
| Command(resume) | 向暂停点送回操作结果 | 回传 true 不能绕过业务库审批 |
| recursion_limit | 限制图执行步数 | 不等于金额、费用、时间或权限限制 |
本图是固定工作流,独立于 agent.py 中由模型选择工具的循环。两者共用业务函数,便于比较确定性流程与 Agent 的适用范围。完整 API 语义以 interrupts 与 persistence 为准。
三、从“会 import”到“能排错”的实验
| 改动或故障 | 预期 | 如果不满足,优先检查 |
|---|---|---|
| 第一次暂停后关进程 | 下次命令可以读取状态 | checkpoint 路径是否相同、是否真正落盘 |
| 换一个 thread_id 恢复 | 没有待恢复节点 | ID 映射是否混用会话与任务 |
| 只传 approved,不写业务审批 | execute 拒绝 | 是否把图状态当成授权事实 |
| 审批节点恢复重跑 | 不产生第二份副作用 | interrupt 前是否放了外部写操作 |
| 相同业务号改变正文 | 明确冲突 | 缺少内容指纹或规范化规则 |
| 同一线程并发 resume | 需要串行化/乐观版本控制 | 单机演示不提供分布式线程锁 |
自动化验证命令:
python -m unittest discover -s examples/knowledge-assistant -p test_protocol.py -v
其中框架用例启动两个不同 Python 进程,最后直接查业务库工单数。它比在同一个 Python 对象上继续调用更能证明持久化;但还没有覆盖集群迁移、checkpoint schema 升级与节点重命名。
四、扩展到长任务还需哪些边界
并行分支需要明确状态合并规则:追加消息、集合去重、金额累加都不等于简单字典覆盖。添加 reducer 后,测试分支乱序、重复结果和部分失败;共享业务写仍走幂等接口。
长等待需要超时、取消、审批到期和人工接管。进程退出不应清除待办;再次恢复时检查新权限。状态保存业务 ID 与最小必要数据,避免把整份敏感资料或 token 永久放进 checkpoint。
版本发布需要记录图版本、状态 schema 与兼容迁移。修改节点名称或 interrupt 的顺序可能影响旧任务恢复;用旧版本生成待办,再让新版本恢复,失败时保留旧 worker 路径或人工迁移。不能只测试新图的新任务。
多 Agent需要明确每个成员能看到的资料、工具权限、任务所有权与预算。多个模型输出赞同不等于事实正确;总调用数、环路、重复执行和冲突裁决进入评测。先用一个 Agent 或固定流程证明需求,再增加协作结构。
🛑 现在可以停:能解释 interrupt、checkpoint、thread_id 与业务授权各自做什么,就已越过“只会套框架”的阶段。
✅ 检查点
- 为什么 interrupt 前不能直接创建工单?
- 为什么图的递归步数限制不能代替业务预算?
- 上线新图之前,除了新任务还要测试什么?
展开答案
- 恢复可能重跑该节点,导致重复副作用;先保存意图,执行通过独立幂等服务。
- 一步可能很贵或包含多个工具,仍需要时间、token、费用和动作限额。
- 旧版本生成的暂停任务、状态 schema、节点与暂停点兼容,以及取消和权限变化后的恢复。
用两个进程验证恢复;暂停点前避免副作用;业务授权单独检查;升级要能处理旧任务。
🔗 接下来去哪
➡️ 下一站:17b · 企业知识助手交付项目。