Agent 为什么会"失忆"
想象一下,你连续几天都在和同一个 AI 助手讨论旅行计划。第一天,你告诉它自己不坐红眼航班;第二天,你补充说更喜欢靠过道的位置;到了第三天,它却像第一次见到你一样,又从头询问所有偏好。
这种体验并不意味着模型不够聪明,而是因为大多数模型调用本质上都是无状态的:一次请求结束后,模型不会自动保留上一次对话。即使上下文窗口越来越长,也只是意味着模型一次能"看到"更多内容,并不等于它拥有了稳定、可更新的长期记忆。
因此,只要 Agent 要跨会话工作,就绕不开几个问题:什么信息值得记住,应该以什么结构保存,需要时怎样找回来,以及由谁决定记忆的写入和更新。
业界通常把解决这类问题的方案称为"Agent 记忆"。目前比较流行的产品和开源项目包括 Mem0、Zep、Graphiti、OpenViking、Letta 和 MemGPT。它们都希望让 Agent 在跨会话工作时保留并使用过去的信息,但采用的技术路线和解决的问题层级并不相同。
四条路线,解决的是四个不同问题
先把这些项目放在一起看,可以得到下面四条路线:
| 路线 | 代表项目 | 核心思路 | 更像什么 |
|---|---|---|---|
| 提取式记忆 | Mem0 | 从对话中提取值得记住的事实,需要时检索回来 | Agent 的外接记忆库 |
| 时间知识图谱 | Zep、Graphiti | 把人物、事件、关系及其变化组织成带时间的图 | Agent 的动态世界模型 |
| 层级上下文数据库 | OpenViking | 用目录树组织 Memory、Resource 和 Skill,按需检索不同详细度的内容 | Agent 的上下文文件系统 |
| Agent Runtime | Letta、MemGPT | 让 Agent 自己管理上下文、记忆和执行循环 | 运行 Agent 的操作系统 |
它们最核心的区别可以概括为:
Mem0 关注"提取和找回哪些事实",Graphiti 和 Zep 关注"事实之间有什么关系、何时有效",OpenViking 关注"如何组织并按需读取不同层级的上下文",MemGPT 和 Letta 关注"Agent 在整个生命周期中如何主动管理自己的状态与记忆"
Mem0:给现有应用加一层长期记忆
Mem0 是一个独立的长期记忆层,通常放在应用与大模型之间。如果已经有一套 Agent 或聊天应用,只想让它记住用户偏好和历史决策,Mem0 是比较容易理解和接入的一条路线。
它的典型工作过程是:
text
用户对话
↓
LLM 提取值得长期保留的信息
↓
去重、更新并存入向量数据库
↓
下次对话前,根据问题搜索相关记忆
↓
把少量相关记忆加入模型上下文
例如,用户说:
我以后出差尽量订靠过道的位置。
Mem0 不一定保存整段原话,而是提取成类似这样的记忆:
text
用户偏好靠过道的座位
下次用户让 Agent 订机票时,应用调用 Mem0 搜索相关记忆,然后把这条偏好放进 Prompt。
Mem0 的主要特点包括:
- 接入相对简单,通常只需在对话后调用
add,在模型调用前执行search - 默认保存经过 LLM 提炼、去重的事实,而不是完整聊天记录
- 可以按
user_id、agent_id、run_id等维度隔离记忆 - 主要擅长保存用户偏好、项目决策、个人资料和跨会话信息
- Agent Runtime 仍由 LangGraph、CrewAI 或应用自己的代码负责
所以,把 Mem0 归为"轻量提取式记忆"比较合适。不过这只是一种概括,并不代表 Mem0 只能使用向量检索。Mem0 也提供 Graph Memory,用来表达人物、事件和关系;从整体产品形态看,它仍然更接近一个可以嵌入现有 Agent 的记忆组件。
适合 Mem0 的场景包括:
- 客服记住用户偏好
- 教育助手记住学生的掌握情况
- 个人助手记住用户的日程习惯
- 给现有 Agent 快速增加跨会话记忆
当信息开始涉及复杂关系、连续变化或历史状态时,仅靠一条条事实和语义搜索就未必足够精确。这也引出了下一条路线:时间知识图谱。
参考资料:Mem0 工作原理
Zep:面向生产环境的上下文与记忆平台
如果说 Mem0 更擅长记住一条条事实,那么 Zep 更关心事实之间的关系,以及这些关系如何随时间变化。Zep 早期经常被介绍为"给聊天机器人使用的长期记忆服务",现在更强调 Context Engineering 和 Context Graph。
它不仅保存"用户喜欢什么",还会把对话、业务数据和文档转换成由以下元素组成的图:
- 实体,例如用户、公司、产品、项目
- 关系,例如就职于、购买过、负责、依赖
- 事件或原始数据片段
- 事实成立与失效的时间
- 事实来自哪段原始数据
例如,系统先后收到:
text
2025 年:小王负责支付系统
2026 年:小王转去负责搜索系统,支付系统改由小李负责
普通向量记忆可能同时搜出两条记录,却不清楚哪条现在有效。Zep 的时间图会保留历史,同时标记关系的有效时间,从而能够回答:
text
小王现在负责什么?
2025 年小王负责什么?
支付系统的负责人什么时候发生了变化?
可以把 Zep 理解为一个围绕时间上下文图构建的生产级平台。除了保存和查询图数据,它还负责托管、扩展、低延迟检索、上下文组装和治理。
参考资料:Zep 图模型说明
Graphiti:Zep 开源的时间知识图谱框架
Graphiti 不是 Zep 的另一个竞争产品,而是由 Zep 团队开发、构成 Zep 技术基础的开源框架。
两者的关系可以简单理解为:
text
Graphiti:开源的时间图构建与查询框架
↓
Zep:基于这套思路构建的生产级托管平台
Graphiti 会把持续进入的数据组织成三类核心信息:
Entity:人、产品、组织、概念等实体Fact/Edge:实体之间的事实和关系Episode:产生这些事实的原始对话、文档或事件
它与普通知识图谱的重要差别,是关系带有时间语义。Graphiti 会区分:
- 事实什么时候开始成立
- 事实什么时候不再成立
- 系统什么时候得知这条事实
- 系统什么时候得知它已经失效
每条推导出的事实还可以追溯到原始 Episode。检索时则可以结合向量搜索、全文搜索和图遍历。
Graphiti 或 Zep 适合以下场景:
- 客户关系和组织关系经常变化
- 需要理解人物、项目、文件之间的多跳关系
- 需要回答"当时是什么状态"
- 需要追踪事实来源
- 企业数据持续更新,不能每次整体重建知识图谱
这条路线比 Mem0 更有结构,也更擅长时间和关系推理,但部署、数据建模和维护成本通常也更高。
OpenViking:把记忆放进可导航的上下文目录
OpenViking 是面向 AI Agent 的上下文数据库。它管理的不只是 Memory,还把外部知识 Resource 和可复用能力 Skill 放进同一个上下文空间。
它的核心结构可以简化为:
text
viking://
├── resources/ 外部知识
├── user/{user_id}/
│ ├── memories/ 用户与任务记忆
│ ├── resources/ 用户私有资源
│ ├── skills/ 用户技能
│ └── sessions/ 会话
└── agent/
└── skills/ 共享技能
与把所有内容平铺成向量记录的做法不同,OpenViking 为每个 Context 分配稳定的 viking:// URI,并保留目录、范围和上下级关系。向量检索负责找到相关区域,目录树负责限定搜索范围,Agent 再沿目录读取真正需要的内容。
OpenViking 还使用 L0、L1 和 L2 控制读取深度:
| 层级 | 内容 | 主要用途 |
|---|---|---|
| L0 Abstract | 一句话摘要 | 快速召回和初筛 |
| L1 Overview | 目录概览 | 判断相关性和继续导航 |
| L2 Detail | 原始文件和完整内容 | 获取事实、细节与证据 |
因此,它的典型检索过程不是直接选出若干相似片段并放入 Prompt,而是先定位相关区域,再逐层深入:
text
问题
↓
向量检索定位候选目录
↓
读取 L0 或 L1 判断相关性
↓
沿目录进入相关分支
↓
按需读取 L2 原文
OpenViking 的主要特点包括:
- 使用目录树统一组织 Memory、Resource 和 Skill
- 同时保留稳定路径、上下级关系和语义检索能力
- 通过 L0、L1 和 L2 控制上下文读取量
- 将权威内容与向量索引分开,内容由 RAGFS 保存,VectorDB 负责召回
- 既支持自动采集和召回,也允许 Agent 主动浏览、读取和维护上下文
这条路线适合知识和记忆具有天然目录结构、需要按作用域隔离,或者希望 Agent 像浏览文件系统一样逐步探索上下文的场景。它不像 Graphiti 那样重点表达实体关系和时间变化,也不像 Letta 那样接管整个 Agent Runtime;它更接近位于 Agent 下方的一层统一上下文基础设施。
参考资料:OpenViking 架构说明
MemGPT:受操作系统启发的 Agent 记忆架构
前面几条路线主要讨论记忆怎样保存、组织和检索,MemGPT 则把问题向上推进了一层:能不能让 Agent 自己管理记忆?
MemGPT 最初是 UC Berkeley 团队在 2023 年提出的研究项目。它从操作系统的虚拟内存获得灵感:
既然操作系统可以在内存和磁盘之间调度数据,让程序感觉自己拥有很大的内存,那么 Agent 也可以在有限上下文窗口和外部存储之间搬运信息
它通常将记忆分成多个层级:
text
模型当前上下文
├── 系统指令
├── Agent 身份和重要事实
├── 最近对话
└── 当前任务信息
外部存储
├── 历史消息
├── 长期档案
├── 文档
└── 可搜索的其他信息
关键不只是"应用在调用模型前检索一次",而是 Agent 本身拥有记忆工具,可以决定:
- 哪些信息应该写入长期记忆
- 哪些核心记忆需要更新
- 什么时候检索旧信息
- 上下文空间不足时应该移出什么
- 是否需要继续执行下一轮操作
也就是说,MemGPT 把记忆管理变成了 Agent 推理循环的一部分,而不只是外围的 RAG 插件。这套方法在论文中被称为"虚拟上下文管理"。
Letta:从 MemGPT 演变而来的 Agent 平台
Letta 与 MemGPT 也需要分开理解。它们紧密相关,但指向的对象并不完全相同:MemGPT 更偏向原始研究和 Agent 设计模式,Letta 则是从这套思想发展出来的框架与平台。
更准确的关系是:
text
MemGPT
原始论文、记忆架构和 Agent 设计模式
↓ 演进
Letta
用于构建、运行、持久化和调试有状态 Agent 的框架与平台
2024 年,原团队将开源框架改名为 Letta,希望把"MemGPT"留给论文中的原始设计模式,而用"Letta"表示范围更大的 Agent 框架和平台。
Letta 不只提供记忆存储,还管理:
- Agent 的持久化状态
- 上下文窗口的组装方式
- 可编辑的记忆块
- 工具调用和执行循环
- 文件、数据源和技能
- 多次运行之间的身份延续
- 本地或云端部署
- Agent 的调试与观察
因此,使用 Letta 通常不只是"给现有 Agent 接入一个记忆组件",而是在 Letta Runtime 中创建和运行一个 Agent。当前 Letta 已经超出原始 MemGPT 架构,提供多种 Agent 类型和更现代的执行循环,但"有状态 Agent"和"记忆属于 Runtime 核心能力"的思想仍然延续下来。
参考资料:MemGPT 与 Letta 的关系
用同一个例子理解四条路线
概念说得再多,最终还是要落到数据怎样保存、怎样被 Agent 使用。假设用户说:
我原来在北京工作,下个月搬去上海;以后推荐活动时优先考虑上海。
Mem0 的处理方式
Mem0 可能提取并保存:
text
用户下个月搬到上海
用户偏好上海的活动
调用方负责在推荐活动前搜出这些记忆。
Graphiti 和 Zep 的处理方式
Graphiti 或 Zep 可能构建:
text
用户 --居住或工作于--> 北京
有效至:某日
用户 --居住或工作于--> 上海
有效自:某日
用户 --偏好活动城市--> 上海
系统既能回答现在的位置,也能回答过去的位置,并知道关系何时发生了变化。
OpenViking 的处理方式
OpenViking 可能把相关信息放进用户自己的记忆目录:
text
viking://user/{user_id}/memories/
├── profile/
│ └── location.md
└── preferences/
└── activity-city.md
目录摘要负责说明这里保存了用户的位置变化和活动城市偏好,向量检索负责找到相关目录,Agent 再按需读取具体记忆。原始会话仍可作为更详细的上下文保存在 Session 中,不必让每次请求都携带全部历史内容。
MemGPT 和 Letta 的处理方式
Letta 或 MemGPT 风格的 Agent 会进一步处理:
text
Agent 判断这是不是重要信息
→ 调用记忆工具更新用户档案
→ 调整自己的核心上下文
→ 在未来推荐任务中主动使用
→ 必要时检索更详细的历史信息
这里的重点不再是某一种存储结构,而是"谁负责管理记忆":由 Agent Runtime 和 Agent 自己共同完成。
应该怎么选
这四条路线没有绝对的优劣,关键是先判断自己缺的是一个记忆组件、一种数据结构、一套上下文基础设施,还是完整的 Agent Runtime。
| 需求 | 更值得先看 |
|---|---|
| 给现有聊天应用快速增加用户记忆 | Mem0 |
| 数据有大量实体关系和时间变化 | Graphiti |
| 不想自己维护图基础设施,希望使用生产级服务 | Zep |
| 希望用目录统一组织记忆、知识和技能,并分层读取上下文 | OpenViking |
| 从头构建具有长期身份和自管理记忆的 Agent | Letta |
| 研究 Agent 如何像操作系统一样管理上下文 | MemGPT 论文 |
实际系统也不一定只能选择其中一种。例如,可以用 Letta 管理 Agent 的执行与状态,再接入专门的知识图谱或上下文数据库。真正需要注意的是职责边界:由谁决定写入什么、由谁处理更新与冲突、由谁负责检索,以及最终哪些内容进入模型上下文。
Agent 记忆并不是简单地"加一个向量数据库"。它更像一组逐层展开的工程问题:先决定记什么,再决定怎样组织和找回,最后决定谁来管理整个记忆生命周期。理解这几个层次之后,Mem0、Zep、Graphiti、OpenViking、MemGPT 和 Letta 之间的差异也就清楚了。
参考资料
- Mem0:How Mem0 Works
- Mem0:Graph Memory
- Zep:Understanding the Graph
- Graphiti:官方 GitHub 仓库
- OpenViking:官方 GitHub 仓库
- OpenViking:架构说明
- MemGPT:Towards LLMs as Operating Systems
- Letta:MemGPT Is Now Part of Letta
- Letta 官方文档
✨ 微信公众号【凉凉的知识库】同步更新,欢迎关注获取最新最有用的知识 ✨