大可的 AI Builder 手记
跟随系统
颜色主题
长沙小桌实战
大可 Dako
大可 Dako大可 DakoAI Builder · Agent 实践者用 AI 做真正能用的产品。专注探索 Agent 工程化落地、Vibe Coding 实践与商业化交付。
内容平台即将上线,敬请期待
产出超过验证吞吐时,只有三个选项静态与类型秒级反馈,语法、类型、lint覆盖不到运行时行为单元测试秒级反馈,函数级行为happy path 盲区大集成与契约分钟级,真实依赖与契约环境不稳会误报端到端分钟级,浏览器与全链路慢,失败定位成本高人工评审小时级,只判机器判不了的吞吐最低,瓶颈本身不能默认发生:扩容、降速或降标准,必须显式选
反馈时延决定自主迭代频率,人工只留给机器判不了的问题。

让验证速度追上生成速度

当产出量超过验证吞吐,只有三个选项:扩验证容量、降 agent 速率、降质量标准,且不能默认发生。

当 agent 的产出量超过你的验证吞吐,只有三个选项:扩验证系统容量、降 agent 产出速率、降质量标准。没有第四个。最危险的是让它默认发生——没人数过吞吐,也没人声明放宽了什么,只是 review 从细看变成扫一眼。

剪刀差已经出现

数据是一致的:Google DORA 研究发现团队采用 AI 越多交付稳定性越降,超过三分之一的开发者对 AI 代码缺乏信任;METR 的对照实验里,资深开源开发者在自家成熟项目上用 AI 辅助反而慢 19%(预期快 25%),额外时间耗在 prompting、等待、读输出和纠正上;百余模型的安全测试显示 AI 生成代码约 45% 引入已知安全缺陷,且模型「让代码跑起来」的能力大幅增长、「让代码安全」的能力基本持平,差距在拉大。bytebytego-verification

原因不是模型不够强,而是成本结构反转:写代码从慢环节变成快环节,验证成为瓶颈。而且 AI 的错误类型——安全缺陷、重复代码——恰好是类型检查和 happy-path 测试的盲区。另一个体量问题:AI 倾向产出更大的 diff,注意力被摊薄,5000 行的 PR 最后换来一句 "looks good to me"。

剪刀差还改变了选型的权重。同一种逻辑有十种写法时,模型必然产出支离破碎的风格混合体,人读得慢、机器验证也难;反过来,格式化、测试、依赖管理内置于同一条工具链的技术栈,人和 agent 需要的东西高度重合——可预测、明确、结构统一。Google 把这概括为:瓶颈从生成转向验证之后,「审查的严谨性」取代「编写的速度」成为选型主轴 go-ai-engineering。还有一条机制层的观察:agent 在没有外部验证的情况下反复重构,第一遍可能 95% 正确,后续交互会复合错误率并污染上下文窗口——把工具链自带的确定性检查放到 agent 随手可用的位置,本身就是验证吞吐的一部分。

验证系统自己也会被压垮

这不是假想,Anthropic 自己正在经历。一手数据:工程师人均季度产出代码量是 2021–2025 年间的 8 倍,其中 80% 由 Claude 写出;测试总量涨了 10 倍,工程师数量基本没变;结果是半年内 CI 任务量涨了 25 倍。那套决定「每个变更跑哪些测试」的确定性服务连续多次濒临过载,负责人连续两天被叫醒。

三个补丁的续命时间一次比一次短:机器核数加倍,撑了 70 天;改成分片并行,撑了 29 天;改成每日重启,撑不到一天。而推倒重设计只花了一个人三周——同样体量的重构放在一年前大约要一个季度。判断很直接:写代码不再是瓶颈之后,补丁的续命时间随负载增速递减,重设计的工期却随 AI 辅助缩短;给 v0 设计留出当前感知规模 10–20 倍的余量,比三番五次打补丁便宜。

根因值得记住:测试结果历史放在进程内,为了保序只允许单写者——这个结构从第一天就堵死了水平分片。重设计后的形态是 worker 无状态(收到结果追加进日志就返回),独立消费者每几秒把日志滚动汇成每个测试一条历史,查询侧直接读汇总。滞后不只是慢:监听器落后一小时,选择器就在用过期数据做决策——坏变更合并后全组测试开始红、依赖抖动会让红色阻塞所有合并、刚修好的测试反而没人跑了。

还有两条给 agent 时代专门准备的做法。一是把服务指标做成 agent 的眼睛和耳朵:进来多少 CI 任务、出去多少,两边对上账,agent 就能自己在指标上爬坡、逐个排查增量劣化,比人盯快得多。二是 agent 与人的自验证方式不同:人能自行判断哪些失败与自己无关,agent 需要一份明确的「有效测试集」才知道该盯哪条,否则它把测试集里的每一处红都当成自己的失败反复返工 anthropic-ci-test-selection。

按反馈时延匹配验证层级

完整链条是 静态 → 单元 → 集成 → 运行时 → 基线 → 端到端 → 人工。层数不固定,深度由风险决定:低风险改动跑前两层就够,涉及资金、权限或不可逆副作用的必须走到端到端加人工。

匹配原则是反馈时延决定自主迭代频率:

  • 秒级反馈(编译、类型检查、单测)支撑高频自主迭代。agent 能在一次循环里试错几十次,前提是每次几秒内得到判定。
  • 分钟级反馈(集成测试、契约测试、浏览器自动化)覆盖更真实的行为,代价是迭代频率下降一个量级。
  • 人工判断只留给机器判不了的问题:意图是否合理、取舍是否可接受。把人工放在能自动判定的环节上,是用最贵的资源做最便宜的事。

前移,并检查假修复

Shift Left:同类检查尽量前移。编辑器里或 commit 时发现缺陷,成本远低于 review 时和生产时。能静态查的不要等到运行时,能在 CI 查的不要等到灰度。

同时要防假修复:验证的是根因已消除,不是错误信号消失。agent 在「让测试变绿」这件事上很有创造力,典型手法包括删掉报错的日志、把日志级别从 error 降到 debug、吞掉异常、放宽断言阈值。评审时盯这几类 diff,看到测试断言被改动,先问为什么。

先写检查,再写代码

给 agent 一套能自己跑的检查,比让它多写几版更有用。检查分三种,各回答一个问题,不能互相替代 addy-agentic-verification:

  • 端到端测试回答「应该发生什么」。它模拟真实用户流程(注册、加购、结账、看到确认),绕过内部结构,只看用户能看到的结果。它是最难糊弄的判据:要么整条流程通过,要么不通过。给 agent 当靶子时,完成标准就从「实现这个功能」变成「让这条 E2E 通过」——后者它自己能追。代价是慢、偏 flaky,所以只留少量高价值的核心流程。
  • 属性测试回答「绝不允许什么」。例子测试只能覆盖你想得到的输入;属性测试反过来:写一条必须始终成立的约束,由工具生成成百上千个输入去打破它。常见四类属性是 round-trip(编码再解码等于原值)、不变式(排序不改变元素个数、余额不为负)、幂等(同一操作做两次等于一次)、等价(优化后的函数与朴素正确版结果一致)。找到反例后要缩小成最小反例并留作回归。关键是让 agent 写属性而不是写例子:它自己想的例子往往按内部逻辑挑,属性则逼它面对生成器给出的任意输入。
  • 差分测试回答「新旧哪里不一样」。替换旧系统时,把新旧两版放在同一批输入上并排跑,不一致要么是新引入的 bug,要么是一处需要记录的破坏性变更。输入要随机生成或回放真实流量,别用手挑的样例。比对前先归一化不承载语义的差异(顺序、无关字段),否则会得到无穷无尽的假差异;把每一处「有意改变」记进一张 approved-changes 清单,别让「不一样」变成可以接受的状态。旧系统是 oracle,你不必给 agent 讲清每个边界;但旧系统也可能有错,差异只说明不同,是否保留仍由人判断。

检查本身还得快、得确定。这不是在省时间,是在训练:如果测试慢或不稳,agent 会从循环的激励里学会「重试比修复更划算」——一旦偶尔重跑就变绿,重试就成了它的首选策略;如果一次要跑十几分钟,它就会把更多改动攒到一起再跑,最后定位不到是哪一处改坏的。flaky 测试要从主套件里立刻摘掉,一条时红时绿的测试比没有测试更糟,它毁掉的是对所有其他结果的信任 addy-agentic-verification。

还有一层常被跳过:检查项要按任务类型定制,而不是共用一套笼统的「完成」。 一位 Java Champion 迁移 900 张教学幻灯片时,把门定义成截图、视觉差异、动画、PDF 输出和内容完整性五项——并排跑新旧两版、对截图做视觉与算法比对、连生成的 PDF 也比对,用他的话说,「这样 agent 就不能只说一句迁移完成,我们有证据」。同一套原则换到重构上,门就变成测试通过、所有目标文件都处理到、文档已更新、不留 TODO。门的具体项因任务而异,原则不变:agent 要能拿出证据证明满足完成定义,「模型说完成了」不算完成 java-champions。

这位开发者的另一句总结更凝练:委派执行,不委派责任——结果仍由人负责。他明确划了一条线:错别字可以自动修,但凡涉及内容、版本、日期或含义变化,都必须先讨论。同一位受访者还提到一个反直觉的做法:非平凡任务先让 agent 采访你,把仍隐含的假设与预期挖出来——「一个好 agent 能极快地执行一个错误的想法,但这不会让绕路更便宜」 java-champions。

可行动性判据

验证信号只报告开发者能采取行动的问题。一条每次都红、没人知道该改什么的告警等于没有告警,它的真实作用是训练团队忽略这个面板。持续监控误报率并调阈值——高频误报侵蚀信任后,真警告会被一并忽略。

速度、精度、覆盖三者不可兼得,必须显式声明取舍。不要默认全要,那只会导致慢、漏且不被信任的组合。选哪个取决于变更的风险等级:高风险变更放弃速度,探索性原型可以放弃覆盖。

同一套判据也适用于评估集本身,而这里省下的不是精度,是吞吐。OpenAI 整理 SWE-bench Verified 时,从 2294 个原始任务里随机抽出 1699 个,招 93 名精通 Python 的开发者逐条核查五件事:问题描述是否清晰、测试是否覆盖边界条件、测试是否稳定、参考 patch 是否引入新错误、难度是否合理。最终只留下 500 个,被核查的任务淘汰约 71%。高淘汰率同时买到信噪比和预算:评估成本随之下降约 80%。这一项不能忽略——复杂 Agent 任务单条要跑数分钟到数小时,用前沿模型完整跑完一个评估集往往是数千美元量级的 token 费用。ai-agent-book 砍掉判不准的用例,和「review 从细看变成扫一眼」不是一回事:前者改了用例的验收定义并留下记录,后者什么都没改,只是少看了。

验证信号本身也有噪声

变异测试是另一种加固手段:生成代码变体跑同一测试套件,测试没红说明测试集漏检。AI 引入的缺陷常绕开手写样例,靠不变式(见上一节)更容易兜住。

最后是测量本身的可靠性。Anthropic 量化过 agentic coding eval 的基础设施噪声:最宽裕与最严配置之间差 6 个百分点(p<0.01),而 leaderboard 前几名常常只差几个点。资源限制会改变 eval 实际测的东西——紧限制奖励精简策略,宽限制奖励暴力重型策略,混在一个分数里不加区分会掩盖差异。建议同时指定保底分配与硬 kill 阈值两个参数,把资源配置当一等实验变量记录;leaderboard 差距低于 3 个点应持怀疑态度,直到配置被记录并匹配。anthropic-infra-noise

同一把尺子也要拿来量你自己的分差。有限样本上的成功率自带抽样误差,标准误约为 sqrt(p(1-p)/n):100 个用例、成功率 70% 时,95% 置信区间大约是 70% ± 9 个百分点。所以「新模型 73%、旧模型 70%」根本不足以支持切换——它整段落在噪声里。ai-agent-book

比较两个配置要做配对分析:逐题记录谁胜出,用 McNemar 检验或配对 bootstrap 判定差异,而不是把两个独立测得的成功率相减;配对的意思是两组共享同一批任务和同一批随机条件。由于 Agent 每次运行本身也会变,每个配置至少跑 3–5 个随机种子,报告均值和波动范围,单次运行只够用来筛方向。如果预期收益只有 2–3 个百分点,而评估集只有几十题,正确动作是先扩样本——标准误按 1/sqrt(n) 收缩,靠这点分差跑不出结论。并行验证多个假设时还要防多重比较:收紧显著性阈值,或者对正向结果独立复跑。分差超过噪声、配对分析成立、且能复现,才值得据此换模型或发布改动。ai-agent-book

还有一条容易忘的清理规则:每个强约束都要过双目的检验——同时服务质量与交付流动,两者都不服务的约束应当移除。约束会自己堆积腐化。

参考资料

  1. Why Code Verification Matters More Than Ever in the Age of AI
  2. Quantifying infrastructure noise in agentic coding evals
  3. 《AI Agents in Depth》第七章 Agent 的评估
  4. Agentic coding is straining CI. Here's how we scaled test impact analysis at Anthropic
  5. Agentic Verification
  6. GitHub Blog:三位 Java Champion 如何使用 Copilot(委派执行不委派责任)
  7. Why Go is an Ideal Language for AI-Assisted Software Engineering(Google)