资讯动态

Agent长期记忆实战:六大主流方案对比与选型指南

发布时间:2026/10/26 18:15:49 来源:尧图企业网站定制
1. 为什么 Agent 的“长期记忆”是个绕不开的硬骨头做 Agent 开发的朋友大概率都经历过这个场景你精心调好了一个对话助手聊到第十轮的时候它突然把你第一轮说过的关键信息忘得一干二净回答开始跑偏甚至自相矛盾。这不是模型不够聪明而是它的“记忆”机制出了问题。大语言模型本身是无状态的每次调用都是一次全新的推理它不会自动记住你上一句说了什么。我们平时用到的“上下文窗口”本质上只是短期记忆——把历史对话拼接到 prompt 里一起送进去。但上下文窗口有长度限制token 消耗也是真金白银更麻烦的是当对话轮次一多早期信息会被稀释甚至截断。所以长期记忆成了 Agent 从“玩具”走向“可用产品”的关键分水岭。所谓 Agent 长期记忆说白了就是让 Agent 能够跨会话、跨时间地存储、检索、更新和遗忘信息。它要解决的核心问题有三个存什么哪些信息值得记、怎么存用什么结构组织、怎么取在需要的时候精准召回。这三个问题看起来简单但真正落地时会牵扯出向量检索、知识图谱、记忆衰减、冲突消解等一系列工程难题。目前市面上围绕 Agent 记忆已经涌现出一批有代表性的项目比如 Mem0、Zep、Graphiti、Letta原 MemGPT、LangMem、Memary 等。它们的设计思路差异很大有的走向量数据库路线有的押注知识图谱有的干脆把记忆管理做成一个操作系统。我花了不少时间把这几个主流方案都跑了一遍也踩了不少坑这篇文章就把它们的设计思路、核心机制和实操要点掰开揉碎讲清楚适合正在做 Agent 应用开发、需要给产品加记忆能力的同学参考。2. 六个主流记忆项目的整体设计思路拆解在深入每个项目之前先建立一个全局认知Agent 记忆系统的设计本质上是在结构化程度和检索效率之间做权衡。结构化程度越高比如知识图谱信息之间的关系越清晰但构建和维护成本也越高结构化程度越低比如纯向量存储写入快、实现简单但检索精度和关系推理能力会打折扣。2.1 记忆系统的三种主流架构范式我把目前主流方案归纳为三种范式理解这三类基本就能看懂所有项目的设计取向。第一种是向量存储范式代表项目是 Mem0 的早期版本和 LangMem。核心思路是把每段记忆转成 embedding 向量存进向量数据库检索时用相似度匹配。优点是实现简单、写入快、天然支持语义检索缺点是缺乏关系推理能力容易召回语义相似但实际无关的内容而且记忆之间的时序和因果关系很难表达。第二种是知识图谱范式代表项目是 Zep 和 Graphiti。它把记忆拆成实体和关系构建成图结构检索时可以做多跳推理。优点是关系表达能力强、时序清晰、支持复杂查询缺点是构建成本高需要实体抽取和关系抽取写入延迟明显高于向量方案。第三种是分层记忆范式代表项目是 LettaMemGPT和 Memary。它模仿操作系统的内存管理把记忆分成核心记忆、工作记忆、归档记忆等层级通过一套调度机制在层级之间搬运信息。优点是贴近人类记忆的工作方式能平衡上下文窗口和长期存储缺点是调度逻辑复杂调参空间大。2.2 选型时真正该关注的四个维度很多人选记忆方案时只看“支持不支持向量检索”这其实太片面了。根据我的实操经验下面四个维度才是决定项目能不能用的关键。维度关键问题影响写入延迟单条记忆写入耗时多少影响实时对话体验检索精度召回内容与查询的相关性决定 Agent 回答质量关系推理能否处理多跳、时序问题影响复杂场景表现维护成本是否需要额外服务、调参难度决定落地可行性举个具体例子如果你做的是一个客服 Agent用户问题大多是单跳的事实查询“我的订单到哪了”那向量方案完全够用没必要上知识图谱。但如果你做的是一个个人助理 Agent需要理解“我上周提到的那个项目和我今天说的这个需求有什么关系”那就必须要有关系推理能力知识图谱方案更合适。2.3 一个容易被忽略的点记忆的“遗忘”机制大部分项目在宣传时都在讲“记得多”但真正决定体验的往往是“忘得对”。人类记忆会自动衰减不重要信息Agent 也一样。如果所有信息都无差别存储检索时噪声会越来越大最终拖垮回答质量。Mem0 在这方面做得比较细它有一套基于重要性和时效性的打分机制低分记忆会被降权甚至清理。Zep 则通过时序图谱天然支持“时间衰减”越久远的关系权重越低。而一些简单方案压根没有遗忘机制用久了记忆库就变成垃圾场。这一点在选型时一定要重点考察。3. 核心项目深度解析与实操要点这一章我逐个拆解几个代表性项目重点讲它们的设计精髓和实际使用中的关键细节。3.1 Mem0把记忆做成一个可插拔的中间层Mem0 的定位很清晰——它不想取代你的 Agent 框架而是作为一个记忆中间层插在模型和存储之间。它的核心 API 就两个add和search用起来非常轻。Mem0 的记忆提取流程是这样的当你调用add时它会把对话内容送给 LLM让模型判断哪些信息值得记住然后抽取成结构化的记忆条目fact再存入后端存储。检索时它同时走向量检索和元数据过滤返回最相关的记忆。from mem0 import Memory m Memory() # 添加记忆 m.add(我喜欢喝美式咖啡不加糖, user_iduser_001) # 检索记忆 results m.search(用户喜欢喝什么, user_iduser_001) print(results)这里有个实操要点Mem0 的记忆抽取质量高度依赖你用的 LLM。我试过用不同模型跑同样的对话抽取出的记忆条目差异很大。用能力强的模型它能准确识别出“用户偏好”这类值得记的信息用弱模型它可能把寒暄也当成记忆存进去。所以生产环境建议用能力较强的模型做抽取。另一个坑是user_id 和 agent_id 的隔离。Mem0 支持多用户、多 Agent 的记忆隔离但如果你在调用时忘了传对应的 id记忆就会串。我踩过一次测试时两个用户的记忆混在一起排查了半天才发现是 id 没传对。3.2 Zep时序知识图谱的重量级选手Zep 是我个人比较欣赏的一个项目它的核心是Graphiti——一个专门为 Agent 记忆设计的时序知识图谱引擎。和传统知识图谱不同Graphiti 的每条边都带时间戳这意味着它能回答“用户上个月说过什么”这类时序问题。Zep 的记忆构建流程分三步实体抽取、关系抽取、图谱写入。当你写入一段对话它会先用 LLM 抽取出其中的实体人、事、物和关系然后在图谱中创建节点和边。检索时它支持语义检索、关键词检索和图遍历三种方式的组合。from zep_cloud.client import Zep client Zep(api_keyyour_key) # 创建 session client.memory.add_session(session_idsession_001, user_iduser_001) # 添加记忆 client.memory.add(session_idsession_001, messages[...]) # 检索 memory client.memory.get(session_idsession_001)Zep 的强项在于关系推理。比如你问“和我上次提到的那个朋友一起吃饭的地方在哪”它能通过图谱找到“朋友”这个实体再找到关联的“餐厅”实体最后定位到具体地点。这种多跳查询是向量方案做不到的。但代价也很明显写入延迟高。因为每次写入都要调 LLM 做实体和关系抽取一条记忆的写入可能要几秒。如果你的场景是高频实时对话这个延迟会很难受。我的建议是异步写入不要阻塞主对话流程。3.3 GraphitiZep 背后的图谱引擎也可以单独用Graphiti 是 Zep 团队开源的时序知识图谱框架可以独立于 Zep 使用。如果你不想用 Zep 的云服务又想享受图谱记忆的能力Graphiti 是个不错的选择。Graphiti 最核心的设计是双时间轴每条记忆既有“事件发生时间”又有“信息写入时间”。这个设计解决了一个很实际的问题——当用户更正之前说过的信息时系统能知道哪个版本更新。比如用户先说“我住在北京”后来说“我搬到上海了”双时间轴能正确表达这个变更而不是简单覆盖。from graphiti_core import Graphiti graphiti Graphiti(neo4j://localhost:7687, neo4j, password) # 添加 episode await graphiti.add_episode( nameuser_moved, episode_body用户从北京搬到了上海, source_descriptionconversation, reference_timedatetime.now() )实操中要注意的是Graphiti 依赖 Neo4j 作为图存储后端你需要自己部署 Neo4j 实例。这对小团队来说是个额外的运维负担。另外实体抽取的 prompt 需要针对你的领域做调优通用 prompt 在垂直领域效果会打折扣。3.4 LettaMemGPT把记忆当操作系统来管Letta 的前身是 MemGPT它的设计理念非常有意思——把 LLM 当成 CPU把上下文窗口当成内存把外部存储当成硬盘。Agent 通过一套“函数调用”机制主动在内存和硬盘之间搬运信息。Letta 把记忆分成几个层级核心记忆始终在上下文里存放关键人设和用户信息、对话记忆当前会话历史、归档记忆长期存储按需检索。Agent 可以自己决定什么时候把信息从归档记忆调入核心记忆什么时候把不重要的信息踢出去。这个设计的精妙之处在于它让 Agent 有了自主管理记忆的能力而不是被动地依赖外部检索。但代价是复杂度高你需要理解它的记忆调度逻辑还要调教 Agent 学会正确使用记忆工具。3.5 LangMemLangChain 生态的原生记忆方案如果你已经在用 LangChain 或 LangGraphLangMem 是最顺手的选项。它和 LangGraph 的 state 机制深度集成记忆的读写都通过 graph 的节点来完成。LangMem 支持两种记忆类型语义记忆事实性知识和程序性记忆Agent 的行为模式。它提供了create_manage_memory_tool和create_search_memory_tool两个工具直接挂到 Agent 上就能用。from langmem import create_manage_memory_tool, create_search_memory_tool manage_tool create_manage_memory_tool(namespace(memories,)) search_tool create_search_memory_tool(namespace(memories,)) agent create_react_agent( anthropic:claude-3-5-sonnet-latest, tools[manage_tool, search_tool], )LangMem 的优势是生态整合好缺点是相对年轻一些高级功能比如记忆冲突消解还在迭代中。如果你的项目对记忆精度要求极高可能需要自己补一些逻辑。3.6 Memary轻量级的开源记忆层Memary 是一个相对小众但设计简洁的开源项目它的思路是用知识图谱 向量检索的混合方案但实现比 Zep 轻量很多。它不需要复杂的图数据库用本地存储就能跑起来适合快速验证和小规模部署。Memary 的记忆检索会同时走向量相似度和图关系两条路然后做结果融合。这个混合策略在实测中比纯向量方案召回质量高不少尤其是在处理“关联性查询”时。4. 实操过程与核心环节实现光讲设计思路不够这一章我把一个完整的记忆系统搭建过程走一遍用 Mem0 向量库的组合做示范因为这套方案最容易复现。4.1 环境准备与依赖安装先明确技术栈Python 3.10、Mem0、Qdrant 作为向量存储后端、OpenAI 或兼容的 LLM 接口。pip install mem0ai qdrant-client openaiQdrant 我选择用 Docker 起一个本地实例这样数据可控调试也方便。docker run -p 6333:6333 -v $(pwd)/qdrant_storage:/qdrant/storage qdrant/qdrant这里有个细节向量维度要和 embedding 模型对齐。如果你用 OpenAI 的 text-embedding-3-small维度是 1536如果用其他模型维度可能不同。Qdrant 在创建 collection 时会自动推断维度但如果你手动创建一定要确认维度匹配否则写入会报错。4.2 记忆写入流程的完整实现写入是记忆系统的入口这一步的质量直接决定后续检索效果。我把它拆成四个环节。第一个环节是内容预处理。原始对话往往包含大量噪声比如“嗯”“好的”“哈哈”这类无意义内容。直接丢给记忆系统会浪费存储和 token。我的做法是先做一轮轻量过滤把明显无信息量的内容剔除。第二个环节是记忆抽取。Mem0 内部会调 LLM 做这一步但你可以通过自定义 prompt 来优化抽取效果。比如针对客服场景你可以让模型重点抽取“用户诉求”“订单信息”“情绪状态”这几类。第三个环节是去重与冲突检测。这是很多人忽略的一步。如果用户反复说同一件事记忆库里会堆积大量重复条目。Mem0 内置了简单的去重逻辑但对于“信息更新”场景用户改了口它处理得不够好。我的做法是在写入前先检索一遍相似记忆如果发现冲突就标记旧记忆为失效。第四个环节是写入存储。这一步要注意批量写入和异步处理避免阻塞主流程。import asyncio from mem0 import Memory config { vector_store: { provider: qdrant, config: { host: localhost, port: 6333, collection_name: agent_memory } } } m Memory.from_config(config) async def add_memory_async(content, user_id): # 异步写入不阻塞主对话 await asyncio.to_thread(m.add, content, user_iduser_id)4.3 检索策略的调优过程检索是记忆系统的出口也是最需要调优的部分。我总结了几个关键参数。top_k 的选择返回多少条记忆。太小会漏掉关键信息太大会引入噪声。我的经验值是 5-10 条具体看场景。事实查询类场景 3-5 条够用需要综合多信息的场景可以到 10 条。相似度阈值低于阈值的记忆直接丢弃。这个阈值需要根据你的 embedding 模型实测确定。我一般从 0.7 开始试逐步调整。重排序向量检索返回的结果顺序不一定最优可以加一层 rerank。用一个小的交叉编码器模型对候选记忆重新打分能明显提升精度。def search_with_rerank(query, user_id, top_k10, threshold0.7): # 先粗召回 candidates m.search(query, user_iduser_id, limittop_k * 2) # 过滤低分 filtered [c for c in candidates if c[score] threshold] # 重排序这里用简单的分数排序示意实际可接 rerank 模型 reranked sorted(filtered, keylambda x: x[score], reverseTrue) return reranked[:top_k]4.4 记忆注入到 Agent 的完整链路检索出来的记忆怎么用最直接的方式是拼接到 system prompt 里。但要注意 token 预算不能把所有记忆都塞进去。我的做法是分两步先做记忆摘要把检索到的多条记忆压缩成一段简洁的上下文再按优先级注入核心记忆放前面次要记忆放后面超出预算的截断。def build_prompt_with_memory(query, user_id): memories search_with_rerank(query, user_id) memory_context \n.join([f- {m[memory]} for m in memories]) system_prompt f你是一个有记忆的助手。 以下是关于用户的已知信息 {memory_context} 请基于这些信息回答用户问题。 return system_prompt实测下来这种注入方式比直接把原始对话历史塞进去效果好很多token 消耗也低。5. 常见问题与排查技巧实录这一章是我踩坑最多的部分整理成速查表希望能帮你少走弯路。5.1 记忆检索不准的排查思路检索不准是最常见的问题表现是 Agent 答非所问或者明明存过的信息检索不出来。排查时按这个顺序走。现象可能原因排查方法完全检索不到写入失败或 id 不匹配检查存储里是否有数据确认 user_id 一致检索到无关内容相似度阈值过低提高阈值加 rerank检索到旧信息缺少冲突消解检查是否有重复/过期记忆语义匹配但事实错误embedding 模型不适配换用领域适配的 embedding我遇到过一个典型问题用户问“我上次说的那个餐厅”检索出来的却是另一个餐厅。原因是两个餐厅的 embedding 很接近向量检索分不出来。后来加了元数据过滤按时间、按地点才解决。这告诉我一个道理纯向量检索在需要精确区分的场景下不够用必须结合元数据或图谱。5.2 记忆膨胀与性能下降的应对用久了记忆库会越来越大检索变慢噪声变多。这是所有记忆系统都会遇到的问题。我的应对策略有三条。第一是定期清理把长期未被检索到的记忆归档或删除。第二是记忆合并把语义重复的条目合并成一条。第三是分层存储热记忆放快速存储冷记忆放慢速存储按需加载。Zep 和 Graphiti 在这方面有天然优势因为图谱结构本身就支持按时间衰减权重。而纯向量方案需要你自己实现这套逻辑。5.3 多用户多 Agent 场景的隔离问题生产环境往往是多用户、多 Agent 并存记忆隔离做不好会出大问题。我见过最严重的一次是 A 用户的记忆被 B 用户检索到直接导致隐私泄露。隔离的关键是命名空间设计。Mem0 用 user_id agent_id run_id 三级隔离Zep 用 session_id user_id。你在设计时要提前规划好隔离维度不要等到出问题才补。提示测试阶段一定要用两个不同的用户账号交叉验证确认记忆不会串。这个测试花不了几分钟但能避免上线后的重大事故。5.4 记忆写入延迟的优化技巧知识图谱类方案写入慢是通病。我的优化经验是把写入拆成同步和异步两部分。同步部分只做最轻量的操作比如把原始内容存进队列异步部分再做实体抽取和图谱构建。这样用户感知到的延迟就很低。另外实体抽取的 LLM 调用可以批量化。把多条待处理记忆攒一批一起送进去比一条一条调用的吞吐量高好几倍。6. 几个项目横向对比与选型建议讲了这么多最后落到选型上。我把几个项目的关键指标整理成表方便你对照自己的场景做决定。项目架构范式写入延迟关系推理部署复杂度适合场景Mem0向量为主低弱低快速落地、单跳查询Zep时序图谱高强中复杂关系、时序查询Graphiti时序图谱高强中高需要自建图谱Letta分层记忆中中中需要 Agent 自主管理LangMem向量为主低弱低LangChain 生态Memary混合中中低轻量验证选型的核心逻辑是先看你的查询复杂度再看你的运维能力。如果查询大多是单跳事实向量方案足够别过度设计。如果查询涉及多跳关系和时序那知识图谱是刚需多花点运维成本值得。如果团队小、想快速验证从 Mem0 或 LangMem 起步跑通了再考虑升级。我个人在实际项目中的体会是没有银弹混合方案往往是最终答案。我现在的做法是用向量存储做快速召回用轻量图谱做关系补充两者结合。这样既保证了响应速度又兼顾了关系推理。当然这套方案的复杂度也上去了需要根据团队情况权衡。最后分享一个小技巧记忆系统的效果评估一定要建立评测集。我一开始靠感觉调参调来调去没方向。后来建了一个包含 100 条查询的评测集每条标注了期望召回的记忆每次调参跑一遍看准确率和召回率效率高了很多。这个评测集不用很复杂但一定要有否则你根本不知道改动是变好还是变坏。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑