做 Agent 跑过几个真实项目之后你大概率会遇到同一个问题每次对话听上去都挺聪明但换个会话它就完全不记得你是谁、之前聊过什么。上下文窗口再大一断就断片。这就是我今天想认真聊一聊的 Agent 记忆系统。这两年开源社区冒出不少方案Mem0、Letta、Zep、Cognee看名字好像都差不多真做技术选型的时候会发现它们的设计思路天差地别。这篇报告不打算贴一堆官方 README而是把我实际跑过的几个开源记忆系统放在一起从技术架构、记忆提取、检索策略、二次开发成本几个维度做一次横向拆解最后给出一套可以直接抄作业的选型思路。这也就是这篇博文的定位了给正在做 AI Agent 应用、纠结要不要自研记忆模块的工程师给团队里负责技术调研的小朋友以及那些想给现有应用加“长期记忆能力”但又怕踩坑的朋友提供一个稍微有点依据的对照参考。全文涉及到的项目我都尽量基于 2024 至 2025 年间的社区版本和实际使用经历来描述版本迭代快的项目会特别标注。1. 先把记忆这件事拆清楚Agent 到底缺哪种记忆1.1 记忆不只是“存下来”至少分三层很多人一听到“记忆系统”第一反应是接一个向量数据库把历史对话 embedding 一下再塞进去。这个直觉方向没错但只覆盖了很小一部分。一个可用的 Agent 记忆系统一般要处理三类信息短期记忆、长期记忆、还有程序性记忆。短期记忆对应的是当前会话内的工作上下文比如用户刚刚上传的文件、这轮对话里已经算好的中间状态。长期记忆解决跨会话的一致性问题比如用户的偏好、项目背景、过往决策结论。程序性记忆更像技能是 Agent 完成某类任务的方法和规则。开源记忆系统通常只重点解决第二类也就是跨会话的长期记忆同时对第一类做接口对接对第三类基本不碰。拿实际例子说你让 Agent 每天帮你整理邮件摘要它得记住你是做跨境电商的、关心物流异常关键词这就是长期事实记忆它还得知道上回已经对某个客户做过一次跟进避免重复处理这是事件记忆它每次调用邮件 API 前的鉴权 token 放哪里这算工作记忆。开源项目的差别主要在于它们各自选择了不同形态来承载这几类信息。1.2 开源方案差异的本质抽象层级不一样我对比过一圈之后的一个核心结论是这些开源项目之间的真正分歧不是你选 A 还是选 B 的 API 风格问题而是它们在 Agent 系统架构里的抽象层级不同。有的项目定位是“记忆接口服务”比如 Mem0它把自己做成一整套提取、存储、检索的封装Agent 应用只需要调用 add、search、get_all 这类接口。有的项目是“带记忆的 Agent 运行时”比如 Letta原 MemGPT它直接把记忆管理内嵌到 Agent 执行逻辑里用类似操作系统虚拟内存的方式调度上下文。还有项目是“记忆基础设施”比如 Zep它围绕时序知识图构建记忆图谱提供图查询接口给上层 Agent 调用。这不只是实现细节的区别它会直接决定你的接入深度、运维成本、以及项目长期演进的自由度。所以后面的对比我尽量不横向罗列表面功能而是抓住架构层级这个主要矛盾来展开。1.3 记忆系统到底在解决什么场景痛点从应用场景来看需要引入独立记忆系统的信号通常有几个。第一是上下文窗口反复爆掉频繁做 truncation 导致信息丢失。第二是用户发现 Agent “翻脸不认人”同一个用户第二次对话完全不记得第一次给过的偏好产品留存率和体验都会受明显影响。第三是知识型 Agent 反复执行重复的信息收集比如每周都要用户重新提供名字、公司、历史背景。如果只是单轮问答、一次性生成记忆系统确实是多余复杂度。一旦应用进入多轮交互、个性化推荐、业务助理这类场景记忆系统几乎就是刚需。这也是开源社区在 2024 年下半年开始大量涌现相关项目的原因——大家发现上下文拼接 向量检索这条手工路线没法支撑复杂产品最终还是需要一个专门的中间层。2. 主流开源 Agent 记忆系统全景定位与底层逻辑2.1 Mem0主打“接口友好”的托管式记忆层Mem0 是目前社区热度最高的方案之一它的定位非常清晰给开发者提供一个与模型无关的记忆服务层。它不做 Agent 运行时而是把你给它的对话、文档片段加工成结构化的记忆项然后缓存到向量库并提供 search 接口供 Agent 拉取。实际用下来Mem0 的几个特点值得说。第一是它自带了一套 NLP 提取逻辑会过滤掉寒暄、重复、低信息量内容不是无脑把整段对话存进向量库。第二是它有记忆评分机制默认会返回与任务相关性最高的记忆项而不是全部召回。第三是它支持被集成为 LangChain 工具如果你已经有 LangGraph 这类编排层接入成本很低。需要留意的是Mem0 社区版默认支持一些后端存储生产级部署涉及到的嵌入模型和向量库选型通常要自己组装。它的记忆项管理是粗粒度和细粒度混合的有时候提取出来的记忆会碎片化影响后续检索的精确度。这一点在后面坑位部分我会展开说。2.2 Letta原 MemGPT把上下文调度做成“虚拟内存”Letta 是我个人觉得在设计上最有想法的项目它的灵感直接来自操作系统的内存管理。LLM 的上下文窗口被理解为“内存”外部存储理解为“磁盘”Agent 的对话循环被设计成类似于操作系统的换页机制重要的信息留在上下文里不重要的主动卸下。这意味着 Letta 不是简单提供记忆接口而是直接改变 Agent 的运行逻辑。它要求 Agent 通过函数调用来“写内存”“读内存”系统会维护一个核心记忆块memory block里面有人的身份信息、对话历史摘要、业务配置等。对话过程中它自动判断哪些记忆需要被“换入”上下文、哪些已经过期可以被“换出”。这个设计对长期运行型 Agent 非常合适尤其是那种需要连续监督、持续执行多步骤任务的场景。但它也有代价学习曲线明显比 Mem0 陡峭因为你需要理解它的 memory block 结构和调度规则。另外它的体系里为了兼容不同模型函数调用协议的组织方式也需要一定的适应成本。2.3 Zep用“时间知识图谱”来记住关系与事件Zep 走的是另一条非常有意思的路线它把记忆建模成一个随时间演化的知识图谱。你丢给它对话历史它会抽出实体人、组织、产品、地点、事件、关系然后把这些主体之间的关系随时间线保存在图数据库里。这套设计最适合业务关系复杂的场景。举个典型例子一个销售类 Agent 需要记住“某客户公司最近引进了新的采购负责人并且上季度追加过一次订单”。向量库能存住这段话的语义句但很难直接表达“公司与人员之间的所属关系”以及“订单随时间变化”这种结构化事实。Zep 的图结构可以比较自然地支撑这类查询遍历、过滤、聚合关系链。另外Zep 的默认配置里已经整合了冗余的 embedding 图存储双通道检索时可以同时做向量相似度匹配和图路径遍历再融合排序。这个混合检索能力很多开源方案还没有做扎实。它的不足之处在于部署偏重依赖服务较多资源占用比 Mem0 这类轻量方案高一个量级。2.4 LangMem 与 LangGraph 生态如果不离开 LangChain 生态的首选LangMem 是 LangChain 组织在记忆系统方向上的官方尝试定位是 LangGraph 的记忆层组件。它提供了简单但足够用的记忆操作从对话中提取可保存的事实、把用户偏好提炼成记忆项、从既有记忆库中检索相关内容。我觉得 LangMem 更适合已经深度绑定 LangChain 生态的团队。理由很简单接入成本最低不需要额外引第三方记忆服务直接在 LangGraph 的节点里调用记忆工具即可。像记忆通知器Memory notifier、跨线程记忆继承这些能力它在 LangGraph 语境下处理得很顺滑。不过如果跳出 LangChain 生态你会发现 LangMem 的独立使用体验一般文档和抽象都和 LangGraph 的图执行模型强耦合自研编排引擎的团队用起来会比较别扭。2.5 Cognee侧重知识图谱的“记忆 认知”管道Cognee 这个项目把重心放在“从原始知识构建图谱”这件事上。它把自己比喻成一套认知管道输入文本片段输出一个包含实体、概念、关系的知识层这个知识层后续可以被 Agent 当作系统信息的一部分加载。如果你主要的需求不是“记住这段对话”而是“从一堆文档里抽取出能够长期支撑 Agent 判断的业务知识”Cognee 会比 Mem0 这类对话记忆方案更贴近目标。它支持多种后端、模块化的图谱构建流程作为基础设施扩展性不错。2.6 一套简明的横向对照下面这张表是我整理的横向对照维度方便你在脑海里先建立一个坐标系项目抽象定位记忆形态主要存储上手难度典型场景Mem0记忆服务层记忆项 向量多种向量库低通用 Agent 的长期记忆增强LettaAgent 运行时Memory Block 调度自带状态 向量库高长期持续运行的任务型 AgentZep记忆基础设施时间知识图谱 向量图数据库 向量库中高关系密集型业务场景LangMem编排层组件记忆项 向量由 LangGraph 集成低LangChain 生态内的快速接入Cognee知识管道知识图谱多种图后端中文档知识沉淀与语义互联这张表不是打分排名更多是帮助你把注意力放在“架构定位差异”上。真正选型的时候定位远比某一个功能点的强弱重要。3. 多维对比从工程视角逐个拆关键环节3.1 记忆提取谁在做信息筛选谁在无脑入库记忆系统的第一道工序是从原始对话或文档里提取“值得记住的东西”。这一步直接决定后续所有检索的上限。如果原始信息本身是垃圾后面向量化、召回做得再好也没用。Memo0 的思路是用一小套信息过滤规则 嵌入模型双通道优先保留包含事实、偏好、明确指令的片段。它会尝试把“用户来自上海”这类事实性陈述抽出来当作独立记忆项而把“好的我会帮你处理”这种回应过滤掉。这种过滤很容易造成两类问题过度过滤导致重要细节丢比如用户在对话中无意提到的偏好被当闲聊或者过度保留导致记忆库膨胀比如同一信息不同时间被重复抽取。Letta 的记忆提取逻辑与它的换页机制绑定更有针对性。它会按照开发者定义的 memory block 结构来决定信息进哪些槽位。比如一个 customer-service Agent 的 memory block 被定义为 {user_profile, orders_summary, interaction_history}那么从对话中提取出的信息会先去匹配这些槽位。这套机制的优点是结构化程度高后续检索准确率容易做上去缺点是开发者必须提前定义好槽位 schema对不确定性的容忍度低。Zep 则把提取往实体关系方向做。它输出的不是一段文字而是实体节点和关系边。在这个过程中Zep 需要比较强的命名实体识别和时间关系抽取能力对一些无明显关系的闲聊场景图谱会显得非常稀疏信息密度不如向量方案。LangMem 作为一个组件提取逻辑比较轻量主要依赖事件驱动的“通知器”机制应用层决定什么时候把某段对话发给记忆系统它再执行提取。换句话说是半自动主动权在编排层。3.2 存储模型向量、块、图谱背后是不同的查询能力存储形态本质上决定了 Agent 能通过哪些“方式”回忆起记忆。我用一个实际例子说明差距用户对 Agent 说“我想预订下周三上午从上海到北京的机票”。向量库的检索逻辑是把这句话 embedding 后去向量空间里找相近的历史片段。它能匹配到语义相似的旧行程但无法直接回答“我上一次出差北京是什么时候、有没有长期合作的酒店”这种需要关系和属性过滤的问题除非之前这句话被完整存过。Zep 的图查询在处理这类问题就自然很多它可以直接走“用户节点 - 出差事件节点 - 目的地北京”的路径把这个出行频率和偏好酒店属性返回。这是结构性优势而不是某一项工程参数的提升。Letta 的 memory block 更像是一个受控的槽位结构它能存储任意结构化字段但不会自动建立实体之间的关系。它最擅长的是把当前 Agent 的工作状态完整保存下来比如任务进度、剩余步骤、已确认条件下次启动时无缝接续。LangMem 的存储模型基本跟随 LangGraph 的状态机制通过 checkpoint 和 memory 集合组织适合在同一个图执行流程里共享状态跨流程的深度检索能力偏弱。3.3 检索与召回谁在被动喂上下文谁在主动选策略检索环节是记忆系统体验差异最明显的地方。最粗糙的做法是“全量倒进上下文”这个在记忆量小的时候勉强能用一到上千条记忆就直接撑爆上下文窗口。成熟开源方案都会围绕相关性评分、时效衰减、优先级分层做一套策略。Mem0 在检索时默认带有记忆评分通过重新排序选出 top-k 条相关记忆。这一点体验很好尤其当你的记忆库有几千条记录时它能有效避免无关记忆干扰 Agent 的决策。它的时效处理相对简单没有做很强的分级衰减陈旧记忆与新鲜记忆的权重差别依赖嵌入模型对时间信息的理解这其实是有隐忧的。Zep 因为有了时间知识图谱天然支持时间窗口过滤比如查询“过去一个月内出现的实体”“某某客户最近三次交互”。它能做到按时间切片取图这在向量库方案里很难低成本实现。Letta 的调度策略最有意思不是每次对话都全量检索记忆而是由 Agent 自己通过工具调用来触发“读记忆”。也就是说记忆系统不会主动把所有相关内容灌进上下文而是等 Agent 需要的时候才去拉。这类似操作系统里的缺页中断能极大降低无效占用。3.4 扩展性与二次开发服务化、插件、自部署的成本对比讲完上面的“理论层”得落地到工程实践。我实际部署过这些项目之后一个直观感受是文档漂亮和部署省心不能画等号。Mem0 社区版在资源占用和启动速度上都比较友好。它默认支持 PostgreSQL/PGVector、Qdrant 等常见向量库如果你已经有向量库在跑加一个 Mem0 服务大概花半天时间就能接通。它更适合那种“我现在就要给 Agent 加记忆越快越好”的团队。Zep 部署起来相对重一些。它内部依赖 Neo4j 和一个 Python 服务端自己还要处理嵌入模型服务配置链路比 Mem0 长得多。但好处是构建完成之后它的图数据库能持续积累业务关系数据长期复用价值更高。如果你的平台本身已经有图形数据库基础设施Zep 落地成本可以被摊薄。Letta 因为带着完整运行时所以部署视角并不像一个服务更像是在你的应用里嵌入了一个“带记忆的 Agent 引擎”。如果需要深度改造 Agent 执行流程Letta 的二次开发成本高但改造完成后记忆能力与执行逻辑融为一体不像 Mem0 那样还需要你自己把检索结果拼进 prompt。LangMem 在 LangGraph 团队的项目里部署最简单它不是一个独立服务而是 Python 包随你的编排代码一起跑。但它的限制也很明确不做多 Agent 共享记忆的跨服务方案记忆只在 LangGraph 应用内共享。3.5 许可、数据安全与合规注意点开源不等于可以随便用。我见过的团队超过一半选型时只看 GitHub Star 数和热门程度很少看开源许可证。Mem0 的社区版采用 Apache-2.0商用相对友好。Letta 使用 Apache-2.0。Zep 是一个较早版本使用 Apache-2.0后来部分版本引入了企业版功能要注意区分社区版和企业版的边界。Cognee 选用 Apache-2.0相对宽松。LangMem 属于 LangChain 系列使用 MIT 许可。不过项目版本一旦迭代许可证可能随时调整请以你锁定版本的 LICENSE 文件为准别只看我这份报告里的结论。除了许可证还有数据安全层面的考量。记忆系统存储的是用户历史交互内容这是敏感数据重灾区。自部署开源方案相比调用云服务数据出境风险可控但你要自己负责存储加密、访问控制、删除机制。我记得 Zep 有提供基于时间的记忆修剪策略但 Mem0 社区版对“按用户维度物理删除全部记忆”这类操作体验就比较一般需要你在应用层做补偿。合规要求严格的产品强烈建议部署前先做数据分类和脱敏方案。4. 选型实操不同阶段项目的落地建议说实话很多团队做选型都被一个误区卡住拿着一个具体功能点反复比较却忘了自己项目当前最缺什么。我做这类对比看过太多项目后最后总结出来的选型框架非常朴素先判断你的 Agent 现在是在“阶段一跑通 demo”还是在“阶段二生产可用”还是在“阶段三复杂业务规模化”。处于阶段一也就是产品还在快速验证阶段建议直接上 Mem0 或者 LangMem。这两个方案接入成本最低能让你在最短时间看清记忆能力到底能不能解决产品的问题。我在给一个客服问答 Agent 加记忆能力的时候用 LangMem 大概一个晚上就完成了接入效果立刻体现在跨会话回复质量上。进入阶段二你需要把记忆真正跑在线上就要考虑稳定性、写入吞吐、检索延迟、数据隔离。如果已经有 LangGraph 编排LangMem 继续用是最高效路径如果用的是自研编排Mem0 的服务化形态更友好。不建议在这个阶段换 Zep除非你的场景里关系查询的需求已经很明确。阶段三的标志是 Agent 开始处理跨多天的任务流业务实体关系复杂记忆库规模上万条。这个时候再上 Zep 或者 Letta 这类重方案收益会比较明显。因为它们一个胜在结构化关系查询一个胜在长期运行的上下文调度都是普通向量检索在规模上去之后很难做到的。另外如果团队有充足的后端资源也可以考虑自研“轻量记忆管道”用消息队列 向量库 定时摘要的方式组装。自己写的好处是可控性最强记忆提取逻辑可以完全贴合业务 Schema坏处是工程量大、迭代周期长没有三个月很难达到成熟开源方案的稳定性。对自己写不写的判断标准就一条记忆业务规则每天都在变吗如果每天都在变建议用开源方案自带的可配置机制如果基本稳定可以自研。选型这里我再多提一个经常被忽略的维度团队的知识背景。如果你们团队擅长图谱和数据库Zep 的学习曲线不是问题如果团队是模型应用背景对图数据模型不熟那么 Zep 多半会变成维护负担。记忆系统最终是要有人去长期运维的选一个团队能接得住的方案往往比选一个理论上更优的方案更重要。5. 实战避坑清单这些坑我踩了一遍又一遍5.1 记忆污染Agent 记住不该记的东西比记不住更可怕这是所有记忆系统落到真实场景中最容易翻车的问题。我跑一个保险咨询 Agent 的时候用户随口在对话里说了一句“我爸最近身体不太好”这本来只是闲聊但记忆系统会把“用户提到父亲身体不好”抽成一条长期记忆以后 Agent 每次回答都会刻意绕开健康话题甚至误解为用户身体出问题。这类误抽取直接导致用户体验出问题还会误导后续决策。应对方案比较复杂没有银弹。我目前的实践是分级提取只把用户明确表达过的偏好和历史决策存进长期记忆其余一律作为短期上下文保存在当轮会话中不让他进入向量库。然后配合定期检查把那些置信度低于阈值的记忆项批量清理。如果一个记忆项连续多次没有被检索到就可以把它降级处理。5.2 检索误召回看似相似的记忆实际上毫无用处向量检索有一个很隐蔽的坑语义相似的文本不一定是有效记忆。比如用户之前说“我要去深圳出差”Agent 留下一条记忆。下一次用户说“我要去深圳参加展会”向量检索返回上次的出差记忆Agent 自动关联出酒店和交通建议但两次行程其实是完全独立的。这可能让 Agent 给出错误启发式回答。不同方案对这个问题做的缓解不一样。Zep 因为带时间关系可以让 Agent 判断“上次出差”的事件时间节点规避混淆Mem0 则主要依赖重排模型Letta 通过 memory block 结构让开发者提前决定哪些字段需要审计哪些不需要。实操中我会在检索结果后加一层规则只有包含明确身份信息或偏好词的记忆项才能进入高权重召回事件型记忆统一降低优先级。5.3 token 成本被低估记忆检索不是免费的记忆系统的成本包含三块写入时的 token 消耗、检索时的 embedding 消耗、被召回后的上下文 token 消耗。第一块最难控制。每次对话结束都跑一次全量记忆提取成本立刻直线上升。想象一下你的产品日活十万每个用户每轮对话多花 2000 token 做记忆提取那就是每天多几个亿 token一年下来是一笔很可观的成本。建议在工程上做聚合批处理用户会话结束后的空闲时间才去跑记忆提取而不是每轮都执行。检索侧尽量用低维 embedding 模型召回量控制在 top-5 以内召回后再放给大模型做相关性判断。这一套优化组合拳跑下来实测能把记忆相关成本压到原来的三分之一左右。5.4 并发与数据一致性不是所有方案都能直接扛住线上流量开箱即用的记忆系统在单用户 demo 时都很好用一到并发场景就原形毕露。Zep 这种依赖外部图数据库的方案连接池配置不当很容易在高并发下吃掉大量数据库连接然后整个记忆查询链路变慢Agent 响应时间也跟着受影响。Mem0 社区版在写入侧没有很强的削峰能力如果你准备直接把它暴露给线上流量建议在前面加一层任务队列。跨线程一致性问题也要特别留意。同一用户的记忆如果被两个 Agent 实例同时写入很容易出现覆盖旧值、丢失更新的情况。多数开源方案默认没有加 CAS 乐观锁需要你在应用层串行化同一用户的记忆写入请求。我踩过这个坑之后做了一个简单的用户级分布式锁才让 Update 操作变得安全。5.5 监控与评测最难的不是上线而是知道有没有退化记忆系统上线后我有一个非常深刻的体验功能测不出来只能靠线上数据反馈。你很难通过几组测试用例判断记忆系统到底有没有改善用户体验因为没有标准答案。我建议从三个指标入手量化记忆命中率、回答相关性评分、用户重复提问率。记忆命中率反映的是 Agent 在多少轮对话中实际用到了记忆项回答相关性评分可以在测试集上做人工标注用户重复提问率则直接反映记忆系统有没有降低用户反复澄清信息的频率。没有这三类指标你后续对记忆系统做的每一次调参都可能是在盲人摸象而且很难判断一个改动是优化还是退化。6. 一些额外想说的回到开头那个问题Agent 记忆系统开源项目那么多到底选哪个我的看法没有变过——先想清楚你的 Agent 处在什么阶段再去匹配架构定位。千万不要因为某个项目人气高就闭眼上车记忆系统是整个 Agent 产品的“第二曲线”它的架构选择会强烈影响你后续的迭代节奏。最后分享一个我自己一直沿用的习惯给 Agent 加记忆能力时先做成“只读”再开放“写入”。也就是说第一版先把记忆系统接入检索侧只读取预设的高质量记忆知识库跑通之后再开放自动提取写入。这样即使写入逻辑有问题也不会污染线上 Agent 的行为。等记忆写入的稳定性验证充分了再逐步放开自动提取整个过程风险可控。这套渐进式接入的思路我在好几个项目里都验证过踩坑的代价明显小很多。如果你正在做 Agent 相关开发这篇报告里的任何结论都建议拿到真实业务场景里再验证一遍。开源项目更新速度极快我写这份对比的时候好几个项目都在频繁迭代最终还是要以你锁定版本的实际表现作为决策基准。祝接入顺利少踩记忆污染和 token 失控的坑。