AI生成代码能运行,仍可能无法使用
作者复盘本地多代理开发中的验收短板:生成的塔防游戏虽有完整外观和循环,却把普通对象放入期望类实例的弹丸列表。案例说明仅确认程序启动,无法证明核心功能正确。
AI 深度解读
AI 写出的页面能打开、控制台没报错,离「功能可用」还有多远?作者在消费级硬件上运行多智能体团队时,遇到的短板是 QA:负责验收的 Hans 接连放过了首次开火就崩溃的游戏,以及命令能执行却很难用的工具。
这篇系列第 8 篇的结论很直接:验收失效,未必需要更大的模型来救场。先把「怎样才算能用」写成具体动作,比一句「请测试一下」更有帮助。对用 AI 生成前端页面和小工具的人,这几个失败案例很有参考价值。
页面能打开,为什么第一下操作就崩了
他们团队生成过一个塔防游戏:单文件 HTML,使用 canvas,图形由代码绘制,包含 Enemy、Tower、Projectile 等类,也有正常运行的游戏循环。静态看起来,交付已经完成。
问题藏在炮塔第一次开火时。创建投射物和更新投射物的两段代码,对数据结构的理解不一致:
// a Tower fires by pushing a plain object:
projectiles.push({ x, y, target, ttl });
// but the game loop expects Projectile instances:
class Projectile { update() { /* move, check for a hit */ } }
for (const p of projectiles) p.update(); // TypeError: p.update is not a function
关键是最后一行:循环要求每个元素都有 update() 方法,但塞进数组的只是普通对象。Projectile 类虽然定义了,却没有被实际使用。
加载时,地图、炮塔、敌人都能画出来。直到第一发投射物进入数组,才会触发 TypeError: p.update is not a function。
Hans 第一次验收给了 PASS,实际上根本没有运行游戏。作者随后加强规则:没有执行过就不能通过;增加 CANNOT VERIFY,避免「没法测」被当成通过;明确要求用 node -e 执行 JavaScript,并追踪用户的第一次操作。
第二次,Hans 确实启动了无头 Chromium,加载页面、截图、检查控制台。没有报错,于是再次给出 PASS。
但截图拍在加载完成时,没有放置炮塔,也没有开火。测试执行了,触发故障的动作仍然缺席。
页面加载成功,只能证明加载这一步成功。
作者还把同一游戏交给了 120B 协调模型。它根据同样的加载截图,也给出了通过判断。这个案例支持的是:增加模型规模没有自动补齐验收动作。作者据此主张,应把指令写成「放置炮塔并完成一次射击」,而不是「检查页面能否加载」。
命令执行成功,也可能根本不好用
另一个交付物是命令行任务工具。Hans 使用任务的完整标识符执行命令,操作成功,便认为工具正常。
但实际标识符是原始 UUID。用户输入 python3 taskflow.py done 1,得到的却是 Task ID 1 not found.;真正需要输入的是 da258ee6-66ca-4f1a-a27e-9169b15739bf。
这里没有出现运行异常。问题在于,测试者手里已经拿着正确参数,绕过了用户最费劲的一步:找到并输入那个标识符。
完整 UUID 能否被复制、列表里是否容易找到,原文没有交代,不能仅凭这一点判定整个工具完全不可用。但作者指出的验收缺口成立:验证「给定合法 ID 能否完成任务」,没有覆盖「人能否顺利完成任务」。
后来,Hans 在一个长篇配图故事网站上给出了更有价值的报告:
Verification Result – CANNOT VERIFY
- story.md – present and complete.
- All 50 scene images (scene1.png … scene50.png) – present and each > 5 KB.
- index.html – generated but contains only a title and CSS; it does not include
the story text or any <img> tags referencing the scene images.
要看最后一项:index.html 只有标题和 CSS,既没有故事正文,也没有引用图片的 <img> 标签。
story.md 完整,50 张场景图从 scene1.png 到 scene50.png 全部存在,每张都大于 5 KB。这些检查都通过了,网站仍没有完成展示故事的任务。
Hans 这次没有被文件清单迷惑,而是指出了交付物之间缺失的连接。CANNOT VERIFY 至少让这次验收没有被错误地归入 PASS。
输出路径也是交付的一部分
作者还遇到了环境制造的假成功。多进程运行时,各 agent 的工作目录是自己的 profile 文件夹。使用相对路径或基于 ~ 的路径,可能把文件写到意外位置。
原本应该进入 /home/user/hermes-runs/ 的输出,最终落到了类似 /home/user/.hermes/profiles/gatsby-manager/home/hermes-runs/ 的目录。文件确实写了,接收它的流程却找不到。
作者的修正是统一使用绝对输出路径。另一次,启动器配置指定了某个脚本,但脚本没有复制到对应位置,启动立即失败。
这与前面的 QA 问题相通:命令返回、文件生成,都是局部信号。要验证交付完成,还得确认文件位于预期位置,并且下一环节能够实际使用它。
我的判断
我赞同作者把重点放在验收方法上。前端交互、命令行操作、资源组装,分别暴露了三种常见遗漏:没有触发行为、跳过使用成本、没有检查最终呈现。它们都很难靠一张截图或一份文件列表覆盖。
但「不需要更好的模型」仍应收窄理解。原文给出的是具体项目里的失败案例,没有不同模型、多轮任务的系统对照数据。120B 模型这一次也误判,能说明大模型不会自动保证正确验收,不能证明模型能力对 QA 毫无影响。
加强指令也是经验之谈。原文没有提供足够数据,说明增加规则后漏检率下降了多少。对于会反复迭代的项目,我更倾向于把已经发现的关键操作固化成可重复的测试,让 agent 负责探索和解释异常,减少每次重新理解验收要求的成本。
报告状态也可以再分清楚。故事页面明确缺正文和图片,按通常的软件验收习惯,更接近「验证失败」;CANNOT VERIFY 更适合环境缺失或证据不足。无论叫什么,关键是说明执行了什么、观察到了什么、还有什么没覆盖。
能拿来做什么
- 让 AI 验收交互页面时,把首个关键操作写进要求。塔防游戏需要放置炮塔、等待射击,并检查射击后的运行状态;只检查加载阶段不足以覆盖这个功能。
- 验收命令行工具时,从用户实际获得的信息开始操作。先查看任务,再选择任务并执行完成命令,才能暴露标识符难以使用的问题。
- 验收内容型网站时,同时检查源文件和最终页面。正文与图片存在之后,还要确认 HTML 引用了它们,浏览器里也能看到对应内容。
- 多 agent 或多进程交接文件时,使用明确的绝对路径,并让接收方从该路径读取一次。验收报告应写清执行动作、观察结果和未覆盖项,让 PASS 有可核对的依据。