AI 记忆框架调研与实测

本文最后更新于 2026-10-09

AI 的长期记忆,可以先理解为:把对后续交流有用的信息保存下来,下一次需要时再找回来。 比如你告诉一个助手“以后叫我阿林”,换一次对话,它仍然知道怎么称呼你,而不是每次都重新问。

不过,“记住了”只是第一步。过两天你又说“还是叫我小林吧”,它应该改用新称呼,而不是把两个名字一起丢给大模型,让模型猜。偏好也会变:之前喜欢苹果,后来不喜欢,再后来又喜欢了,这时该保留什么?

我这次调研,就是想给一个对话助手接上这样的记忆能力。看了九个开源项目,也跑了几轮实际测试。结果里,比“能不能存进去”更值得展开的,是存进去以后,能不能更新对、找对人,以及真的忘掉。

三句话之后,现在到底喜欢什么构造示例,用来解释偏好变化,不是原始用户对话。
  1. 第一次我喜欢苹果形成一条当前偏好
  2. 第二次最近不喜欢苹果了修订同一个偏好,而非多加一条矛盾事实
  3. 第三次现在又喜欢了当前答案应使用这次确认的信息
当前状态喜欢苹果
历史变化喜欢 → 不喜欢 → 喜欢
回答依据最新确认与对应来源

当前状态和历史记录可以同时保留,但用途不同。问“现在喜欢什么”和问“以前怎么变化的”,不能拿同一堆旧句子不加区分地回答。

先给一个阶段判断:简单的用户事实与偏好,我会继续以 Mem0 做基线,同时验证 MemOS;需要关系与时间推理时,再单独评估图记忆。 这不是九个项目的通用排行榜,而是下面这些需求和接法下的选择。

这篇保留的是 2026 年 9 月 29 日的研究快照。后续部署版本有变化,不能把新版本功能直接算进这轮测试。

先拆开记忆

记录不等于记忆

聊天记录回答的是“说过什么”,长期记忆还要判断“哪些话值得以后继续使用”。

“我平时喜欢太空故事”,适合成为一个内容偏好;“今天先讲这个”,可能只是当次选择。“我在故事里是一名船长”,也不能直接存成真实职业。如果把所有句子都当事实,记得越多,反而越容易答错。

把全部历史对话直接放进提示词,也是一条可以尝试的路线。对话短、人数少时,没必要一上来就搭复杂框架。但随着历史变长,需要处理输入长度、费用、隐私范围和旧信息冲突。摘要能缩短内容,也要检查它有没有省略条件、把临时要求压缩成长期偏好。

我在这轮里更关注:从对话中提取少量有来源的记忆,并能单独查询、修订和删除。

写入与读取

可以先分成两条路,不必认为每说一句话,系统就要立刻重新整理整个记忆库。

记忆怎样进入下一次对话概念流程。后台写入何时触发、是否等待完成,需要由具体产品决定。
写入这句话是否值得以后记住
  1. 确认来源与主体谁说的、何时说的,是现实信息还是故事角色
  2. 判断并对照旧记忆长期信息还是当次指令;新增、更新、忽略或待确认
  3. 保存并核对结果正文、条件与证据同步;确认新版本实际可读
读取这个问题需要哪些记忆
  1. 先限定可访问范围用户、产品或设备范围;权限由业务系统验证
  2. 找相关且适用的信息按字段、关键词或语义检索,检查条件与当前状态
  3. 交给模型组织回答只使用有依据的信息;冲突或缺失时不补猜测

写入解决“以后该记什么”,读取解决“现在该用什么”。 两条路都要有自己的失败处理,不能只看搜索接口有没有返回内容。

这里容易混在一起的,还有三样东西:

部分 在做什么 不能替它包办什么
大模型 理解对话,提取事实,判断新旧信息的关系 不能保证每次主体和长期性都判断正确
记忆框架 组织写入、更新、检索,以及来源或时间等信息 不会天然知道产品的全部业务规则
数据库与索引 保存记录,按条件或相似度找到记录 不决定“这句话是否应该被记住”

Embedding(向量嵌入) 是把文字转成便于比较的一组数字,用来找语义相近的内容。它是检索工具,不等于记忆本身。搜到一句“我不喜欢苹果”,也不能仅凭相似度判断这是不是最新状态、是不是同一个人说的。

分类也一样。基本资料、偏好、经历、关系、备忘、图片关联,可以作为整理入口;但给句子贴上“偏好”标签,并不会自动解决真假、主体、适用条件和权限。

框架各自管什么

九个项目的方向

这些项目都叫“记忆”,实际关注点并不相同。下面按官方定位和本轮阅读的实现路径简要整理,链接可以直接去看源码。

项目 值得看什么
Mem0 事实记忆的新增、查询与管理,以及不同存储适配。适合作为直接接入的一条基线。
Hindsight 保存信息、召回和基于记忆进一步思考的区分,以及多路检索。
MemOS 记忆容器、读写管理、检索与可选调度组件。需要先明确自己用哪条路径。
Graphiti 用实体和关系组织事实,保留来源片段与时间,适合研究关系如何变化。
EverOS 本轮阅读路径以 Markdown 为源记忆,再生成检索索引,便于理解源记录与索引的关系。
LangMem 可嵌入程序的提取与更新工具,存储由应用选择;它不是一套固定数据库服务。
Memobase 将用户画像与经历事件分开管理,适合观察当前状态和发生过的事情怎样共存。
VoiceMem 语音交互中的记忆编排:说话期间预取、后台写入。这个思路值得看,但本轮没跑完整语音链路。
SimpleMem 先把对话整理为较独立的信息,再检索;需要检查它怎样区分历史条目与当前事实。

例如 Graphiti 的实体、事实边和来源片段,比一张“偏好表”更适合表达关系。但有了图结构,不等于短句一定提取得出来。反过来,一个只保存当前偏好的系统,也不一定需要图数据库。

先问要记住什么,再决定需要哪些结构。 项目名字和功能清单只能帮助缩小范围,最终还得把自己的场景跑一遍。

实际怎么接的

后面展开的共同测试,集中在四条路径:

框架版本 本轮存储 接入方式
Mem0 2.1.0 Milvus 2.5.16 外部模型先决定原子事实与操作,再显式新增、更新或删除
Hindsight 0.10.1 PostgreSQL 同样先做业务判断,保存时仍保留框架自身的再次提取与召回
MemOS 2.0.33 PostgreSQL 与 pgvector 同步 fast 路径,补充分类过滤与既有记录更新的衔接
Graphiti 0.30.2 Neo4j 5.26.12 Community 保留实体与关系提取,补分类约束、过滤和向量请求适配

前三家尽量共用外部提取规则,Graphiti 则保留自己的实体、关系处理方式。因此测的是当前接通的完整路径,不是把同一份事实塞给四个数据库,再比较数据库谁快。

有些能力也不能算成框架开箱即用:本轮 MemOS 的 PostgreSQL 接口没有按传入分类条件过滤,我补了 SQL 条件;Graphiti 的分类与过滤也用了本地兼容层。这些代码将来都要维护,不能在选型时藏起来。

Mem0 这条路径有一个版本细节:2.1.0 的自动提取不能理解为“任何改口都会自动更新原 ID”。这轮需要覆盖旧事实时,明确调用更新接口。预先整理事实后使用 infer=false,只是绕过内部提取判断,不代表检索不再需要向量模型。

MemOS 的后台调度与额外整理功能没有启用。测试同步读写跑通,不能顺便宣布后台整理也验证完成。

测试里的几个问题

怎样检查是否记对

只问一句“我喜欢苹果”,再问“我喜欢什么”,很容易做出一个成功演示。所以测试里加了改口、不同时间条件、当次指令、虚构角色、访客换人、冲突和删除。

每个案例沿着实际结果往下看:输入是什么,模型提取了什么,数据库里留下什么,查询拿到什么,最后回答有没有用对。最后回答不带近期对话,避免模型直接照着刚说过的话回答,让一个没写好的记忆库看起来也能记住。

此外,四家各回放了同一批 50 段已有会话,流程完成数分别是 Mem0 47、Hindsight 45、MemOS 44、Graphiti 48。这里没有人工确认的完整标准答案,这四个数字只是流程完成数,不是准确率。Graphiti 完成得多,也不能据此说它记得最好。

更能解释问题的是 16 个共同针对性场景,以及后面单独补的一次 Graphiti 删除验证。下面挑几个展开。

这些结果来自本地小样本;跨日期由日志或输入时间模拟,不代表生产并发、真实长期运行或记忆衰减的验证结果。

刚写入却没读到

早期 Mem0 测试里,有一次刚写入称呼,立即回读没看到新记录。下一次用户改称呼,提取模型拿到的旧记忆是空的,于是判断应该新增。稍后再查,两个称呼都在。

表面看是“模型不会更新”,实际是它根本没看到要更新的对象:

写入第一条 → 立即回读为空 → 再次改口被判为新增 → 两条称呼并存。

复测时,我先按实际 ID 和最新正文确认记录可读,再处理下一次变化。此轮额外等待约 228~458 ms,称呼与偏好的四组更新案例随后用到了最新值。

复测改变的是核对步骤,没有修改 Mem0 源码或切换读取的一致性配置。轮询是这次测试的核对办法,生产里还需要确定可靠的写后读取、当前记录管理与幂等策略,也就是重复请求不要产生重复记录。不能为了把接口耗时测得更低,就忽略下一次读到的还是旧值。

正文更新还不够

Hindsight 的苹果偏好案例里,正文已经改了,但保存的证据、业务版本和确认时间还停在第一次。最终回答没有确认最新偏好。

一条看起来更新了的记忆按实测问题简化的示意。字段展示不是原始记录或用户原话。
第一次保存正文:喜欢苹果

证据:第一次表达

业务版本:1

确认时间:第一次

后续改口之后正文:最新偏好

证据:仍是第一次

业务版本:仍是 1

确认时间:仍是第一次

正文、证据和时间各自都可能是合法字段,但放在一起已经不一致。下游一旦依赖这些字段判断新旧状态,问题就会出现。

在这个固定版本的接法里,官方 PATCH(局部更新接口)能更新正文,却不接受我们要同步的 metadata(证据、版本等附加字段)和 tags(标签)更新。如果业务依赖这些字段,就要设计额外记录或其他可验证的同步路径,不能只在展示页上写“版本 2”。

同一个“喜欢 → 不喜欢 → 又喜欢”案例,Mem0 与 MemOS 使用了最新偏好;Graphiti 漏掉了首次与最后的事实,回答仍是不喜欢。这个结果比“支持时间图谱”更具体:时间机制可以处理已经形成的事实,却不能替代前面的正确提取。

条件和临时指令

“晚上小声一点,白天可以大声”,不是两条互相冲突的音量要求。它们有不同的适用条件,应该共存。

这组指定案例里,Mem0、Hindsight 和 MemOS 保留了条件;Graphiti 没有形成对应事实边,没能回答。另一个当次小声的案例中,MemOS 路径却把它保存成长期偏好。

后一个错误发生在共用的外部提取模型,不是 PostgreSQL 自己创造了偏好。这里换一家数据库没有用,要修的是:怎样区分“以后一直这样”和“这次先这样”。

分类规则最好带正反例,而不只是写几个目录名。比如“长期音量习惯可以保存;因当前环境临时调小音量,不直接保存成长期习惯”。然后仍然要测,提示词里写清楚不等于模型必然执行正确。

谁说的与怎样忘掉

访客换人的案例中,前三条受控路径把新说话人的信息错绑到账号本人。Graphiti 没提取出对应事实,也不能算它正确识别了身份。

这说明账号、设备和实际说话人不是同一个概念。在多人使用的对话产品里,主体确认和权限规则得单独设计。给查询加一个用户字段,只能过滤已经正确归属的记录,救不了写入时就绑错的人。

删除也不能只检查一次搜索。Graphiti 第一次删除用例,在删除前根本没形成事实边,那次验证无效;补例确实形成了 4 条事实边,删除后回读与召回为空,但仍留有 5 个实体或来源片段节点。Mem0 的历史接口里也还保留着旧正文。

搜不到,不等于所有隐私数据都已删除。 需要分别检查当前事实、历史、来源原文、实体摘要、索引,以及业务侧保存的文件和日志。

还有一个没完成的地方:年级冲突的案例返回了“待确认”,却没把候选事实存进可跨会话查询的待确认库。下次回答不知道,只代表它没使用一个确定事实,不代表冲突已经被管理好了。

检索时间花在哪

先分段再比较

这轮另做了每家 30 次只读检索,带一级与二级分类条件。采用小库热态,运行时还有其他研究任务;包含问题向量化、检索和框架整理,不含最终回答或语音处理。

P50 是中位数,P95 用来看较慢那部分请求。下面把整体召回和其中的问题向量化分开展示,先看通常要等在哪一步。

检索的等待不只在数据库9 月 29 日分段计时批次,每家 30 次有效请求。条长统一按 250 ms 标尺绘制,数值为 P50。
整体召回问题向量化
Mem0
194.1 ms
178.0 ms
Hindsight
191.3 ms
165.3 ms
MemOS
204.3 ms
176.9 ms
Graphiti
186.0 ms
168.0 ms

两条柱分别取各阶段的中位数,不是堆叠构成图,不能相减当成数据库耗时。不同路径还有并行或嵌套步骤,不能把各阶段的 P50、P95 直接相加。

路径 整体召回 P50 整体召回 P95 问题向量化 P50 问题向量化 P95
Mem0 194.1 ms 557.9 ms 178.0 ms 548.5 ms
Hindsight 191.3 ms 483.7 ms 165.3 ms 445.6 ms
MemOS 204.3 ms 602.5 ms 176.9 ms 582.1 ms
Graphiti 186.0 ms 402.7 ms 168.0 ms 387.8 ms

分段记录里,Mem0 的稠密检索数据库步骤 P50 为 4.95 ms,Hindsight 并行检索为 19.78 ms,MemOS 按向量查询为 18.10 ms,Graphiti 数据库驱动计时为 8.97 ms。它们的步骤定义不同,还包含连接、取回或解码,不是纯 SQL 的排名。

这组数据支持的判断是:当前小库路径里,远程问题向量化是一个很显眼的等待来源。 如果只换数据库,很可能没有碰到主要等待点。至于换成本地向量模型、做缓存或提前检索能改善多少,要另测质量、命中率和实际延时,不能从这张图直接推算。

也别把这里的约两百毫秒写成“语音助手响应时间”。麦克风输入、语音识别、回答生成和语音合成都不在这个计时里。

现在怎么选

我的选择

这轮需求主要是用户事实、偏好、条件和可追溯更新,还没有复杂关系推理。在这个范围里,我的选择是:

  • Mem0 保留为基线。 受控操作、业务字段和现有 Milvus 接法比较直接,几个改口案例能使用最新记忆。写后可见性、删除历史、主体规则仍然要补。
  • MemOS 继续做部署候选。 同步读写与分类查询已接通,也值得继续看它的管理方式。但本地兼容代码和可选后台功能的维护、验证成本不能省略。
  • Hindsight 保留为检索对照。 多路检索和严格分类 tags 有价值;若需要频繁同步业务证据、时间与分类,要先解决这轮暴露的更新边界。
  • Graphiti 不作为当前首版默认。 短句漏事实、偏好变化漏边,会影响这类问答。若问题变成“谁与谁有什么关系,这段关系什么时候改变”,再用相应案例评估它,而不是沿用偏好测试的结论。

其余路线也不是被判定为“不行”。想自己控制提取与存储,可以考虑 LangMem,但要承担应用侧适配;重视可读源记录,可以继续看 EverOS;画像和经历要分开管理,可以研究 Memobase;关心语音等待的编排,VoiceMem 值得看;希望先压缩会话信息,可以看 SimpleMem,并单独验证当前状态的更新。

我不准备把这些都接进同一个产品。选型是找一条适合当前需求、问题可以查清、成本能承担的路线,不是把功能最多的几个框架叠起来。

如果自己动手试,我建议先拿几段构造对话跑完整过程:改一次称呼,反复改变一个偏好,加一个白天与夜晚的条件,再试一次临时指令、换人和删除。不要只截取模型最终回答,把实际存下来的记录也打开看。

能记住一句话,是一个好的开始。能解释为什么保存它、现在该不该用它,以及怎样修正或删除它,才是我判断一个记忆系统是否合用的依据。