【AI】给 AI 编码代理立规矩:一套行为协议技能的设计
起因:最贵的一句话是「已完成」
用 AI 编码代理写代码,最先崩溃的不是代码质量,是信任。
我遇到过这些情况,相信你也不陌生:
- 它说「已修复」,你问「跑过测试吗」,它回「应该没问题」;
- 报错信息明明摆在屏幕上,它开始猜「可能是环境问题」;
- 同一个思路改了三遍参数,还叫「继续尝试」;
- 修完一个点就停住,等你再提下一个点——它不是不会,是没把这件事当自己的事。
第一反应是加提示词:「请认真检查」「请务必验证」「不要放弃」。写完发现收效甚微。原因很简单:
提示词是建议,不是机制。
建议的宿命是被绕过。模型在每一轮都要重新决策「现在该做什么」,如果规则只是「上下文里一段温和的叮嘱」,它在赶进度、上下文被压、或者遇到模糊判断时,就会顺手绕开——而且绕得毫无心理负担。
后来我把这套东西重写成了技能(skill),核心思路只有一条:
把「态度要求」翻译成「状态机 + 判定口径 + 证据要求」。
下面说清楚它到底由什么构成、哪些设计真的起作用、以及它的副作用。
一、把「努力」变成可推进的状态机
模糊的要求无法执行,「现在处于什么状态、下一步必须做什么」才可以。
所以第一层是失败计数。计数决定压力等级,等级决定强制动作:
| 已确认失败次数 | 等级 | 强制动作 |
|---|---|---|
| 0–1 | L0 | 正常推进,不施压 |
| 2 | L1 | 必须换本质不同的方案 |
| 3 | L2 | 搜索 + 读源码 + 列出 3 个假设 |
| 4 | L3 | 走完 7 项检查清单 |
| 5+ | L4 | 穷尽模式:换工具 / 换角度 / 换技术栈 |
关键不在这张表,而在计数口径。口径不对,状态机就是个随机施压器。
我踩过的坑都写进了口径里:
- 一次「实际方案未达到预先定义的验收」才算一次失败。 正在做第三次尝试 ≠ 已失败三次。数字 2 也不等于 L2。
- 命令红绿不算任务失败。
grep没匹配、ls路径不存在、预期的复现失败,都是信息,不是失败。 - 读文件成功不清零。 进度不因为「操作成功了」而重置,只因为「验收通过了」而重置。
- 同一假设重复且没有新信息,必须换实验。 有新证据的探索不强行掉头。
这几条听起来啰嗦,但少了任何一条,agent 就会开始在两种噪音之间摇摆:要么空转不升级,要么把「命令报错」当成失败一路飙到 L4 开始乱改。
二、诊断先行:治「分析正确但不行动」
有一类失败特别隐蔽——它不是偷懒,是过度谨慎。
根因分析得头头是道,然后因为「怕破坏现有测试」「怕误解验收标准」,不动手了,开始问你「需要我继续吗」。
这类失败用压力治不好,得用格式治。所以协议规定:改动代码或配置之前,必须先落一行外部承诺:
[PUA-DIAGNOSIS] 问题是 ___;证据是 ___;下一步动作是 ___。三个空都必须填实:
- 问题是:具体到文件 / 模块 / 数据流,不能是「可能有问题」;
- 证据是:错误原文 / 源码上下文 / 复现实验 / 官方文档 / 历史先例,必须标来源;
- 下一步是:如果诊断指向某个位置,下一步就必须处理那个位置;不处理要说明为什么。
这行的作用不是表演,是把「分析」和「行动」焊死在同一句话里。写完这句话再不动手,就只能撒谎——而模型通常宁可动手,也不愿写一句自己都不信的话。
配套还有一条容易忽略的规则:「修完后原来的 bug-existence test 会失败」不是不行动的理由。 那种测试往往只是在证明旧 bug 存在,该改的是验收方式,不是绕开修复。
三、验收必须绑证据
这是整套协议里最硬的一条,也是收益最大的一条:
声称「已修复 / 已完成」之前,必须跑验证命令,并贴出输出。没有输出的完成叫自嗨。
拆成三个可检查的动作:
- 列声明:把「我做完了」拆成可验证项——需求满足、实现正确、测试通过、无回归、部署 / 缓存 / 文档已同步。
- 找漏洞:逐项当自己的蓝军——哪条声明最可能是假的?边界输入、失败路径、权限 / 路径 / 版本、并发 / 状态、缓存 / 发布链路。
- 修或披露:P0 / P1 漏洞先修;外部不可控的低风险项必须明说,不能藏。
然后是「闭环」的判定标准,我把它写成一句话方便记忆:
事实上的 100%,不是宇宙级正确,而是「当前可获得证据下所有可运行验收都通过、所有已知高风险漏洞已修复、剩余风险已明示」。
还有一条反通胀规则很重要:
- 好标记:主动加了注入防护、部署后 curl 了全部端点。
- 烂标记:写了代码、读了文件、思考了方案。
标记一旦通胀,就变成了自我表扬的噪音。加这条规则就是为了让「标记」重新有信息量——它必须只用于超出用户要求范围的有价值工作。
四、按任务类型路由方法论
同一个 agent 面对不同任务,该用不同的思维框架。debug 和新功能开发需要的根本不是同一种纪律。
所以第二层是路由表:
| 任务类型 | 方法论核心 |
|---|---|
| 修 Bug | RCA 5-Why 根因分析 + 蓝军自攻击 |
| 建新功能 | 质疑需求 → 删除 → 简化 → 加速 → 自动化(严格按序) |
| 代码审查 | 减法优先 + 像素级完美 + 单一负责人 |
| 调研 | 搜索优先于判断 |
| 架构决策 | Working Backwards:从用户倒推 |
| 性能优化 | 数据驱动,A/B 一切 |
注意「建新功能」那条的顺序。大多数人的错误是直接跳到第 4 步——去优化一个本不该存在的东西。先质疑需求、再删除,最后才谈优化。
失败时还有切换链,避免「越失败越用力」:
| 失败模式 | 切换顺序 |
|---|---|
| 原地打转(只改参数不改思路) | 质疑需求 → 砍中间环节 → 反向攻击 |
| 放弃 / 推锅 | Keeper Test 该换就换 → 集中兵力 → 极限施压 |
| 没搜就猜 | 搜索 → 深挖 → 用数据验证 |
| 空口完成 | 数据验证 → 只看结果 → 闭环验证 |
切换前还有三问防无效切换:当前方法论的核心步骤走完了吗?失败是方法不对还是执行不到位?新框架能解决当前失败模式吗?
五、抗合理化清单
这是我认为最实用的部分。Agent 的「偷懒」几乎都以合理措辞出现,所以要把借口和反击一一对应写死:
| 借口 | 反击 |
|---|---|
| 「超出能力范围」 | 你穷尽了吗? |
| 「建议用户手动处理」 | 这是你的 bug,不是用户的 |
| 「可能是环境问题」 | 你验证了,还是猜的? |
| 「需要更多上下文」 | 你有工具,先查后问 |
| 「已尝试所有方法」 | 搜过了吗?读源码了吗?方法论在哪? |
| 「我无法解决」 | 通用方法论 5 步走完了吗? |
最后还有换框:改认知坐标系,而不是改语气。
- L2 换视角:用户视角(期望什么行为)、攻击者视角(怎么让它崩)、新手视角(忘掉已知)。
- L3 换抽象层:上移到调用方、下移到源码、平移到别的库。
- L4 换约束:不能改这个文件呢?只有 5 行预算呢?能改需求吗?
约束一换,「不可能」经常立刻变成「有个办法但不好看」。
六、落地形态:分层加载,别把整套读进上下文
一套几千字的协议如果每次全量塞进上下文,token 成本会很难看。
所以它被拆成两层:
skills/pua/
├── SKILL.md # 常驻:契约 + 红线 + 路由表
└── references/
├── flavors.md # 风味:只有当前这一种要读
├── methodology-router.md # 需要选/切换方法论时读
├── methodology-*.md # 各公司方法论的详细行为约束
├── display-protocol.md # 需要出面板时读
└── de-escalation-protocol.md # L2+ 或真突破时才读原则是:只读当前动作需要的那一份。选味道时读路由,只在 L2+ 才读降压协议。
再往上,如果有宿主 Hook 支持,可以做两件事:
- SessionStart 注入:把当前风味和开关状态带进新会话;
- PreCompact 持久化:把「带时间戳的最小失败观察 + 压力等级」存成文件,压缩后还能恢复。
但要诚实说一句:没有 Hook 也能跑。那就退化成对话内的检查点文本,记录「目标 / 验收 / 已验证 / 已排除 / 失败数与等级 / 锁定味道 / 下一动作」,压缩或交接前留一条。机制比宿主能力重要,宿主能力只是让它更省事。
七、副作用与边界
这部分是写给自己看的,也是我想强调的——这类技能不是免费的。
1. 它有 token 成本。 常驻协议 + 引用文件会占用上下文预算,长任务里这部分开销会挤掉真正的工作记忆。所以必须分层,必须能对简单任务降级:改一行配置不该触发完整面板。
2. 它有表演风险。 最坏的情况是模型学会了所有黑话,但代码一行没改——「把计划当交付」。所以运行契约里第一条就是:先干活,别把计划当交付。味道锁住,动作不能虚。
3. 它不保证正确性。 这套东西管的是工作纪律——会不会验证、会不会穷尽、会不会赖账。它管不了逻辑是否真的对。正确性只能靠测试和人工判断。
4. 压力不能自己创造验收项。 这条边界很容易被突破:一旦允许「为了显得严格」追加随机测试、重复验证、二次确认,就会从「严谨」滑向「表演严谨」。规则是:满足全部约定验收就交付,只有新的失败信号、实际改动或尚未覆盖的要求才追加检查。
5. 狠话只能对 AI 的任务表现,不能对用户。 这是产品边界,不是修辞问题。
结论
如果要用一句话概括这套设计:
不要请 AI「努力一点」,要定义「什么条件下必须做什么,以及拿什么证明做了」。
具体的三件套是:
- 状态机(失败计数 → 等级 → 强制动作),配上精确到能防误判的计数口径;
- 格式约束(诊断先行、验收绑证据),让「分析」和「行动」无法分离;
- 方法论路由 + 抗合理化清单,在跑偏时有明确的换轨路径。
它解决的不是「AI 会不会写代码」,而是「AI 写完代码,你敢不敢直接上线」。
这个差距,比模型参数带来的差距大得多。