跳到主要内容
在使用基于模型决策的非确定性系统(例如,由 LLM 提供支持的代理)时,详细检查它们的决策过程会很有用
  1. 理解推理:分析导致成功结果的步骤。
  2. 调试错误:确定错误发生的位置和原因。
  3. 探索替代方案:测试不同的路径以发现更好的解决方案。
LangGraph 提供时间旅行功能来支持这些用例。具体来说,您可以从先前的检查点恢复执行——无论是重播相同的状态还是修改它以探索替代方案。在所有情况下,恢复过去的执行都会在历史记录中产生一个新的分支。 要在 LangGraph 中使用时间旅行
  1. 使用 invokestream 方法,使用初始输入运行图表
  2. 识别现有线程中的检查点:使用 @[getStateHistory] 方法检索特定 thread_id 的执行历史记录,并找到所需的 checkpoint_id。或者,在您希望执行暂停的节点之前设置一个断点。然后,您可以找到在该断点之前记录的最新检查点。
  3. 更新图状态(可选):使用 @[updateState] 方法修改检查点处的图状态,并从替代状态恢复执行。
  4. 从检查点恢复执行:使用 invokestream 方法,输入为 null,配置中包含相应的 thread_idcheckpoint_id
有关时间旅行的概念性概述,请参阅时间旅行

在工作流程中

此示例构建了一个简单的 LangGraph 工作流,该工作流生成一个笑话主题并使用 LLM 编写一个笑话。它演示了如何运行图表、检索过去的执行检查点、选择性地修改状态以及从选定的检查点恢复执行以探索不同的结果。

设置

首先,我们需要安装所需的软件包
npm install @langchain/langgraph @langchain/anthropic
接下来,我们需要为 Anthropic(我们将使用的 LLM)设置 API 密钥
process.env.ANTHROPIC_API_KEY = "YOUR_API_KEY";
注册 LangSmith 以快速发现问题并提高 LangGraph 项目的性能。LangSmith 允许您使用跟踪数据来调试、测试和监控使用 LangGraph 构建的 LLM 应用程序。
import { v4 as uuidv4 } from "uuid";
import * as z from "zod";
import { StateGraph, START, END } from "@langchain/langgraph";
import { ChatAnthropic } from "@langchain/anthropic";
import { MemorySaver } from "@langchain/langgraph";

const State = z.object({
  topic: z.string().optional(),
  joke: z.string().optional(),
});

const model = new ChatAnthropic({
  model: "claude-sonnet-4-5-20250929",
  temperature: 0,
});

// Build workflow
const workflow = new StateGraph(State)
  // Add nodes
  .addNode("generateTopic", async (state) => {
    // LLM call to generate a topic for the joke
    const msg = await model.invoke("Give me a funny topic for a joke");
    return { topic: msg.content };
  })
  .addNode("writeJoke", async (state) => {
    // LLM call to write a joke based on the topic
    const msg = await model.invoke(`Write a short joke about ${state.topic}`);
    return { joke: msg.content };
  })
  // Add edges to connect nodes
  .addEdge(START, "generateTopic")
  .addEdge("generateTopic", "writeJoke")
  .addEdge("writeJoke", END);

// Compile
const checkpointer = new MemorySaver();
const graph = workflow.compile({ checkpointer });

1. 运行图

const config = {
  configurable: {
    thread_id: uuidv4(),
  },
};

const state = await graph.invoke({}, config);

console.log(state.topic);
console.log();
console.log(state.joke);
输出
How about "The Secret Life of Socks in the Dryer"? You know, exploring the mysterious phenomenon of how socks go into the laundry as pairs but come out as singles. Where do they go? Are they starting new lives elsewhere? Is there a sock paradise we don't know about? There's a lot of comedic potential in the everyday mystery that unites us all!

# The Secret Life of Socks in the Dryer

I finally discovered where all my missing socks go after the dryer. Turns out they're not missing at all—they've just eloped with someone else's socks from the laundromat to start new lives together.

My blue argyle is now living in Bermuda with a red polka dot, posting vacation photos on Sockstagram and sending me lint as alimony.

2. 识别检查点

// The states are returned in reverse chronological order.
const states = [];
for await (const state of graph.getStateHistory(config)) {
  states.push(state);
}

for (const state of states) {
  console.log(state.next);
  console.log(state.config.configurable?.checkpoint_id);
  console.log();
}
输出
[]
1f02ac4a-ec9f-6524-8002-8f7b0bbeed0e

['writeJoke']
1f02ac4a-ce2a-6494-8001-cb2e2d651227

['generateTopic']
1f02ac4a-a4e0-630d-8000-b73c254ba748

['__start__']
1f02ac4a-a4dd-665e-bfff-e6c8c44315d9
// This is the state before last (states are listed in chronological order)
const selectedState = states[1];
console.log(selectedState.next);
console.log(selectedState.values);
输出
['writeJoke']
{'topic': 'How about "The Secret Life of Socks in the Dryer"? You know, exploring the mysterious phenomenon of how socks go into the laundry as pairs but come out as singles. Where do they go? Are they starting new lives elsewhere? Is there a sock paradise we don\\'t know about? There\\'s a lot of comedic potential in the everyday mystery that unites us all!'}

3. 更新状态

updateState 将创建一个新的检查点。新检查点将与同一线程关联,但具有新的检查点 ID。
const newConfig = await graph.updateState(selectedState.config, {
  topic: "chickens",
});
console.log(newConfig);
输出
{'configurable': {'thread_id': 'c62e2e03-c27b-4cb6-8cea-ea9bfedae006', 'checkpoint_ns': '', 'checkpoint_id': '1f02ac4a-ecee-600b-8002-a1d21df32e4c'}}

4. 从检查点恢复执行

await graph.invoke(null, newConfig);
输出
{
  'topic': 'chickens',
  'joke': 'Why did the chicken join a band?\n\nBecause it had excellent drumsticks!'
}

以编程方式连接这些文档到 Claude、VSCode 等,通过 MCP 获取实时答案。
© . This site is unofficial and not affiliated with LangChain, Inc.