AI 编码前的规格包:先给边界,再让它写代码

AI 编码前的规格包:先给边界,再让它写代码
Spec Coding 编辑部 · Spec-First 工程实践内容

给 AI 编码工具使用的规格包模板:先写清任务边界、允许修改的文件、验收标准、测试证据和评审规则,再开始生成代码。

发布于 2026-05-03 · ✓ 已更新 2026-05-06 · 阅读约 6 分钟 · 作者:Spec Coding 编辑部 · 审校:编辑与事实核查政策

规格包不是长文档,而是开工边界

AI 编码工具生成 diff 很快,但它并不天然知道“应该生成哪个 diff”。规格包就是在生成代码前交给工具的一页工作单:这次要改变什么行为,允许改哪些文件,不允许做什么,验收标准是什么,最后要交哪些证据。它不是完整设计文档,也不是一句随手写的 prompt,而是一个可以被评审的边界。

目的不是让 AI 变慢,而是阻止最贵的那种快:看起来很快地补了一个功能,同时改了无关 helper、加了新依赖、写了只证明自己实现的测试,最后让 reviewer 猜测哪些改动被授权。

什么时候适合使用

规格包适合边界已经相对清楚的任务:一个 bug fix、一个 endpoint 变更、一个窄 UI 行为、一段迁移逻辑,或者一个可以在单个 PR 里完成的功能。如果这件事还需要产品发现、架构取舍或安全审批,就不要直接交给 AI 写代码。先写更高层的规格,或者用 规格生成器功能规格模板 把问题拆清楚。

判断标准很简单:AI 生成完以后,reviewer 能不能根据这份包判断它是否做对?如果答案还是“看情况”,那就还没到生成代码的时候。

最少要有六个字段

可复制规格包

AI 编码规格包

任务:
- 要实现的行为:
- 必须保持不变的用户或系统行为:

允许修改范围:
- AI 可以编辑的文件/目录:
- AI 可以读取但不能修改的文件:
- AI 不能修改的文件:

非目标:
- 不做无关重构。
- 未经批准,不添加依赖。
- 不重命名公开字段、路由、事件名或错误码。
- 除非本任务包含生成器,否则不修改 generated files。

验收标准:
- Given:
  When:
  Then:
- Given:
  When:
  Then:

失败路径:
- 无效输入:
- 权限或归属失败:
- 超时、重试或部分失败:
- 回滚或恢复期望:

评审前必须提供的证据:
- 需要新增或更新的测试:
- 需要运行的现有测试:
- 手工检查、截图、日志或指标:
- PR 描述必须把每条验收标准映射到证据。

合并阻断:
- 任何验收标准没有证据,PR 就还没准备好。

例子:只加重试,不顺手重构

假设支付 webhook 在 ledger 服务超时时需要重试一次。糟糕的提示词是“给 webhook handler 加重试逻辑”。这会让模型自由发挥:改 client、换错误处理、引入 retry library,甚至改签名校验。规格包应该窄很多。

任务:
- 当 LedgerClient.recordPayment 超时时,webhook handler 重试一次。

允许修改范围:
- src/payments/webhook-handler.ts
- src/payments/webhook-handler.test.ts

非目标:
- 不修改 LedgerClient 公开 API。
- 不添加 retry library。
- 不修改 webhook 签名校验。

验收标准:
- Given LedgerClient 第一次超时
  When handler 处理有效支付事件
  Then 它重试一次并记录支付。
- Given LedgerClient 连续两次超时
  When handler 处理事件
  Then 返回现有的可重试失败响应。
- Given 签名校验失败
  When handler 收到事件
  Then 不调用 ledger。

这样 reviewer 就不用猜。diff 要么只改两个文件,要么越界;测试要么证明每条标准,要么不完整。AI 仍然可以帮忙,但它不能自己决定工作的形状。

文件所有权要写清楚

很多 AI 代码漂移都从文件范围开始。模型看到一个 helper,觉得它可以更干净,于是顺手改了。一个小任务就变成了软重构。规格包要把“可以读”和“可以写”分开写。比如“可以查看 API client,但不能修改它”;如果看起来必须改别的文件,就停止并请求批准。

这对多人协作也重要。明确写范围可以减少冲突,也让 PR 更容易回滚。你不需要在评审时从整个仓库里判断意图,只需要看生成结果有没有遵守那一页边界。

要证据,不要信心

AI 最后的回复如果只是“实现完成”,价值很低。更有用的是:“AC-1 由 webhook-handler.test.ts 里的 retries once on timeout 覆盖”。规格包应该要求它每次都给出这种映射。

UI 任务的证据可能是截图和视口列表;API 任务的证据可能是契约测试和错误响应 fixture;数据库任务的证据可能是迁移 dry-run 和回滚说明。证据形式会变,但规则不变:每条验收标准都不能只停留在口头声明。

和 Spec Skills 搭配使用

Spec Skills 适合放在这里:先把粗糙工单整理成规格包,再让编码工具在这个包内实现。如果生成过程中暴露出缺失决策,先更新规格包,再进入下一次实现,而不是让 AI 自己猜。

这也让 AI 编码治理 变得具体。治理不一定是厚重流程。它可以是一条重复习惯:每个 AI PR 都从规格包开始,每条验收标准都映射到证据,越界改动必须在评审前移除。

先审规格包,再审代码

PR 到来后,先打开规格包。看 diff 是否留在允许文件内;看每条验收标准是否有证据;看是否新增依赖、重命名公开字段或未经允许修改 generated file。确认这些之后,再读实现细节。

如果规格包写错了,就修规格包再生成。如果实现忽略了规格包,就退回 PR。不要默默替 AI 修掉所有问题,否则团队会学到一个坏习惯:不清楚的规格也能靠 reviewer 兜底。Spec-First 的好处,恰恰是把这个兜底动作前移。

把评审记录写成表,而不是评论串

我更喜欢在 PR 描述里放一张小表,而不是让 reviewer 去几十条评论里拼结论。表格不需要复杂,只要能回答三个问题:这条标准在哪里实现,哪里证明,哪里还有风险。这样做还有一个好处:如果同一类 AI PR 反复出问题,团队能回头看记录,而不是靠记忆复盘。

AI PR 评审记录

验收标准 | 实现文件 | 证据 | 评审结论
AC-1 超时后重试一次 | webhook-handler.ts | timeout retry test | 通过
AC-2 连续超时返回可重试失败 | webhook-handler.ts | double-timeout test | 通过
AC-3 签名失败不调用 ledger | webhook-handler.test.ts | invalid signature test | 通过

越界检查:
- 未新增依赖
- 未修改 LedgerClient API
- 未修改签名校验逻辑

剩余风险:
- 真实 ledger 超时延迟未在本地复现,只通过 mock 验证
- 发布后观察 payment_webhook_retry_total 指标 24 小时

这张表不是为了增加仪式感,而是为了让审核变短。Reviewer 不必重新理解整份 diff,只需要抽查映射是否真实存在。如果表里写了某个测试,测试不存在,或者测试并没有覆盖那条标准,PR 就退回。

团队可以从一条规则开始

不用一开始就要求所有 AI 生成代码都走完整流程。更现实的做法是先选高风险区域:支付、权限、数据迁移、API 契约、后台高危操作。只要这些区域的 AI PR 必须附规格包,收益就很明显。等团队熟悉后,再扩展到普通功能。

如果你担心阻力,可以把规则写得更具体:凡是 AI 生成代码修改了生产路径、数据库结构、公开 API 或权限判断,就必须附规格包;只改测试文案或内部注释,可以走轻量流程。规则越具体,团队越容易接受。

我会退回的三种规格包

规格包不等于把工单复制一遍。下面三种我会直接退回,因为它们看起来有格式,实际上没有约束住 AI。

退回不是为了刁难。规格包越模糊,AI 越会自己补空白;它补得越多,reviewer 越难判断哪些改动是任务要求,哪些只是模型顺手做了。

一页检查清单

关键词:AI 编码规格包 · Spec Skills · AI coding guardrails · 验收标准证据 · generated code review

专题阅读路径

这篇文章归入 验收标准 主题。先读 Hub,再结合下面的清单、模板或工具落到具体项目里。

编辑说明与免责声明

发布于 2026-05-03。本文用于软件工程教学与实践参考,帮助团队把 AI 编码放进可评审的 Spec-First 工作流。