记忆与持久化

让 AI 拥有记忆:使用 Checkpointer 实现多轮对话与状态保存

📚 学习目标

学完这篇文章后,你将能够:

  • 理解 LangGraph 的 Checkpointer 机制
  • 使用 MemorySaver 实现内存级的状态持久化
  • 使用 thread_id 管理多用户会话
  • 构建具备长期记忆能力的聊天机器人

前置知识

在开始学习之前,建议先阅读:


1️⃣ 为什么需要 Checkpointer?

默认情况下,LangGraph 的图是无状态的。每次调用 invoke,它都会从头开始并使用给定的初始状态。

但在聊天应用中,我们需要系统“记住”之前的对话内容。Checkpointer 就是为此设计的:它会在图的每一步执行后,自动将状态快照保存到存储介质中。

2️⃣ 使用 MemorySaver

对于开发和测试,我们可以使用内置的 MemorySaver,它将状态保存在内存中。

import { MemorySaver } from '@langchain/langgraph';

// 1. 初始化 Checkpointer
const checkpointer = new MemorySaver();

// 2. 编译图时传入
const graph = new StateGraph(StateAnnotation)
    // ...添加节点和边...
    .compile({ checkpointer });

3️⃣ Thread ID:识别会话

为了区分不同用户的对话,LangGraph 使用 thread_id(线程ID)。所有的状态都与特定的 thread_id 绑定。

import { randomUUID } from 'crypto';

const config = {
    configurable: {
        thread_id: randomUUID() // 为当前会话生成唯一 ID
    }
};

// 第一轮对话
await graph.invoke(
    { messages: [new HumanMessage("我是小明")] }, 
    config
);

// 第二轮对话(使用相同的 config)
await graph.invoke(
    { messages: [new HumanMessage("我叫什么名字?")] }, 
    config
);

当第二次调用 invoke 时,LangGraph 会:

  1. 根据 thread_id 查找上次的状态快照。
  2. 将新的输入消息追加到之前的历史记录中(基于我们在 Annotation 中定义的 reducer)。
  3. 让 LLM 看到完整的对话历史,从而能够回答“我叫什么名字”。

4️⃣ 持久化原理

5️⃣ 生产环境存储

MemorySaver 仅适用于测试,因为程序重启后数据会丢失。在生产环境中,你应该使用持久化存储的 Checkpointer:

  • @langchain/langgraph-checkpoint-postgres: 使用 PostgreSQL 数据库。
  • @langchain/langgraph-checkpoint-sqlite: 使用 SQLite 数据库。

用法完全一致,只需替换 new MemorySaver()new PostgresSaver(...)

💡 练习题

  1. 实操题:编写一个脚本,模拟两个不同的用户(使用两个不同的 thread_id)与同一个 Graph 进行对话。验证它们的对话历史是否互不干扰。

📚 参考资源

项目代码


✅ 总结

核心要点

  • Checkpointer 自动保存图的运行状态。
  • thread_id 是检索特定会话状态的钥匙。
  • 结合数组 Reducer 和 Checkpointer,我们可以轻松实现多轮对话记忆。

下一步:在下一篇文章《人机交互(Human-in-the-loop)》中,我们将学习如何利用这一持久化机制在图执行中途“暂停”,等待人工审批后再恢复执行。

登录以继续阅读

解锁完整文档、代码示例及更多高级功能。

立即登录

On this page