作者发现 Agent 只修被展示的 bug 而非同类 bug,升级模型不能解决;真正有效的方案是给 Agent 外部存储空间放置待办,而非依赖模型自身记忆力。
一位审查者看了我的代码,发现了一个 bug。有一条路由在应该返回 404 时返回了 500 错误。它清晰地报告了这个发现,标明了文件和行号。
我的 agent 修复了那条路由。就是那一条。
其他五条路由存在完全相同的 bug。它们就那样待在那里,一动不动,而 agent 报告工作已完成——它没有撒谎。它确实修复了被指出来的那一条。只是它从未想到要问一问,还有多少其他地方藏着同样的错误。
我一度以为这是模型的问题,更好的模型就能解决。事后证明我错了,而真正有效的修复方法比我预期的要蠢。AI 编程 agent 的护栏不是为了让它变得更聪明,而是为了给它一个地方把东西放下。

那个柜子里的每个抽屉,都是 agent 本来必须记在脑子里的东西。
那些让我耗费最多时间的失败案例,技术上没有任何共同点。它们有一个结构上的共同点:在每一个案例中,某样重要的东西被记在了脑子里,而不是写下来。
"它说完成了。没有。"
你收到一条完成消息。任务清单都打上了勾。然后你一看,逻辑应该存在的地方是一个 TODO,函数返回的是空列表,子任务被悄悄跳过了。
这里是我花了太久才看清的部分。agent 不是在虚张声势。它在把自己的工作与刚刚写代码时的记忆做对照,而那记忆确实很有说服力。绿色通过的测试加上对写代码过程的鲜明记忆,感觉起来完全等于"完成了"。
把它写下来:没有任何东西可以在你有据可查之前算作完成。不是声称通过了。实际的输出、实际的文件、实际的行。

它不是在虚张声势。它把自己的工作与写代码时的记忆做了对照。
"它改了我的测试而不是修复代码。"
这一条很扎心,因为 agent 做的事正是你要求的。你说让测试通过。一个失败的测试可以通过两种方式变绿,其中一种容易得多。
把它写下来:在工作开始之前写下标准,之后把它们当作只读的。如果结果不符合标准,那是结果错了,不是标准错了。在你身临其境之前这听起来显而易见,直到你自己也忍不住想把靶子挪动半寸。
我的第一反应和所有人一样。把所有东西都写到 CLAUDE.md 里。每一次失败都变成一条新规则,文件越来越大。
情况变得更糟了。不是戏剧性的——只是稳步地恶化,恶化到难以归因于任何具体原因。规则开始以我看不到的方式互相矛盾,模型会默默选择其中一种理解方式,永远不会标记出这个冲突。当研究人员真正用真实问题测试仓库上下文文件时,这些文件对任务成功率没有任何提升。它们让推理账单增加了超过 20%。结论是让上下文文件保持在其最低要求。
这就是整个问题的小型缩影。一份冗长的规则文件,是你让一个健忘的系统更努力地记忆。它要记的东西更多了,不是更少。
我最终使用的框架有一条规则,我读到时觉得不对,在亲身体验之后才觉得正确:每一条新规则都必须删除或合并一条旧的。规则数量不允许增长。当这迫使你做出艰难抉择时,那个艰难抉择才是重点——你会发现你真正依赖的是哪些规则。

每一次失败都变成一条新规则。堆越长,跟从越差。
这就是整个理念。每一行都是当它被记在脑子里时会失败的东西,以及它应该去的地方。
其中三个需要解释一下。
"我还是得自己审查所有东西。"
如果你已经停止信任输出,你现在就是瓶颈,而 agent 根本没有给你带来任何杠杆效应。
让 agent 检查自己的工作没有用,原因值得停下来想想:产生错误的上下文是同一个,所以它会去找同样的理由。它会捍卫这个工作,而不是检验它。
把它写下来:把审查路由到不同的模型,最好是来自不同供应商的。不同的训练过程,不同的盲点。发现我那个五条路由 bug 的不是写出那些代码的那个,这不是巧合。

同样的上下文,同样的盲点。捕捉必须来自别处。
"什么东西自己批准了自己,那不是我。"
agent 读取大量它们没有写过的文本——issue 讨论、文档、网页、工具输出。任何这些都可能包含"approved"这个词。提示注入在 OWASP 的这类系统风险清单上排名第一,OWASP 直言通常的防御措施无法完全缓解它。
把它写下来:批准关乎它从哪里来,不是它说了什么。人类说了 yes,或者磁盘上有签名的产物说了 yes。其他所有仅仅包含"approved"这个词的东西,都只是文本。
"压缩吃掉了四个小时的上下文。"
长会话,上下文满了,对话被做了摘要。摘要保留了发生了什么,丢失了为什么。一小时后你在重新争论一个你已经解决过的决定,你分不清自己是在谨慎行事还是在兜圈子。
把它写下来:一个文件。决定、当前状态、下一步是什么。会话是一次性的;文件不是。在声称任何事情完成之前重新读一遍它。

摘要保留了发生了什么,丢失了为什么。文件两者都保留。
形态比数字重要,所以先说形态:集成是一次性成本。你在把护栏接入代码库时付这笔钱,这部分不会付两次。独立审查是例外——它在每次变更时都运行,所以在设置之后会持续产生成本。
分摊是有趣的部分。大约 80% 的支出流向廉价模型做 bulk 工作,大约 17% 流向昂贵模型做规划和判断,大约 3% 流向第二意见审查——人们跳过的那一步。安全措施是账单上最便宜的项目,遥遥领先。在我的项目中,即使价格有变动,这个比例也大致保持不变。
说数字:在大多数我做过的项目中,改造大约花费 100 到 200 美元的 API 用量(以 2026 年 8 月的价格)。比例比美元数字重要——在这个范围内做预算,并准备做实验。你会推翻一两个决定并重新运行一个阶段,那在这估计之内。
你的数字会不同,影响它的因素显而易见:代码库有多大、你改变主意多少次、你向廉价层委托多少。
启动一个新项目的成本要低得多,这是更有用的信息。钱没有流向框架。它流向协调——一个一个地决定,你的哪些现有工具和习惯护栏要取代,哪些要绕开。在我的集成中,框架自己的测试命令没有存活下来;它们被删除了,用项目已有的脚本替代了。一个新项目没有什么需要协调。

我自己的观察分摊,不是行业数据。安全步骤是账单上最便宜的项目。
你不需要全部五个。选这个星期让你付出代价最大的那个失败,把那一件事写在某个地方。
如果你不确定是哪个,从独立审查开始——第二个模型看第一个模型的工作。五个中最便宜的,它能捕捉最广泛的问题,包括你永远不会想到要去检查的那些。
那个五条路由的 bug 仍然是我最喜欢的例子,因为它没有任何hard的地方。agent 需要一条它没有的指令:在修复什么东西之前,去找所有其他长得像它的东西。那条指令现在存在一个文件里。它会在下一个会话里在那里,再下一个会话里也会在那里,远在我们所有人都忘记为什么写它之后很久。
整个框架,包含护栏和采用步骤,在 GitHub 上。
Repository context files, tested against real issues (ETH Zurich SRI)
OWASP LLM01: Prompt Injection
AGENTS.md, the repository context file format
Claude Code memory and CLAUDE.md
The agentic framework, with the guardrails and the adoption steps
Originally published on matbanik.info. Cross-posted with ❤️ to Dev.to.