☰
开源Agent记忆系统横向对比:从Mem0到Zep的选型指南
2026/10/31 12:24:45 网站建设 项目流程

这年头做 Agent 的,谁没被“上下文不够用”坑过?我自己就吃过一个大亏:去年给团队做客服机器人,用户在对话框里聊了二十分钟报修流程,中间切出去接了个电话,回来问一句“那我那个订单到底怎么处理”,Agent 直接回复“您好,请提供一下订单号”。问题的根子不在模型能力,而在 Agent 没有记忆——前一轮的有效信息全丢了。

后来我把市面上能排上号的开源 Agent 记忆系统整体过了一遍,包括 Mem0、Letta(原 MemGPT)、Zep 与 Graphiti、LangGraph 持久化方案、Cognee 这些代表,从存储架构、检索方式、生命周期管理、部署成本、生态成熟度几个维度做了横向对比。这篇文章就是那份对比报告的完整版。想给 Agent 配记忆、准备做选型、或者单纯想搞清楚“记忆系统到底在解决什么问题”的同学,这篇可以当个参考底稿,我尽量把每家的底层逻辑和落地代价都说人话。

1. 为什么非要在 Agent 里单独搞一套记忆系统

1.1 没有记忆的 Agent,连三件小事都做不好

先说个基本判断:模型本身的上下文窗口再大,也撑不起真正可用的 Agent。原因很俗——上下文不是免费的。我自己实测过,一个中型的 RAG 客服流程,把知识库检索结果、历史对话、工具返回信息全塞进上下文,一轮请求的 token 消耗比纯对话高出五到十倍,长会话跑几十轮之后,即便模型没“忘”,成本也先崩了。

更关键的是,Agent 的任务形态决定了它必须记住三类东西:

  • 事实性信息:用户叫啥、住在哪、订单号、会员等级、上次投诉的诉求。
  • 事件性信息:昨天聊到哪了、刚才工具返回了什么结果、用户对哪个方案明确拒绝过。
  • 偏好性信息:用户习惯长话短说、讨厌被追问订单号、对价格敏感、希望回复里带表情。

这三类信息混在一起,如果全放在上下文里,不仅贵,还会互相干扰。用户一个月前说的“我打算搬家”,跟今天聊“新家需要装宽带”,其实是两条有关联但不同优先级的记忆。没有单独的存储与检索机制,模型要么把它们当成同一批东西强行推理,要么干脆把旧信息丢了。

1.2 对比报告的评价维度,我是这么定的

市面上的开源方案看着多,真正拿来对比的时候,如果只看“谁 Star 多”就太草率了。我这次所有项目都用同一套维度去打量:

  • 存储形态:内存、向量库、关系数据库、图数据库,还是分层混合结构。这个决定了它能承载的记忆规模和查询方式。
  • 写入方式:是对话后自动异步提取,还是同步强制写入,还是靠 Agent 自己主动调用 API 写入。这个决定了系统对业务代码的侵入程度。
  • 检索召回:语义相似度、关键词、图遍历、规则加权,还是混合策略。
  • 生命周期:记忆会不会过期、会不会自我修正、有没有重要性分层。这个决定了长期运行后系统会不会“被垃圾记忆淹死”。
  • 集成成本:需不需要额外部署服务、有没有 SDK、跟 LangChain/LlamaIndex 这类框架的兼容性。
  • 运维代价:依赖哪些中间件、是不是要配套向量库和图数据库、并发上来之后扛不扛得住。

带着这六个维度去看项目,很多宣传话术就骗不了人了。所谓“记忆系统”,本质上就是存储系统加一套围绕 LLM 特化的读写策略,没有银弹,只有取舍。

2. 六个代表性开源方案,逐个拆

2.1 Mem0:把“记忆提取”做成开箱即用的服务

Mem0 是目前开源 Agent 记忆领域名声最响的项目之一,核心定位是“Add memory to your AI apps”。它的一大特点是独立于具体 Agent 框架运行,你把对话历史丢给它,它自己完成实体抽取、关系提炼、事实标准化,然后分层存储。

这套系统的记忆分成短期记忆和长期记忆:短期记忆直接关联当前会话上下文,长期记忆沉淀用户画像、事实偏好这类跨会话稳定的信息。我用下来最大的感受是——它确实把“从对话里挖记忆”这件事工业化、产品化了。你不用自己设计提取 prompt,也不用自己写向量化脚本,SDK 里add和search两个接口就能完成大部分需求。

实际接入大概是这种感觉:

from mem0 import Memory memory = Memory.from_config({ "vector_store": {"provider": "qdrant"} }) # 写入一条记忆,绑定用户 memory.add( "用户在上海工作,养了一只柯基,平时工作日没空接电话", user_id="user_10001" ) # 后续 Agent 需要时检索 results = memory.search("用户的宠物和可用时间", user_id="user_10001")

如果你只想先跑通一个原型,Mem0 是最容易出效果的一个。唯一要留意的是它的核心能力依赖 LLM 做信息抽取,所以每次写入都会产生 token 开销,量大了之后账要算清楚。

2.2 Letta(原 MemGPT):让大模型像操作系统一样管理自己的记忆

Letta 的前身 MemGPT 在圈内属于“概念级”项目,论文标题就叫《MemGPT: Towards LLMs as Operating Systems》。它把大模型看成 CPU,把上下文窗口看成物理内存,把外部存储看成磁盘,让 Agent 自己决定哪些东西留在“内存”里、哪些要被“换页”出去。

这个思路解决了一个很本质的问题:模型不知道哪些记忆重要,只能靠外部规则硬塞,而记忆的调换时机必须动态决策。Letta 的实现里有一整套自编辑记忆机制,Agent 可以在对话过程中主动修改自己的记忆块,比如把“用户现在用的手机是 iPhone 14”更新为“用户换成了 Pixel 8”,而不是每次都追加一条新记录。

这种自我管理的方式非常优雅,但也带来了调试难度。我的经验是:如果你做的是研究原型、或者产品逻辑里确实需要长期动态角色设定,Letta 会给你很强的支撑;但如果你只想要一个用于客服问答的“记忆插件”,它的抽象层级反而偏高,心智负担不小。

2.3 Zep 与 Graphiti:让记忆变成一张会过期的知识图谱

Zep 的核心思路跟前面几家很不一样,它不用传统向量库,而是把记忆建模成时序知识图谱。什么意思呢?它不只记住“甲和乙是朋友”,还会记住“甲和乙是什么时候成为朋友的”“这段关系后来有没有变化”“哪条记忆已经过期了”。Graphiti 就是支撑这套能力的开源核心库,负责完成事实的增量抽取和图的动态更新。

时序知识图谱对一类场景特别有用:需要跟踪状态变化的关系型记忆。比如用户上个月说“我在考虑退订”,这个月说“还是留着吧”,传统向量库会把它当两条语义相似但互相矛盾的记录放着,靠模型猜;时序图谱系统则会明确记录这条记忆发生了状态翻转,重新检索时给最新状态更高权重。

我用 Zep 体验到的最大价值是“记忆不太容易污染”。因为它把事实、关系、事件分开存,检索时可以沿图谱链路走,而不是一锅端做相似度召回。代价是部署复杂度上去了,图数据库的运维要额外投入,项目本身的抽象层级也偏高。

2.4 LangGraph 持久化记忆:框架原生的轻量方案

LangGraph 是 LangChain 生态官方的 Agent 编排框架,它内置了两层记忆能力:Checkpointer负责保存图执行的完整状态快照,支持断点续跑;Store则用于跨线程、跨会话的长期记忆存储。如果你本来就在 LangChain 体系里做开发,LangGraph 的记忆方案是接入成本最低的。

以代码感官来说,它非常轻:

from langgraph.checkpoint.memory import MemorySaver from langgraph.graph import StateGraph checkpointer = MemorySaver() graph = StateGraph(...) app = graph.compile(checkpointer=checkpointer)

你用invoke跑完一轮,状态自动存了;下一次带着相同线程 ID 进来,它能把之前的状态恢复回来。它跟 Mem0 这类产品的最大区别在于:LangGraph 的记忆基本上还是“状态保存与恢复”,没有专门做信息抽取、知识提炼、生命周期分层这些事。如果你只需要断点续聊、会话恢复,它完全够用;如果你想做长期用户画像管理,那还是得上专门的记忆服务。

2.5 Cognee:用认知图谱给 Agent 补全上下文

Cognee 是这几个项目里相对小众、但思路非常有意思的一个。它主打的是“ECL”——实体(Entity)、认知(Cognition)、链接(Link)知识图谱。简单说,系统不只是抽取实体和关系,还会把 Agent 在不同时间对事物的看法、判断、推理过程也纳入记忆。

我理解它的定位是“给 Agent 一个可解释的认知背景”。普通记忆系统告诉你“用户提到了 A 和 B 有关”,Cognee 还能告诉你“用户为什么认为 A 和 B 有关”,虽然这个判断也是模型给的,不一定完全准确,但至少在调试链路时你能看到推理依据。这个特性对追求可解释性的项目很有价值。

接入方式也比较直接,面向 Python 生态:

import cognee cognee.add("用户希望退款,理由是对延迟发货不满") result = cognee.search("用户与发货相关的诉求")

它在隐私敏感、部署在本地的场景里比较吃香,因为它默认不强依赖外部云服务,图谱数据可以落在自己的环境里。

2.6 绕不开的源头:Generative Agents 的记忆流范式

严格意义上 Generative Agents(斯坦福小镇那个项目)不算一个可部署的记忆系统,但它提出的**记忆流(Memory Stream)**是几乎所有后续系统的思想源头。每条记忆按时间排序,附带重要性评分、最近访问时间、相关度评分,检索的时候按这三个维度的加权总分召回。

公式大致是:

综合评分 = α * 时间衰减因子 + β * 重要性 + γ * 相关度

后续的 Mem0、Letta 多多少少都吸收了这套“分层 + 加权 + 动态老化”的思想。我强烈建议每个想深入记忆系统的人都读一读它的开源实现,哪怕不用任何框架,自己照着这个逻辑写一个最小实现,都会对“记忆为什么需要老化”有更深的理解。

3. 核心维度横向对比:一张表看清打架的地方

3.1 存储架构:向量库、图库,还是分层混合

先说存储形态,这个决定了系统的底座。我这次对比的项目大致分成三类:纯向量库、图数据库、分层混合存储。

项目核心思路存储形态检索方式上手难度最适合的场景
Mem0独立记忆层向量库 + 图谱混合混合检索,以语义为主低通用业务 Agent、快速接入
Letta记忆即虚拟内存分层上下文 + 外部存储记忆自编辑 + 动态换页中高研究原型、长对话产品
Zep / Graphiti时序知识图谱图数据库图遍历 + 矢量召回高长期客服、关系型记忆
LangGraph框架原生状态内存 / 数据库快照状态恢复 + Store 查询低LangChain 生态的会话恢复
Cognee认知图谱图谱 + 向量实体链路搜索中可解释性要求高的场景

这里面最需要展开的是 Mem0 的“混合”。它底层虽然有向量库,但并不是只做相似度召回,而是会先做实体提取,再用实体关系过滤候选集,最后才做语义排序。这种“图谱过滤 + 向量召回”的混合策略,比单纯“把整段话向量化再搜相似”要精准得多,代价是每次写入的提取步骤更重。

3.2 写入与召回:谁更智能,谁更稳

记忆系统的差距,其实主要在写入环节就拉开了。Mem0 的提取策略是“最大化信息密度”,它会把“用户今天下午三点要去机场接人”这种低价值信息直接丢掉,只保留“用户近期有差旅安排”这种可复用事实。Zep 的写入则是“持续更新状态”,它对同一实体的关系会做增删改,而不是无限追加。Letta 的写入完全由 Agent 自主控制,灵活但不可控。

召回策略上的差异同样明显。向量库方案的通病是:它只回答“哪些句子最接近”,不回答“哪些事实最重要”。所以用了 Mem0 这类系统之后,你还得自己调检索参数——比如限制 top-k 数量、做时间过滤、给不同记忆类型加权。Zep 因为是图结构,检索时可以走“用户节点 → 关系边 → 相关事实节点”的路径,天然能把不相干的信息挡住。

有一点我非要提醒:检索召回不等于翻历史。很多人以为记忆系统就是“把对话记录存下来,搜索的时候把相关段落捞出来”,这是 RAG 思路,不是记忆思路。真正的记忆系统要做到“从对话中提炼可复用的、跨会话的、可更新的记忆单元”。你要是贪图省事直接拿 RAG 冒充记忆,短期看不出问题,跑一个月后记忆库里全是重复片段,检索质量会断崖式下跌。

3.3 部署难度、开源协议与社区活跃度

开源协议的坑比很多人想象的大。某些项目是开源核心 + 商业闭源组件混着来,社区版和云版本功能差距不小。我建议选型前一定去仓库里看一眼 LICENSE,别看 README 里吹多少功能,哪些功能在社区版要自己搭、哪些要付费走云,都得列清楚。

从部署难度看,排序大概是:LangGraph(纯嵌入) < Mem0(单服务 + 向量库) < Cognee(需要中间件) < Letta(需要服务端和数据库) < Zep/Graphiti(需要图数据库运维)。如果你的团队没有专门的中间件运维能力,Zep 这条路线要谨慎,图数据库本身就是一个需要调优的组件,不是装完就能“稳了”的东西。

活跃度方面,Mem0 和 LangGraph 因为体量大、迭代快,社区问答资料相对丰富;Letta 社区很活跃但偏研究向,文档里的“最佳实践”经常是论文味比较重的抽象描述;Cognee 更新频率不低,但这类垂直小众项目最大的风险是“哪天核心维护者不玩了,你的记忆系统就没人管了”。

4. 场景化选型建议:不同目的,别拿同一把尺子

4.1 快速验证 MVP:首选 Mem0 或 LangGraph

如果你只是想把 Agent 的记忆能力跑通,让产品在演示时不丢人,我强烈建议先用 Mem0 或者 LangGraph 起步。Mem0 能在半天之内接入,帮你把用户画像、会话记忆、偏好检索全搞定。LangGraph 更省事,但它只解决“状态恢复”,不解决“知识提炼”,如果你的演示场景里需要 Agent 记住用户“上周问过哪些问题”,那还是 Mem0 更合适。

你的 MVP 如果跑了两三周,记忆条数上千了,这个时候再去评估“要不要换更重的方案”也不迟。一上来直接上时序图谱或者虚拟内存架构,团队耗不起。

4.2 生产级客服场景:Zep/Graphiti 的价值会被长期放大

客服、导购、售后这类的长期对话业务,最需要的不是“记住用户说过的每句话”,而是“记住用户状态的变化”。用户改地址、退货、升级会员,这些是事件,不是句子。事件之间还有因果和时序关系。

我用 Zep 这类时序图谱的体验是:它在处理状态翻转类记忆时的准确性是向量库体系很难追上的。比如用户一个月内两次投诉同一个问题,第二次投诉时 Agent 必须知道“这是第二次,之前处理结果是什么”,图结构能让它沿着“用户→投诉事件→处理结果→复购行为”的路径把所有关联事实一次捞出来。

这个场景的代价你也必须接受:上线前要做好数据模型设计,不能指望系统自动把图谱画完。

4.3 多 Agent 协作与研究型场景:看 Letta 和 Cognee

多 Agent 系统里,每个子 Agent 的记忆既要共享又要隔离,Letta 的“记忆即虚拟内存”抽象在这里特别顺手——你可以把这个 Agent 的记忆块挂给另一个 Agent,也可以单独复制一段。Cognee 的认知图谱则适合那些要求“每个记忆都有推理依据”的场景,比如医疗问诊、金融投诉处理这类需要解释逻辑的领域。

说实话,这类场景目前还没有标准答案,各家用得都很野。我的建议是别太早锁定一个框架,先在记忆层之上做一层薄薄的接口封装,将来换实现的时候不至于把所有业务代码重写一遍。

4.4 已经在 LangChain 生态里的团队:别为了记忆引入新架构

这条是给“已经在 LangChain 体系里写好 Agent”的团队的建议。你如果只是想要断点续聊、会话合并、跨会话记住用户 ID 这类基础能力,LangGraph 内置的 checkpointer 和 Store 完全够用,不必再引入一个独立记忆服务。多一个服务就多一个故障点、多一类数据同步问题,Agent 系统的运维复杂度已经够高了,能少一事就少一事。

当你真正遇到“基础记忆不够用”的痛点——比如用户画像无法跨会话自动沉淀、记忆条数上千之后检索质量下降——再考虑把 LangGraph 里的搜索逻辑替换成 Mem0 或者 Zep,LangGraph 的模块化不至于把你绑死。

5. 实操避坑:这些坑我替你们踩过了

5.1 记忆污染:最隐蔽的杀手

记忆系统跑久了,八成会出一个很恶心的问题:写入的“把关”不够严,垃圾记忆反向污染了正常检索。比如用户说一句“我今天心情不好想投诉”,系统可能提取成“用户对服务不满”,下次用户问“这个套餐怎么续费”,Agent 检索时反而捞到“服务不满”这条记忆,语气变得小心翼翼,甚至主动道歉。

我自己处理记忆污染的常规手段有两个。一是给写入流程加“重要性门槛”,低信息密度、纯情绪、纯寒暄的记忆直接丢弃;二是给记忆打标签,分事实、偏好、事件三类,检索时按当前任务类型过滤标签。

还有一条经验:不要允许模型自由追加记忆,要给它“更新”而不是“追加”的接口。用户的手机号从 138 换到 139,应该更新原记忆,而不是新增一条,多出两条且互相矛盾的记忆就是灾难。

5.2 记忆过期了,Agent 仍然在喂过期数据

记忆时效性比大多数人以为的严重得多。用户说“我这个月要搬家到下城区”,下个月你再问“通勤建议”,还拿“下城区”当新鲜事,就露馅了。向量库没有“时间观念”,你存进去一条、检索就召回一条,过期多久全靠你外部维护时间戳。

Zep 的时序图谱天生解决这个问题,记忆自带生效时间窗口;Mem0 和 LangGraph 这类方案则需要你手动维护生命周期。我的实践是:给每条记忆加一个valid_until字段,定时任务对所有长期记忆做一次“过期确认”,该删的删,该降权的降权。别偷懒,这个定时任务不做,三个月后记忆库里全是半年前的过时信息。

5.3 并发与规模:记忆层的瓶颈会反噬 Agent

有人问“Agent 怎么扛并发”,这是个好问题。记忆系统本身是有状态的,比无状态 API 服务难扩展得多。你在前面无脑开十个 Agent 实例,后面一个记忆服务分成十个写入并发打过去,先崩的是向量库和图数据库,而不是模型 API。

我的经验原则是:记忆服务的写入要走队列异步化,对话响应不需要等记忆写入完成再返回。用户聊完一轮,Agent 先回复,记忆在后台异步入库。检索路径则要考虑缓存,把高频记忆(当前用户画像、最近会话摘要)直接缓存在内存里,别每次请求都打向量库。我实测过,不缓存的情况下,一次检索十来毫秒,看起来不快不慢;但并发上百之后,全被数据库连接池拖死。

5.4 隐形成本:记忆不是免费的

很多人在选型的时候只看安装部署难度,忽略了运行成本。用 LLM 做信息抽取,每条对话都产生额外的 embedding 调用和抽取 prompt 调用,这个成本跟对话本身的成本差不多,甚至更高。Zep 图数据库需要配套图谱计算资源,Letta 的自编辑内存会周期性地触发模型调用“反思”现有记忆是否需要调整。

成本控制上有两个直观的技巧。第一,抽取用的模型可以降档,用便宜的小模型做信息抽取,对话才用主力模型,我试过,抽取质量下降不到百分之十,成本降一半;第二,记忆检索要分级,先试缓存、没有再打向量库、还不行才走 LLM 重排,用推理链路换钱。

5.5 安全与隔离:记忆越强,责任越大

记忆系统存储的是用户隐私,比日志的敏感度还高。至少要做到用户级隔离:用户 A 的 Agent 永远检索不到用户 B 的记忆。这个在向量库里很容易漏,因为 embedding 本身不区分用户,检索时如果不带user_id过滤条件,跨用户串记忆就是一个安全隐患。

我坚持两条底线:一是所有记忆按用户分库或者分 collection 存储,二是记忆检索必须强制注入用户身份过滤,并且这个过滤逻辑不要写死在下层存储接口里,而是在应用层显式校验。别觉得多此一举,等出了数据事故再后悔就来不及了。

6. 几点选型心得,当个结尾

对比做完了,说几个我在实操中总结的私人看法。没有哪家开源记忆系统是完美的,Mem0 胜在接入快,Zep 胜在关系表达强,Letta 胜在理论深度,LangGraph 胜在省心,Cognee 胜在可解释。真正的分水岭往往不在技术本身,而在你的团队有没有精力把一个方案跟到生产环境稳定运行。

如果让我给一个最直接的入门路径,我会说:先用 LangGraph 把状态恢复做了,让 Agent 不会断篇;再用 Mem0 把用户画像和偏好沉淀下来;当你的记忆图谱复杂到需要表达“状态翻转、关系演化”的时候,才值得上 Zep 的时序图谱。别一上来就抱着最重的架构不放,记忆系统的复杂度是逐步逼出来的,不是一开始就需要的。

最后再分享一个小技巧:不管选哪一家,一定要在项目早期就把记忆的“调试面板”做出来——能查看某条记忆如何被写入、为什么被检索、检索相关性打分是多少。没有这个面板,记忆系统出了问题你只能靠猜,那种调试体验会非常痛苦。有了可视化调试,记忆系统才真正变得可控。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询