Agent长期记忆设计实战:六大方案对比与选型建议 做了大半年Agent应用我被问得最多的一个问题不是工具调用也不是并发而是——你这Agent怎么聊两句就失忆了要聊清楚这个话题就必须把Agent长期记忆的设计思路掰开揉碎讲一遍。这篇内容是我们团队把这大半年里对比过的六个主流项目从MemGPT到Mem0从LangChain到Graphiti逐一复盘后的浓缩版适合正在做Agent应用、正准备上长期记忆功能、或者只是好奇Agent到底能不能记住事的人。1. 先看清问题Agent为什么普遍记性不好很多刚接触Agent开发的人第一步想到的是把对话历史一股脑塞进上下文然后发现Agent依然答非所问。其实这不怪模型而是我们对记忆这件事的理解从一开始就是错的。1.1 上下文窗口不是内存只是短期工作台要理解长期记忆先要破除一个常见误解大模型的上下文窗口再大也不是内存。上下文窗口更像是你桌面上的白纸——你可以在上面写很多东西但一关电脑、换一个会话这张纸就清空了。即便你用了支持超大上下文的模型把两小时前的一段重要约定一直放在窗口里也会遇到两个问题放得下不等于找得回。窗口里塞满了对话原文Agent在需要某个信息时未必能精准找到反而被大量无关内容干扰导致回答跑偏。成本随窗口长度线性上涨。长上下文并不是免费的很多场景下你每轮都把历史全量喂给模型费钱且响应变慢。大模型本身的无状态是原生缺陷每次调用都是一次全新的对话模型并不知道自己上个回合说过什么。所以我们需要在模型外面加一层记忆系统。长期记忆本质上不是模型能力而是工程问题——你需要在模型之外设计一套写、存、读、更新的机制让Agent在合适的时机把关键信息放进仓库又在合适的时机把它们搬到桌面上。1.2 长期记忆要回答的三个问题我看过不少方案也自己动手搭过发现不管怎么设计万变不离三个核心问题记什么是存原始对话还是存摘要是提取用户偏好、实体、事实还是把知识文档也纳入记忆什么时候记、什么时候读是每一轮都写还是后台异步定期处理读取时是全量注入还是按需检索或者让Agent自己决定调用怎么更新、怎么忘推进一个新事实时旧记忆是该被覆盖还是共存记忆会不会过期用户说我不喜欢这个时系统能不能把之前的对立偏好正确处理掉这三个问题就是下面六个方案最主要的差异点。你能看到有的方案在记什么上做文章有的在什么时候记上做文章有的在怎么更新上下足了功夫各有各的侧重点。1.3 评价记忆系统的六个维度后续选型时我会反复用这六个维度去衡量具体方案先列出来方便你对照维度要回答的问题容量能存多少历史而不崩溃精度取回的信息是否准确、够细新鲜度能不能感知记忆已经过期成本存储、检索、token消耗是否可控可控性开发者能不能干预写入和读取接入成本落地到自己项目要花多少精力你不可能六个维度全都要不同项目取舍不同。接下来要拆解的六套方案本质上是这六个维度上的不同取舍组合。看清了取舍你就明白为什么没有最好的记忆方案只有最合适的记忆方案。2. 六路方案全景名字、流派与一句话定位我筛选了六个有代表性、社区讨论度高的项目或思路MemGPT现在的Letta、LangChain系Memory模块加LangMem、Mem0、Zep系Graphiti、Cognee以及最常被拿来自建的RAG向量记忆。先给一个速览表后面逐节拆。2.1 一句话定位项目/体系核心思想存储介质典型读取方式MemGPT / Letta把上下文当物理内存用虚拟内存机制换入换出外部JSON存储上下文管理LLM自己调用函数读写LangChain Memory LangMem框架内提供多种记忆策略SDK实现提取内存/向量库/图存储自动注入检索结果Mem0提取-存储-合成三层记忆流水线向量库语义检索聚合记忆体Zep / Graphiti带时间戳的时序知识图谱图数据库图谱查询时间窗口Cognee图谱向量的混合记忆引擎向量库图库语义检索/图遍历RAG自建向量记忆把历史对话切片向量化检索注入向量库top-k检索2.2 五大流派细看下来表面六个名字背后其实是五条路线操作系统派代表性就是MemGPT/Letta。核心思路是让Agent像操作系统管理物理内存一样管理自己的上下文。模型需要什么记忆就通过函数调用去外部存储拿拿完放回用完换出。框架派LangChain/LangMem这类思路是把记忆作为开发框架的标准化模块不管是Buffer还是Summary还是向量检索都给你封装好你来配置。数据管道派以Mem0为代表。它不依赖模型自主决定而是用一套独立的提取-去重-更新-存储流水线把记忆当成数据库来管理主动从对话里挖掘结构化记忆。知识图谱派Zep/Graphiti和Cognee都偏向知识图谱。前者强调时序图谱后者强调与语义记忆结合。它们的共同点是不仅要知道发生过什么还想知道谁和谁有什么关系。检索增强派把长期记忆简化为向量检索问题靠语义相似度取回相关历史。这是最容易被理解、也最容易自己动手的一档。这五派没有绝对优劣但有一个共性值得先点出来长期记忆不是存得越多越好而是在正确的时间找回正确的内容。接下来我会重点讲清楚每一派的实际取舍以及它们各自适合什么场景。3. MemGPT / Letta让Agent自己管理换入换出3.1 为什么想到把操作系统搬进来MemGPT之所以叫Mem是因为它把大模型上下文窗口类比成操作系统的物理内存把外部存储类比成虚拟内存。这个类比非常精准物理内存小、速度快、一断电就清空虚拟内存大、速度慢、持久化。LLM的上下文窗口恰好就是那块又小又快又一次性的物理内存。那谁来决定什么时候把哪段记忆从硬盘搬到内存呢MemGPT提供了一套函数调用机制把这些操作封装成系统可调用的工具。Agent在推理过程中如果发现需要某段记忆就会主动发起读操作如果发现自己正在处理一段重要内容但当前上下文放不下就主动把旧内容归档换出。这套逻辑本质上是在复刻操作系统里的分页与调度。我在自己做长会话Agent时最开始就是用MemGPT的论文思路搭原型。说实话第一次看到它把LLM的函数调用跟OS的系统调用对应起来时是有一种对上了的爽快感的。它彻底回答了谁来决定记忆的存取——答案是模型自己而非外部脚本。3.2 主上下文、外部上下文与中断具体到实现MemGPT里有几个关键概念主上下文main context模型当前真正看到的内容受窗口大小限制。外部上下文external context存放不常被模型看到的记忆需要时可被加载。中断interrupt当外部信息被加载到主上下文时系统会触发一次新的推理让模型在完整信息下再回答。比如用户说你上周答应帮我写个Rust爬虫Agent发现这句话提到一个实体Rust爬虫但当前上下文没有相关内容它就会调用工具从外部存储把这个记忆取回触发中断并继续回答。整个过程不需要开发者外挂一套检索服务完全由模型自己决定。这个中断机制的细节很值得琢磨它相当于给Agent安了一个记忆触发器。模型在生成回答之前先检查自己的上下文里是否缺少必要信息缺了就主动去取。这和人类回忆的过程有点像——你被问到一个问题发现记不清会停下来说让我想想然后从长期记忆里翻出相关内容再回答。MemGPT把这个过程形式化了。3.3 这套设计好在哪里又难在哪里先说优点。MemGPT最大的价值是让记忆管理从开发者的义务变成了模型的能力视角你不用再为每个场景手写检索逻辑Agent可以按需取用上下文里始终只保留当下最相关的内容长对话能力理论上接近无限。但实际落地时我个人遇到的麻烦也不少自我管理不可控。模型可能判断失误该换出的没换出该读的没读最终还是要靠提示词和工具设计去约束。写操作的语义模糊。什么算值得归档什么算临时信息模型分不清容易积累垃圾记忆。成本不透明。每一次外部读取都可能触发一轮完整调用调用链变长后费用和延迟都会上升。如果要上手建议先去读Letta的官方文档和MemGPT论文把小规模Demo跑通再谈生产。它对长记忆控制理论的启发意义远大于开箱即用的意义。我在团队内部推广时经常把它定位成思维模型而不是生产组件——用它来理解Agent记忆的层级关系比直接落地它更有价值。4. LangChain系框架内记忆的务实与天花板4.1 从Buffer到Summary三种常规记忆的边界LangChain是最早把Memory概念普及到大众的框架之一。它早期提供的几类记忆很多初学者都踩过坑ConversationBufferMemory把对话全量缓存。实现最简单但token和存储无限膨胀对话长了根本扛不住。ConversationWindowBufferMemory只保留最近N轮对话。省成本但窗口之外的重要历史会直接丢失。ConversationSummaryMemory定期把旧对话总结成摘要。省token但摘要会丢细节尤其丢数字、名字这类精确信息。ConversationSummaryBufferMemory缓冲区加摘要的混合体超过阈值就把窗口前面的内容摘要化。比前面几种实用但本质上仍是启发式管理。VectorStoreRetrieverMemory把历史对话按语义向量化每次按相似度取回几段。已经接近RAG思路但缺少记忆的更新与冲突处理。这些模块的共性是它们主要解决的是单条链内的短期状态管理离真正的Agent长期记忆还有距离。你可以在简单的Demo里用得很顺手一旦Agent要给多个用户服务、跨多个会话保留画像就会立刻暴露问题。4.2 LangMem把记忆提取变成正式管线LangChain团队后来也意识到光靠Buffer这类临时工不行于是推出了LangMem。它更像是记忆的SDK通过LLM调用从对话中提取语义记忆用户偏好、事实等和情景记忆发生过的事件再写入存储同时提供冲突管理机制比如新旧记忆矛盾时的策略。LangMem的设计思路接近后面要讲的Mem0的提取派但深度绑定了LangChain/LangGraph生态。如果你本来就在用LangGraph编排AgentLangMem可以顺滑地接进去如果你用的是别的框架就得多写不少胶水代码。从我试用的体感来说LangMem的优势是开箱即用跟LangGraph的状态管理配合得不错短板则是它更像一套示例性质的SDK真要支撑复杂生产场景还需要自己在提取质量、去重策略上投入不少调优工作。4.3 框架内方案的隐藏坑我自己用过一段LangChain系记忆有几个体会值得分享记忆和状态要分清。LangGraph的checkpoint存的是Agent执行到哪一步、中间变量是什么那是执行状态不是用户长期记忆。很多人把两者混为一谈最后发现重启后机器人照样失忆。摘要记忆在跨语言、跨术语场景下失真严重。比如金融场景里昨天成交价¥123.5被摘要成价格有波动恢复对话时模型就只能乱编了。框架升级频繁API改动大。LangChain的Memory类在不同版本里反复改接口我做的一个小项目从0.1升到0.3光记忆相关代码就重写了一遍。如果做生产系统建议把记忆存取封装成自己的接口别在业务代码里到处直接调用框架类。提示框架内方案最适合做快速验证尤其是POC阶段。但如果你想做严肃的长期记忆最终还是要落到更专门的项目上或者自己在框架之上做一层稳健封装。总之LangChain系的价值是教育意义大于生产意义——它帮你理解了记忆有哪些类型、各自什么代价但真正要做长期记忆的时候你会发现还是得自己动手或者转向下面这些专门方案。5. Mem0提取-存储-合成把记忆当数据来管5.1 从消息到记忆的三步流水线Mem0是我个人用得比较多、也比较推荐的一个开源项目。它的核心思想跟操作系统派完全不同不指望模型自己管理记忆而是专门跑一条记忆流水线从对话和文档里主动提炼出结构化的记忆。它的流程可以拆成三步提取对每轮对话或每份文档让LLM提取出关键事实、实体和用户偏好。比如用户说我喜欢极简风格的仪表盘不要红色系统会提取出两条偏好而不是把这句话原样存进去。去重与合并新提取的记忆会跟库里已有记忆做语义比对如果高度相似就把新旧内容合并或更新避免重复堆积。合成与存储最后形成记忆体memory写入向量库同时保留元数据供检索和审计。这套流程的好处是存储的不是原文碎片而是精炼后的用户画像。想象一下你收藏的不是几百条聊天记录而是一张动态更新的档案卡每次对话后档案卡被悄悄修正一次。这对Agent的个性化体验提升非常明显也是我为什么在多个项目中优先选它的原因——它直接站在数据管理的视角处理记忆而不是把记忆当成提示词拼接的一部分。5.2 ADD、UPDATE、NOOP记忆的增删改查Mem0在处理记忆更新时会对提取出的每条新信息做操作判定。大致有这几种结果ADD新事实和现有记忆没有冲突直接新增。UPDATE新事实部分覆盖旧记忆需要合并。比如用户之前说我喜欢邮件通知后来改口我只在紧急时收邮件系统应该更新而不是新增。DELETE新信息表明旧记忆已失效。NOOP新信息与现有记忆重复或价值不大不动作。这已经非常像数据库里的change data capture了。记忆不再是静态文本而是有状态的动态数据。对生产级Agent来说这个设计很重要因为用户的偏好是会变的如果系统只增不改最终会积累一堆互相矛盾的印象。我在实际集成Mem0时最关注的其实是UPDATE的触发条件。它依赖LLM判断新旧信息是否矛盾而LLM对矛盾的理解是概率性的。所以我在记忆写入前加了一层置信度过滤只有高置信度的信息才允许触发UPDATE或DELETE低置信度的先存成草稿记忆。这个调整让我的Agent在记忆稳定性上好了很多算是踩过坑之后的一个经验。5.3 为什么Mem0比传统RAG更适合做Agent记忆很多人把RAG等同于长期记忆但我试用Mem0之后体会很深刻RAG擅长检索原文不擅长沉淀认知。RAG取回的总是原始文本片段而Agent记忆需要的是关于用户的事实、偏好、画像——这些信息往往散落在多轮对话里需要被提炼和综合。Mem0的提取-合成机制本质上是在帮Agent完成从数据到知识的加工步骤。当然Mem0也不是银弹。它的提取环节依赖LLM能力意味着你要为记忆构建支付token成本去重和合并如果参数没调好可能会把相似但不同的记忆错误合并。我在生产环境里用的建议是给每条记忆加上来源时间戳和置信度这样即使合并错了也能追溯。另外如果你做的是知识密集型场景比如企业知识库问答Mem0的定位其实不太适合它更适合用户画像型的个性化记忆。6. Zep / Graphiti时间感知的图记忆6.1 为什么记忆会过期这件事很重要前面讲的所有方案都默认记忆是写入后持续有效的。但真实世界的记忆是会过期的。用户上个月说我喜欢A方案这个月可能就变了系统三天前记录了一个实体关系今天这个关系可能已经解除。如果记忆系统没有时间概念Agent就容易拿过期的旧印象回答新问题。Zep早期版本主打对话摘要和记忆服务后来团队推出了开源的Graphiti方向移到时序知识图谱上。Graphiti的核心差异不是存成图而是给图里的每一条边都打上有效时间和入库时间形成双时序结构。这样系统查询记忆时可以根据时间窗口筛选出当时确实生效的信息。举一个具体场景一个企业客服Agent用户三月份说要升级到企业版五月份又反馈企业版账单看不懂。如果记忆系统没有时间概念Agent可能会把三月份的决策当成当前意图推荐一堆升级引导有了时间戳系统就知道升级决定是两个月前的事现在用户的诉求是账单解释。这就是新鲜度维度的价值。6.2 识别实体、抽取关系、按时间窗口检索Zep/Graphiti这类方案的管线大致是从对话中识别实体人、组织、项目、产品等和事件。抽取实体间的关系比如Alice负责A项目、A项目使用了B框架。把实体作为节点、关系作为边连同发生时间一并写入图数据库。查询时支持在某个时间点X和Y的关系是什么这类带时间条件的图查询。这套设计最典型的应用场景是客服机器人客户在三个月内反复抱怨某个问题图记忆能自动勾勒出这个客户发起过哪些工单、每个工单指向哪个产品模块、有没有同类问题反复出现的完整脉络。相比纯粹的向量检索图记忆更适合做多跳推理和关系追溯。这里有一个很关键的工程细节实体识别和关系抽取的质量直接决定图谱的可用性。我用Graphiti做过一次小规模验证发现如果抽取环节不做领域微调图里会出现大量重复实体的变体比如Alice和aliceexample.com被当成两个节点。所以上图谱方案一定要先做好实体对齐的预处理否则查询结果会让你怀疑人生。6.3 图谱型记忆的代价不过图谱方案的门槛也明显。首先图数据库比如Neo4j的运维和查询写法比一套向量库重得多其次实体识别和关系抽取如果做得不好图里全是噪声查询结果反而比RAG还差再者记忆在这个体系里不是简单的文本你需要专门设计一套工具API让Agent去查询图谱这对小团队来说学习成本不低。我个人的判断是如果你的场景需要精准的时间线、实体关系和多人协同图记忆值得投入如果只是给单个用户做个性化推荐Mem0和RAG的性价比会高得多。做选型时不要因为图谱听起来高级就上先想清楚你的需求里到底有没有关系推理和时间回溯这两个硬指标。7. Cognee与RAG自建向量记忆另一个极端的可行性7.1 Cognee图谱与语义的结合Cognee是另一个值得关注的项目。它的定位是可组合的记忆架构简单说它把非结构化的输入按层级处理成语义记忆、实体/事实/关系和可操作的程序性记忆然后既做向量检索又做图谱遍历让Agent可以从多个角度回忆。它的设计哲学是不要绑定特定存储。你可以用向量库、也可以用图库或者两者都接。对开发者来说Cognee提供了更高层的记忆抽象不用自己从零写实体抽取和向量化管线。不过它也继承了图谱方案的复杂性和LLM抽取的不稳定性生产使用前要把评估环节做扎实。我试用Cognee的总体印象是它更像一个记忆中台的雏形适合团队想做一个统一记忆服务、但还不想从零造轮子的阶段。它的可组合性是一把双刃剑——灵活性高意味着配置项多如果你对记忆系统没有清晰的认知很容易在参数海洋里迷失方向。7.2 自己用向量库搭一套最简记忆如果你不想引入任何额外框架最直接的长期记忆方案就是自己搭RAG把每轮对话按窗口切片用Embedding模型转成向量存入向量数据库每次Agent需要记忆时把当前问题向量化做相似度检索取回最相关的几个片段注入到系统提示词或上下文开头。我实际跑通过这样一套简单管线步骤不复杂对话分片按轮或按固定长度切块每块带上时间戳、对话ID、参与人元数据。向量化入库用OpenAI或开源的Embedding模型把每块转成向量存进Qdrant、Chroma或pgvector。检索注入用户发起新请求时先用问题向量检索top-k片段拼进上下文。定期摘要压缩当某段历史太长时用LLM生成摘要替换原始片段。这套方案的好处是透明、可控、成本清晰很适合团队从零起步。我记得第一次搭完看到Agent能准确引用三天前的对话细节的时候还是很有成就感的。但它的天花板也很明显没有实体关系、没有冲突合并、没有过期机制语料一多检索结果会越来越碎片化Agent会开始记住了很多但记不牢。7.3 自建方案的真实限制我用这套RAG记忆做了一个内部工具的真实感受它能应付用户上个问题说过什么这种短程记忆但到了用户在三个不同时间提过同一个需求的变体这种中程记忆就很容易错乱。原因很简单——相似度检索只保证语义接近不保证逻辑一致。你取回的三段历史可能彼此矛盾Agent也没有机制去仲裁谁对谁错。所以我的结论很明确自建向量记忆适合作为起步方案和兜底方案但如果你对Agent记忆的需求超过了简单的提词器就一定要考虑Mem0这类带更新机制的提取派方案或者Graphiti这类有时序图结构的方案。从成本和维护角度看自建方案在数据量小的时候最划算随着规模上来你花在检索调优和去重上的时间反而会超过直接用成熟方案的投入。8. 我的选型建议不同规模Agent该抄谁的作业8.1 个人助手与POC怎么选如果你是在做个人知识库助手或者一个用来验证概念的Demo我最推荐先用LangChain或直接自建向量记忆跑通主流程再在关键路径上接入Mem0做重点记忆提取。理由很简单——起步阶段最重要的是让系统先能用、让人先看到记忆带来的体验变化而不是一上来就把架构搞得无比完备。等到你确实验证了长期记忆能让用户体验明显变好再往生产级方案迁移。8.2 生产级Agent怎么组合如果一个Agent要面向真实用户长期运行我的建议是按场景组合而不是单选一个原始对话和历史事实交给Mem0或自建向量库做语义检索和画像沉淀。用户偏好变化与时效性要求高的场景引入Graphiti这类时序图谱答案才会跟得上变化。长任务执行中的中间状态交给LangGraph的checkpoint这类系统状态存储不要让用户记忆和任务状态混在一起。知识库文档问答继续用RAG但和用户记忆分开建索引。这里最重要的教训是我踩过坑后才明白的不要把用户记忆、对话历史、任务状态混在同一套存储里。它们的写读频率、更新策略、生命周期完全不同塞在一起后期几乎没有维护的余地。我们早期图省事把历史对话、用户偏好、任务队列全塞进一个向量库结果不到一个月检索质量就开始崩最后花了整整一周做数据迁移。分开存储分开运维长期看省力得多。8.3 最后一点实操心得如果让我给一个最靠谱的起步顺序我会这样建议先用RAG向量库做简单历史召回让Agent的短期延伸记忆先跑起来然后花一周时间仔细看Mem0的源码或文档把提取-更新-合并这套思路消化掉最后当你发现用户画像随时间变化真的影响体验时再考虑上Graphiti这类时序图谱。不要一开始就追求大而全。长期记忆本质上是产品能力的演变过程不是一次技术选型就能一步到位的。我现在回头看最有效的不是某个项目的具体代码而是把它当成一套从数据到知识、从知识到记忆的系统工程来设计。每种方案解决一个维度的问题组合起来你的Agent才能真正拥有一个可持续生长的长期记忆。