用 Spec Skills 起草验收标准(AC)
用 Spec Skills 起草可测试的验收标准:结构化 prompt、失败模式二次过滤,以及人工评审如何兜住 AI 漏掉的问题。
为什么 AC 是规格里最难写的一块
我写规格写了十五年,每次动笔最怕的仍然是 acceptance criteria 那一段。Goals 好写,Non-goals 写起来甚至有点解气,数据模型几乎是自动生成的。但 AC 是写到哪儿就开始挥手的地方:“用户应该看到成功提示”“错误会被妥善处理”“性能可接受”。每一句都是埋在 QA 侧的潜在 bug,因为契约从头到尾没有被真正定义。
AC 难写,是因为它强迫你把行为描述到穷尽,又不能滑进实现细节。你得把那些自己其实不愿意想的失败模式一个个点名;你得决定空输入到底是校验错误还是 no-op;你得选边站,回答并发编辑到底是覆盖还是冲突。大多数团队跳过这一步,然后在生产环境里被现实补课。我用 Spec Skills 起草 AC,恰恰就是因为它根本不让我跳过。
Spec Skills 的 AC prompt 和裸 LLM 输出到底差在哪
当我把一个 feature 丢进一个普通的对话模型里要 AC,得到的是四条像营销文案的 bullet:“用户可以删除账号”“删除过程很快”“错误会清晰展示”。Spec Skills 的 AC prompt 是结构化的。它强制每条输出走 Given/When/Then,要求每个条款都对应 feature spec 里的某个具体段落,并且在返回草稿前就会先把“快”“清晰”这类模糊谓词拎出来打标。如果我的输入里写的是“删除接口应该很快”,Spec Skills 会直接驳回,让我补一个具体的延迟预算数字。
还有一件普通 prompt 不会做的事:Spec Skills 每次都会强制要求五个标准用例。主流程。校验失败。鉴权或权限失败。并发边界。回滚或撤销。如果这个 feature 真的没有某一类,我必须明确写上“N/A — 只读”,而不能静悄悄地省掉。仅这一条规则,为我抓出的漏项比任何其他评审手段都多。
一个具体的例子:批量删除用户
上个月我真刀真枪写过 AC 的一个接口:POST /admin/users/bulk-delete,请求体是一个用户 ID 数组。我手写的第一版是三条 bullet:“接受一个 ID 数组”“删除匹配的用户”“返回删除数量”。Spec Skills 的结构化过滤把它扩展成了十一条 Given/When/Then,其中有一条是我自己绝对会漏掉的:
Given an admin submits a bulk-delete request containing 500 user IDs When 3 of those IDs belong to users with active billing subscriptions Then the endpoint returns 409 Conflict with a body listing the 3 blocked IDs And no users in the batch are deleted (all-or-nothing semantics) And an audit log entry records the attempt and the blocking reason
“all-or-nothing”这个决策原本不在我的 feature spec 里。Spec Skills 通过反问“部分成功是否可接受?”把这个歧义点翻到桌面上,我又回去找产品确认。那段对话发生在写任何一行代码之前——这正是它应该发生的位置。
失败模式二次过滤
主流程 AC 起草完之后,Spec Skills 会跑一遍它自己叫“what breaks”的二次过滤。prompt 非常直接:对每一条 AC,列出这个行为在对抗性输入、网络分区、竞争条件或操作者失误下可能的崩溃方式。对 bulk-delete 这个接口,这一趟过滤生成了:数组里出现重复 ID 怎么办?同一个管理员两秒内提交了两次同样的请求怎么办?删了 500 个里的 200 个之后数据库连接断了怎么办?裸 LLM 会高高兴兴写出十条主流程 AC 就收工。Spec Skills 把第二遍过滤变成必选项,除非失败用例被显式覆盖或带着理由写进“延后处理”,否则它不会返回一个看起来干净的结果。
人工评审:要么可测试,要么打回
Spec Skills 只起草。它不拍板。每一条 AC 都要过我亲自把关的人工评审环节,规则是二元的:如果我没办法在脑子里想出一个确定性的测试用例能判这条 AC 过或不过,我就打回去重写。“用户体验应该显得响应迅速”是许愿。“接口在 100 并发下 p95 延迟不超过 500ms”是 AC,因为我能为它写压测。
我大概会把第一版草稿里 15% 到 20% 的条款打回。大多数时候不是因为 AC 写错了,而是因为它在复述实现(“服务调用了删除任务”)而不是在描述可观测行为(“后续 GET 请求在 2 秒内已经查不到这条用户记录”)。这种区分,目前还必须靠人做。
Spec Skills 帮我兜住的几类 LLM 失败模式
在裸 LLM 的 AC 输出里,我反复看到三种模式:
- 漏掉负向用例。裸模型倾向于只写主流程,因为训练数据里大部分就是这样。Spec Skills 的五用例强制要求把校验、鉴权、并发、回滚都塞进每一版草稿。
- 同义反复型 AC。“当用户删除账号时,账号被删除。”Spec Skills 会把 Then 子句只是重复 When 子句的条款全部打标,在 Then 描述出可从外部观察到的后果之前,它不会把草稿返回。
- 复述实现型 AC。“系统调用了审计日志模块”是实现。真正的行为是“调用之后存在一条审计记录”。Spec Skills 的 prompt 禁止使用描述内部动作的动词,要求改用外部可观察的动词。
AC 模式库:可复用的套路
慢慢地我积累出了一个小型的 AC pattern 库,Spec Skills 在识别到匹配的 feature 形状时会从里面挑:分页(cursor 还是 offset、边界条件)、鉴权失败(401 还是 403、token 过期、scope 不匹配)、错误信封(一致的结构、必填字段、本地化)、幂等性(重试安全的 key、replay 窗口、冲突语义)。遇到一个新的分页接口,Spec Skills 会把分页 pattern 当起点丢给我,我再根据具体情况调。这样每个 feature 大概能省 30 分钟,同时整条 API 表面的行为会更一致。
让 AC 直接流进测试骨架
Spec Skills 会从通过评审的 AC 里生成测试 stub——把 Given/When/Then 映射成 describe/it 骨架,断言部分留成 TODO。对 bulk-delete,十一条 AC 在我写任何生产代码之前就变成了十一个 pending 的集成测试。这就给出了一个非常具体的 definition of done:这十一个测试全过,feature 就能发。没有范围蔓延,没有被遗忘的边界,也没有“测试我们回头再补”。
人的直觉还是会比工具强的几种场合
Spec Skills 有三类行为是它稳定地漏掉的。领域知识:如果一次用户删除涉及合规含义(GDPR 删除时限、SOC 2 审计要求、HIPAA 保留规则),除非我把条文喂进去,否则它不知道。时间敏感型行为:cron 之间的交互、webhook 的重试窗口、缓存失效。只要我 prompt 它,它能把 AC 写出来,但它不会主动把时间性问题推到台前。跨 feature 的交互:bulk-delete 和每小时的导出任务会怎么相互影响?这个问题只有了解系统的人能回答。
让我判断这件事在起作用的两个指标
在最近六个 feature 里我会跟踪两个数字。第一版接受率:大约 82%。如果是 100%,说明工具只是在替我写那些本来我自己就会写的东西;如果跌破 60%,我就得和它对着干了。第二个数字:规格锁死之后在 QA 阶段才被发现的漏掉的边界用例,从用 Spec Skills 之前的每个 feature 大约 4 条,降到了 1 条。那剩下的 1 条基本都属于前面说的领域知识类,对此我心甘情愿——这是人类要处理的问题,不是 prompt 能解决的问题。
Spec Skills 生成后,人要做第二遍“可测试性”检查
我不会直接接受生成出来的验收标准。先让 Spec Skills 起草,再让 QA 或开发把每条改成能执行的输入、状态和预期输出。判断标准很土:能不能写成一条测试用例。
Draft cleanup: - Bad: user receives a helpful error - Better: Given email is missing "@" When the user submits signup Then the API returns 422 with code invalid_email And no user row is created And the UI keeps the typed value in the email field
边界:Spec Skills 适合把模糊需求拆成测试点,不适合替产品做取舍。涉及合规、价格、权限和默认开启策略时,生成结果只能当草稿。
可复制产物:Spec Skills 工作流包
把这段用于真实的 Spec Skills 运行前。它会把输入、边界和人工评审点放在同一处,避免输出看起来完整但责任不清。
Spec Skills 工作流包:用 Spec Skills 起草验收标准(AC) 本次要做的决策: - 把这篇文章里的工作流应用到一个真实工单,并确认输入、边界、输出和人工评审点。 责任人检查: - 产品责任人: - 工程责任人: - QA 或运维评审: 范围边界: - 本次包含: - 本次不包含: - 仍需确认的假设: 验收证据: - 测试或 fixture: - 日志、指标或截图: - 人工复核步骤: 工具边界:模型可以起草结构和问题,范围、契约行为、发布风险仍然必须由责任人确认。 评审追问: - 没参加需求会的人还会误解哪里? - 哪个证据能证明这次改动足够安全,可以发布?
编辑复核记录
复核日期:2026-04-28。本次补充了可复用产物,按相关主题 Hub 检查了文章定位,并收紧下一步链接,让页面更像可操作参考,而不是孤立长文。
专题阅读路径
这篇文章归入 验收标准 主题。先读 Hub,再结合下面的清单、模板或工具落到具体项目里。
继续阅读
编辑说明与免责声明
最近复核:2026-04-28。编辑部检查了示例、内链和可复制评审片段,确保内容更适合真实项目使用。
本文用于软件工程教学与实践参考,不构成法律、税务或投资建议。示例场景用于解释规格方法,不对应真实客户数据。
- 作者信息:Spec Coding 编辑部
- 编辑政策:编辑与事实核查政策
- 联系方式:联系页面