记忆与持久化
让 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 会:
- 根据
thread_id查找上次的状态快照。 - 将新的输入消息追加到之前的历史记录中(基于我们在 Annotation 中定义的 reducer)。
- 让 LLM 看到完整的对话历史,从而能够回答“我叫什么名字”。
4️⃣ 持久化原理
5️⃣ 生产环境存储
MemorySaver 仅适用于测试,因为程序重启后数据会丢失。在生产环境中,你应该使用持久化存储的 Checkpointer:
- @langchain/langgraph-checkpoint-postgres: 使用 PostgreSQL 数据库。
- @langchain/langgraph-checkpoint-sqlite: 使用 SQLite 数据库。
用法完全一致,只需替换 new MemorySaver() 为 new PostgresSaver(...)。
💡 练习题
- 实操题:编写一个脚本,模拟两个不同的用户(使用两个不同的
thread_id)与同一个 Graph 进行对话。验证它们的对话历史是否互不干扰。
📚 参考资源
项目代码
- 查看本节完整代码:quick-start/7.memory.ts
✅ 总结
核心要点:
- Checkpointer 自动保存图的运行状态。
- thread_id 是检索特定会话状态的钥匙。
- 结合数组 Reducer 和 Checkpointer,我们可以轻松实现多轮对话记忆。
下一步:在下一篇文章《人机交互(Human-in-the-loop)》中,我们将学习如何利用这一持久化机制在图执行中途“暂停”,等待人工审批后再恢复执行。
登录以继续阅读
解锁完整文档、代码示例及更多高级功能。