开源Agent记忆系统横向对比:Mem0、Zep、Letta与LangGraph选型指南 1. 为什么 Agent 记忆系统会变成刚需做 AI Agent 开发这一年多我最大的感受是记忆系统的好坏直接决定了一个 Agent 项目是“demo 级玩具”还是“生产级工具”。很多刚接触 Agent 框架的开发者会问大模型本身就有上下文窗口为什么还要单独搞一套记忆系统这个问题很关键我建议所有入坑 AI Agent 的人先想清楚这一层再去看具体方案。1.1 我先讲一个自己踩过的坑去年我做了一个开源 Agent 项目用来帮团队做知识库问答和任务拆解。第一版代码很简单把所有对话历史直接塞进 prompt然后调大模型 API。单轮问答效果不错但只要用户聊到第三轮就明显感觉到模型开始“失忆”前面刚说过喜欢简洁回答后面它就开始长篇大论上午确认过的项目截止时间下午再问就变成了“我不确定您之前有没有提到过”。最离谱的一次用户连续问了五个相关问题Agent 把第三个问题的结论完全忘掉给出了自相矛盾的答案。这时候我才意识到上下文窗口再大也不等于记忆。大模型的上下文是“临时工作台”每次请求结束就清空了。想要跨会话、跨天、跨用户地记住关键信息必须在模型外面搭一套独立的记忆体系。这就是 Agent 记忆系统存在的意义。后来我去调研了社区里几乎所有叫得上名字的开源记忆方案做了对比和落地测试这篇报告就是我当时调研过程的完整复盘。1.2 Agent 记忆到底在记什么先说清楚概念。Agent 记忆通常分成三类工作记忆就是当前任务上下文比如正在进行的多轮对话、正在执行的子任务状态对应到工程上就是会话窗口或者 LangGraph 里的 thread 状态。长期记忆跨会话保存的事实、偏好、知识比如“用户是后端工程师”“用户偏好 Python”“项目截止时间是周五”。这部分是需要外部存储和检索的。情景记忆记住“发生过什么”比如“上次讨论时用户否定了方案 A”“三天前已经发过版本 v1.2”。情景记忆往往带时间属性像 Zep 这类时间感知图记忆就是专门做这个的。还有一个容易被忽略的维度是程序性记忆也就是 Agent 自身学会的技能和操作路径严格来说这属于 Agent skill 的范畴。大部分开源记忆系统做的是长期记忆和情景记忆工作记忆通常由 Agent 框架本身管理。理解了这个分类再去读各项目的文档就不会被“记忆”这个词搞得一头雾水。1.3 这篇报告能帮你解决什么问题如果你正在做以下事情这篇报告应该对你有用你在选型一个 Agent 记忆组件但面对 Mem0、Zep、Letta、LangGraph Checkpoint 等一堆开源项目不知道选哪个。你已经把记忆系统接进项目了但发现检索不准、写入重复、上下文膨胀这些问题不知道怎么排查。你想搞清楚这些记忆系统的底层原理避免被各种营销概念带偏。我在报告里不做那种“人人都有优点缺点”的废话直接给结论、给对比、给代码、给排坑经验。每个方案我都实际部署过不是在 GitHub 上刷 star 就算了解的那种“云调研”。2. 主流开源方案全景扫描目前社区里讨论度最高的开源 Agent 记忆系统我整理下来就五个代表Mem0、ZepGraphiti、Letta原 MemGPT、LangGraph Checkpoint、Cognee。另外还有一些小众但很有特点的项目比如 Memary、LangMem、SuperMemory我也一并提几句。2.1 Mem0目前最像“记忆即服务”的开源组件Mem0 是我最先测的方案。它的设计思路很明确给 Agent 提供一层独立的“记忆存储与检索”能力。底层支持 Qdrant、pgvector、Milvus 等向量库上层封装了记忆提取、检索、更新的完整流程。Mem0 的亮点在于它对“记忆增量更新”做了专门处理。用户每次说了新内容它不只是往里塞一段向量而是先让 LLM 判断这段内容是否包含值得保存的记忆再和历史记忆做对比能合并的合并、该删除的删除。这个机制说实话很聪明避免了我之前遇到的“记忆越存越乱”问题。社区热度也很高GitHub 上 star 涨得飞快文档、示例代码都很齐全官方还有托管版本可以白嫖额度。对大多数团队来说Mem0 是最稳妥的“第一个记忆系统”。2.2 Zep / Graphiti知识图谱路线的时间感知记忆Zep 这个项目的核心技术叫 Graphiti是构建时间感知知识图谱的引擎。和向量检索路线完全不一样Zep 会把对话、文档拆成实体和关系节点带时间戳边带时效权重。检索的时候不是做相似向量召回而是从图谱里做“时态图遍历”直接回答“用户三周前对这个问题是什么态度”。这套设计的好处是可解释性强。你问它为什么召回这条记忆它能给你看完整的实体关系路径。Zep 在做“情景回忆”方面几乎是吊打纯向量方案。代价就是部署有点重依赖 Neo4j 或类似图数据库维护成本比 Mem0 高一个量级。适合知识密集、关系复杂、对可解释性有要求的场景。如果让选一个性能最强的我可能会投 Zep如果让我选最省心的那我投 Mem0。这两条路线的差异基本代表了当前 Agent 记忆系统的两个流派。2.3 Letta原 MemGPT用操作系统的思路管记忆Letta 这帮人把大语言模型比作操作系统上下文窗口有限相当于“内存”外部记忆存储相当于“磁盘”模型内部的自我反思机制相当于“页面置换”。系统会自动决定哪些信息留在上下文里、哪些信息换出到外部存储、什么时候从外部把旧记忆加载回来。这个抽象很有意思它解决的是“上下文爆炸”的问题。用 Letta 的时候你不需要手动设计该把什么记忆塞进 prompt它会通过记忆编辑工具自己管理。换句话说它把记忆管理从“开发者的责任”变成了“Agent 的一种能力”。实际用下来Letta 更适合做那种长时间自主运行的 Agent比如个人助理、自动研究员。但它因为定制了整套 runtime所以如果你想把它嵌进已有的 LangGraph、LangChain 流程会有点别扭。它更像一个完整的 Agent Server而不是一个可插拔的组件。2.4 LangGraph Checkpoint不算记忆系统但绕不开LangGraph 是现在主流的 Agent 编排框架之一它的 Checkpoint 机制在 dev 圈里经常被误归为记忆系统。严格来说它管的是工作记忆持久化把图的每个节点状态、消息列表、分支进度存到存储里每次恢复时从 checkpoint 接着跑。这个很像给流程图加了“存档点”。LangGraph 官方也有 long-term memory 的探索比如 MemoryStore 接收器能按用户维度存跨线程的 key-value但整体还是偏基础没有 Mem0 那种记忆提取、更新、遗忘的完整闭环。所以我的建议是LangGraph Checkpoint 该用就用它解决工作记忆但长期记忆还是老老实实接一套独立的记忆系统。2.5 Cognee把记忆做成结构化知识管线Cognee 的定位稍微不同它更像是一个“记忆构建管线”从原始文档、对话记录里抽取实体、概念、关系然后构建成知识图谱和向量索引最终给 Agent 提供结构化查询能力。如果你的 Agent 需要的是“基于知识库的推理”而不是“记住用户说了什么”Cognee 会比普通 RAG 工具更合适。我在一个文档问答项目里用 Cognee 做过知识抽取它的实体识别准确率还算能打缺点是配置文件比较多上手曲线比较陡。2.6 其他值得记录的项目Memary把记忆划分为短期、长期和反思层用知识图谱组织设计理念很清晰适合做用户画像型 Agent。LangMemLangChain/OpenAI 团队出的记忆工具包通过“提取、修剪、固化”三条管道管理记忆和 LangGraph 生态结合紧密。SuperMemory更偏个人知识库记忆当年号称“ChatGPT 记忆插件”适合做私人笔记助手不太适合做通用 Agent 组件。3. 多维对比五个关键维度给出结论纸上谈兵没意思我把五个方案真正部署了一遍从五个维度做了对比。这里的结论都是基于我自己的测试环境可能和官方宣传的数据有差异但我尽量做到客观把测试条件和限制说清楚。3.1 存储与索引向量库、图数据库、KV 的战场存储层的选型决定了记忆系统的能力边界。Mem0 默认走向量库落地最简单。Qdrant 一个 docker 就能拉起来pgvector 可以复用现有 PostgreSQL基本没有额外学习成本。向量索引擅长做“语义相似”但细粒度的关系查询就要靠 LLM 二次加工。Zep 用图数据库回忆逻辑强很多比如“用户上周提到的技术栈和今天的话题有没有关联”图遍历可以直接给出路径。但图数据库的运维门槛真的不低如果团队里没人懂 Neo4j我建议慎重。Letta 的存储比较轻主要靠自带的 SQLite/PostgreSQL 保存记忆块和指针文件配合嵌入模型做检索。它不追求对复杂关系的建模更看重“记忆块怎么调度到上下文”。LangGraph Checkpoint 是 KV/文档型存储按 thread_id 存状态快照完全不涉及语义索引。它只负责“状态恢复”不管“语义召回”。Cognee 是混合型图谱和向量都做数据先入图再入向量两边同步。这个方案在理论上最全面但你得同时维护两套存储资源消耗和复杂度都偏大。3.2 检索策略相似度搜索、图遍历、混合检索哪种好用这一块直接影响用户体感。Mem0 的检索采用“向量相似度 LLM 相关度排序”的组合。第一次召回先拿 Top-20 候选过 LLM 打分后保留 Top-3准确率明显比单纯向量搜索高。缺点是引入 LLM 调用后每次检索会有几百毫秒额外延迟成本也上去了。Zep / Graphiti 是图先行的检索按实体邻域和时间窗口做遍历时间复杂度低结果稳定不会出现“向量搜到八竿子打不着的内容”这种尴尬。它有一套基于时间衰减的边权重机制近期记忆天然排前面。Letta 的检索更像“虚拟内存分页”Agent 自己决定加载哪块记忆块从磁盘回到上下文。这套机制灵活但对于那些依赖确定性检索的开发者来说你没法预测它也下一次会换入什么。LangGraph Checkpoint 的“检索”就是按 thread_id 取状态没有语义检索。Cognee 则是图谱过滤加向量召回的混合先在图谱里拿相关子图再把子图内的文本向量化去配权重。3.3 上下文压缩与遗忘机制谁能主动“断舍离”记忆系统最怕的就是无限膨胀。我到后期测试发现如果只存不删再强的检索也会被噪声淹没。Mem0 有清理机制每条记忆会有更新时间、访问次数超过阈值或者被用户新信息覆盖就会被标记为“已过期”并移出活跃集。这个机制是 LLM 驱动的清理决策有语义判断不会误删关键信息。Zep 靠时间衰减实现软遗忘旧关系的权重越来越低检索时即便命中也不会排到前面相当于“自然遗忘”。我觉得这个设计非常优雅命中了一条旧记忆但权重很低比直接删掉更符合人类记忆规律。Letta 的上下文管理由 Agent 自己做它通过自我反思决定“这个记忆块应该被丢弃还是归档”。效果好不好很大程度取决于模型本身的判断力实测中 GPT-4 级别的模型表现良好换成开源小模型就有点不稳。Cognee 有显式的“审计/清理”工具算是半自动。LangGraph Checkpoint 不做语义清理状态存了就存了过期靠你自己删。3.4 框架集成与工程成熟度最简单的判断方式是看它怎么融入 LangGraph、LangChain、LlamaIndex 这些主流程。Mem0 提供了现成的 LangChain/LlamaIndex 集成还支持 OpenAI Agents SDK基本就是“装包 写两行配置”的事。我自己从零接入到跑通只用了两个小时这是它最吸引人的地方。Zep 有官方 Python/TypeScript SDK接口设计得也还可以但因为底层是图数据库接入前必须先把它管理的图谱 schema 设计好否则后续查询会很别扭。Letta 自成体系你可以把它当成独立 Agent 运行时用但想塞进 LangGraph 流程就基本不可能生态封闭性较高。Cognee 的集成是管线式 API输入文档、输出记忆适合用批处理任务去调。LangGraph Checkpoint 则只和 LangGraph 本身绑定别无分店。3.5 成本、自托管难度与社区健康度如果我做项目评估一般会看三件事部署成本、维护成本、社区活跃度。Mem0 自托管最轻量一个向量库加一个 Python 服务就够CPU 资源吃紧的小机器也能跑。社区非常活跃Issue 响应快遇到问题基本在 GitHub 上搜一圈就有答案。Zep 默认依赖 Neo4j如果你没有现成图数据库经验起步会比较痛苦一旦跑起来日常维护主要还是图索引的优化ES 级别的调优经验在这里同样适用。Letta 有一体化 Docker 镜像部署简单但它需要相对强的算力跑记忆压缩任务小内存机器跑起来比较吃力。Cognee 部署中等文档繁杂社区热度一般。LangGraph Checkpoint 部署零成本但它的能力边界很窄社区讨论基本都是围绕 LangGraph 本身展开的。3.6 一个不算严谨但很直观的对比表项目记忆类型存储索引检索方式遗忘机制接入难度适用场景Mem0长期/情景向量库语义相似 LLM 重排增量合并/过期清理低通用 Agent 增强记忆Zep / Graphiti长期/情景时间感知知识图谱图遍历 时间权重时间衰减中高知识密集、关系复杂场景Letta / MemGPT全类型SQLite/PostgreSQL记忆分页自动调度Agent 自我反思中自主长时间运行的 AgentLangGraph Checkpoint工作记忆KV/文档存储按 thread_id 恢复手动清理低LangGraph 流程状态持久化Cognee长期/知识库图谱 向量图过滤 向量混合半自动中高文档知识抽取与推理这个表我建议保存下来做技术方案预选型的时候可以直接对照着划掉没必要的选项。4. 一个可以直接复制的组合LangGraph Mem0 Qdrant光说不练假把式。我把自己跑通并且现在还在用的一个组合分享出来Agent 编排走 LangGraph长期记忆接 Mem0向量库用 Qdrant。这套组合最稳也是社区沉淀最多的搭配。4.1 为什么选这个组合LangGraph 负责把 Agent 的思考流程拆成节点比如“意图识别 → 记忆检索 → 调用工具 → 生成回复”。Mem0 负责在“记忆检索”节点里提供长期记忆让 Agent 能回忆起用户几天前说过的话。Qdrant 只是 Mem0 的底座换 PostgreSQL 的 pgvector 也一样我选 Qdrant 纯粹是因为它容器化部署最简单监控面板也直观。4.2 先把基础设施跑起来Qdrant 用一行 docker 指令就能启动docker run -d --name qdrant -p 6333:6333 qdrant/qdrantMem0 我建议用 pip 安装官方 Python 包它支持“独立服务模式”和“嵌入式模式”。嵌入部署最省事同一个进程里直接调 APIpip install mem0ai openai如果你要从零开始还需要准备嵌入模型。Mem0 默认走 OpenAI 的 embedding但国内团队用阿里、智谱、OpenAI 的都见过。我自己为了省钱换了本地开源的 bge-m3用 sentence-transformers 加载效果也没差太多。4.3 核心代码写记忆、读记忆、更新记忆下面这段是我实际项目里摘出来的去掉业务逻辑之后保留了核心调用链。from mem0 import Memory # 初始化 Mem0向量存储指向本地 Qdrant m Memory.from_config({ llm: { provider: openai, config: { model: gpt-4o-mini, temperature: 0 } }, embedder: { provider: huggingface, config: { model: BAAI/bge-m3 } }, vector_store: { provider: qdrant, config: { host: localhost, port: 6333, collection_name: agent_memory } } }) # ------------------- 记忆写入 ------------------- # 每次用户说话后调用 add 提取值得保存的记忆 result m.add( 用户偏好使用 Python 和 FastAPI正在做一个开源 Agent 项目计划两周后发布 v1.0, user_iduser_12345, metadata{source: chat, session_id: s_67890} ) print(result) # 输出哪些记忆被新增、更新、删除 # ------------------- 记忆检索 ------------------- # 生成回答前先检索和当前问题相关的历史记忆 related m.search( 用户做的是什么技术栈的项目, user_iduser_12345, limit3 ) print(related)在 LangGraph 里接的时候我把它设计成一个remember_nodefrom langgraph.graph import StateGraph, END, START from langgraph.graph.message import add_messages from typing import Annotated, TypedDict class AgentState(TypedDict): messages: Annotated[list, add_messages] memory: dict async def remember_node(state: AgentState): query state[messages][-1].content related m.search(query, user_iduser_12345, limit3) # 把检索到的历史记忆拼到上下文中 memory_block \n.join([r[memory] for r in related]) return {memory: {related: memory_block}}关键在于不要每一次都把所有记忆往 prompt 里塞只塞检索召回的最相关的 3 条上下文干净token 成本也低。4.4 参数调优的几个心得limit 别贪多我刚开始设置 limit10以为召回越多越好结果模型被不相关的记忆干扰回答质量反而下降。后来压到 3 条效果好很多。user_id 一定要按业务隔离多用户场景下如果漏了 user_idA 用户的记忆可能被 B 用户检索到这是隐私事故级别的问题。metadata 里带上时间给每条记忆打上一级时间戳后续做时间衰减、做 Zep 那种“最近优先”的逻辑才有数据支撑。温度设为 0记忆提取和检索重排都是判断类任务温度高了会导致提取结果不稳定同样的话这次提取一条下次提取两条。4.5 从 Demo 到生产还差三步第一加一层异步写入。对话过程中同步调用add()会拖慢首字响应改成把对话日志先发消息队列异步消费后再写进记忆系统。我用的 Redis Stream 比较简单几百人在线没问题。第二做记忆审计。给记录维护每次写入的来源和置信度来源分为“用户主动声明”“Agent 推断”“历史对话提取”。审计表能极大帮助纠错用户说“我其实不是后端程序员”的时候可以直接把错误记忆标记失效。第三定期做“记忆合并压缩”。Mem0 的 add 方法本身会触发增量更新但每周最好跑一次离线批量任务把分散的碎片记忆合并成大块记忆性能会显著改善。5. 常见问题与排查技巧实录下面这些都是我真实遇到、并且在社区里也被反复讨论的问题。每个方案、每个组合都有各自的脾气这块总结比原理部分更值得细看。5.1 记忆写入太多、太碎污染严重刚开始用 Mem0 时我提取到的记忆全是“用户今天说了句好的”“用户发了一个表情包”这种垃圾内容。问题出在提取阈值的设置上。Mem0 有一个infer参数控制是否让 LLM 判断记忆重要性默认在某些版本是开启的但如果你用的模型能力不行它没办法区分“闲聊”和“关键信息”。我后来做了一层硬性过滤内容长度少于 10 个字的直接不保存文本里没有实体词技术栈、人名、时间、偏好动词的不保存。另外短期高频出现的内容会不断触发更新导致“同一件事存了 50 条”。我在生产环境加了“记忆合并窗口”一小时内相同主题的对话以最后一条为准保存前先检索一遍是否已有近似记忆有就直接更新不新增。5.2 检索不准始终差一口气如果你发现记忆系统总是唤不起真正有用的内容先别急着怪系统。按这个顺序排查嵌入模型是否适配你的领域通用 embedding 对专有名词不敏感换成领域微调的 embedding或者用 LLM 做二次重排提升最明显。检索的 query 是否完整用户可能只说“那个项目怎么样了”这种 query 直接去向量库搜基本搜不到有效记忆。正确做法是先让 Agent 把 query 做扩展改写成包含实体和时间线索的完整句再去检索。是否做了时间衰减纯向量检索没有时间概念两周前的记忆和昨天的记忆权重一样这对情景记忆是致命的。至少要手动加一个时间因子对旧记忆降权。5.3 多用户、多会话场景下的数据串线这是所有记忆系统最危险的问题。我测试 Zep 的时候因为 Session 和 User 的关系没有理清楚出现过用户 B 在对话里“想起”了用户 A 的项目细节。后来我们强制规定user_id是业务用户的唯一标识必须由业务方传入禁止从消息内容里推断。session_id只是线程标识默认不跨用户共享。所有检索入口先按 user_id 做数据权限过滤再进入语义检索不能只依赖向量相似度做隔离。这条规则适用于 Mem0、Zep、Letta所有记忆方案都得遵守。5.4 上下文窗口被历史记忆撑爆有些开发者说“我加记忆系统之后token 消耗反而上去了”大概率是把记忆模块的输出全量拼到了 system prompt。正确做法是分两层短期会话内只塞最近 2 轮对话靠 LangGraph 的状态管理就够了。长期记忆只塞检索召回的 Top-3 到 Top-5每条压缩成一句话摘要。记忆系统应该是“外挂索引”不是“全量搬运工”。把记忆当 prompt 的一部分无脑拼接是很多 Agent 项目的通病。5.5 记忆安全我踩过的合规坑最后必须聊一个很多人不注意的点记忆系统是最容易泄露隐私的组件。你让 Agent 记住用户偏好同时也意味着你要保存这些数据而这些数据可能包含手机号、公司内部信息。我现在的做法是敏感字段脱敏后再写入记忆比如手机号中间四位打码。记忆数据加密存储至少要用 TLS 传输存储端做静态加密。提供“删除记忆”接口用户可一键清空这是很多主流产品的合规硬要求。我之前在一个内部项目中把未脱敏的用户日志直接灌进了记忆系统后来做安全巡检的时候差点出问题。从那时起所有记忆写入前都要过一遍脱敏规则宁可损失一些召回精度也不能在合规上留下隐患。6. 最后再分享一点个人体会测试完这五个方案我的一个强烈感受是开源 Agent 记忆系统目前没有“银弹”。Mem0 均衡易用Zep 推理更强Letta 适合自主 AgentLangGraph Checkpoint 是框架必备Cognee 适合做知识管线。选型一定是从自己的场景出发先确认要解决的是“跨会话记住偏好”还是“复杂关系情景推理”再选方案不要被 star 数量带着走。如果让我给刚入坑的人一个最省心的建议先用 LangGraph 做编排用 Mem0 做长期记忆向量库选 qdrant 或用已有的 pgvector。这套组合稳定性高、社区活跃、遇到问题有大量现成答案。等你的项目真的发展到需要关系推理、可解释召回的时候再考虑上 Zep/Graphiti 也不迟。记忆系统是 Agent 能力提升的关键一环但它不是越复杂越好。先把基础链路跑通让记忆闭环转起来再慢慢沉淀属于你自己的最佳实践。