Opus 5.5 时代 spec 还重要吗?24 次 Agent 运行实录

我们给 Claude Code 三个普通工单:一个优惠码功能、一次错误格式整理、一次 schema 变更,每个都运行了多次:用一句话 prompt、用 spec,部分情况下还删掉了仓库里的书面规则。在第一次运行前就已冻结的隐藏验收测试给每个结果打分。所有 prompt、diff 和分数都可以下载。

Spec 运行9 次中 9 次通过全部隐藏检查
非 spec 运行15 次中 7 次通过全部隐藏检查
弄坏了仓库之外的东西3 次运行,全部发生在删掉书面规则的仓库里

三个发现

1. 模糊 prompt 大多能用

在小而易读的仓库里,模型凭一句话就正确修复了崩溃、堵住了堆栈泄露、给折扣加了上限、回填了数据。如果你的评审问题是“能不能跑”,当前的模型经常能通过。

2. 书面约束能阻止破坏

一份 13 行的移动端契约文档和三行 README,就足以阻止破坏性改动,即使只用一句话 prompt。没有它们时,三次 API 运行中有两次弄坏了已发布的 app,一次迁移删掉了 billing 会读取的列。

3. Spec 消除了差异,连漏洞也一样

同一个模糊 prompt 产生了两种优惠码策略,以及三种处理过期优惠码的方式。spec 运行之间每次都一致,包括 spec 漏掉的一个情况,其中一次运行指出了这一点。

三个案例

案例运行次数通过全部隐藏检查没有 spec 时出了什么问题
Checkout 优惠码6模糊 2/3 · Spec 3/3有一次运行允许同一优惠码无限次重复使用;三次运行在“过期优惠码是否计费”上分成了三种做法。
API 错误格式9无文档 0/3 · 有文档 0/3 · Spec 3/3没有契约文档时,3 次运行中有 2 次把 body.error 改成了对象,弄坏了 mobile v3.x。有文档时,全部都保留了两种错误结构。
姓名拆分迁移9无规则 2/3 · 有规则 3/3 · Spec 3/3有一次运行删掉了 users.name 并改了 createUser 的函数签名。六次非 spec 运行全部在第一个空格处拆分姓名。

Checkout 优惠码

“Add coupon codes to checkout.” 三次运行中两次全部做对。第三次认定优惠码没有使用次数限制,并且明说了。

查看优惠码运行

API 错误格式

“Clean up our API errors.” 一个设计得不错的错误格式,却让每个移动端用户看到空白的错误横幅;以及避免这一问题的 13 行文档。

查看 API 运行

姓名拆分迁移

“Split name into first_name and last_name.” 正确的回填之后紧跟着 DROP COLUMN name,总结里附了一条没人会去处理的警告。

查看迁移运行

新增:同样的运行,换到四个 Claude 模型上

我们在 Sonnet 5.5、Haiku 4.5 和 Fable 5.1 上重跑了全部三个案例,总计 78 次运行。有 spec 时,四个模型合计 30 次运行中有 28 次通过了全部隐藏检查。没有 spec 时,48 次中只有 12 次通过;而 Anthropic 在 Terminal-Bench 4.0 上排名更高的那个模型,3 次运行里 3 次都删掉了计费系统在读的列。

对比 Opus 5.5、Sonnet 5.5、Haiku 4.5 和 Fable 5.1

运行是如何录制的

每次运行条件相同

  • Claude Code 2.1.284,模型 claude-opus-5-5,headless 模式 claude -p,录制于 2026 年 9 月 28 日。
  • 每次运行使用一份全新的 fixture 仓库副本。没有用户设置、hooks、插件或 MCP server(--setting-sources project --strict-mcp-config)。
  • 只有一个 prompt,没有后续消息,打分前没有人工修改。
  • 每次运行耗时 37 到 89 秒,3 到 8 轮。

打分方式

  • 每个案例都有一套隐藏验收测试,在第一次运行前写好并冻结,从未给 agent 看过。
  • 测试只调用改动前就已存在的接口(函数或 HTTP),并接受任何合理的错误报告方式,所以 API 设计不同不算失败。
  • 如果某项检查测试的是模糊 prompt 从未说明的规则,案例页面会标注出来。
  • 运行结束后发现并修复了一个测试 harness 的 bug;迁移页面有说明,运行包里包含两个版本的测试套件。

运行包

每个运行包包含 fixture 仓库、原始 prompt、隐藏测试套件、运行脚本,以及每个模型上每次运行的 diff、隐藏测试结果、自带测试计数和最终消息。采用 CC BY 4.0 许可。

这些结果不能说明什么

每个变体跑三次,只能说明某件事会发生,不能说明它发生的频率。仓库特意做得小而干净,这样结果可以追溯到某一个 prompt 或某一个文件;更大的代码库会给 agent 更多误读的机会。spec、文档和测试套件都是我们写的,实际工作中 spec 也是这样产生的,但这意味着 spec 覆盖的正是我们测试的内容。优惠码案例中 spec 留下的那个漏洞,我们如实报告,没有隐藏。

如果你用其他模型或工具重复这些实验,我们希望把你的结果和我们的并列发布。发给我们。

把一句话工单变成 agent 会遵守的规则

从 spec packet 生成器开始,或者阅读 spec-first 工作方式如何与 agent harness 配合。

编辑说明

这些页面上的每个数字都来自运行包里录制的运行。打分前,我们没有修改 agent 的任何输出。