拆开8个明星 Memory Agent 项目:AI 到底怎样记住你?
从事实更新、时间图谱到文件系统与经验归纳,拆解八个 Memory Agent 项目的记忆机制。
博客本文目录
你上个月告诉 AI:“我住在杭州。”
这个月你说:“已经搬到上海了,下周开始在新公司上班。”
又过两天,你问:“周末去哪儿逛逛?”
一个有记忆的助手,应该知道从上海出发。如果你问“我去年住在哪儿”,它又得找回杭州。如果你补一句“刚才说错了,是苏州”,它还要理解:这次是纠正,不是又搬了一次家。
记住三句话很容易。让三句话在各自正确的时刻生效,才是 Memory Agent 的工程难点。
这次我对照官方文档、仓库和关键源码,拆了八个有代表性的项目:Mem0、Graphiti、Letta、OpenViking、Hindsight、Cognee、MemOS、Supermemory。重点看它们如何写入、组织、更新和调用记忆。
调研日期是 2026 年 9 月 22 日。这是源码与文档调研,没有把这些系统部署到同一环境跑分。文中的机制说明有来源,场景举例与选型判断是基于机制的分析。
八篇深度拆解
这篇是全景总览。下面八篇独立长文沿源码展开,可以按顺序阅读,也可以直接选择关注的项目。
-
Mem0 深度拆解:一次 add 和 search 背后的记忆流水线
从事实提取到候选召回与评分,沿着源码追踪一条记忆,解释 ADD-only、去重边界,以及“关键词命中却搜不到”的原因。
-
Graphiti 深度拆解:给知识图谱加上时间之后,记忆怎样更新?
从 episode、实体和关系出发,理解事实时间与系统时间,看看时序知识图谱怎样处理变化、冲突与历史查询。
-
Letta 深度拆解:Agent 怎样用 Git 维护自己的长期记忆?
以当前 Letta Code 为入口,追踪文件记忆、后台更新和上下文编译,理解“已经记下”与“本轮用上”之间的距离。
-
OpenViking 深度拆解:为什么 Agent 记忆需要目录和摘要?
从 L0/L1/L2 和分层检索出发,拆解上下文导航,再看队列、摘要与索引的一致性为什么决定系统是否可靠。
-
Hindsight 深度拆解:Agent 怎样从经历中形成有证据的认识?
沿着 retain、recall、reflect,区分事实、经历、归纳与心智模型,理解证据追踪和检索预算背后的工程取舍。
-
Cognee 深度拆解:文档怎样变成 Agent 可用的关联知识?
跟踪记忆接收、知识构建和混合召回,解释后台状态、路由与空结果处理,理解上传成功为什么不等于知识就绪。
-
MemOS 深度拆解:记忆为什么需要容器、调度器和来源过滤?
从容器、调度与来源过滤拆解多种记忆的组织方式,重点讨论任务状态,以及如何避免把模型的话写成用户偏好。
-
Supermemory 深度拆解:从文档摄入到画像注入,记忆何时真正生效?
从文档摄入走到记忆派生、画像和上下文注入,追踪缓存、隔离与更新时间,让应用接入过程中的隐含状态变得可见。
八篇沿用 2026 年 9 月 22 日的调研截点,正文保留固定提交与官方来源;分析中的验证方案不代表已执行的实验。
一、先弄清楚:Memory 到底比聊天记录多了什么?
把历史消息存进数据库,解决的是“数据还在”。
把历史消息检索出来,解决的是“可能找得到”。
一个持续工作的助手,还要解决另外几件事:哪些信息值得长期保留,谁说的才可信,旧事实何时失效,以及一次成功经验怎样影响下一次行动。
可以把完整链路写成:
对话或执行记录 → 提取候选记忆 → 核验主体、来源和时间 → 组织与持久化 → 按任务检索 → 装入上下文 → 根据反馈修正。
这里有三种很容易混淆的内容。
“用户偏好中文”是事实或偏好;“上次迁移失败,因为漏了索引”是一次经历;“迁移前先检查索引”是从经历中提炼的做法。LangMem 的官方概念指南分别用 semantic、episodic、procedural memory 描述这些方向。来源:LangMem 概念指南
这也解释了为什么不能只问“哪个 Memory 项目最强”。有的主要维护用户事实,有的组织知识,有的直接参与 Agent 的行为形成。
二、Mem0:把事实写进去,把取舍放到检索阶段
Mem0 很适合作为理解记忆基础设施的入口:应用调用 add() 写入,再调用 search() 找回相关信息,最后把结果交给回答模型。
但如果你还用“提取事实,再判断 ADD、UPDATE、DELETE”介绍它,已经需要补上版本说明。
当前的新算法采用 ADD-only 自动提取:新事实与旧事实并存,检索负责找出适合当前问题的内容。 这里的 ADD-only 指自动提取路径,不意味着产品永远不能显式编辑或删除数据。来源:Mem0 迁移指南
它的写入路径可以概括为:先读取少量相关旧记忆作为去重上下文,用一次 LLM 调用提取新事实,再批量生成向量、去重并存储。读取时综合语义、关键词与实体匹配信号;具体可用信号也受所选存储后端支持情况影响。源码:Memory 写入与检索
回到搬家的例子:杭州与上海可以同时留在记忆中。“现在住哪里”和“去年住哪里”应该选中不同记录。
我的判断是,这条路线把一部分复杂度从写入时的覆盖决策,转移到了读取时的时间判断与排序。好处是保留历史;代价是不能指望普通相似度搜索自然理解所有新旧关系。
还要留意开源与托管的分界:当前迁移文档说明,图记忆已从 OSS SDK 移除,属于 Platform 功能;README 的新成绩也明确对应包含专有优化的托管平台。下载开源包,并不等于拿到了榜单上的完整系统。来源:当前 README
三、Graphiti:把“事实什么时候成立”写进图里
Graphiti 的中心对象是随时间变化的实体与关系。它把输入的 episode 转为图中的实体和关系,结合实体消歧、关系处理与混合检索来维护记忆。来源:Graphiti 仓库
最值得看的是关系边的数据结构:valid_at、invalid_at 描述事实的有效区间;created_at、expired_at 记录系统对这条关系的建立与失效处理。它区分了“事情发生的时间”和“系统知道或处理它的时间”。源码:EntityEdge
假设你 9 月告诉系统:“我 7 月就搬去上海了。”
只记消息时间,系统可能把搬家理解成发生在 9 月。保留事实时间,才有机会正确回答“8 月我住哪儿”。
遇到矛盾关系,代码可以标记旧边失效,同时保留时间历史;这一步依赖抽取与关系判定,并非写几个时间字段就自动获得事实正确性。源码:关系消歧与失效处理
这种结构尤其值得关系密集的应用研究:一个人的家庭关系、公司的成员变动、客户与订单之间的联系,都可能比“找几段相似文本”更需要明确的关系和历史。
工程代价也随之出现:实体合并错了,两个人的经历可能被串起来;关系抽错了,图查询会非常高效地找出错误答案。
Graphiti 与 Zep Cloud 也应分开看。前者是开源图引擎,后者是上层产品,不能直接把后者的完整能力和测试结果记在前者头上。
四、Letta:让 Agent 维护自己的上下文
Letta 继承了 MemGPT 的问题意识:有限的上下文窗口,怎样支撑长期存在的 Agent?不过当前选源码入口时要注意,letta-ai/letta 已把活跃实现指向 letta-ai/letta-code,旧 V1 服务留在 archive 分支。来源:Letta 当前入口
今天的一个关键机制是 MemFS:用 Git 管理的记忆文件系统。
按照当前概念文档,system/ 下的核心内容进入系统提示;其他文件按需读取,目录树提供寻找记忆的线索。记忆编辑通过提交形成版本历史。MemFS 默认并没有语义向量索引,文件搜索与会话历史搜索也属于不同路径。来源:MemFS
它相当于把记忆分成两部分:一部分是经常放在桌面的工作说明,另一部分是需要时再翻的档案。
更微妙的细节藏在提示词源码里:修改记忆不等于当前这一轮的提示已经被改写。 新内容需要经过提交,并在后续重新编译上下文时被采用。源码:本地 MemFS 提示词
所以,评价这类系统时,不能只检查磁盘上有没有 memory.md,还要检查下一次模型请求究竟读到了哪个版本。
如果目标是一个持续工作的编程助手,让它逐渐维护项目约定、用户偏好和操作经验,这条路线很有启发。相应地,系统也需要控制核心记忆的长度,并能审查 Agent 对自身规则做过什么修改。
五、OpenViking:让目录结构参与记忆检索
OpenViking 把 memory、resource、skill 组织到 viking:// 虚拟文件系统中,并提供三级内容:L0 是简短摘要,L1 是概览,L2 是完整细节。来源:OpenViking 仓库
这套设计试图解决一个常见问题:明明只问某个项目,检索却从所有项目的大向量池里捞出一堆“语义上很像”的内容。
在目录组织下,系统可以先限定项目或记忆子树,再利用摘要判断往哪里找,最后读取更具体的文件。目录与摘要共同提供了检索上下文。
它还把两个容易被混为一谈的接口分开:find() 直接执行查询;search() 利用会话上下文做意图分析,再进行检索。后者多了一段规划过程,不能默认认为二者延迟相同。来源:检索机制
源码中的 HierarchicalRetriever 负责层级检索与评分;重排是可配置能力,没有可用重排配置时会走相应的向量检索路径。源码:层级检索器
我的理解是,这条路线把“如何组织资料”变成了检索算法的一部分。它适合项目、文档、技能较多,且希望能浏览记忆结构的场景。
代价也在同一个地方:目录归错,或者摘要省略了关键限制,后续检索就可能沿着错误方向继续走。可读、可编辑的结构,仍然需要检查更新后的索引与摘要是否同步。
六、Hindsight:把记住事实、查找事实和归纳经验拆开
Hindsight 提供三个很能说明设计意图的动作:retain、recall、reflect。
retain 将输入整理为记忆,并区分外部世界的事实与 Agent 自己的经历;在写入之后,后台还可以将多个事实归纳成 observations,并维护支撑这些归纳的证据。来源:Retain 机制
recall 负责找回材料。其文档描述了语义、关键词、图关联和时间等检索策略。比如“去年春天做过什么”和“这个错误码以前出现过吗”,需要的检索线索就不相同。来源:Recall 机制
reflect 则进入另一层:它会运行一个取证与推理循环,访问归纳结果和原始事实,再生成带引用的解释。来源:Reflect 机制
用一个工程例子理解:
“上次发布漏了数据库迁移”是一条经历;“这个项目的发布故障多次与迁移遗漏有关”是一项归纳;“这次发布前应优先检查哪些步骤”则需要结合当前任务推理。
这里真正值得学习的是,原始记录、归纳结论和临时推理,各有位置。
也因此,不能把 reflect() 的回答耗时与另一个系统返回检索片段的耗时直接比较。前者做了更多工作。对实时语音助手,我会先研究怎样用快速 recall 支撑当前回答,再把较重的归纳安排到后台,而不是每轮都调用一次反思流程。
七、Cognee:从多种资料中构建可检索的关联知识
如果你的材料不仅是对话,还有文档、代码与知识库,Cognee 值得单独看。
它当前的公开接口强调 remember() 与 recall():前者组织摄入和后续处理,后者检索相关上下文。文本可成为实体、关系与片段,代码也能形成符号及依赖关系。当前 README 还提供了不依赖生成式 LLM 的本地文本路径,因此“所有写入都必须调用大模型”也不是准确概括。来源:Cognee 当前说明
顺着 remember.py 可以继续追到 add、cognify 与改进处理;recall.py 则协调多种检索类型。旧教程常见的 add → cognify → search 仍有助于理解分层,但介绍现状应补上新的上层入口。源码:remember、源码:recall
我的选型判断是:当问题围绕“这批材料之间有什么联系”,可以优先研究这类知识组织路线。比如将需求文档、接口说明与代码依赖联系起来,再为 Agent 提供任务上下文。
需要付出的代价是摄入与维护:源文件变化之后,哪些片段、实体、关系和派生知识需要更新?这比“首次导入成功”更能检验长期可用性。
八、MemOS:把记忆做成可组合、可调度的模块
MemOS 关心的是更完整的记忆生命周期。它用 MemCube 组织可管理的记忆单元,再通过 MemReader、MemScheduler 等模块处理读入、检索、更新与组织。来源:MemOS 仓库
MemCube 的抽象中包含文本、激活和参数记忆接口。这里要特别防止一个误读:框架有这些抽象,并不意味着接上任意闭源模型 API,就能读取它的 KV cache 或修改它的参数。来源:MemCube 文档
从应用工程角度,我更关注 MemScheduler:不同消息类型进入队列,由相应处理器执行记忆更新、读取或重新组织。它把这些操作从一次简单的“存进去”扩展为有状态的后台流程。来源:MemScheduler 文档
这类设计适合研究多用户、多知识库、多任务之间如何管理记忆。也要辨认具体产品形态:Python 核心、官方本地插件与云服务的能力和运行依赖,应分别核对。
异步返回成功,只能说明任务被接受到某个阶段,不能自动证明新记忆已经可检索。 真正上线时,应分别观测排队、提取完成、索引可见,以及下一轮回答使用了什么。
九、Supermemory:把记忆、画像和资料接入做成统一产品
Supermemory 的产品切入点很直接:应用既需要知道用户是谁,也需要检索相关资料,还需要把已有内容接进来。
它提供自动维护的静态与动态画像,并允许在取画像时带上查询,返回相关记忆;同时提供文档检索、连接器和多种 Agent 集成。当前官方仓库也已经介绍了本地运行方案。来源:Supermemory 仓库
这很适合用来理解“画像”和“检索”的互补:用户长期偏好可以预先提供,当前任务涉及的细节再按问题寻找,减少完全依靠查询词触发记忆的遗漏。
在关系语义上,官方区分更新、扩展与推导:新事实可能替代旧状态,也可能只是补充细节,或者从已有信息形成推论。来源:关系语义说明
但推论必须与用户明确说过的话区分。系统可以推测一个人喜欢某类活动,不能把这个推测改写成“用户确认自己喜欢”。
这部分拆解以公开文档和接口契约为主。公开 SDK、插件以及可下载本地程序,不能单独证明生产核心引擎的全部源码都在当前仓库中。因此也不应仅凭仓库首页的许可证,推断所有分发组件具有相同开放范围。
十、怎么选:先找到你真正需要的那层能力
如果已有聊天或客服产品,希望增加跨会话事实记忆,我会先研究 Mem0;如果还需要画像、资料连接器与现成接入路径,再对照 Supermemory。
如果频繁问“谁与谁有关”“当时是什么状态”,重点看 Graphiti。如果资料天然按项目、目录与技能组织,且需要逐层读取,重点看 OpenViking。
如果要做一个持续工作的 Agent,让它维护自己的上下文和工作习惯,重点看 Letta。如果希望把多次经历归纳为有证据支撑的认识,重点看 Hindsight。
如果核心输入是多源知识材料,重点看 Cognee;如果记忆管理已经涉及多个模块、队列与生命周期,重点看 MemOS。
这些是基于机制的研究优先级,不是跑分排名。项目能力也有重叠,最终可能需要组合,而非八选一。
还有两个值得补充的参照:Memobase 围绕用户画像和事件时间线组织记忆;LangMem 提供提取、管理及提示优化原语,并能结合 LangGraph 的存储体系。前者帮助理解画像路线,后者适合已有编排框架、希望自己掌握记忆策略的团队。来源:Memobase、来源:LangMem
十一、比 Star 更重要的,是这六个验证问题
我不会把各家首页上的 LoCoMo、LongMemEval 成绩拼成一张冠军榜。
即使数据集名字相同,回答模型、检索预算、评判方式、是否加入额外推理,以及测试的是 OSS 还是托管平台,都可能不同。Mem0 已明确披露榜单与托管实现的边界,就是一个具体例子。来源:Mem0 基准说明
更有价值的起点,是为自己的产品准备一小组可以反复运行的验证:
- 跨会话。 在独立会话中写入和提问,确认答案来自持久记忆,而非仍留在当前窗口的聊天记录。
- 变化与纠正。 同时测试“搬家了”“说错了”“去年住过”,看系统是否区分状态变化、纠错和历史。
- 主体隔离。 两个用户给出相反偏好,再交叉提问。
user_id、标签或目录只有经过可信身份绑定和服务端检查,才构成实际隔离。 - 来源与推测。 让系统指出记忆来自哪次用户陈述或工具结果,检查它是否把自己的推测写成已确认事实。
- 删除与失效。 删除后继续搜索,同时检查画像、摘要、图关系等派生内容。检索时不展示,与数据已经清理,是两项不同验收。
- 延迟与成本。 分开统计写入提取、检索、重排、反思和最终回答,再测端到端的 P50、P95,以及每次成功任务的总成本。
如果产品面向中文,还要加入中文姓名、同音字、亲属称呼与相对时间。“去年过年”和“春节后换了工作”,比英文姓名加精确日期更接近真实使用。
对于实时语音,用户说完后多久听到第一句话,应单独测量。后台记忆积压多久、刚说的信息何时能被另一会话查到,也应单独测量。一次检索接口很快,证明不了整通对话很流畅。
写在最后
拆完这些项目,我最关心的变化是:记忆正在成为一套可以检查、更新和调用的状态管理机制。
有的系统通过时间关系保留历史,有的通过目录减少无关上下文,有的让 Agent 编辑自己的工作说明,还有的把经历逐渐归纳成可复用的认识。
但无论采用哪种结构,用户最终在意的都是很具体的问题:
你记住的是我说过的话,还是你猜出来的话?我改变了想法之后,你会跟着改吗?我要求忘掉的时候,你真的能做到吗?
把这几个问题做好,记忆才会变成信任。
被这些页面引用
- Cognee 深度拆解:文档怎样变成 Agent 可用的关联知识?
- Graphiti 深度拆解:给知识图谱加上时间之后,记忆怎样更新?
- Hindsight 深度拆解:Agent 怎样从经历中形成有证据的认识?
- Letta 深度拆解:Agent 怎样用 Git 维护自己的长期记忆?
- Mem0 深度拆解:一次 add 和 search 背后的记忆流水线
- MemOS 深度拆解:记忆为什么需要容器、调度器和来源过滤?
- OpenViking 深度拆解:为什么 Agent 记忆需要目录和摘要?
- Supermemory 深度拆解:从文档摄入到画像注入,记忆何时真正生效?
- Agent Security · 智能体与 MCP 工具链安全防护
- 杨昌业