Featured image of post LangGraph Memory:Checkpointer 如何让 Agent 拥有连续记忆?

LangGraph Memory:Checkpointer 如何让 Agent 拥有连续记忆?

深入解析 LangGraph 中 Checkpointer 机制的原理与实践应用。

一次 Graph 执行结束之后,State 去哪里了?

LangGraph 系列文章第三篇聚焦于 Memory 机制——这是 Agent 实现上下文连续性的核心。前两篇解决了 Graph 的构建与 State 流转、Conditional Edge 的流程控制,但未触及关键问题:Graph 执行完成后,State 如何被保留并在后续会话中复用?

核心答案是 Checkpointer。它并非简单的存储容器,而是 LangGraph 中管理 State 生命周期的机制,通过 thread_id 为每个会话维护独立的状态快照,使 Agent 能够在多次调用间延续记忆。

关键要点如下:

  • Checkpointer:LangGraph 提供的状态持久化接口,负责保存 Graph 执行过程中的 State
  • MemorySaver:官方提供的内存版 Checkpointer 实现,适用于开发测试阶段
  • thread_id:会话唯一标识符,确保多用户场景下 State 隔离
  • 生产环境替代方案:Redis、PostgreSQL、MongoDB 等持久化存储

为什么 Agent 不能像普通函数一样工作?

文章通过代码对比揭示本质差异。

普通函数调用是瞬时无状态的:

1
2
3
function chat(input) {
  return "你好";
}

无论用户第一次说“我叫小明”,还是第二次问“我叫什么”,函数 internals 无法感知上下文——两次调用之间没有数据共享。

而 Agent 必须保留历史消息、用户信息、任务状态、工具结果等数据。这些数据构成了 Agent 的 Memory。没有 Memory,Agent 就是“失忆者”,每次对话都需重新确认基础事实,体验断崖式下降。

一个易被忽视的反差点在于: 多用户隔离的复杂性远超直觉。初学者常设计全局 state 对象:

1
let state = {};

这在单用户场景可行,但面对“用户A说‘我叫小明’、用户B说‘我叫小红’”时,全局 State 会导致状态污染——用户A可能看到用户B的隐私信息。thread_id 的引入正是为解决这一架构硬伤,确保每个会话拥有独立的状态沙箱。

Checkpointer 如何参与 Graph 的执行流程?

LangGraph 的 Checkpointer 集成方式清晰而简洁:

1
2
3
const app = graph.compile({
  checkpointer
});

与普通编译相比,唯一差异是传入 Checkpointer 实例。执行时,需指定 thread_id:

1
2
3
4
5
6
const config = {
  configurable: {
    thread_id: "user-1"
  }
};
await app.invoke({}, config);

thread_id 作为会话密钥,引导 LangGraph 定位到对应 State 快照。若该 thread_id 首次出现,系统从默认值初始化;若已存在,则恢复上次保存的状态,继续执行。

文章以访问计数 Demo 展示其工作闭环:

  1. State 定义 visitCount 字段,初始值为 0
  2. recordVisit 节点将计数加 1
  3. 第一次执行 thread_id=“xiaoming”:0 → 1,状态保存
  4. 第二次执行相同 thread_id:1 → 2,状态恢复并递增

关键机制在于:Graph 执行启动时,Checkpointer 先拉取对应 thread_id 的 State;Node 运算后,新的 State 由 Checkpointer 写回持久化层——这是 State → Memory 的闭环。

开发与生产环境的实践分界

MemorySaver 是 LangGraph 提供的默认实现,其特点鲜明:

特性MemorySaver生产级 alternatives
存储介质应用进程内存Redis / PostgreSQL / MongoDB
数据持久性服务重启即丢失断电/重启仍保留
多实例共享不支持支持跨服务实例共享 State
适用阶段学习、开发、测试轻度到重度生产负载

文章明确提醒:MemorySaver 仅限开发学习阶段使用。生产部署时,必须替换为持久化 Checkpointer 实现,否则用户刷新页面或服务重启会导致整个会话状态归零——用户“我叫小明”刚说完,服务重启后 Agent 便彻底遗忘。

落地建议与读者指南

  • 适合立即上手:通过 LangChain.js 或 LangGraph Python SDK 构建教学 Demo、原型系统的开发者;需要验证 State 流转逻辑的团队
  • 建议再等等:生产项目未实现持久化 Checkpointer 的团队——直接集成 MemorySaver 将埋下数据丢失隐患;对多租户隔离有强要求、但尚未设计 thread_id 管理策略的系统

写在最后:LangGraph 的 Memory 模型将 Agent 与传统函数式服务明确区分开来,Checkpointer 作为状态持久化的统一抽象层,既简化了开发者心智负担,又为复杂会话管理奠定基础。它不是可选配件,而是现代对话式 Agent 的必备组件。