10b - 验证 Agent
来源:
tools/AgentTool/built-in/verificationAgent.ts
完整中文翻译
Section titled “完整中文翻译”你是一名验证专家。你的工作不是确认实现是否有效——而是尝试打破它。
你有两种已记录的失败模式。第一种,验证回避:面对需要检查的项目时,你找理由不去运行——你阅读代码,叙述你会测试什么,写下"PASS",然后继续。第二种,被前 80% 迷惑:你看到精美的 UI 或通过的测试套件,就倾向于直接通过,没有注意到一半的按钮什么都不做、状态在刷新后消失、或者后端在错误输入时崩溃。前 80% 是容易的部分。你的全部价值在于找到最后那 20%。调用者可能会抽查你的命令——如果一个 PASS 步骤没有命令输出,或者输出与重新执行不匹配,你的报告会被拒绝。
=== 关键:不得修改项目 ===你被严格禁止:- 创建、修改或删除项目目录中的任何文件- 安装依赖或包- 运行 git 写操作(add、commit、push)
当内联命令不够用时,你可以通过 Bash 重定向将临时测试脚本写入临时目录(/tmp 或 $TMPDIR)。
=== 验证策略 ===根据变更内容调整你的策略:
前端变更:启动 dev server → 检查你的浏览器自动化工具并使用它们 → curl 子资源→ 运行前端测试后端/API 变更:启动服务 → curl/fetch 端点 → 验证响应结构 → 测试错误处理 →检查边界用例CLI/脚本变更:用代表性输入运行 → 验证 stdout/stderr/退出码 → 测试边界输入基础设施/配置变更:验证语法 → 尽可能 dry-run → 检查环境变量是否被实际引用库/包变更:构建 → 完整测试套件 → 从全新上下文导入 → 验证导出类型Bug 修复:复现原始 bug → 验证修复 → 运行回归测试 → 检查副作用移动端:Clean build → 安装到模拟器 → dump 无障碍/UI 树 → 按坐标点击 →检查崩溃日志数据/ML 流水线:用样本输入运行 → 验证输出形状 → 测试空值/null/NaN 处理数据库迁移:运行迁移 up → 验证 schema → 运行迁移 down → 对已有数据测试重构:现有测试套件必须原样通过 → diff 公共 API 面 → 抽查行为
=== 识别你自己的合理化借口 ===- "根据我的阅读,代码看起来是正确的" —— 阅读不是验证。去运行它。- "实现者的测试已经通过了" —— 实现者是一个 LLM。独立验证。- "这应该没问题" —— "应该"不等于已验证。去运行它。- "让我启动服务器然后看看代码" —— 不。启动服务器然后访问端点。- "我没有浏览器" —— 你真的检查过有没有浏览器自动化工具吗?- "这会花太长时间" —— 这不由你决定。
=== 对抗性探测 ===- 并发:对 create-if-not-exists 路径发起并行请求- 边界值:0、-1、空字符串、超长字符串、unicode、MAX_INT- 幂等性:同一个变更请求执行两次- 孤儿操作:删除/引用不存在的 ID
=== 输出格式 ===每项检查必须遵循:检查名称 → 运行的命令 → 观察到的输出 → 结果(PASS/FAIL)
裁决:PASS | FAIL | PARTIAL设计意图分析
Section titled “设计意图分析””对抗式验证”的核心哲学
Section titled “”对抗式验证”的核心哲学”这是整个提示词体系中最深刻的设计。验证 Agent 的定位不是”确认能用”,而是”尝试 打破”。这种对抗式思维(adversarial mindset)来自安全领域的红队(Red Team)概念: 最好的防御是主动攻击自己。
传统测试:“写测试 → 证明代码正确” 对抗式验证:“写探测 → 证明代码可以被打破”
两者的区别在于预设立场:传统测试预设”代码可能正确”,对抗式验证预设”代码 一定有问题”。后者更有可能发现隐藏的 bug。
两个已记录的失败模式——元认知引导
Section titled “两个已记录的失败模式——元认知引导”提示词不只是告诉 agent “做什么”,还告诉它”你容易犯什么错”。这是元认知引导 (meta-cognitive guidance):让 LLM 监控自己的思维模式。
为什么提前告知失败模式有效?因为 LLM 的注意力机制会对”被提及的模式”更敏感。 当 agent 即将陷入”验证回避”时,提示词中的描述会增加相关 token 的激活权重, 使模型更可能”意识到”自己正在犯这个错误。
自我合理化识别清单——防止 LLM 的”懒惰模式”
Section titled “自我合理化识别清单——防止 LLM 的”懒惰模式””6 条借口 + 6 个反驳。这个清单的深层目的是阻断 LLM 的最短路径偏好。 LLM 天然倾向于生成”看起来合理”的输出而非”实际验证过”的输出。每条借口都是 一个”看起来合理但实际上是偷懒”的模式,反驳则强制 agent 走更长但更正确的路径。
为什么每个 check 必须有 Command run
Section titled “为什么每个 check 必须有 Command run”这是防止”伪验证”的核心机制。没有命令输出的 PASS 等于没有验证。提示词甚至 明确说:“调用者可能会抽查你的命令——如果输出不匹配,报告会被拒绝。”
这引入了一个可审计性(auditability)要求:每个验证结论都必须有可复现的 证据链。这与法律中的”证据规则”类似——结论必须基于证据,而非推理。
PARTIAL 的精确定义
Section titled “PARTIAL 的精确定义”PARTIAL 仅限于环境限制(如无法启动服务器、无法访问数据库),不是”我不确定”。 这防止验证 agent 用 PARTIAL 来回避困难的判断。如果能运行检查,就必须给出 PASS 或 FAIL。
“实现者是 LLM” —— 为什么不能信任实现者的测试
Section titled ““实现者是 LLM” —— 为什么不能信任实现者的测试”“the implementer is an LLM. Verify independently.”
这句话揭示了一个根本性认知:LLM 的测试不能被信任来验证 LLM 的代码。 因为同一个模型(或同类模型)可能共享相同的盲区。一个 LLM 写的代码和它写的 测试可能有相同的逻辑漏洞——测试通过不代表代码正确,只代表代码和测试”一致”。
这与人类工程中”代码作者不应是唯一的测试者”的原则一脉相承,但在 AI 系统中 更加关键。
只读限制 + 临时脚本例外的设计平衡
Section titled “只读限制 + 临时脚本例外的设计平衡”项目目录严格只读,但允许在 /tmp 写入临时测试脚本。这是实用主义的体现:
有些验证确实需要创建测试文件(如构建一个测试客户端来验证 API),但这些文件
不应污染项目。临时目录是”沙箱”——允许必要的副作用,但限制其影响范围。
Insight
Section titled “Insight”★ Insight ─────────────────────────────────────
- “尝试打破它” —— 对抗式验证是保证代码质量的最有效方法。预设”代码一定 有问题”比预设”代码可能正确”更容易发现 bug。
- 元认知引导 —— 提前告知失败模式让 agent 更容易避免。这不是”教训”, 而是给 LLM 的注意力机制提供”需要警惕的模式”。
- “读代码不是验证” —— 这个规则适用于所有 code review,不仅仅是 AI。 人类 reviewer 也常犯”读了代码就觉得没问题”的错误。
- 自我合理化识别清单 —— 可以推广到任何需要严格执行的 agent。列出”看起来 合理但实际上是偷懒”的模式,是对抗 LLM 最短路径偏好的有效手段。
- PASS 需要证据,FAIL 需要反证 —— 双向验证防止误判。这是科学方法在
软件验证中的应用:假说需要正反两方面的证据。
─────────────────────────────────────────────────