Agent这个概念从2023年火到现在,技术圈的朋友应该感受很深:写Prompt、接Tool、调Function Calling,大家都能玩得转,但一旦要让Agent记住几小时甚至几天前的事,就总感觉哪里不对。长期记忆确实是当前Agent落地最大的短板之一。这篇我想用从业者的视角,把LangChain、Dify、CrewAI、AutoGPT、MemGPT(也就是后来的Letta)、MetaGPT这六个主流项目的记忆设计思路放在一起拆一拆,看完你至少能知道:长期记忆到底记什么、存在哪、怎么取、忘了怎么办,以及自己做Agent时该抄哪种作业。
1. 先理清楚:长期记忆到底难在哪
1.1 LLM本身就是个没有记忆的实习生
绝大多数人刚接触Agent时,会下意识觉得“LLM什么都知道,那它肯定也能记住我们聊过什么”。这是最大的误解。LLM的本质是做一个概率补全:你给它一串Token,它预测下一个Token是什么。它既不保存你的历史对话,也不维护任何用户档案,每次接口调用它看到的只是一个静态的上下文。你可以把它理解成一位能力很强但完全没带文件夹的实习生,你问他什么他都能答,但上一个任务做了什么,他转头就忘。
让Agent拥有长期记忆,本质上不是给LLM“装上记忆”,而是围绕LLM搭建一套外部系统:谁来负责写入、谁来负责存储、谁来负责检索、谁来负责在需要的时候把对应记忆塞回上下文。这就是为什么现在所有主流Agent框架都在记忆模块上做了不少文章,但侧重点各不相同。
1.2 记忆不是一块,是三块
我们在聊长期记忆之前,最好先把记忆拆一下类。认知科学里通常把记忆分成工作记忆、情景记忆、语义记忆三类,对应到Agent上非常贴切:
- 工作记忆:就是当前上下文窗口里的内容。包括系统提示词、最近几轮对话、中间推理过程。它的特点是容量小、实时性高,对应LLM的Context。
- 情景记忆:Agent经历过的事件,比如“昨天帮用户分析过一份销售报表”“上一轮用户提到过自己用的是Linux”。这类记忆通常以对话历史、任务记录的形式存在。
- 语义记忆:抽象出来的规则和知识,比如“用户是产品经理,偏好的汇报格式是金字塔结构”“遇到数据类问题时要先确认数据口径”。这类记忆是从经历中归纳出来的,而不是原始记录的堆砌。
很多项目嘴上说着做“长期记忆”,实际只是把原始对话丢进向量库里,这顶多算是情景记忆的存档,离语义记忆还差得远。
1.3 评价一套记忆系统的四个维度
看一个Agent项目的记忆设计水平,我习惯用四个维度去框:
- 写入策略:什么东西值得记?是全部对话都记,还是只记任务结果、关键实体、用户偏好?
- 存储介质:存在哪?内存、JSON文件、关系型数据库、向量数据库,还是把它们组合起来用?
- 检索策略:需要记忆时怎么找?按最近时间捞、按关键词搜、按向量相似度召回,还是让Agent自己决定调哪段记忆?
- 遗忘与压缩机制:记忆无限增长怎么办?要不要遗忘,怎么压缩,旧信息如何归档?
下面看六个项目,基本都是在这四个维度上做出了不同取舍。
2. 六个主流项目的记忆设计思路拆解
2.1 LangChain:把记忆当成可插拔的模块
LangChain大概是最早把“记忆”做成体系化抽象的框架。它定义了一个BaseMemory基类,所有记忆方案都围绕chat_memory(存储对话历史)和output_key(决定拿哪部分中间结果当记忆)来扩展。你可以在一个Chain里自由切换不同的记忆策略,这种模块化的思路降低了理解成本,但也带来了碎片化问题。
LangChain里目前常见的记忆方案有这么几种:
- ConversationBufferMemory:最朴素的方案,把历史对话原封不动存起来,调用时全部塞进Prompt。代码写起来很简单:
from langchain.memory import ConversationBufferMemory from langchain.chat_models import ChatOpenAI from langchain.chains import ConversationChain memory = ConversationBufferMemory(return_messages=True) chain = ConversationChain( llm=ChatOpenAI(), memory=memory ) chain.run("我叫张三,是一名后端工程师") chain.run("你记得我的职业吗?")这个方案在小规模试用时很顺手,但对话一长,Token很快就被历史占满,属于只能“浅尝辄止”的入门方案。
ConversationBufferWindowMemory:只保留最后N轮对话,用滑动窗口控制上下文大小。相当于每聊几轮就“翻篇”,实现成本低,但早期重要信息会直接丢掉。
ConversationSummaryMemory:让LLM把过去的对话实时总结成摘要,再存摘要。它牺牲了一部分细节,换来了可控的Token长度。我自己的经验是,摘要质量非常依赖LLM的总结能力,如果对话里包含精确的数字、路径、配置项,摘要往往会丢关键细节。
ConversationSummaryBufferMemory:把前面两个方案做了折中:近期对话保留原文,超过一定阈值后,把更早的内容总结成摘要。这是我在LangChain体系里最常用的方案,等于给对话记录做了两级存储。
VectorStoreRetrieverMemory:把每条对话片段向量化存入向量库,用相似度检索召回最相关的历史片段。它的思路已经接近RAG,适合知识密集型场景,但需要把“什么时候该记住”交给Embedding的相似度来判断,误召回的情况时有发生。
LangChain的记忆设计本质上是“上下文管理的加强版”,它不是让Agent主动管理记忆,而是由开发者事先选好策略,把历史数据在每次调用前拼进Prompt。它解决的是“能记一点”,而不是“该记什么”。
2.2 Dify:平台化应用里长出一棵记忆树
Dify和LangChain不在一个赛道上。LangChain是开发框架,Dify是带图形化编排界面的应用开发平台。它的记忆方案是典型的平台思维:不让你自己写存储逻辑,而是把记忆能力拆成会话记录、知识库、对话变量三块,分别解决不同层次的问题。
先说会话记录。Dify的每个应用背后都有一张PostgreSQL表,用户的每一轮消息、Agent的每一步执行结果都会被持久化。当用户重新进入同一个会话时,历史消息会自动出现在上下文中。这一层等于解决了“情景记忆”的存档问题,而且做得非常透明——你在编排画布里基本上不需要写代码,勾选几个选项就能开启。
第二层是知识库。Dify让用户把文档上传后做切片和向量化,存入向量数据库(默认支持Weaviate、Qdrant等),在对话时通过RAG把相关知识检索出来。这一步解决的是“语义记忆”的一部分,但要注意,知识库里的内容是静态资料,不是从对话里动态总结出来的,它更像是外挂的参考手册。
第三层是对话变量和外部记忆。你可以在工作流里声明各种变量,跨步骤传递中间结果;也可以在外部业务系统里存好用户标签、偏好,通过API注入到Prompt中。这层灵活度最高,适合把业务数据变成Agent记忆的场景。
Dify的设计思路值得点赞的地方在于“分层清晰”:无状态能力的持久化交给我平台,动态提取的记忆交给工作流编排,外部业务记忆通过API打通。缺点是深度受限。如果你需要细粒度控制记忆召回时机、自定义遗忘策略,在Dify里会比较别扭,因为它把复杂度藏到了平台内部,你要么接受默认逻辑,要么绕到插件体系里去改。
2.3 CrewAI:多Agent协作下的三级记忆体系
CrewAI是目前热度很高的多Agent编排框架。它默认不要求开发者自建记忆体系,而是直接内置了三种记忆:短期记忆、长期记忆、实体记忆。
- 短期记忆:记录当前任务组(Crew)内最近执行的活动,相当于一组Agent在工作中共享的临时速记本,用于协同过程中快速回溯“刚才谁做了什么”。
- 长期记忆:跨任务沉淀下来的关键信息,比如某次任务的成功方案、某个客户的要求。CrewAI会把任务结果抽取成长期记忆,供后续任务复用。
- 实体记忆:专门保存实体信息,比如人名、组织、地点、偏好。设计意图很明显:避免同一个用户信息反复问、反复传,让Agent之间共享一份“人物卡片”。
在底层实现上,CrewAI默认使用SQLite存储短期数据,通过ChromaDB或向量库存长期记忆和实体记忆。搜索时对长期记忆做基于任务描述的相似度匹配,对实体记忆做基于实体名称的匹配。这种设计很贴合真实团队协作模型——每个人的记忆不是孤立存在的,而是通过共享的“团队记忆库”在传递。
不过要提醒一点:CrewAI的记忆是任务结果驱动的,它记录的是“这次任务产出了什么”,而不是“这个用户当时的心情如何”。如果你的Agent需要很强的个性化拟人记忆,比如记住用户说话风格、未明说的偏好,CrewAI默认方案覆盖得并不好,需要自己在任务执行回调里做二次加工。
2.4 AutoGPT:把记忆写在文件里的自由派
AutoGPT出来的时候,大家第一次看到Agent能自主拆解任务、自己写文件、自己调工具。它的记忆设计方式非常“原始”但也非常直观:把Agent认为重要的信息结构化后,直接写入一个文件/向量库。
早期AutoGPT的记忆指令看起来像这样:Agent在执行过程中会调用remember相关命令,把信息存成一段文本或者JSON块;当它需要回忆时,会调用recall命令,用关键词或语义搜索把相关历史片段拿回来。
这种由Agent自己决定“记什么”的思路,在理念上非常激进,因为它把记忆的写入策略从开发者手里让渡给了LLM本身。实际跑起来你很快会发现,LLM对自己“什么重要”的判断并不可靠,经常把解析网页的过程、无关的闲聊也存进去,造成记忆库越滚越大、噪声越来越多。再加上早期没有设计遗忘机制,时间一长,检索出来的往往是最相似但不是最重要的记录,整个Agent会进入一种“记忆很多、但都用不上”的怪圈。
AutoGPT对行业的贡献不在于它的记忆实现有多完善,而在于它证明了“Agent自主记忆”的可能性。后来的很多框架都吸收了它的思想——记忆不能只靠规则堆,要让Agent拥有写入记忆的主动性。
2.5 MemGPT / Letta:把记忆当操作系统来管
MemGPT是我认为目前最“有理论野心”的一个项目。它最初是一篇论文的产物,核心思想非常有意思:把LLM有限的上下文想象成内存,把外部存储想象成磁盘,然后借鉴操作系统里的虚拟内存管理方式,让Agent在“内存”和“磁盘”之间做页面的换入换出。
具体来说,MemGPT里的记忆分为两层:
- Main Context:对应主存,包含系统提示词、工作区(当前任务的关键信息)、最近对话。它的容量受限于上下文窗口。
- External Context:对应磁盘,包含外部数据库、历史对话归档、工具返回数据。它几乎无限大,但不能直接被LLM看到。
为了让Agent在这两层之间移动信息,MemGPT定义了一组记忆管理函数,比如memory_read、memory_write、memory_search,Agent可以自己调用这些函数决定“我现在需要回忆什么”“我要把哪段信息写回长期存储”。这等于把记忆管理动作内化为Agent能力的一部分,而不是开发者预设的固定策略。
Letta是MemGPT的下一代平台实现,主打“具有自我编辑记忆的Agent服务器”。它把记忆维护做成一个不断自省的过程:Agent会定期检查自己的记忆是否过时、是否需要补充或删除。这种自我编辑能力,让它更接近语义记忆的本质——记忆是动态维护的结论,而不是静态存储的日志。
MemGPT的缺点也比较明显:运行时开销大,LLM需要额外调用多个记忆管理函数,Token消耗比普通Agent高;而且要玩明白它,你必须理解“主存-外存”这套模型,思维门槛不低。但如果你做的Agent长期积累大量信息,又要求检索质量高,MemGPT是值得认真借鉴的设计范式。
2.6 MetaGPT:用文档工程沉淀团队记忆
MetaGPT走的是另一条截然不同的路。它不把Agent当作单个个体,而是模拟一个软件公司:产品经理Agent写PRD、架构师Agent画图、工程师Agent写代码、测试Agent跑测试。它认为,软件开发这类复杂任务单靠一个Agent的个人记忆是不够的,真正的长期记忆应该体现在团队共享的结构化产物流转里。
MetaGPT记忆设计的两大支撑点是SOP(标准作业程序)与结构化文档。每个Agent在执行任务时,把结果写进约定好的文档格式(PRD、设计文档、代码文件等),再通过消息中心传给下一个Agent。这样,文档本身就是记忆的载体,项目推进过程中每一个阶段的关键决策都沉淀在文档里,任何Agent都可以在后续阶段读取它。
这种设计把“个人记忆”的问题巧妙转化成了“组织记忆”的问题,特别适合强依赖流程和交付物的场景。比如做一个完整应用,解析用户需求后,产品Agent把需求写进PRD,架构Agent看到PRD后输出技术方案,工程Agent依据方案写代码——即使工程Agent之前没和用户直接对话过,它也能通过PRD“继承”所有上下文。
但如果你想让MetaGPT模拟一个贴心聊天助手,它就是错的方向了。因为它几乎不关心个体记忆,它关心的是项目工件。Agent之间流转的是文档,不是情感和个性化偏好。
3. 横评:一张表看清六个项目的设计差异
3.1 关键维度对比
把前面六个项目放在同一张表里看,差异会非常明显。
| 项目 | 核心思路 | 存储介质 | 记忆粒度 | 主要检索方式 | 遗忘/压缩机制 | 适合场景 |
|---|---|---|---|---|---|---|
| LangChain | 对话记忆外挂模块 | 内存/数据库/向量库 | 对话轮次/摘要 | 滑动窗口/摘要/向量召回 | 窗口截断、摘要压缩 | 需要灵活搭配记忆策略的LLM应用 |
| Dify | 平台分层记忆 | 数据库/向量库 | 会话级/文档级/变量级 | 会话恢复/RAG检索 | 平台内部管理 | 平台化应用交付,低代码搭建 |
| CrewAI | 团队协作分级记忆 | SQLite/向量库 | 任务级/实体级 | 任务相似度/实体名 | 任务分组、实体更新 | 多Agent协作任务流 |
| AutoGPT | 自主写入的原始记忆 | 文件/向量库 | 事件记录级 | 关键词/语义搜索 | 基本没有 | 早期研究、实验性质Agent |
| MemGPT/Letta | 操作系统式分层记忆 | 数据库/向量库 | 页面/文档/实体 | 记忆读写函数自主调度 | 自我编辑、归档 | 长生命周期、自省型Agent |
| MetaGPT | 文档即组织记忆 | 结构化文档/消息中心 | 工件级(PRD等) | 按阶段读取约定文档 | 文档版本迭代 | 多Agent软件开发流水线 |
3.2 从对比中能看出的三条趋势
第一,记忆正在和上下文解耦。早期LangChain的思路是“把记忆拼回上下文”,本质是上下文增强;而MemGPT和Dify已经把记忆当成独立系统来设计,是否需要召回、召回什么,逐步交由Agent自主决策。这个趋势意味着,上下文窗口再大,也不能替代结构化的外部记忆。
第二,从“存对话”走向“存知识”。AutoGPT和早期LangChain方案习惯存原始对话,但Dify的知识库、MetaGPT的文档、MemGPT的自我编辑记忆,都在做“从原始信息中提炼知识”的工作。原始对话是日志,提炼过的结论才是记忆。
第三,遗忘机制开始被正视。六个项目里,除了AutoGPT几乎没做遗忘,其他项目都不同程度设计了窗口截断、摘要压缩、实体更新、文档迭代等机制。记忆不等于无限堆积,过滤掉噪声才是长期记忆能真正长期可用的前提。
4. 落地实操:给Agent加长期记忆的八条经验
4.1 按场景选型,不要为了“长记忆”而上长记忆
我在真实项目里看到最多的坑,是不分场景地堆对话历史。如果你只是一个客服问答机器人,用户聊完这个会话就走了,短期记忆就够了,硬要做长期记忆反而增加开销和误召回风险。而如果是一个长期项目分析师Agent,需要跨周跨月维护用户资产配置情况,那就必须上实体记忆加文档记忆。先问自己:这个Agent的价值是否依赖过往信息?如果依赖,依赖到什么程度?
4.2 记忆写入不要全盘照抄,要提炼结论
很多初学者喜欢把对话历史全部存进去,这是最懒也是最差的做法。你应该明确:哪些信息需要以原始形态保存,哪些需要提炼成结构化记录。比如用户说的这段话里有自己的技术栈、当前项目阶段、喜欢简洁回答三种信息,把这些提炼成JSON片段存入语义记忆,远比存整段对话要好检索、好维护。至于原始对话,顶多保留最近N轮用于即时上下文衔接。
4.3 检索质量是记忆系统的命门
记忆存得再好,检索不准就相当于没有记忆。提升检索质量有三个实操技巧:一是给记忆片段写元数据标签,比如记录了用户偏好、记录了任务产出、记录了某个知识概念,检索时先按标签过滤再按相似度排序;二是混合检索,把关键词匹配和向量召回结合起来,避免纯语义找回一堆“意思相近但完全无关”的内容;三是控制召回数量,我习惯限制在Top3到Top5条,超出这个量级反而会干扰LLM的注意力。
4.4 遗忘和压缩要定期做
长期记忆最怕无限膨胀。建议设定一个定期维护机制,比如每周对记忆库做一次清理:把过时的信息标记归档、把重复信息去重、把零散的事件记录合并成结论。在技术上可以仿照MemGPT的思路,让Agent定期调用一个memory_audit函数来审查自己的记忆质量。如果你嫌维护工作太重,至少要在写入时做限制,超过N条后强制淘汰最旧的一条。
4.5 记忆权限和安全问题别忽略
Agent记忆里存了用户数据,就必须考虑访问控制和隐私合规。多用户场景下,要确保A用户的记忆不会被B用户检索到;企业内部场景,敏感信息建议做脱敏后再进记忆库。这一点在Dify、LangChain里都可以通过隔离存储和过滤层来实现,但很多人做到这一步才发现自己漏了数据出境评估。
4.6 常见问题与排查方法
| 症状 | 可能原因 | 排查方向 |
|---|---|---|
| Agent完全不记得早前对话 | 短期窗口太短,早期信息被截断 | 检查窗口轮数和摘要策略 |
| 记忆有但Agent用不上 | 检索召回不准 | 查看召回日志,测试不同Embedding和检索TopK |
| 上下文太长,费用飙升 | 记忆内容未做提炼,原始对话全进Prompt | 增加摘要层,限制召回条数 |
| 记忆越用越乱 | 缺少遗忘机制,噪声堆积 | 增加定期清理和归档流程 |
| 多用户数据串了 | 存储隔离没做好 | 检查记忆库的设计,按用户ID做隔离 |
4.7 一个通用模板:小型Agent记忆系统的设计草图
如果你想自己实现一套不依赖重型框架的记忆系统,可以参考这个最小可用方案:
1. 存储层: - 最近20轮对话:Redis,兜底内存,过期时间1天 - 用户实体信息:PostgreSQL,以用户ID为分区 - 长期语义记忆:向量数据库,带元数据标签 2. 写入层: - 对话结束后,调用LLM抽取“用户偏好/任务结论/待办事项”三类信息 - 抽取结果转为JSON,写入实体表或向量库 3. 检索层: - 每次请求先按用户ID加载实体信息 - 根据当前对话语义,从向量库召回Top3记忆片段 - 合并最近对话 + 实体信息 + 召回片段,组装成上下文 4. 维护层: - 每天凌晨执行记忆压缩任务,合并重复实体、归档过期信息这套结构不依赖特定框架,LangChain、Dify、CrewAI都能嫁接到类似思想上,只是API不同。
5. 最后说几句踩坑体会
我在给不同客户落地Agent时,吃过不少记忆相关的亏。最典型的一次是给某客服场景做Agent,上了完整的向量记忆库,模型也换了长上下文版本,结果效果还不如之前只存最近10轮对话的方案。后来复盘发现,问题出在“什么都想记住”上——用户的每个问题都进向量库,检索的时候召回了一堆相似但没用的问题,反而把关键信息挤掉了。后来改成只存“用户明确表达的偏好”和“解决不了的问题标记”,效果立刻上来了。
我的体会是,长期记忆设计没有银弹,它更像是在“召回率”和“精准率”之间做取舍的艺术。别迷信某个框架自带的神奇记忆模块,关键是你是否清楚自己的Agent到底需要哪种记忆、愿意为记忆付出多少成本和复杂度。动手之前,先把这个问题想明白,比选什么都重要。