LangGraph 09:时光旅行
前言
有了 Checkpoint,图就不再是「跑完即弃」:可以从历史快照续跑、改输入再分叉,甚至在并行失败后只重跑出错分支。
本文只讲检查点时间线上的操作:错误恢复、invoke(None) 回放、update_state 分叉。
跨线程长期记忆见下一篇 《LangGraph 10:Store 与 Context》。
聊天模型对接 火山方舟 Coding Plan。
下文需要 Python 3.12+,依赖用 uv 管理。
依赖
建议使用 Python 3.12 及以上。
用 uv 初始化工程并声明依赖。
1 | uv init langgraph-timetravel |
在项目根目录创建 .env:
1 | OPENAI_API_KEY=你的火山方舟 API Key |
不要把 .env 提交进 Git。
Saver 与 thread_id 的基本用法见 《LangGraph 08:Checkpoint 持久化》。
示例
错误恢复思路
并行图中,同一超步里可能一边成功、一边抛错。
启用 checkpointer 后,成功节点的结果往往已写入检查点;修好出错逻辑后,对同一 Saver 与 thread_id 再 invoke(None, config=...),可从中断处续跑。
下面用可变开关模拟:第一次 node_joke 失败;关掉开关后空输入续跑。
请保持同一个 InMemorySaver 实例;换进程或新进程时,内存检查点不会自动保留,需要 Postgres 等持久化后端。
1 | import os |
排障流程通常是:get_state_history → 定位失败超步 → 修逻辑或数据 → invoke(None)。
跨进程恢复请改用 Postgres 等持久化 Saver,而不是新建空的 InMemorySaver。
Replay 回放
回放:选中历史里某个检查点的 config,再 invoke(None, config=该检查点)。
输入填 None 表示「不要新用户输入,从该快照的 next 继续」。
1 | import os |
回放会再次执行 next 指向的节点,适合复现或对比生成结果。
带副作用的节点(写库、扣费)回放前要自己做幂等。
Fork 分叉
分叉:在某一历史点用 update_state 改状态,再 invoke(None) 走出另一条时间线。as_node 表示「这些更新视为刚从该节点执行完」,从而影响后续 next。
1 | import os |
as_node=START 适合「改用户输入再整段重跑」。as_node="router_node" 适合「跳过路由、直接指定下游所需字段」。
验证
- 恢复:第一次失败后关掉开关再
invoke(None),应补上笑话并产出final_output。 - Replay:从
next == ("node_poem", "node_joke")的检查点空输入续跑,应再次生成诗与笑话。 - Fork:改
user_input含「笑话」后,输出应走笑话分支。
总结
- 恢复 / 回放:同一 checkpointer +
invoke(None, config=检查点)。 - 分叉:
update_state(..., as_node=...)再续跑,走出新时间线。 - 下一篇换一条记忆轴:跨线程 Store 与请求级 Context,见 《LangGraph 10:Store 与 Context》。