AI编程代理为何总在生崩?三层架构与自愈机制

AI 编程代理的可靠性问题需靠分离判断与执行、让失败沉淀为规则来解决。
文章指出 AI 编程代理在生产环境中反复翻车的根源不是模型能力,而是任务结构:单步 90% 正确率在十步串联后只剩 35%,错误随步骤复利放大。作者提出 D.O.E. 三层架构,将散文式意图(指令)、判断(编排,由 CLAUDE.md 描述)与确定性操作(执行脚本)分离,让模型只做少量决策而非五十次临时执行。配合自愈机制——要求恢复排在诊断根因、修复、加测试、加标准之后——每次失败都留下可复用的规则与测试。指令中的 Edge cases & learnings 部分让下一个会话提前读到踩过的坑。免费开源的 Agent Ops Kit Lite 提供模板与密钥 linter,可当天试用。
症状:演示时惊艳,周二就翻车
用 Claude Code、Cursor 或 Codex 部署一个修复,它改对了文件、写了像样的提交信息、执行了部署,然后一个小问题出现:CRLF 换行符破坏了服务器上的 shell 脚本,环境变量从错误的文件读取,webhook 密钥在重新部署时轮换。代理注意到失败,通过重试或重置状态来“修复”,然后报告成功。下周新会话里,它原封不动地重演一遍。
这不是模型笨,而是工作的形状决定的。单步任务和真实生产任务之间存在结构性错配。

算术问题:错误会复利
假设代理每一步有 90% 的正确率——对于“解析这个 API 响应并写入正确的行”这类步骤已经算慷慨。串联步骤后概率相乘:
| 模型执行的步骤 | 成功率 |
|---|---|
| 3 个决策,其余由脚本完成 | 0.9³ = 73% |
| 5 步 | 0.9⁵ = 59% |
| 10 步 | 0.9¹⁰ = 35% |
真实任务(获取、解析、转换、验证、写入、部署、验证)往往有十到五十步。如果模型每一步都靠临时编写代码或命令来执行,整个作业的成功率就会崩塌,你只能全程盯着。
修复方案不是更好的提示词,而是把有标准答案的步骤从模型手里移走。
三层架构:指令、编排、执行
作者将其称为 D.O.E. 模型。每一层只做一类工作,层与层之间的边界才是关键。
| 层级 | 性质 | 存放位置 | 变更者 |
|---|---|---|---|
| Directive(指令) | 用散文表达意图:目标、输入、工具、输出、边缘情况、验证方式 | directives/*.md | 人类撰写;代理追加学习记录 |
| Orchestration(编排) | 判断:哪个指令适用、用哪些输入、是否成功 | 代理本身;CLAUDE.md 是它的职位描述 | 人类,极少改动 |
| Execution(执行) | 确定性:获取、解析、转换、部署 | executions/*.py | 代理编写;测试守护 |
指令中永远不含代码,脚本中永远不含策略(“如果……就询问用户”),代理两者都不含:它读一个、跑另一个。这样模型做三个决策而非五十次执行,而决策正是模型真正擅长的事。一个解析响应的脚本只要正确一次,就永远正确。
一个指令长什么样
**CLAUDE.md** 是 Claude Code 在每次会话开始时自动读取的仓库级配置文件,放在项目根目录,内容为 Markdown。它通常用来存放项目约定、构建与测试命令、代码风格、禁止事项等。在 D.O.E. 模型中,它承担“编排层职位描述”的角色:告诉代理三层架构如何划分、遇到某类任务该读哪个指令文件、失败时按什么顺序处理。与之对应,Cursor 使用 `.cursorrules`,更通用的多代理约定则常用 `AGENTS.md`。这些文件本身不含业务代码,只描述“如何工作”,因此人类极少改动,改动一次即对之后所有会话生效。
# Directive: Deploy the API
## Goal
Ship the current branch to the API server and prove it's live.
## Execution tools
executions/deploy_service.py --target api # 规范化 CRLF/BOM,上传,重启
## Edge cases & learnings
- 从 Windows 提交的 shell 脚本带 CRLF 结尾,报 "bad interpreter"。
deploy_service.py 现在会规范化它们。
- webhook 密钥在重新部署时轮换;脚本会刷新它。
## Verification
GET /health 返回 200 且 commit hash 匹配 HEAD。
“Edge cases & learnings”部分才是投资回报所在。代理遇到的每个坑都被写在下一个会话行动之前能读到的地方,而不是凌晨两点重新发现。
自愈机制:让第三个月远好于第一周
光有结构只能止血。真正让系统随时间变好的是关于失败的一条规则:恢复不等于修复。出问题时,代理按固定顺序执行循环:
- 诊断根因:不断追问“为什么”,直到找到修复后能防止复发的那一层。
- 修复:在代码、配置或基础设施中解决。
- 添加测试:能捕获该问题的测试。
- 添加标准:写入指令(如果模式可机械检测,再加 lint)。
- 最后才恢复:重新处理卡住的项目、重启服务。
大多数代理会话先做第 5 步就停了。“我们重新处理卡住的项目”和“加个 cron 重试失败”感觉像进展,却把根因留在原地。把恢复放在最后意味着每次失败都留下一个测试、一条规则,有时一个 lint,让整类错误变得不可能再发生。
一个真实例子
在构建自家商店的结账流程时,一个密钥 linter 在仓库的旧辅助脚本中发现了硬编码的 Stripe 密钥。删掉那个密钥只是恢复。真正的修复是让 lint_secrets.py 在每次提交前运行,并在 CLAUDE.md 中加一行要求它。这类错误从此无法进入该仓库的 git,无论谁(或什么东西)在敲键盘。
恢复(recovery)与修复(fix)的区别值得展开。 恢复指让当前卡住的工作流重新跑起来——重试、重启服务、重置状态、手动重新处理队列项。它的目标是“这一次过去”。修复则针对根因:如果 CRLF 破坏了 shell 脚本,修复不是重新上传一个 LF 版本,而是让部署脚本在传输前自动规范化换行符,并加一条测试或 lint 防止再犯。恢复是战术性的、一次性的;修复是结构性的、可累积的。代理天然偏好恢复,因为恢复见效快、反馈明确,而修复要求它跳出当前任务去追问“为什么”。把恢复排在循环最后,就是用流程强制它先做结构性工作。
密钥 linter 是一类静态检查工具,扫描代码库中疑似硬编码的凭据——API key、token、私钥、webhook secret 等——并在提交或 CI 阶段报错。它通常基于正则模式(如 sk_live_、AKIA 前缀)加上熵值检测来识别高随机性字符串。与运行时防护不同,linter 在代码进入版本库之前就拦截,因此能阻止密钥被写进 git 历史——而 git 历史一旦写入就很难彻底清除,即使事后删除文件,密钥仍留在旧提交中。把 lint_secrets.py 挂到 pre-commit hook 或 CI,意味着无论人类还是代理提交,这条规则都自动生效,不依赖任何一方的记性。
今天就能免费开始
- 在仓库根目录放一个
CLAUDE.md(或.cursorrules/AGENTS.md),写明三层架构和自愈循环。 - 挑出代理最常失败的一个任务,按上述六节写一份指令,指向一个脚本。
- 把该任务中的确定性部分移入脚本,并给脚本加测试。
- 告诉代理:“读 CLAUDE.md,然后运行部署指令。”观察它往“Edge cases & learnings”里追加什么。
作者在 GitHub 上发布了免费的 Agent Ops Kit Lite(MIT 协议),包含 CLAUDE.md、操作原则指令、指令模板和密钥 linter,足以在一个下午对单个任务试用该方法。作者同时销售完整版 Agent Ops Kit(29 美元),含更多指令、经过测试的执行脚本和多代理模板;免费版可独立使用。
核心洞察
AI 编程代理的可靠性问题不是靠换更强模型或写更巧的提示词解决的。它需要在架构上分离“判断”与“执行”,并让每次失败都沉淀为可复用的规则和测试。这套方法的价值在于复利:第一周搭结构,第三个月系统自己会变得更好。对于用小团队运维平台、不想全程盯着代理的开发者,这是一个值得尝试的起点。
相关推荐

uGAP:统一100+非洲地理数据集的AI平台
uGAP是开普敦大学团队开发的非洲地理空间AI平台,统一120余个非洲数据集并提供Python SDK,支持数据发现、处理与模型训练一站式工作流,已用于气旋洪水制图等实战场景。

Cursor能控制你的电脑了:AI代理可驱动桌面应用测试
Cursor 新增桌面控制能力,AI 代理可驱动 iOS 模拟器等桌面应用测试自己构建的功能。本文分析这一更新对开发工作流的影响、技术实现可能路径及可靠性考量。

Vibecoding自研推理引擎:理想丰满,现实骨感
Reddit开发者分享Vibecoding自研推理引擎的真实经历:用WebGL2和GLSL在浏览器跑GGUF Q4模型,却陷入tokenizer调试地狱。本文分析浏览器端LLM推理的工程难点,以及为何直接clone llama.cpp是更理性的选择。