三亩地 三亩地SAN MU DI · CODE DIARY
ARTICLE DETAIL

日记详情

真实记录编程学习的某一天,欢迎挑你感兴趣的翻一翻。

LangGraph 失败恢复详解:为什么成功节点不会重复执行?

LangGraph 失败恢复详解:为什么成功节点不会重复执行?

前面我们已经学习了 Checkpoint、get_state_history()、Replay 和 Fork。

这一篇继续看一个更实用的问题:

如果同一个 SuperStep 中,一个节点执行成功,另一个节点执行失败,修复后恢复运行时,成功节点还会不会重新执行?

LangGraph 中:已经成功的任务结果可以被检查点保存,恢复时直接复用。

1. 一个节点失败后,LangGraph 保存了什么?

假设图结构是:

START | node_change_topic | +------> node_poem | +------> node_joke | v node_output | END

其中node_poemnode_joke属于同一个 SuperStep。

为了模拟失败,可以故意让:

defnode_joke(state):raiseException("人为中断")

第一次执行时:

node_change_topic 执行成功 ↓ node_poem 和 node_joke 并行执行 ↓ node_poem:成功 node_joke:失败 ↓ 图中断

这时查看历史检查点:

history=list(graph.get_state_history(config))

可以看到对应的tasks中:

PregelTask(name="node_poem",error=None,result={"poem":"..."})

而失败节点:

PregelTask(name="node_joke",error="Exception('人为中断')",result=None)

所以这里可以理解为:

result = 节点已经成功产生的结果 error = 节点执行失败时记录的异常

2. 为什么 node_poem 不需要重新执行?

虽然node_poemnode_joke在同一个 SuperStep 中运行,但其中一个失败,并不会让另一个已经成功的结果全部丢失。

检查点已经知道:

node_poem 成功 result 已保存 node_joke 失败 error 已保存

因此恢复时,LangGraph 可以:

复用 node_poem.result + 重新执行 node_joke

而不是:

node_poem 再执行一次 node_joke 再执行一次

这对包含大模型调用、API 请求、数据库查询等昂贵操作的工作流尤其重要。


3. 修复 BUG 后如何恢复?

先把node_joke修好:

defnode_joke(state):topic=state["topic"]joke=model.invoke([HumanMessage(f"写一个关于{topic}的笑话")]).contentreturn{"joke":joke}

然后重新编译图:

new_graph=builder.compile(checkpointer=checkpointer)

这里最重要的是:

必须继续使用之前那个 Checkpointer。

因为历史 Checkpoint 就保存在它里面。

如果重新创建:

checkpointer=InMemorySaver()

那就是一个新的空存储器,原来的历史也就找不到了。

恢复时:

res=new_graph.invoke(None,config={"configurable":{"thread_id":"123"}})

这里:

input=None

表示:

不再提供新的输入 而是从当前 thread_id 已保存的状态继续

实际恢复结果中:

node_joke 重新执行 node_output 继续执行 node_poem 没有重新执行

最终输出中的诗仍然是第一次node_poem成功时生成的内容,说明它的结果被复用了。


4. 失败恢复和 Replay 有什么区别?

这两个概念看起来很像,但目的不同。

Replay:

我主动找到一个历史 Checkpoint 然后从那里重新执行

例如:

graph.invoke(None,old_checkpoint.config)

而失败恢复是:

上一次执行因为异常中断 ↓ 修复 BUG ↓ 继续使用原来的 Checkpointer ↓ 通过相同 thread_id 恢复 ↓ 接着未完成的任务继续执行

可以简单记:

Replay 重新走一次 失败恢复 上次没走完,现在接着走

它还在解决:

任务执行到了哪里,以及哪些计算已经完成。

← 返回列表