跳到内容

时间旅行 ⏱️

先决条件

本指南假设您熟悉 LangGraph 的检查点和状态。如果不是,请先查阅持久化概念。

在使用基于模型做出决策的非确定性系统(例如,由大型语言模型(LLM)驱动的代理)时,详细检查其决策过程会非常有用。

  1. 🤔 理解推理:分析导致成功结果的步骤。

  2. 🐞 调试错误:找出错误发生的位置和原因。

  3. 🔍 探索替代方案:尝试不同的路径以发现更好的解决方案。

我们将这些调试技术称为时间旅行,它由两个关键操作组成:回放 🔁 和 分支 🔀。

回放

回放允许我们重温并复现代理过去的动作。这可以从图的当前状态(或检查点)执行,也可以从特定检查点执行。

要从当前状态回放,只需将 null 作为输入与 threadConfig 一起传递即可。

const threadConfig = { configurable: { thread_id: "1" }, streamMode: "values" };

for await (const event of await graph.stream(null, threadConfig)) {
    console.log(event);
}

要从特定检查点回放动作,首先检索该线程的所有检查点。

const allCheckpoints = [];

for await (const state of graph.getStateHistory(threadConfig)) {
    allCheckpoints.push(state);
}

每个检查点都有一个唯一的 ID。在确定所需的检查点(例如 xyz)后,将其 ID 包含在配置中。

const threadConfig = { configurable: { thread_id: '1', checkpoint_id: 'xyz' }, streamMode: "values" };

for await (const event of await graph.stream(null, threadConfig)) {
    console.log(event);
}

图会高效地回放先前已执行的节点,而不是重新执行它们,这得益于其对先前检查点执行的了解。

分支

分支允许您重温代理过去的动作并探索图中的替代路径。

要编辑特定检查点(例如 xyz),在更新图的状态时提供其 checkpoint_id

const threadConfig = { configurable: { thread_id: "1", checkpoint_id: "xyz" } };

graph.updateState(threadConfig, { state: "updated state" });

这将创建一个新的分支检查点,例如 xyz-fork,您可以从此检查点继续运行图。

const threadConfig = { configurable: { thread_id: '1', checkpoint_id: 'xyz-fork' }, streamMode: "values" };

for await (const event of await graph.stream(null, threadConfig)) {
    console.log(event);
}

更多资源 📚