751 字
2 分钟
LangGraphlanggraph
LangGraph 核心能力 05:Time-travel 重放与分叉

用检查点做时间旅行:重放历史、从旧状态分叉新路径,以及如何清理越来越多的 checkpoint。

LangGraph能力 - 时间旅行 (Time-travel)#

LangGraph 支持通过检查点实现时间回溯:

  • 重放:从先前的检查点重新执行。
  • 分支:从先前的检查点以修改后的状态分叉,探索其他执行路径。

两者均通过从先前检查点恢复运行。检查点之前的节点不会重新执行(结果已保存)。检查点之后的节点会重新执行,包括所有大模型调用、API 请求以及中断(可能产生不同结果)。

1. 重放 (Replay)#

使用先前检查点的配置调用图,从该点开始重放。

alt text

使用get_state_history找到你希望从中重放的检查点,然后使用该检查点的配置调用invoke:

Python3 点击展开代码
43 lines 展开代码

这里稍微复习一下细节,这里TypedDict让字典定义可以写类型,并且写了NotRequired,所以invoke的时候传入{}也是合法的。如果你有印象,我们在LangChain的invoke中会传入一个Message列表,这个列表可以是AIMessage、HumanMessage等的对象,也可以是content block。invoke聊天图的时候,传入的一定要是state的一部分,比如

graph.invoke({
"messages": [
{"role": "user", "content": "你好"}
]
})

持久化在前面章节介绍过了,我们用graph.get_state_history(config)会得到一个历史快照的迭代器,list化之后可以拿到一个这个thread_id下的所有历史快照(每个超步保存的一个StateSnapshot),我们这时候就可以看看保存的信息。

然后,我们用before_joke = next(s for s in history if s.next == ("write_joke",)),从列表中找到第一个准备开始写笑话之前的节点,在这个图中指的就是generate_topic,然后我们就可以从这个存档开始继续跑,前面置None不传入信息,后面放入找到的历史快照。

2. 分支 (Fork)#

分叉会从过往的一个检查点创建一个新分支,并修改状态。对先前的检查点调用update_state以创建分叉,随后使用None调用invoke来继续执行。

alt text

Python3 点击展开代码
13 lines 展开代码

graph.update_state(…)会基于旧checkpoint创建新的checkpoint分支,传入历史checkpoint的config,放入要更新的state字段就行了。

3. 能力总结#

时间旅行适合进行调试、人工审核或者分叉试验。当我们想进行正常循环的时候,比如经典的"生成 -> 评估 -> 不满意就继续改",或者拿官腔说是evaluator-optimizer的时候,可以直接在图上做环就行了。

generator -> evaluator -> conditional edge
pass -> END
fail -> generator

如果一直用时间回溯,虚拟的未来会越来越多。旧checkpoint还在,新checkpoint继续加进去,内存都会保存到python的进程内存中,越来越臃肿。

旧的checkpoint我们可以通过两种方式清理:

  • 直接删除整条thread,checkpointer.delete_thread(thread_id)
  • 用LangSmith或者Agent Server配置TTL

专题阅读

LangGraph

这篇文章属于同一条阅读链。你可以直接在这里切换,不用再回到列表页重新找。

当前进度7 / 11

留言区

留言

欢迎纠错、补充、交流。昵称和评论内容必填;如果你愿意,也可以留下联系方式,仅站主可见。

0

正在加载评论...

0 / 2000

阅读导航

文章目录

当前阅读位置将在这里显示

0 节