跳转到主要内容
Agent 记忆系统

Agent 记忆系统学习笔记(四):从 LangGraph / LangMem 看懂框架级记忆抽象

AI 辅助写的

用 LangGraph / LangMem 作为第四个样本,理解 short-term memory、long-term memory、checkpointer、store、semantic / episodic / procedural memory,以及 hot path 和 background 写入。

写在前面:为什么第四篇看 LangGraph / LangMem

前三篇分别看了三种系统路线:

Mem0:自动抽取 + 多信号召回
Zep:时间知识图谱 + Context Block
Letta:Agent 自主管理记忆 + 上下文层级

这一篇我想换一个角度,不再只看某个记忆产品,而是看框架级记忆抽象

LangGraph / LangMem 的价值在于,它把记忆问题拆得很清楚:

短期记忆:当前 thread 的 state 和 checkpoint
长期记忆:跨 thread 的 store 和 namespace
语义记忆:facts about user
情景记忆:past experiences / examples
程序记忆:instructions / prompts / behavior rules

如果说 Mem0、Zep、Letta 分别是不同的系统实现,那么 LangGraph 更像一套开发框架里的基本积木。它不替你决定所有记忆策略,而是告诉你:哪些东西属于状态,哪些东西属于 store,哪些东西应该同步写,哪些东西可以后台写。


一、LangGraph 的核心问题:记忆先是状态管理

很多 Agent 记忆讨论会直接跳到向量库、图数据库、长期偏好。但 LangGraph 的起点更工程化:一个 Agent 工作流本身就是一个状态机。

每次调用图,都会有 state。state 里可能有:

messages
summary
retrieved documents
tool outputs
intermediate artifacts
human feedback
下一步要执行的节点

如果这些状态不能持久化,Agent 就无法跨轮继续,也无法在中断后恢复,更无法做 human-in-the-loop 或 time travel。

所以 LangGraph 的记忆首先不是“长期知识”,而是“工作流状态”。

LangGraph 的两类持久化:Checkpointer 和 Store
LangGraph 把短期记忆和长期记忆拆成两个不同系统:thread state 用 checkpointer,跨会话数据用 store。
短期记忆
Graph State
当前 thread 的 messages、summary、工具结果、临时产物
persist
Checkpointer
按 thread_id 保存 state snapshot;支持恢复、time travel、interrupt
长期记忆
Application Data
用户偏好、事实、样例、动态 prompt、共享知识
put / search
Store
按 namespace + key 存 JSON 文档,可开启 semantic search

LangGraph 把持久化拆成两套系统:

Checkpointer:保存 thread-scoped graph state
Store:保存 cross-thread long-term memory

这个划分非常重要。它让我们把“当前会话连续性”和“跨会话长期记忆”分开看。


二、短期记忆:Checkpointer 保存 thread state

短期记忆在 LangGraph 里通常指 thread-scoped memory。

一个 thread 就像邮件里的一个会话串。用户在这个 thread 里持续和 Agent 对话,Agent 需要记住当前对话发生过什么。

LangGraph 用 checkpointer 保存 graph state 的 checkpoint。调用时传入:

thread_id

框架就能找到这个 thread 对应的状态,并在下一次调用时继续使用。

短期记忆适合存:

最近消息
当前任务状态
工具调用结果
中间产物
会话摘要
等待用户确认的 interrupt 状态

它的核心价值不只是聊天连续性,还包括:

恢复中断任务
查看历史 state
time travel 到过去 checkpoint
容错和重试
human-in-the-loop 审批

这和 Mem0 / Zep 的长期召回不一样。Checkpointer 解决的是:“这个工作流刚刚进行到哪里?”


三、长期记忆:Store 保存跨会话数据

长期记忆在 LangGraph 里通过 store 实现。

Store 保存的是 application-defined data,也就是应用自己定义的 JSON 文档。每条数据通常放在一个 namespace 下面,再用 key 标识。

比如:

namespace = (user_id, "memories")
key = memory_id
value = {"text": "用户喜欢短而直接的回答"}

Store 可以在 graph node 内部读写。也就是说,某个节点在调用模型前可以:

根据当前用户输入搜索长期记忆
把搜到的记忆拼进 system prompt
必要时把新记忆写回 store

和 checkpointer 的区别是:

维度CheckpointerStore
范围单个 thread跨 thread
内容graph state snapshots应用定义的长期数据
用途会话连续性、恢复、中断、time travel用户偏好、事实、样例、共享知识
访问方式通过 thread_id 恢复 state通过 namespace / key / search 访问

所以,如果用户在 thread A 说“记住我叫 Bob”,然后在 thread B 问“我叫什么”,这就不应该只靠 checkpointer,而应该写进 store。


四、三类长期记忆:Semantic、Episodic、Procedural

LangGraph / LangMem 的另一个价值,是把长期记忆按类型拆开。

三类长期记忆:Semantic、Episodic、Procedural
LangGraph / LangMem 的价值在于先区分要学习什么,再决定怎么存和怎么召回。
Semantic Memory
事实和知识:用户偏好、资料、概念、关系。
Episodic Memory
经历和案例:过去怎么完成任务,常作为 few-shot example 召回。
Procedural Memory
规则和行为:系统提示词、流程偏好、工具使用习惯。

Semantic Memory:事实和知识

Semantic memory 是事实记忆。

例如:

用户喜欢 Python。
用户偏好简洁回答。
Alice 负责 ML 团队。
某个项目使用 Postgres。

这是大多数人想到“长期记忆”时最先想到的东西。Mem0 主要处理的也是这一类。

Semantic memory 可以有两种常见形态:

Profile:一个持续更新的用户画像 JSON
Collection:一组独立 memory 文档

Profile 的好处是整体性强,坏处是越大越难安全更新。Collection 的好处是易追加、召回率高,坏处是关系和全局一致性更难维护。

Episodic Memory:经历和案例

Episodic memory 记的是过去发生过的事件或经验。

在 Agent 里,它经常表现为 few-shot examples:

之前遇到类似任务时,Agent 是怎么做的?
哪个工具调用序列成功解决了问题?
用户之前如何评价某种回答?

它回答的不是“事实是什么”,而是“过去怎样处理过”。

这类记忆对 coding agent、客服 agent、自动化 agent 特别重要。因为很多能力不是背事实,而是复用成功轨迹。

Procedural Memory:规则和行为

Procedural memory 记的是“怎么做事”。

在 AI Agent 里,它通常不是真的改模型权重,而是改:

system prompt
instructions
tool usage guidelines
workflow rules
response style

LangMem 的 prompt optimizer 就属于这个方向:从成功和失败轨迹中总结行为改进,再生成新的 prompt 规则。

这点对整个系列很重要。前面 Mem0 和 Zep 更多偏 semantic / episodic;Letta 的 persona、policies、scratchpad 则很接近 procedural / working memory。LangGraph 把这些类型统一到了一个分类框架里。


五、写入时机:hot path 还是 background

长期记忆还有一个关键问题:什么时候写?

LangGraph 文档把它分成两类:

记忆写入时机:hot path vs background
LangGraph 不强迫一种写入方式,而是让你在实时性、延迟和质量之间做工程取舍。
Hot Path
在用户请求链路里写记忆;新记忆立刻可用,但增加延迟和复杂度。
适合
用户明确说“记住”、需要马上跨线程可用的事实
Background
后台异步提取记忆;不阻塞主流程,但有延迟和触发策略问题。
适合
会话结束总结、定时整理、批量提取长期偏好

Hot path 写入

Hot path 是在用户请求链路里直接写记忆。

比如用户说:

记住,我以后都想用中文回答。

Agent 立刻把它写入 store。下一轮马上生效。

优点:

实时
透明
新记忆立刻可用

缺点:

增加延迟
Agent 要分心判断是否写入
写入质量可能影响主任务

Background 写入

Background 是在主流程之外异步整理记忆。

比如:

对话结束后总结用户偏好
每天批量整理用户历史
后台从工具调用轨迹中抽取可复用经验
定期优化 system prompt

优点:

不影响主链路延迟
可以用更复杂的抽取逻辑
适合批处理和人工审核

缺点:

新记忆不会立刻生效
需要任务队列和触发策略
可能出现过期或重复记忆

这也是记忆系统真正复杂的地方。不是“要不要写入向量库”,而是要回答:

谁来判断这件事值得记?
什么时候写?
写到哪一类记忆?
旧记忆冲突时怎么办?
是否需要用户确认?

六、召回链路:state 直接读,store 按需搜

LangGraph 的召回链路也很清楚:

短期上下文来自 state
长期上下文来自 store
node 负责把二者组装进 prompt
LangGraph 召回链路:state 直接读,store 按需搜
框架级记忆的关键,是把当前线程状态和跨线程长期记忆在 node 里组合起来。
Graph Node
接收当前 state 和 runtime context
Short-term State
当前 thread 的 messages / summary / artifacts
Long-term Store
按 namespace 搜索用户或应用记忆
merge into prompt
当前上下文
state 里最近对话和工具结果
长期记忆
store 里按 query 检索的 facts / examples / instructions
模型调用
把两类上下文一起组织进 prompt

一次典型调用可能是:

1. Graph node 收到当前 state
2. 从 state 读取最近 messages 和当前任务状态
3. 根据 user_id 和当前 query 搜索 store
4. 得到相关长期记忆
5. 把短期状态 + 长期记忆组织进模型 prompt
6. 模型生成回答或工具调用
7. 根据结果更新 state,必要时写入 store

这和“把所有历史对话都塞进上下文”有本质区别。

LangGraph 的方式是分层的:

当前 thread 内的连续性:state / checkpoint
跨 thread 的长期偏好:store / namespace
相关性筛选:search
最终上下文构造:node / prompt

也就是说,记忆不是一个单独 API,而是嵌在 graph execution 里的上下文工程。


七、LangMem:把记忆抽取和行为优化工具化

LangGraph 本身提供 state、checkpoint、store、node 这些基础设施。LangMem 则更进一步,提供围绕长期记忆的工具包。

它重点做几件事:

从对话中抽取和更新长期记忆
管理 semantic / episodic / procedural memory
从反馈和轨迹中优化 agent 行为
和 LangGraph store 集成

如果 LangGraph 是“可以建记忆系统的框架”,LangMem 更像“常见记忆策略的 SDK”。

这两个东西放在一起,形成了一个很完整的抽象层:

LangGraph:状态机、持久化、store、runtime
LangMem:记忆抽取、记忆更新、prompt 优化、行为学习

但它们仍然不是 Mem0 或 Zep 那种开箱即用的 memory service。你需要自己决定:

记忆 schema 怎么设计
namespace 怎么划分
哪些 node 负责检索
哪些 node 负责写入
是否要向量搜索
是否要人工审核
如何处理冲突、遗忘和权限

这就是框架级方案和产品级方案的区别。


八、和 Mem0、Zep、Letta 的对应关系

把前四篇放在一起看,会更清楚:

前四篇放在一起看
LangGraph 更像抽象层:它不替你决定记忆策略,而是提供状态、持久化和 store,让你实现自己的策略。
Mem0
memory ranking layer
Zep
temporal graph + context assembly
Letta
agent-managed memory hierarchy
LangGraph
memory primitives in agent framework

Mem0:记忆是可排序的事实集合

Mem0 更偏产品化记忆层。它帮你自动抽取 memory,再在召回时做语义、图关系、时间、实体等多信号排序。

你关心的是:

怎么接入 memory API
怎么让系统自动记住用户偏好
怎么在回答前拿到相关 memories

Zep:记忆是带时间的关系图

Zep 的重点是事实、实体、关系、时间和 invalidation。

它关心的是:

事实什么时候成立
后来有没有被推翻
哪些实体和关系影响当前问题
如何组装成 context block

Letta:记忆是 Agent 可管理的上下文层级

Letta / MemGPT 的核心是让 Agent 自己管理 memory hierarchy。

它关心的是:

core memory 放什么
archival memory 怎么查
context 满了怎么换页
Agent 如何通过工具修改自己的记忆

LangGraph:记忆是 Agent 应用里的可编排基础设施

LangGraph 不把记忆封装成一个黑盒服务,而是把它拆成:

state
checkpoint
store
namespace
node
prompt assembly
background task

它关心的是:

一个真实 Agent 应用如何可靠运行、恢复、检索、写入和演化

所以 LangGraph 更像 memory operating system 的开发框架,而不是单独的 memory app。


九、我的判断:LangGraph 适合把“记忆”放回工程系统里

看完 LangGraph / LangMem,我最大的感受是:它把“记忆”从一个模型能力问题,重新拉回到工程系统问题。

真实应用里,Agent 记忆至少包含四层:

执行状态:当前任务跑到哪里了
会话上下文:这个 thread 里刚刚发生了什么
长期用户偏好:跨会话稳定存在的事实
行为改进:Agent 应该如何变得更会做事

不同层的生命周期完全不同。

执行状态可能几分钟后就没用
会话上下文可能保留几天
用户偏好可能长期有效
行为规则需要持续评估和版本管理

如果用一个“记忆库”概念把它们全部混在一起,系统迟早会变得混乱。

LangGraph 的优点是:它没有假装所有问题都能靠一个 memory API 解决。它提供了足够底层、但又足够实用的抽象,让你按自己的应用边界来设计记忆。

它的缺点也来自这里:你需要自己承担更多设计工作。

如果你想快速给聊天机器人加长期用户偏好,Mem0 可能更快。

如果你想要时间图谱和事实失效,Zep 更直接。

如果你想研究 Agent 自主管理上下文,Letta 更有启发。

如果你要搭一个复杂、多节点、可恢复、可调度、可观测的 Agent 应用,那么 LangGraph / LangMem 会更自然。


十、这一篇的结论

LangGraph / LangMem 让我重新理解了 Agent 记忆系统的一个基本事实:

记忆不是一个单独模块,而是贯穿 Agent 执行、状态管理、检索、写入、提示词构造和行为优化的系统能力。

它的核心贡献不是提出一种新的记忆数据库,而是把记忆拆成了几个工程上可操作的概念:

短期记忆:thread state + checkpointer
长期记忆:namespace + store
记忆类型:semantic / episodic / procedural
写入时机:hot path / background
召回方式:state read / store search / prompt assembly

这套抽象非常适合用来回看整个系列。

如果说:

Mem0 解决“哪些事实值得记、怎么排”
Zep 解决“事实之间有什么时序关系”
Letta 解决“Agent 如何自己管理上下文”

那么 LangGraph 解决的是:

这些记忆机制如何变成一个可运行、可恢复、可扩展的 Agent 应用架构。

下一篇我会继续看 Cognee / LightRAG 这条路线。它们把重点从“用户和 Agent 的交互记忆”推向“知识图谱增强的长期知识记忆”。这会帮助我们理解另一类问题:当 Agent 面对的不是一个用户偏好,而是一大堆文档、代码和业务知识时,记忆系统应该怎么建。

参考资料

评论

目录

Agent 记忆系统学习笔记(四):从 LangGraph / LangMem 看懂框架级记忆抽象 | Yu的赛博工位