30 秒判断:AI 写代码太快时,逐行审查并不能自动恢复掌控感。更有效的做法是:在需求进入实现前固定不变量,在主路径可运行时检查真实状态,在不可逆决定前停下来,在自动化全绿后继续查看真实失败。本文复盘这套方法在一个 Agent 项目中运行 20 多轮后的结果。
适合谁读:正在用 AI 编写较大项目、却发现自己只能“最后看一坨 diff”的开发者;正在设计 AI coding workflow、review gate 或人机职责边界的人;对“测试全绿但系统仍然不可信”有实际体会的人。
系列位置:本文属于《学习问答助手Agent实践》的人机协作复盘。上一篇《AI 写代码越快,为什么我反而越没有掌控感?》提出小步端到端迭代、决策账本、中途检查、证据包和反向解释;本文记录这些规则经过更多实现之后,哪些真正有效,哪些需要调整,哪些应当淘汰。
结构速览:§0 从“审查代码”转向“控制状态”;§1 人应该停下来的四个位置;§2 哪些控制点真正发现了问题;§3 人的职责怎样变化;§4 AI 的职责怎样变化;§5 哪些流程开始变成仪式;§6 ADR 0007 的保留与调整;§7 当前协作工作流;§8 边界与未解决问题;§9 一页速查。
证据标记:✅ 项目实测=真实运行、真实故障或真实界面;🧪 可回归=自动化测试固定行为;🤔 当前判断=基于当前协作经验的阶段性结论。
0. 从“审查代码”转向“控制状态”
上一篇里最重要的发现是:
AI 生成的代码量 > 人能逐行审查的容量
当代码量超过人的阅读带宽后,继续要求“每一行都看懂”会产生两个坏结果:
- 人花很多时间读无关实现,却漏掉真正影响产品的状态变化;
- AI 为了让每个细节都可审批,频繁停下来询问,开发节奏被切碎。
当前阶段更有效的问题不是:
这段代码写得对不对?
而是:
什么用户可观察结果必须始终成立?
什么状态一旦写错就很难恢复?
什么失败不能被自动化结果悄悄吞掉?
什么证据能证明系统确实进入了预期状态?
掌控感因此从“看过多少行代码”变成四件事:
| 能力 | 当前含义 |
|---|---|
| 可预测 | 实现前能说清准备改变哪些状态和边界 |
| 可解释 | 能从代码、trace 和测试说明当前结果为什么如此 |
| 可干预 | 在方向错误或不可逆操作发生前停止 |
| 可恢复 | 失败后能定位、回滚并用同一探针重新验证 |
这与 ADR 0007 人机协作控制模型的定义一致,但经过更多轮实际开发后,“在哪里停下来”变得比“设置了多少审批步骤”更重要。
1. 人应该停下来的四个位置
1.1 需求进入实现前:固定不变量
不是让负责人审完整个方案,而是在实现前回答:
操作完成后,用户必须看到什么?
什么旧数据不能被覆盖?
什么失败必须显式暴露?
什么边界绝不能越过?
例如“支持增量入库”不是完整契约。真正的用户不变量是:
先导入 3 篇,再导入 4 篇不同文档,当前知识库必须有 7 篇。
这条规则比“实现一个快照合并算法”更能约束系统方向。
1.2 第一条主路径可运行时:检查数据流
涉及状态、存储和用户主流程的改动,不应等所有边角完成后才第一次运行。
更有效的中途检查是:
- 一次真实输入是否产生预期的持久状态;
- 用户此刻看到什么;
- 失败时留下什么;
- 已完成路径是否仍符合控制契约。
此时代码还容易改,人也能建立“数据从哪来、在哪里变化、最终去哪”的系统模型。
1.3 不可逆或高影响决定前:C 级决策
删除数据、覆盖现场、改变安全边界、引入高风险依赖,不能让 AI 先做再解释。
例如:
- 人工改判是否覆盖原 Judgment;
- 评测失败是否自动重发;
- 历史 revision 是否允许原地修改;
- 本地 trace 默认保存多少正文。
这些决定一旦实施,后续即使修代码,也可能已经丢掉了判断问题所需的现场。
1.4 自动化全绿后:查看真实失败现场
这是最容易被忽略的一站。
单元测试证明系统遵守了已经写下的规则,但不能证明:
- 真实模型一定遵守协议;
- 浏览器一定按后端分块节奏绘制;
- 连续操作一定满足跨轮不变量;
- 不同组件对同一个 ID 的理解一致。
所以“测试通过”不是终点,而是进入真实探针和 trace 复核的起点。
2. 哪些控制点真正发现了问题
2.1 真实模型探针发现了 fake provider 无法覆盖的行为
协议单元测试可以证明:
Action → Harness 派发 → Observation → 下一轮
控制流正确。
但真实模型曾在一条响应里自行写出 Action 和 Observation,把预测的 count=0 当作已经发生的工具结果。Harness 虽然记录了 protocol_error,旧实现却仍把原始响应放回 History,污染了下一轮上下文。
这不是 fake provider 的测试遗漏,而是测试边界本身:
Fake provider 能证明控制流,不能证明模型会遵守控制流。
有效控制点是“真实模型运行 + 原始输出 trace + 下一轮上下文断言”,不是继续增加同一个 fake provider 的变体。
相关复盘:04 · 模型会自己伪造工具结果。
2.2 反向解释发现了“只靠提示词”的缺口
在 Agent 预算设计里,最初的回答是“工具结果超界就中止”。
继续追问后才发现:
- 完整工具结果不能截断后塞进 History;
- 模型未必会主动告诉用户回答不完整;
- 即使模型最终调用失败,Harness 也必须能返回部分正文和明确限制;
partial、limitations[]和用户警告必须成为系统状态,而不是模型文案。
这才形成后续的确定性预算收口逻辑。
“反向解释”真正有价值的地方,不是让负责人复述代码做了什么,而是暴露出一个还没有被系统强制的失败语义。
证据入口:018 预算披露决策。
2.3 attempt 级 trace 发现失败根本不在同一层
正式 N/K 运行最初出现了“大量基础设施失败”。
但逐 attempt 查看后,问题实际分成了不同层次:
- 调度器在达到目标 N 后继续启动 attempt;
- 又有运行中样本时提前封存,取消剩余 attempt;
- 被取消样本又被错误归类成基础设施失败;
- 真实模型还独立出现了伪造 Observation 的协议问题。
只看一个失败计数,会得出“模型不稳定”或“供应商不可靠”的错误结论。per-attempt trace 才能把调度、Harness、模型和 Judge 的问题拆开。
证据入口:023B 正式运行与失败样本。
2.4 真实界面发现了自动化没有覆盖的引用身份错位
引用来源曾连续出现两次“来源未匹配”:
- 后端在已经包含
doc_id的block_id前又拼了一次doc_id; - 前端按第一个
#截断block_id,丢掉了后半段。
工具结果和引用文本看起来都存在,单元测试也没有发现,因为真正的错误发生在“检索返回 → 来源键 → Markdown 引用 → DOM 定位”的跨层契约里。
有效控制点是真实界面运行和逐项来源映射,不是再检查一次单个函数。
证据入口:020 引用键故障记录。
2.5 负责人的产品判断改变了评测语义
这些决定无法由测试自动得出:
- X 红线即使已有 K 个通过样本,也必须一票失败;
- N<K 只能是 exploratory,不能形成正式通过;
- 从基础设施失败中排除 Agent 产品失败;
- 人工改判必须 append-only,保留判官原始现场;
- criterion 必须自包含,主判官不再接收问题、证据和运行状态。
它们属于产品定义和证据权威,不属于“哪种代码更优雅”。
这说明人的价值不是读得比 AI 快,而是能判断:
这个事实由谁产生?
谁有权修改?
哪个失败不能被其他成功抵消?
什么情况下“看起来成功”其实破坏了评测语义?
决策入口:023A 主判官输入与失败样本资格、023B 人工绑定与 N/K 聚合。
3. 人的职责怎样变化
当前更合适的分工不是“AI 写、人审”,而是:
| 职责 | 人 | AI |
|---|---|---|
| 产品目标与非目标 | 决定 | 提出候选与反例 |
| 核心不变量 | 确认 | 展开为契约和测试 |
| 数据删除、覆盖和安全边界 | 执行前批准 | 提供影响与恢复路径 |
| 架构实现 | 抽查关键边界 | 主导实现 |
| 故障根因 | 确认语义与归因 | 收集证据、提出解释 |
| 测试和失败探针 | 判断是否覆盖关键风险 | 编写与执行 |
| 完成定义 | 最终确认 | 提供证据包 |
| 文档与文章 | 决定价值与叙事 | 起草、校对和维护 |
人不需要读懂全部代码,但必须能回答:
- 系统现在处于什么状态?
- 哪个证据支持这个结论?
- 如果这里错了,会破坏什么?
- 能不能在不毁掉现场的情况下恢复?
这意味着人的注意力预算要集中在少数高价值问题上,而不是平均分配到每个模块。
4. AI 的职责怎样变化
AI 明显加速的环节也变得更清楚:
- 把设计语言展开成类型、存储、API 和 UI;
- 跨后端、前端、测试与文档同步实现;
- 为已经确认的失败语义补回归;
- 从 trace 和日志中收集根因证据;
- 生成完整诊断界面和可读的决策材料;
- 在契约清晰后,快速完成大范围机械修改。
但 AI 不应该被赋予以下权力:
- 自行决定什么数据可以覆盖;
- 用“测试通过”宣布产品语义正确;
- 把一次真实运行当作长期稳定性证据;
- 让模型自述代替 Harness 的执行事实;
- 为了让流程看起来完整,自行编造不存在的验收。
一个很有代表性的变化是:
AI 可以快速修好一个已经被界定的问题,但“什么算问题”不能完全交给 AI。
5. 哪些流程开始变成仪式
经过 20 多轮实际开发,也发现了一些需要收缩的做法。
5.1 把“确认”本身当成控制
只在最后给出一个“代码已完成,请确认”,负责人没有足够上下文做出有效判断。
确认必须附带:
- 改动了哪种状态;
- 哪些不变量被验证;
- 真实失败是什么;
- 哪些内容仍未验证。
否则点击确认只是把责任转移给人,没有建立系统模型。
5.2 为所有 B 级决策追求数量
决策账本的价值是暴露真正的取舍,不是证明一个功能闭环里“讨论了很多”。
没有候选方案、没有不可兼得代价的条目,不需要为了形式进入审批表。
5.3 用反向解释检查肉眼可见的结果
早期曾让负责人解释“哪些文字来自最终答案”,但真实界面一眼就能确认。
后来形成的原则是:
优先问失败、取消、重启、回滚、版本漂移和聚合语义;
不把反向解释变成界面抄写题。
反思来源:020 协作复盘。
5.4 在前台等待可异步完成的工作
PR 检查、长时间评测和后台入库不应该让人或对话一直盯着进度。
更合适的控制面是:
后台任务 → 状态文件和失败原因
人 → 只在完成、失败或需要决策时介入
实现入口:015 GitHub 后台交付。
5.5 用“测试全绿”代替完成证据
当前更可靠的完成定义是:
用户可观察路径成立
+ 核心不变量有测试
+ 至少一个真实失败探针
+ trace 能解释关键状态
+ 文档与代码状态一致
机器负责“已知行为是否稳定”,人负责“已知行为是否就是产品真正想要的”。
6. ADR 0007 的保留与调整
ADR 0007 把自身定义为试行规则,并要求连续完成 3~5 个实质性功能闭环后复核。现在已经远超这个范围,可以形成第二轮判断。
保留
- 小步端到端迭代:仍然有效,因为它让每条主路径都有输入、输出、失败语义和证据。
- 控制契约:仍然有效,尤其是不变量、禁止行为与失败语义。
- A/B/C 决策分级:方向正确,但 A 级应更自主,B 级应更少而具体。
- 可运行检查点:对数据、状态和安全边界仍然必要。
- 外部实践只作假设:继续保留,不把其他团队的经验直接升格为本项目规则。
调整
- 证据包从“测试通过+代码总结”升级为“自动化+真实探针+失败现场+未验证项”;
- 反向解释只问不能从界面直接观察到底层语义;
- 决策账本只记录真实有冲突、需要人承担后果的决定;
- 完成状态必须同时检查业务代码、文档索引和验收记录;
- 异步工作默认交给后台状态机,不在前台轮询。
应当淘汰
- 把最终集中确认等同于掌控;
- 只有测试全绿就宣布完成;
- 为低风险机械修改制造审批;
- 把一次现象直接变成永久流程;
- 把自动化诊断当作最终根因结论。
这篇文章不声称这些规则让项目一定写得更好。它是一个人、一个项目、二十多个完整功能闭环上的实践观察。无论是这里的经验,还是 OpenAI 《Harness engineering: leveraging Codex in an agent-first world》描述的团队实践,都只能作为参考。最合适的方法取决于团队规模、任务风险、工具链、审查成本和可接受失败;最终仍要由每个团队根据自身的运行证据持续摸索和调整。
7. 当前协作工作流
现在的实际流程可以压缩成:
1. 人给出目标、非目标和不可接受边界
2. AI 阅读设计与代码,提出控制契约
3. 只对真实 B/C 决策请求确认
4. AI 实现第一条端到端主路径
5. 人通过真实运行检查数据流和产品语义
6. AI 补失败探针、测试、trace 和证据包
7. 自动化全绿后,再查真实失败与未验证边界
8. 反向解释只覆盖隐藏的状态和失败语义
9. 文档、索引和验收状态同步后完成
10. 异步发布交给后台 watcher
与上一阶段相比,最大的变化不是增加了更多检查,而是:
检查点更少,但每个检查点都要求提供能改变判断的证据。
8. 边界与未解决问题
这套协作方式仍然有明显成本:
- 控制契约和证据包增加了前期与收尾工作量;
- 负责人一旦忽略关键语义,AI 仍可能高质量地做错方向;
- 真实模型和上游服务有不可控抖动;
- 当前没有对照实验,不能证明流程是结果改善的唯一原因;
- 负责人只读摘要和证据,仍可能错过未被视为风险的实现细节;
- 自动化诊断可以给候选归因,但不能替代人对根因的确认;
- 规则数量仍可能随项目增长重新膨胀,需要继续定期退役。
因此“知道在哪里停下来”不等于“已经建立完美控制”。它只是比试图读完所有代码更接近一个可持续的控制边界。
9. 一页速查
旧问题:AI 写得比人读得快,逐行审查无法持续。
新问题:
哪些状态变化必须由人确认?
哪些失败必须进入判官?
哪些事实必须由 Harness 产生?
哪些结果可以自动化继续,哪些必须停下来?
四个关键停点:
- 实现前固定用户可观察不变量;
- 主路径可运行时检查真实数据流;
- 不可逆决定执行前停下;
- 自动化全绿后检查真实失败现场。
最有效的新证据:
- attempt 级 trace;
- 真实模型探针;
- 失败探针;
- 可重算聚合;
- 源码与运行版本的固定引用。
最重要的变化:
人不再试图审查 AI 写出的所有代码,而是控制定义、证据、不可逆边界和最终语义;AI 不再等待逐行指令,而在这些边界内完成实现、验证和诊断。