记忆越攒越糟:Agent 的过期结论和错误事实该怎么淘汰

2026-07-29

数据截至 2026-07,各产品的额度与报错口径以官方最新说明为准。

**记忆用久了 Agent 变笨,绝大多数情况不是检索没召回,而是召回了不该召回的东西——过期的结论被当成现行事实用了。**很多人第一反应是换更强的检索、加大召回条数、换个模型试试,结果是把更多垃圾一起塞进去,问题反而更重。你要做的是反过来:先判断这条记忆是什么时候写的、当时对不对、现在还成不成立,再决定它该不该出现在这次任务里。

这篇讲的是记忆的淘汰,也就是写进去之后怎么让它失效。记忆系统本身怎么搭、分几层、写什么,看 AI Agent 的记忆是怎么实现的?短期与;单次会话里上下文被脏内容带偏、越聊越跑题,那是另一个故障面,看 上下文被污染。本篇只管一件事:已经沉淀下来的长期记忆,哪些该主动删,怎么判断它坏了。

一、先把”记忆变坏”拆成三类,别混着治

同样是”Agent 说了句不对的话”,成因完全不同,处置动作也相反。混着治的结果就是删了不该删的、留了该删的。

**第一类,过期结论。**写入的那一刻它是对的。比如三个月前你们把认证方式从 Session 换成了 Token,Agent 记下了”本项目用 Session”。这条记忆没有事实错误,只是时间走了。特征是:内容具体、当时可验证、现在和代码库对不上。这类最难被发现,因为它读起来完全像一条正常记忆,只有拿去和现状比对才会露馅。

**第二类,错误事实。**写入时就是错的。来源通常有两个:一是模型自己推断出来的东西被当成观察写进了记忆,二是你在某次对话里随口说错了一句,它信了。特征是:翻遍代码库和文档都找不到出处。这类条目往往措辞比真事实还笃定,因为它是被生成出来的,没有观察的犹豫感。

**第三类,无关细节。**内容是对的,也没过期,但和绝大多数任务无关。典型是某次调试中间态:“在 debug 分支临时把日志级别调到 trace 了”。这种东西单条无害,攒够几十条就开始挤占空间、稀释信噪比,让真正重要的约束排不进召回结果。

三类的处置是不同的:过期结论要替换,错误事实要删除并追责到来源,无关细节要批量清理。你先分类,后面的动作才不会做反。

二、判别表:从现象倒推成因

排查时不要一上来就翻记忆文件,先看 Agent 的具体表现,用现象定位。

现象大概率成因怎么验证处置动作
反复用一个已经删掉的函数/接口过期结论在代码库全文搜这个符号,确认线上分支已无此物定位记忆条目,改写为现状 + 标注变更时间
坚持某个配置项存在,但你从没见过错误事实(推断落盘)搜配置文件和文档,都找不到即坐实直接删条目,回查是哪一轮对话写入的
每次都提某个和当前任务无关的旧模块无关细节挤占召回看这次任务的召回内容,数一下有几条与任务无关批量清理低价值条目,收紧写入门槛
换个说法问就换个答案,前后自相矛盾记忆里同时存在新旧两版结论用同一关键词搜记忆,看是否有多条冲突记录合并为一条,旧的删掉而不是加个”注:已废弃”
只在长任务后半段开始出错不是记忆问题,是单次上下文被稀释开新会话、同样的问题重问一遍,如果正常就不是记忆走上下文管理那条路,别动记忆文件
全新会话第一句就错记忆污染(写死在长期层)把长期记忆临时移走或关掉,在新会话重问同一句,答对即坐实是记忆按前四行分类处置

最后两行是这张表里最值钱的部分,它们组成一个两步对照实验。第一步,开一个干净会话重问同一个问题:还错就说明问题不在这次会话,而在会话之外的某个地方,成本几秒钟。第二步,把长期记忆临时移走再问一遍(记忆文件改个名、或者按你所用工具的开关关掉长期记忆即可):这一步答对了,才真正坐实是记忆在作祟,可以放心去改条目;这一步还是错,说明记忆是清白的,别再动它。很多人只做第一步就直接去改记忆文件,把没病的地方改出病来。

会话内的退化怎么收,属于另一个话题,看 Agent 的上下文怎么管

三、动作:给记忆装上失效机制

分完类,动作层面只有三件事要做。

第一件,让每条记忆带上可判断新旧的信息。至少要有写入时间和来源。来源分两级就够用:一级是观察——你亲眼在文件里看到的、命令跑出来的;二级是推断——模型根据上下文猜的,或者你口头说的没验证过的。推断级的记忆默认视为不可靠,任何时候和代码库冲突,一律以代码库为准。这条规则写进项目约定文件里,写法参考 CLAUDE.md 怎么写?给 AI 立项目

**第二件,把”结构性变更”设成强制淘汰触发点。**不要指望定期人工巡检,没人会做。挂在你本来就要做的动作上更靠谱。比如改完依赖、换完认证方式、重构完目录结构之后,顺手过一遍记忆里相关的条目。想知道最近改了什么,直接看提交历史:

git log --since="30 days ago" --name-only --pretty=format:"%h %ad %s" --date=short

再把记忆文件里提到的关键符号拉出来,和代码库对一遍:

git grep -n "authenticateBySession" -- '*.ts' '*.js'

搜不到就说明这条记忆已经悬空了。这个动作可以做成一个几十行的脚本:从记忆文件里抽出所有形似标识符的词,逐个 git grep,把零命中的列成待审清单。不用追求准确率,能把明显失效的挑出来就够了。

**第三件,写入的时候就控制入口。**记忆变糟的根因往往不在淘汰慢,而在写入太随便。判断标准建议只有一条:**这条信息在三个月后、换一个人接手时,还需要知道吗?**满足才写。临时调试状态、一次性的实验结论、某个分支上的权宜之计,一律不进长期层——真需要就留在分支的提交信息里。

四、什么该主动遗忘,什么必须留住

主动遗忘不是记忆越少越好,是让保留下来的东西都能被信任。

该主动删的有四类。一是被推翻的技术决策,包括当时的理由。理由留着也没用,反而会让 Agent 在新任务里试图”兼顾”两套方案。二是具体的临时数值,端口号、测试账号、某次跑出来的耗时。这些东西变得比谁都快,留着就是定时炸弹。三是人的临时状态,“某某本周在休假”这种。四是一次性任务的中间过程,任务做完只留结论,过程全丢。

该留的也有四类,而且要留得比现在更死。一是踩过的坑和它的因果——某个改法为什么行不通,这类信息代码里看不出来,最有保存价值。二是不成文的团队约定,比如哪个目录不许 Agent 动。三是外部约束,合规要求、上游系统的怪脾气。四是决策边界,什么情况下必须停下来问人、什么情况下可以自己拍板。

有一个反直觉的点:**删记忆的时候,要连同”当时为什么这么记”一起删干净,别留半截。**留一条”以前用 Session,现已废弃”看着很负责,实际效果是让 Session 这个词继续参与检索匹配,该淘汰的关键词照样被召回。要么完整改写成现状,要么整条删掉,不要留悼词。

五、什么情况下别再折腾

记忆调优很容易变成无底洞,你要有明确的收手线。

**止损点一:同一条污染修了两次还在复现。**这说明写入源头没堵住,你在下游反复擦地。停下来去查是哪个环节在往里写,而不是第三次修改同一条记忆。

止损点二:记忆文件已经改到你自己看不懂了。多轮修补之后,条目之间互相打补丁、条件套条件,这种状态下再改一定越改越乱。正确动作是推倒重来:把当前代码库和文档作为唯一事实来源,重新手写一份精简的记忆,宁可只有原来三分之一的条目。清空之前先留一份存档:

cp -r ./.agent-memory ./.agent-memory.bak-$(date +%Y%m%d)

**止损点三:把记忆整体移走之后问题依旧。**这条是硬分界。干净会话 + 不带记忆还是错,那就跟记忆没关系了,可能是工具描述有歧义、可能是模型本身在这个任务上不行、也可能是运行环境和你以为的不一样。继续折腾记忆是浪费时间,换条路查:先固定一个最小可复现的输入,再依次替换模型、替换工具集、替换运行环境,看哪一步变化能让结果翻转。

**止损点四:为了记忆准确开始做复杂的自动化。**给记忆条目做版本管理、做冲突检测、做自动过期,听着很工程化,实际维护成本经常超过它省下的时间。几百条量级的记忆库,人工顺一遍花的时间通常还不如把自动化调通来得多,而且人能看出”这条虽然没过期但已经没意义了”,规则看不出来。先确认自动化真的划算再动手。

回滚点建议直接用版本控制:记忆文件纳入 Git,每次大改单独提交,提交信息写清楚删了什么、为什么删。出问题的时候,git diff 一看就知道是哪次清理误伤了。这比任何自研的记忆版本机制都便宜。

六、避坑清单

**坑一:把模型的推断当观察写进记忆。**为什么会踩——模型回答时语气是笃定的,你顺手就记下来了,尤其是那种”这个项目应该是用了 XX 模式”的表述。怎么避——写入前问一句”这个结论我在哪个文件里能看到”,答不上来就标成推断级,或者干脆不写。

**坑二:用”注:已过期”代替删除。**为什么会踩——删东西心里没底,加个注释感觉更稳妥。怎么避——记住检索是按语义匹配的,废弃内容只要还在文本里就还会被召回,注释只对人有效、对检索无效。要么改写要么删。

**坑三:一次性清空全部记忆。**为什么会踩——污染严重时会想干脆全删重来。怎么避——全删会把那些代码里看不出来的踩坑经验一起丢掉,那才是真正不可再生的部分。清空之前先把踩坑类条目单独摘出来,其余再动。

**坑四:多个 Agent 或多个开发者共用一份记忆,谁都在写。**为什么会踩——共享看起来能省事、能同步认知。怎么避——共享层只放稳定的团队约定,且限定写入权限;个人的、任务级的记忆各自隔离。共享层的每一次改动都要过一遍人,就像改公共配置一样对待。

**坑五:把记忆当日志用。**为什么会踩——每次会话结束顺手让 Agent”总结一下今天做了什么”存进去,看着很有积累感。怎么避——日志的价值是可回溯,记忆的价值是可复用,两者标准完全不同。日志写文件、写提交信息,别写记忆。

**坑六:忽略环境相关的记忆会在换机器后集体失效。**为什么会踩——本地路径、代理设置、依赖版本这些写进记忆时确实是对的。怎么避——凡是和具体机器绑定的信息,一律放环境变量或本地配置,记忆里最多记”这个值从环境变量读”,不记值本身。

**坑七:海外工具的可用性写进记忆当成常态。**为什么会踩——某个海外模型或工具在某段时间恰好能用,就记成了”可以用 XX”。怎么避——不少海外 AI 工具官方对中国大陆有区域限制、不支持直接使用,具体支持范围以各家官网的最新条款为准,且会随时间变化。这类”能不能用”的判断本身就没有稳定性,不该写死在记忆里;真要记,也只记”该工具的可用性以官网条款为准,用前自行确认”,而不是记一个结论。

收束

记忆系统的价值不在于记了多少,在于被召回的每一条都还成立。一条过期结论造成的损失,通常比十条没记下来的信息大得多——后者只是让 Agent 少知道点,前者会让它自信地做错事。

排查完之后,用这份清单自检一遍:

  • 每条记忆是否能说清写入时间和来源级别(观察还是推断)?
  • 最近一次结构性变更之后,有没有对应清理过记忆?
  • 记忆里有没有”已废弃”字样的悼词条目?有就改写或删除。
  • 有没有和具体机器、具体分支绑定的临时值混进了长期层?
  • 记忆文件是否在版本控制里,能否回滚到上一次清理之前?
  • 干净会话 + 空记忆的对照实验,你做过没有?

最后一条最重要。它花你几分钟,能省掉几小时的方向性错误。

会话内的记忆衰减和长期记忆污染容易混淆,前者的表现和处理看 越聊越忘,别把两件事的药吃串了。

想系统学会用 AI?报名体系课或加入会员,照着学、照着用。