[AI辅助创作] Vestigra开发日记(四):AI写代码很快,但证明它写对了很慢
AI 创作声明:本文由作者提供原始素材、核心观点和最终判断,AI 参与结构整理、表达润色和发布格式化。文章发布前由作者审核确认。
前言:代码早就写完了,Issue 怎么还没结束?
最近两天,我盯着 Vestigra 的开发流程,反复冒出一个很奇怪的感觉:
AI 的开发效率好像很低。
这句话听着有点反直觉。AI 不需要休息,找代码、改文件、跑命令都很快,一个 Issue 的实现有时没多久就能写完。
但真实画面通常是这样的:代码改完了,后面还要完整编译、部署到虚拟机、启动产品、跑自动化测试。测试一旦失败,还得先判断是实现错了、脚本错了、虚拟机状态不对,还是单纯的环境抖动。判断完再修,再编译,再部署,再跑一次。
一轮性能测试就可能要五六分钟,长一点甚至超过十分钟。只要重复两三轮,实际写代码的时间反而成了整个 Issue 里最短的一段。
这就很尴尬了。
第三篇开发日记里,我还在想“什么才算真正完成”。到了第四篇,问题变成了另一面:如果每次都要把整个产品重新证明一遍,一个 Issue 到底什么时候才能结束?
一、第一次觉得 AI 慢,确实是产品把它拖慢了
这不是我第一次觉得 AI 开发效率低。
前一次的原因比较直接:Vestigra 当时有严重的 Runtime 性能问题。产品运行时间越长,各种执行事件越慢,文件读写也越来越慢。
AI 的开发活动并不是飘在空中的。它同样要读文件、搜代码、写 diff、调用编译器和执行测试。底层环境开始卡以后,它的每一步都会跟着卡:
- 搜索代码变慢;
- 读取和修改文件变慢;
- 编译、部署变慢;
- 测试结果也迟迟回不来。
当时我把问题归到产品性能瓶颈上,这个判断并没有错。无论操作电脑的是人还是 Agent,只要文件系统和执行环境越来越慢,开发都不可能快。
后来这一轮性能问题处理掉了,我原本以为开发速度会立刻恢复。
结果并没有。
文件能正常读了,命令也不再慢吞吞,但一个 Issue 从开始到真正结束,还是要花很久。
这次拖住它的已经不是产品性能,而是验证。
二、真正耗时的,开始从“写代码”转移到“证明代码”
Vestigra 现在已经积累了一套覆盖面不小的测试:
- Smoke 测试;
- 基础功能测试;
- 真正启动产品、验证实际行为的功能测试;
Ring0测试;- 性能测试;
- 回归测试;
- 针对历史 Bug 留下来的自动化脚本。
这些测试单独拿出来都很有价值。它们能防止我只证明“代码可以编译”,却没有证明产品在真实 Runtime 里还能工作;也能防止前面辛苦修过的问题,过两轮开发又偷偷回来。
但我最开始犯了一个很朴素的错误:
既然这些测试都有价值,那就每完成一个 Issue 全跑一遍。
于是开发闭环逐渐长成了这样:
1 | |
自动化测试只要报错,AI 就不能简单地说“失败了”。它还得继续查:
- 当前实现是不是真的有问题;
- 测试脚本是不是写错了;
- 虚拟机是不是残留了上一轮状态;
- 产品有没有正确启动;
- 这次性能波动是不是偶发噪声。
有时候查到最后,代码根本不需要改,只是环境要重置,再跑一次。
有时候确实是代码问题,那就得把整条编译、部署、启动和测试链路再走一遍。
所以“代码写完”和“Issue 结束”完全是两回事。AI 写得再快,也不能跳过后面那段昂贵的证明过程。
三、测试越完整,我反而越容易把每个 Issue 困住
以前我会下意识地把测试覆盖率和质量画上等号。覆盖得越多,心里当然越踏实。
但真实跑起来以后,我发现自己混淆了两件事:
1 | |
一套测试应该保留,不代表它必须在每一个开发节点都执行。
尤其是性能测试。它本身就要跑五六分钟,有时超过十分钟,而且对机器状态、采样窗口和 Runtime 环境都比较敏感。一次失败消耗的不只是十分钟,还包括读日志、判断原因、调整环境和再次执行。
两三轮下来,一个很小的 Issue 也能被拖成一场持久战。
于是我做了一个一开始听上去很危险的决定:
把大多数自动化测试从单个 Issue 的默认开发链路里拿出去。
这里的“拿出去”不是删除,更不是以后不测了。
我仍然要求开发阶段完成必要编译、部署,并把产品真正启动起来。当前 Issue 的关键逻辑也必须在 Runtime 里跑通,不能退化成“编译成功就算交差”。
我拿掉的,是每次局部修改之后都重复执行整套性能、回归和广覆盖测试的要求。
测试没有变少,只是被放到了不同的节点。
四、AI 不下班以后,Nightly 这个天然窗口消失了
以前人写代码时,长测试有一个很自然的去处:Nightly。
白天开发,下班后让 CI 跑性能测试和完整回归。第二天人回来,再看报告、修问题。人的工作时间结束以后,机器正好接管耗时验证。
AI 没有这个节奏。
一个 Agent 做完当前 Issue,可以立刻做下一个。开发过程不会因为晚上到了就自然停止。如果完整测试还在等待“下班以后再跑”,那它可能永远等不到一个明确窗口。
可如果每个 Issue 后面都跑,AI 就会被测试链路反复堵住。
这不是简单地选择“要效率”还是“要质量”。真正要重新设计的,是完整验证到底跟着什么触发:
- 跟着每一次代码修改?太重;
- 跟着每一个 Issue?还是太频繁;
- 跟着人的作息?AI 又不下班;
- 跟着一个明确的阶段性交付?目前看更合理。
所以我开始把“开发完成”“Issue 验收完成”和“阶段性交付完成”彻底拆开。
五、我现在把验证拆成三个层次
现在这套流程,大致被我分成了三层。
第一层:Issue 开发
负责实现的 Agent 完成当前 Issue,并做必要的编译、部署和核心运行态验证。
这一层追求快速反馈,但不等于只做静态检查。产品必须真的启动,当前改动影响的关键链路必须真的执行。
这里不再默认运行全套性能测试、回归测试和历史 Bug 脚本。
第二层:单个 Issue 的独立验收
实现完成以后,交给独立验收者,只回答一个具体问题:
这个 Issue 是否满足自己的验收标准,并且在干净环境里真的能工作?
它关注的是局部正确性,不负责顺手证明整个 Vestigra 在所有维度上仍然正确。
第三层:Sprint、里程碑或阶段性目标的完整验收
只有一个阶段里的所有 Issue 都完成开发,并且逐个通过独立验收以后,才统一执行完整自动化测试。
这一层才会跑:
Ring0测试;- 广覆盖产品功能测试;
- 性能测试;
- 回归测试;
- 针对历史 Bug 保留下来的自动化脚本。
如果这里发现问题,就创建新的 Issue,重新进入开发和独立验收,而不是假装前面的局部验收没有价值。
现在三个“完成”的关系变成了:
1 | |
它们不是重复做同一件事,而是在证明不同范围的正确性。
| 阶段 | 主要回答的问题 | 验证范围 |
|---|---|---|
| Issue 开发 | 当前实现是否基本可用 | 必要编译、部署、核心运行态验证、当前 Issue 直接相关测试 |
| Issue 独立验收 | 当前 Issue 是否满足自己的验收标准 | 干净环境中的定向功能验证 |
| Sprint / 里程碑验收 | 这一批变更有没有破坏整体产品 | Ring0、广覆盖功能、性能、回归和历史 Bug 测试 |
六、AI 还把我的意思理解错了一次
我第一次把这套流程讲给 AI 时,它给出的方案看上去很接近:开发阶段不跑完整测试,等验收完一个 Feature,再跑一次完整自动化。
我看完以后发现,还是不对。
它只是把完整测试从“每个 Issue 开发完成后”,挪到了“每个 Feature 验收完成后”。名字换了,频率并没有真正降下来,原来的效率问题还在。
我真正想要的是:
- 验收单个 Issue 时,只验证这个 Issue 本身;
- 一个阶段里的所有 Issue 都验收完成以后,再统一执行广覆盖测试;
- 完整测试服务于阶段性交付,不服务于每一个局部变更。
这次误解反而帮我把验证粒度想得更清楚了。
以后我不能只对 Agent 说“开发和验收分开”,因为这句话太容易被形式化执行。真正需要写进流程的是:每一层验收拥有什么范围、由什么条件触发、失败以后回流到哪里。
否则 AI 会非常认真地执行一套看起来分层、实际上仍然很重的流程。
七、两套虚拟机,分别证明“从零开始”和“长期活着”
Vestigra 的开发和验证现在还涉及两套不同环境。
第一套是干净虚拟机。
每个 Issue 完成以后,产品要部署到这套环境里。它不保留上一轮安装和开发留下来的状态,主要回答:
当前实现能不能在一个全新的环境里安装、启动和运行?
第二套是持续运行的虚拟机。
它不会在每个 Issue 后重置。产品持续运行,状态持续积累,等到新的里程碑版本形成后,再部署进去做阶段性验证。
这套环境主要观察另一类问题:
- 长期运行以后会不会逐渐退化;
- 多轮升级以后旧状态会不会污染新版本;
- Runtime、队列和数据是否会随时间积累出问题;
- 干净环境里看不出来的连续性问题会不会再次出现。
一套验证“从零开始”,一套验证“长期活着”。
两套环境都需要,但没有必要让每一个 Issue 同时承担它们的全部成本。
八、走向多 Agent 之前,我得先看清时间花到哪里了
目前我还没有真正开始多 Agent 并发开发。
单 Agent 慢的时候,我多少还能靠感觉发现:它是不是在某一步停了太久,某个测试是不是重复失败,编译和部署是不是明显不正常。
多 Agent 就不一样了。
多个任务一起跑,Issue 在变化,日志不断刷,编译和测试到处发生。整个系统看起来会非常忙,但“很忙”不等于“很快”。某些 Agent 可能已经困在失败重试里,只是被并发制造出来的热闹遮住了。
所以在扩大并发以前,我还需要给 AI 开发系统补一层最基本的可观测性:
| 指标 | 我想回答的问题 |
|---|---|
| 编译耗时 | 时间是不是主要卡在构建和工具链 |
| Issue / Feature 开发耗时 | 实际实现到底花了多久 |
| 单个 Issue 验收耗时 | 局部证明的成本有多高 |
| 完整测试耗时 | 阶段性交付的整体证明有多重 |
| 失败分析与重试耗时 | 多少时间消耗在无效循环里 |
| 不同环境的部署耗时 | 干净环境和持续运行环境分别带来多少成本 |
这套效率追踪现在还没有真正做完。我只是已经确认,不能等到多 Agent 全部跑起来以后,再靠肉眼猜哪里慢。
代码系统需要 observability,AI 开发系统同样需要。
目前的结论:写得快,不等于交付得快
回头看,这两次“AI 怎么这么慢”,其实是两个完全不同的问题。
第一次是环境瓶颈。Vestigra 自己的性能退化,把读写、编译和执行全部拖慢了。
第二次是验证瓶颈。产品逐渐成熟,测试越来越完整,证明一个改动可靠的成本开始超过写出这个改动的成本。
我现在做的不是减少质量保障,而是重新安排质量保障发生的时机:
- 单个 Issue 尽快获得真实运行反馈;
- 独立验收只证明当前 Issue;
- 完整测试留给 Sprint、里程碑或阶段性交付;
- 干净环境负责可重复性;
- 持续运行环境负责连续性;
- 最终再用数据看清开发、验证和重试到底各自花了多久。
AI 不会疲劳,也不会主动下班,但编译、部署、启动、性能测试和失败重试的成本不会因此消失。
当写代码越来越便宜以后,真正昂贵的已经不只是设计“什么才算完成”,还包括设计“要在什么时候、用多大成本,证明它真的完成了”。
这是我目前给 Vestigra 开发流程划下的新边界。
等效率追踪和多 Agent 并发真正跑起来以后,这套边界大概还会再被现实推翻一次。