Agent记忆不是越多越好:我总结了4类必须禁用的"错误记忆"场景

Agent记忆不是越多越好:我总结了4类必须禁用的"错误记忆"场景

Claude平台有一个Memory Tool,让Agent可以跨会话记住信息。第一次听说这个功能时我挺兴奋的——终于不用每次对话都重新交代背景了。

用了一个月之后,我的看法变了。记忆这东西,记对了是加速器,记错了是定时炸弹。

01 记忆出问题时发生了什么

先说一个我自己碰到的case。我在用Agent做一个Node.js项目,项目初期用的是Express框架。Agent记住了这个信息。两周后项目迁移到了Fastify,我在新会话里让Agent帮我加一个中间件。Agent直接给我写了Express的中间件代码,语法、导入路径、注册方式全是Express的。

我纠正了一次:"我们现在用的是Fastify。"Agent说好的,然后给了一份Fastify风格的代码。但下一个会话里,它又写了Express的代码。因为跨会话记忆里存的还是"项目使用Express"。

这不是个例。MemoryAgentBench论文的测试结果显示,在"冲突消解"这项能力上,几乎所有Agent实现的得分都垫底。意思是,当新信息和旧记忆矛盾时,Agent大概率选旧的。

这个偏好在心理学上叫锚定效应。LLM的锚定效应比人还严重——它不会"怀疑"自己之前记住的东西,除非你非常明确地告诉它旧信息已经失效。

02 第一类:快速变化的环境信息

API版本号、依赖库版本、配置参数、部署地址、环境变量值。这些东西的特点是变化频繁,一旦过期就完全无用。

记住"项目用的是React 18",如果三个月后升级到了React 19,Agent会按React 18的API写代码。某些在18里存在但在19里被废弃的写法,Agent会毫无犹豫地用上。报错了之后它可能还会坚持自己的写法,因为"记忆告诉我用的是React 18"。

配置参数更危险。数据库连接串、端口号、密钥名称,这些一旦记错,调试成本极高——因为你很难想到Agent是在用一个过期的记忆来生成代码。你会先怀疑自己的代码写错了,再怀疑环境配置有问题,最后才想到Agent在用旧信息。

我的做法是:所有跟版本和配置相关的信息,不让Agent记忆。每次会话手动提供,或者让Agent自己去读package.json和配置文件。读一遍文件花不了几秒,但可以避免用过期信息。

03 第二类:用户偏好推测

Agent根据你的几次交互推测你的偏好。比如你连续两次要求用TypeScript写代码,Agent记住了"这个用户偏好TypeScript"。

问题是,你偏好TypeScript可能只是因为那两个项目恰好是TypeScript项目。下一个项目是Python的,Agent仍然会尝试用TypeScript的思维模式来回答问题——变量命名用驼峰、类型声明格式不对、建议你装ts-node。

偏好推测的另一个坑是风格偏好。Agent记住了"用户喜欢详细注释",然后每次生成代码都加一堆注释。你在写一段临时脚本时根本不需要注释,但Agent还是加了满满一屏。你删了,它下次又加。

偏好这东西太依赖上下文了。在A项目里的偏好不一定适用于B项目。在写正式代码时的偏好不一定适用于写原型。让Agent推测偏好,推对了省一句话的事,推错了要花几分钟纠正。不值得。

04 第三类:临时调试上下文

你在调一个bug。排查过程中产生了很多临时假设:"可能是数据库连接池满了"、"怀疑是Redis缓存没过期"、"试过重启服务没用"。

这些信息在调试过程中有价值。但bug修完之后,它们就是噪音了。

如果Agent把这些记下来了,后面遇到类似的报错时,它会优先沿着旧的排查路径走。上次是连接池的问题,这次可能完全是另一个原因,但Agent会先去查连接池。更麻烦的是那些"排除过的假设"——上次排除了Redis缓存的可能性,但这次问题恰好就出在Redis缓存上,Agent因为记住了"Redis缓存已排除"而跳过了正确答案。

调试信息应该活在当次会话里,会话结束就清掉。如果某次调试的结论确实有长期价值(比如发现了一个框架bug),手动把结论记下来就好了,不要把整个排查过程都存进记忆。

05 第四类:多Agent共享记忆

这个场景在多Agent系统里特别常见。Agent A负责代码审查,它发现了一个潜在的性能问题,把"函数X存在N+1查询问题"写入了共享记忆。Agent B负责代码生成,读到了这条记忆。

但Agent B缺少Agent A写入时的上下文。Agent A看到的是一个特定的查询模式、特定的数据量、特定的使用场景。Agent B拿到的只是一句结论。

结果Agent B开始过度优化所有涉及函数X的代码,把原本简单直接的查询都改成了批量查询。有些改动反而引入了新问题——比如把一个需要实时数据的查询改成了批量预取,导致数据延迟。

共享记忆的问题在于:写入方的上下文丢失了。一条记忆脱离了产生它的环境,就变成了一条没有边界条件的断言。读取方没有办法判断这条断言在当前场景下是否仍然成立。

06 什么该记

说了四类不该记的,也得说说该记什么。

项目的架构决策。"我们选了微服务架构,服务间通信用gRPC"——这种决策不会频繁变动,记住了能避免Agent反复提出已经否决过的方案。

团队的代码规范。命名规则、目录结构约定、提交信息格式,这些是稳定的。

已确认的bug修复方案。不是排查过程,是最终确认的原因和修复方式。"用户登录超时问题的原因是Session过期时间配置为5分钟,已改为30分钟"——这种精确的结论值得记。

稳定的业务逻辑。"订单金额超过500元需要人工审核"——这类业务规则在产品层面确定之后不会经常改。

07 记忆管理的实践建议

给记忆加过期时间。环境信息类的记忆最多保留一周,到期自动失效。如果信息还有效,Agent可以在下次交互时重新确认。

每条记忆记录写入原因。不要只存结论,把"为什么记这个"也存上。Agent B读到一条记忆时,看到写入原因才能判断是否适用于自己的场景。

定期做人工审核。每周花十分钟看一下Agent记了什么。你会惊讶地发现里面有多少过期信息和错误推断。

区分"事实"和"推断"。"项目用的是PostgreSQL"是事实。"用户可能更喜欢简洁的错误提示"是推断。两者的置信度完全不同,不应该混在一起存储。事实可以直接使用,推断需要验证。

记忆管理不性感,但它决定了Agent长期使用的可靠度。一个记忆干净的Agent,比一个记了一堆垃圾的Agent有用得多。


参考链接:

  • Claude Memory Tool文档:https://platform.claude.com/docs/en/agents-and-tools/tool-use/memory-tool
  • MemoryAgentBench论文:https://arxiv.org/html/2507.05257v1
  • Anthropic测试和评估指南:https://docs.anthropic.com/en/docs/build-with-claude/develop-tests
← 返回博客列表