开发者用 Claude API 搭建自动化 QA Agent,872M tokens 中 97.63% 命中缓存,完成 88 个 issue 闭环,展示了 token 缓存和 AI 代理在产品测试中的实际成本效益。
处理了 8.72 亿个 tokens — 其中 97.63% 是缓存的输入。5,222 次工具调用。88 个 issue 已关闭。没有严重缺陷,但发现了多个高危缺陷,这个产品我在整个构建过程中都在进行 QA。
开始之前说一句。这里没什么奇特的地方 — 没有 Hermes harness,没有自定义框架。只是 Codex 和一个很长的 prompt。我很确定一个配置妥当的 Hermes 运行会更严格地度量所有这些。只是我觉得还没有很多人走到那一步,我想展示一下现在不需要它就能达到的效果。
这开始时不是一个实验。开始时是紧张。
我正准备投放付费广告。一旦开始购买流量,每一个坏掉的页面都会烧钱 — 你要付费把陌生人送到你最糟的 bug 那里。而且我有一个具体的顾虑:我的产品支持多种语言,而我对所有语言的掌握程度并不相等。如果某一个语言环境中有地方悄悄坏了,我可能几周都不会注意到。广告不会停止投放。它们只会继续完美地工作,把人送到坏掉的东西那里。
所以与其花一个下午点点戳戳然后自我感觉良好,我把整个产品交给了 Codex,告诉它别停,直到没有东西可以破坏。
它运行了将近 30 小时。
Prompt 的重要性比我预期的要大,所以这是它的整理版本。其中大部分的具体内容存在是因为模糊的指令会产生模糊的测试。
目标 我即将开始付费广告。在我花钱把陌生人送到这个产品之前,找到他们会遇到什么。
深度 — 正常路径是起点,不是终点:重复和深入钻取,并发发送请求;在流程中途中断,比如刷新、导航、退出登录、返回;中途切换语言并检查状态是否保留;故意杀死一个步骤并验证恢复和使用统计;移动端、平板、桌面;仅键盘、焦点、标签、对比度;以及检查隐私边界 — 任何账户能看到它不应该看到的东西吗?
对每个 issue 记录:用户会看到什么、确切的复现步骤、代码中的根本原因、严重程度(Critical / High / Medium / Low)、修复、现在覆盖它的回归测试、部署后的验证。
流程:先读 docs/。在修复代码时提交小的、可追踪的 commit。部署到 main 并在实时环境中重新验证。一个修复只有在生产环境中通过检查时才算完成。
输出:每种语言单独一份报告,加上一份按严重程度排序的统一汇总。
规则 4 和规则 5 是在运行过程中发生的事情促成的。我稍后会讲到。
观察、复现、调查、修复、测试、验证、重复。
改变现状的规则是拒绝相信单次通过。一个页面工作一次几乎什么都证明不了。所以每个流程都要在刷新、退出登录、重启、语言切换、重复请求、故意失败之后,以及最后在部署后重新访问。
类型检查、linting、构建,以及最终的测试套件在我宣布完成前都通过了。而"完成"不是指最后一个 commit,而是部署了、在实时环境中重新检查了、并同步回了 main。
是的,它处理了 8.72 亿个 tokens
这是头条数字,这是注释,紧紧贴在它旁边的地方。
8.72 亿是一个真正有趣的数字来大声说出来。但它也是 97.63% 的缓存输入。
这就是长时间运行的会话从内部看起来的样子:相同的代码库、相同的报告、相同的累积对话,在每一轮上都被重新处理。累计计数器忠实地计算所有这些。这并不意味着引入或计费为新用法的是 8.72 亿个新 token。
如果你想要描述实际新上下文和生成工作的数字,大约是 2,235 万,非缓存输入加输出。
我发布两个数字,因为一个很大的 AI 使用数字只有在缓存结构放在它旁边时才有意义。没有比率的总量不是度量,是营销。
我必须介入的地方
两天足够长,我定期检查它的进展,不是审查每个 commit,只是看屏幕滑过,问自己我看到的东西是否看起来正确。
第一个问题是我发现的。在除了一种语言之外的每一种语言中,一条特定的记录显示正确。在那一种语言中,它没有。Agent 看过那个屏幕,把它登记为可接受的,然后继续。我手动标记了它。一旦直接指向它,诊断和修复很快就完成了。修复从来不是难的部分。注意到才是。
这正是你应该期望从独立工作的 agent 那里看到的失败模式:它非常擅长"这会抛出错误吗",在"这看起来与我看到的其他十一次类似"的对比上要弱得多。上面 prompt 中的规则 4 因为这个而存在。
第二个问题是在运行已经声明完成后发现的。我自己回顾结果,发现了一个 PostHog 事件没有正确触发,那个记录已完成付款的事件。
想想这在背景中意味着什么。我做这一切是为了为广告活动做准备。我用来判断广告是否有效的数字是坏的。没有屏幕看起来错了。没有测试失败。没有东西抛出。它只会永远悄悄不正确,在对我将要花钱的东西最重要的单一指标上。
这是规则 5。验证超越 UI。一个没有触发其事件的绿色复选框不是一个通过。
实际改了什么
88 个跟踪的 issue,111 个目标修复 commit。差异很有趣:一个观察到的问题通常需要几个独立的改变。单一的不一致可能涉及持久化数据、恢复的 UI 状态、翻译的输出、失败恢复和测试覆盖。与其把这些折叠成几个大 commit,每样东西都被分成小的、可追踪的单位。
修复聚集到几个主题:
从工作流返回时更可靠的状态恢复
更一致地处理重复或并发操作
在操作中途失败时更好的恢复
更强的文件和文档边界处理
跨语言和屏幕尺寸更少的布局破损
对意外内部数据泄露的更清晰保护
对以前没有的路径的新自动化测试
改变的代码量不是重点。重点是每个修复都可以追踪回一个观察到的行为、一个可复现的情况,以及一个验证步骤。
真正让我困扰的部分
没有严重缺陷。很好。
但有高危的。是复数。在一个我构建时一直在进行 QA 的产品中。
这是我一直在回顾的发现,它比上面任何数字都更有用。我没有粗心大意。我一直在检查。而一个艰苦的 30 小时通过仍然浮现出多个高危问题,那些普通开发 QA 直接走过了的。
然后压力活动本身完成了,我通过用自己的眼睛看又找到了两个东西。
现在有个流行的想法是 AI 只是处理这个,你指向一个好的模型指向一个代码库,质量就是一个解决的问题。这次运行是 agent 走了多远的有力证据,它同样是针对那个想法的有力证据。开发时的 QA 遗漏了东西。一个 29 小时的对抗性活动抓住了大部分,仍然遗漏了一个人通过注意发现的东西。所以诚实的结论不是"现在很干净了"。诚实的结论是:
肯定还有潜伏的 bug。
我会再运行一次。现在我相信没有高危的东西还在。相信,不是知道。这个区别就是写这个的全部要点。
我会告诉做这个的人什么
连续性是能力,不是智能。一个一次性的 prompt 修复一个可见的 bug。一个与产品保持的 agent 发现那个 bug 在你加上重试、本地化、生成的文件、以及一个三步回头的用户后的行为。
浏览器访问和代码访问加在一起远强。浏览器自动化告诉你什么失败了。源代码访问告诉你什么可能失败。只有两样加在一起才能让它看到症状、追踪实现、应用修复、走同样的旅程再来确认。
没有回归测试的修复没有完成。屏幕看起来更好不是证据。在可行的地方,每个修正的行为都得到了一个测试,所以未来的改变不能悄悄撤销它。
明确禁止"可能没事"。Agent 跳过小的异常的理由和累倦的人一样,什么都没起火。写规则到 prompt 中:一个跨语言的不一致是一个发现,不是一个心情。
验证超越 UI,尤其是分析。事件、邮件、生成的文件、以及存储的状态是静默失败居住的地方。这些正是生存下来的 bug,一个成功的测试运行。
呆在循环中。Agent 极大地扩展了我的范围。它没有接管所有权。两次重要的东西漏过去,抓住它的东西是一个人看着屏幕想嗯,这很奇怪。
值得改变的问题
这里最有用的结果不是任何单一的修复。这是看着一个 agent 整个产品稳定化周期,导航、检查证据、编辑代码、运行测试、管理改变、等待外部流程、回来验证,连续 30 小时。
这意味着我们一直在对编码 agent 问一个稍微小一点的问题。不仅仅:
"你能建造这个特性吗?"
"你能继续测试这个产品,调查什么坏了,修复根本原因,证明修复保持,并继续到验证标准满足吗?"
这是一个完全不同的工作描述。而现在它可能是我们拥有的最实际的一个,只要有人还在看着。
原发表在 Kanapp Notes。