Agent 记忆系统学习笔记(三):从 Letta / MemGPT 看懂 Agent 自主管理记忆
用 Letta / MemGPT 作为第三个样本,理解 stateful agent、memory blocks、archival memory、context hierarchy,以及 Agent 如何主动管理自己的上下文。
写在前面:第三篇为什么看 Letta
前两篇我们已经看了两种记忆系统路线。
Mem0 更像一个产品化的 memory ranking layer:把对话抽取成 memory,然后用语义、BM25、实体、时间和衰减信号把相关记忆召回。
Zep 更像 temporal graph + context assembly:把用户、业务数据和历史事件组织成 Context Graph,再把相关 facts、entities、episodes、observations 组装成 Context Block。
这一篇看第三种路线:Agent 自己管理记忆。
Letta 的前身和思想来源是 MemGPT。MemGPT 论文的核心比喻很有意思:LLM 的上下文窗口像计算机的主内存,很快、很贵、很有限;外部存储像磁盘,很大但需要主动读取。既然传统操作系统可以通过虚拟内存管理有限的物理内存,那么 Agent 能不能也管理自己的上下文?
Letta 继承了这个思路。它不是只问“如何自动召回 memory”,而是问:
如果 Agent 是一个有状态的程序,它能不能自己决定哪些内容常驻上下文,哪些内容放入外部长期记忆,什么时候搜索,什么时候写入,什么时候修改?
这就是 Letta 最值得学习的地方。
一、Letta 的核心问题:Agent 为什么需要管理自己的记忆
大多数记忆系统会把“召回”放在应用层或基础设施层处理。
典型流程是:
用户输入 → 系统自动搜索记忆 → 把结果塞进 prompt → LLM 回答这当然有效,但它有一个假设:外部系统比 Agent 更知道该召回什么。
Letta 的思路不同。它认为一个真正有状态的 Agent,不应该只是被动接收别人塞进来的上下文,而应该参与管理自己的状态。
在 Letta 里,一个 stateful agent 不只是一次 LLM 调用。它包含:
system prompt
memory blocks
messages
reasoning
tool calls
tools
runs / steps
conversations这些状态都会被持久化到数据库里。即使某些消息被压缩、从上下文窗口里移出去,底层记录也不会丢。
这个定位很关键。Letta 不是把 memory 当成一个旁路组件,而是把 memory 放进 Agent runtime 本身。
二、MemGPT 的操作系统比喻
理解 Letta,最好先理解 MemGPT 的比喻。
MemGPT 论文提出的是 virtual context management。它借鉴操作系统的分层内存:
CPU 可以直接访问的内存很有限
磁盘容量大但访问慢
操作系统负责在内存和磁盘之间调度数据
给程序一种“我有更大内存”的错觉放到 LLM Agent 里就是:
LLM context window = 快速但有限的主内存
外部存储 / archival memory = 容量大但需要搜索的磁盘
Agent memory tools = 在两者之间搬运信息的系统调用所以 Letta / MemGPT 路线的核心不是“检索算法”,而是“上下文管理”。
它要解决的问题是:
什么必须放在上下文里?
什么可以放在外部,需要时再搜?
Agent 什么时候应该写入长期记忆?
Agent 什么时候应该修改自己的 core memory?
Agent 如何在多轮对话中保持状态连续?这让 Letta 和 Mem0、Zep 的气质很不一样。Mem0 和 Zep 更像记忆基础设施,Letta 更像一个带记忆操作能力的 Agent OS。
三、Letta 的记忆分层
Letta 的文档里有一个很重要的 context hierarchy。不同类型的信息,根据重要性、大小和访问频率,应该进入不同层。
这里最核心的是两层:
Memory Blocks:常驻上下文
Archival Memory:外部长期记忆,按需搜索另外还有 files、external RAG、messages、shared blocks 等扩展形态。
我理解 Letta 的核心判断是:
不是所有记忆都应该被检索。最重要的记忆应该直接常驻上下文;低频的大量记忆才应该按需搜索。
这和 Mem0、Zep 很不一样。
Mem0 / Zep 更强调“检索出当前相关内容”。Letta 则先问:“这条信息是不是重要到不应该等检索?”
四、Core Memory:Memory Blocks 为什么重要
Letta 里最核心的抽象是 memory block。
Memory block 是一段结构化的上下文,会被放进 Agent 的 prompt 里。它可以有 label、description、value、limit。常见 block 有:
persona:Agent 自己是谁,应该如何表现
human:用户是谁,有什么偏好和长期背景
scratchpad:当前任务的工作记忆
organization:组织级共享信息
policies:只读规则和约束Memory block 的关键点是:它不需要召回。
只要 block attach 到某个 Agent,它就在上下文里,Agent 每次推理都能看见。
这适合存什么?
用户姓名
非常稳定的偏好
Agent persona
关键约束
当前任务状态
必须长期遵守的政策Letta 文档特别强调 description 字段。因为 Agent 会根据 block 的 label 和 description 判断怎么读写这块记忆。
这点很有启发:Memory block 不是一个随便写字符串的地方,它更像一个带说明书的上下文槽位。description 写得好不好,直接影响 Agent 是否知道该把什么写进去。
五、Archival Memory:外部长期记忆不是常驻上下文
Memory blocks 适合小而重要的信息。但如果信息很多,就不能全部放进上下文。
这时 Letta 用 archival memory。
Archival memory 是一个语义可搜索的外部长期存储。Agent 可以通过工具:
archival_memory_insert
archival_memory_search来写入和搜索。
它适合存:
大量历史互动
研究笔记
文档摘要
技术参考
客服历史
用户调研
不必总是可见、但未来可能有用的信息Letta 文档里有个区分很重要:
Archival memory 是 intentional storage。
Conversation search 是 historical retrieval。也就是说,archival memory 是 Agent 主动决定“这值得长期保存”;conversation search 则是搜索过去实际说过什么。
比如用户说:
我偏好 Python 做数据科学项目。Agent 可以把它写入 archival memory:
User prefers Python for data science.以后也可以通过 conversation search 找到原始对话。前者是抽取后的知识,后者是历史证据。
六、Letta 的关键差异:记忆管理是工具调用
Letta 最有意思的地方,是它让记忆操作变成 Agent 可调用的工具。
这和自动召回型系统很不一样。
在 Mem0 或 Zep 里,应用通常会在回答前自动拿到相关 memory 或 context block。Agent 不一定知道召回过程发生了什么。
在 Letta 里,Agent 可以在对话中决定:
我需要更新 human block。
我需要把这条事实写进 archival memory。
我现在信息不够,需要搜索 archival memory。
我需要修改 scratchpad。这是一种 agent-managed memory。
它的优点是灵活。Agent 可以根据任务需要动态管理上下文,不必完全依赖应用层预设的检索策略。
但它也有代价:
Agent 可能忘记搜索
Agent 可能写入错误记忆
Agent 可能把不该常驻的信息放进 core memory
Agent 可能多次改写 block,产生冲突或覆盖所以 Letta 的记忆路线更像“给 Agent 更大的自主权”,而不是“用基础设施替 Agent 做完所有判断”。
七、Context Hierarchy:什么时候用哪一层
Letta 的 context hierarchy 可以总结成一句话:
越重要、越小、越高频的信息,越应该靠近上下文;越大、越低频、越外部的信息,越应该通过工具检索。
我把它理解成四层:
Memory Blocks:小而关键,必须常驻
适合:
用户名字
Agent persona
核心规则
当前任务状态
高频偏好它的风险是占用上下文,而且如果 block 被错误覆盖,影响会很大。
Files:较大、只读、可部分打开和搜索
适合公司文档、指南、说明书。Agent 不需要一次看完,但可以打开片段、搜索内容。
Archival Memory:长期、低频、按需语义搜索
适合 Agent 自己积累的知识和经历。
它不是每次都出现,但当 Agent 觉得需要时,可以搜索。
External RAG / MCP:无限外部知识
适合超大规模知识库、业务数据库、外部系统。Letta 可以通过自定义工具或 MCP 让 Agent 访问。
这套层级最大的价值是:它把“记忆放在哪里”变成一个可判断的问题,而不是默认全都扔进向量库。
八、Shared Memory:多 Agent 协作里的共享状态
Letta 的 shared memory blocks 也很值得注意。
一个 block 可以被多个 Agent attach。这样多个 Agent 都能看到同一份信息。如果一个 Agent 更新 block,其他 Agent 也能看到更新。
这适合多 Agent 协作:
task_queue:主管 Agent 写任务,Worker Agent 读任务并更新状态
organization:所有 Agent 共享组织背景
user_preferences:多个服务同一用户的 Agent 共享用户偏好
handoff_context:Agent A 交接给 Agent B 前写入上下文
system_config:只读全局配置这个能力说明,memory block 不只是“个人记忆”,也可以是协作状态。
但它也带来并发问题。Letta 文档提醒,memory_rethink 这种完整重写操作在多 Agent 同时编辑时并不安全,容易最后写入覆盖前面的修改。更安全的是 append 型的 memory_insert,或者让某个 Agent 成为 block 的 owner。
这让我觉得 Letta 的 shared block 更像一个轻量共享状态系统,而不是传统数据库。它适合协调,但要小心并发写入。
九、和 Mem0、Zep 的关键差异
现在可以把三篇放在一起看。
| 维度 | Mem0 | Zep | Letta / MemGPT |
|---|---|---|---|
| 核心抽象 | memory fact | temporal Context Graph | stateful agent + memory hierarchy |
| 主要问题 | 如何抽取和召回相关 memory | 如何表达关系和时间变化 | Agent 如何管理自己的上下文 |
| 常驻上下文 | 通常由应用注入搜索结果 | Context Block 注入 | Memory Blocks 常驻 |
| 外部记忆 | memory store | graph / context lake | archival memory / files / external tools |
| Agent 角色 | 使用被召回的 memory | 使用被组装的 context | 主动搜索、写入、修改记忆 |
| 适合场景 | 个性化记忆层 | 关系和状态演化 | 长期自主 Agent、复杂上下文管理 |
简单说:
Mem0 关注怎么把记忆召回得更准。
Zep 关注怎么把记忆组织成时间图谱。
Letta 关注 Agent 如何自己管理记忆和上下文。这三者不是互斥关系,而是三个不同抽象层。
一个复杂系统甚至可能同时用它们的思想:用 memory blocks 放核心状态,用图谱维护业务关系,用向量或多信号检索管理大规模长期记忆。
十、我对 Letta 的判断
Letta 最值得学习的地方,不是某个具体检索算法,而是它对 Agent 的定位。
它把 Agent 当成一个有状态的长期程序,而不是一个每次从 prompt 重建出来的无状态函数。
所以 Letta 的问题意识是:
Agent 的状态如何持久化?
哪些状态应该常驻上下文?
哪些状态应该外置?
Agent 能不能自己编辑状态?
多个 Agent 如何共享状态?
上下文窗口不够时,如何分层管理?这对长期陪伴型 Agent、个人助理、研究助理、多 Agent 工作流都很重要。
它适合:
需要长期人格和用户关系的 Agent
需要 Agent 自己维护任务状态的系统
需要多 Agent 共享上下文或交接的工作流
需要让 Agent 主动整理记忆的研究型产品它不一定适合:
只想简单接一个自动记忆 API
不希望 Agent 自己改记忆
需要严格确定性的记忆写入和召回
记忆治理、审批、审计要求非常强的场景我的判断是:
Letta / MemGPT 的价值在于,它把“记忆召回”升级成“上下文管理”。它不是单纯帮 Agent 找记忆,而是给 Agent 一套管理自己状态的机制。
这也是为什么它应该放在 Mem0 和 Zep 后面分析。Mem0 让我们理解 memory pipeline,Zep 让我们理解 temporal graph,Letta 让我们理解 Agent-managed memory。
十一、这一篇之后,分析框架继续扩展
到这里,这个系列已经有三种视角:
Mem0:记忆是可排序的事实集合
Zep:记忆是带时间的关系图
Letta:记忆是 Agent 可管理的上下文层级所以以后分析任何 Agent memory 系统,我会继续加几个问题:
它是否允许 Agent 主动管理记忆?
哪些记忆是常驻上下文,哪些记忆是按需搜索?
Agent 修改记忆时有没有工具边界?
多 Agent 是否能共享记忆?
记忆被错误修改后如何恢复?
记忆管理是系统自动完成,还是 Agent 自己参与?下一篇我建议看 LangGraph / LangMem。它更像一个框架级抽象,可以把 short-term memory、long-term memory、semantic / episodic / procedural memory 这些概念统一起来。