第二阶段 · 可靠的本地编码 Agent第 9 / 30 章
本章目录

第 09 章 · 验证闭环

本章目标:让 Agent 的“完成”由外部证据驱动,而不是由模型语言风格或自信程度驱动。

1. 生成和验证是不同工作

模型擅长提出修改,但同一个上下文里的模型也容易合理化自己的方案。它可能看到代码看起来正确,就说“问题已修复”,却没有运行测试。Agent 框架应把完成条件变成显式步骤:检查 diff、运行相关测试、运行静态检查,并把结果重新送给模型。

验证闭环是:

目标 → 修改 → 外部检查 → 观察结果 → 修正或完成。

这与主循环重合,但强调最后一跳必须有证据。没有证据,只能叫“提出了一个候选答案”。

2. 验证信号的层级

层级 例子 能证明什么
语法与格式 py_compile、formatter check 文件可解析、格式满足规则
静态分析 类型检查、lint、安全扫描 一部分结构错误与规则违规
单元测试 相关函数测试 局部行为符合断言
集成与端到端 API、浏览器、数据库流程 多模块真实协作
人类验收 产品判断、视觉质量、风险接受 无法完全形式化的价值

检查越靠下,通常越接近用户行为,也越慢、越脆弱。Agent 应先运行便宜且相关的检查,再根据风险扩大范围。

3. 如何选择相关测试

最简单的方法是使用项目规则提供的标准命令。更精细的系统根据修改文件、依赖图和历史覆盖关系选择测试。无论如何,模型必须说明为什么这些检查足够。

只运行原来失败的测试可能造成回归;每次运行完整测试又可能成本过高。可以先跑失败测试与邻近单元测试,成功后再运行模块级或全量检查。验证计划本身也是一个需要预算的决策。

4. 防止“测试迎合实现”

Agent 可能通过修改测试让错误消失。测试当然也可能有问题,但删除断言、降低阈值或跳过测试应视为高风险行为,需要额外说明和审查。Runtime 可以检测测试文件变化,并触发 Reviewer。

另一个风险是只看退出码,不看测试数量。命令因为路径错误没有收集到测试,却返回可疑结果。验证器应记录 collected、passed、failed、skipped 等摘要。

5. 非代码结果怎样验证

网页需要真实打开、点击和截图,不能只检查 HTML 字符串;文档需要渲染后检查分页;数据任务需要行数、约束和样本核对;外部操作需要读取目标系统确认状态。原则不变:找到一个独立于生成文本的观察通道。

对于主观质量,可以让独立 Reviewer 根据明确 rubric 评审,但这仍不等于事实验证。最好把可机械检查的部分先机械化,把人类留给真正需要判断的部分。

6. 完成协议

最终回答应包含修改摘要、验证命令与结果、未运行的检查和剩余风险。Runtime 还可以要求 final response 满足结构化 schema,避免模型漏报失败。

{
  "status": "completed",
  "changes": ["Fix quantity calculation"],
  "checks": [{"command": "pytest -q", "result": "12 passed"}],
  "residual_risks": []
}

核心判断

“我检查过代码”是过程描述;“pytest 收集 12 项并全部通过”是证据。设计 Agent 时,持续把前一种表述改造成后一种数据。