全栈手账 订阅 RSS
SDD

SDD 规格驱动开发

Spec-Driven Development:以结构化规格作为唯一真实来源,AI 编码 Agent 按规格实现,而不是靠一句自由提示词碰运气。 一句话概括:规格是源头,代码是产物。

读了 22 分钟 更新于 10 月 21 日

一、什么是 SDD

1.1 定义

SDD(Spec-Driven Development)是一种 AI 辅助开发工作流:先写出一份结构化规格(目标、非目标、约束、验收标准),把它作为唯一真实来源(Single Source of Truth),再让 AI Agent 依据规格来实现代码。

1.2 三种范式的对比

范式 真实来源 工作方式 典型问题
传统开发 代码 人写代码,文档是附属品 文档滞后、知识在个人脑中
Vibe Coding 提示词 一句话描述,AI 自由发挥 结果不可控、风格漂移、反复重来
SDD 规格 规格约束解空间,AI 在约束内实现 前期投入高、需维护规格

1.3 为什么是现在(2026)

AI Agent 把「写代码」变得前所未有地便宜,于是「定义清楚要写什么」成了新的瓶颈:

  • 代码生成成本 ↓ → 返工成本成为主要成本
  • 提示词质量参差 → 输出质量方差极大
  • 决策隐性化 → 设计决策散落在代码评审和生产事故里

SDD 的应对方式:把隐性的设计决策前移到规格评审阶段,在成本最低的时候做决策。


二、核心理念

2.1 Prompt-only 为何失效

问题 表现
缺项目上下文 生成的代码与既有架构冲突
缺全局约束 命名不统一、重复逻辑、安全策略被绕过
意图靠猜 AI 自行脑补需求,返工率高
无法复用 同一需求换端(Web → App)要重新描述一遍

2.2 三大价值

  1. 可控性:规格限定了允许的解空间,AI 不会自由发挥到不可审查的规模。
  2. 可追溯性:每条代码都能追溯到规格条目;反过来规格变更可定位受影响代码。
  3. 可复用性:规格与语言无关,同一份 spec 可喂给 iOS / Android / Flutter / 后端。

2.3 质量左移

传统「测试左移」停在 CI 阶段;SDD 推动的是质量左移到规格评审:

文本
传统:  需求 → 设计 → 编码 → 测试 → 上线 → 发现问题SDD:   需求 → 【规格评审】→ 方案 → 编码 → 测试 → 上线                ↑ 错误在这里被拦截,成本最低

一份经过产品、技术、安全共同确认的规格,能在编码之前拦掉大部分设计缺陷——因为改一份 Markdown 比改十个文件便宜得多。


三、标准流程

以 GitHub Spec Kit 的实现为准,SDD 分五个核心阶段:

文本
constitution(项目宪法,每项目一次)      ↓specify(写规格:what & why)      ↓  clarify(澄清模糊点,可选)      ↓   plan(技术方案:how)      ↓  tasks(拆解任务)      ↓ analyze(跨工件一致性检查,可选)      ↓ implement(执行实现)      ↓ converge(评估差距,追加剩余任务)→ 循环直到 Converged

3.1 命令与产出对照

阶段 Spec Kit 命令 产出文件 关键约束
项目宪法 /speckit.constitution constitution.md 每项目一次,全局准则
写规格 /speckit.specify spec.md 只写 what & why,严禁谈技术栈
澄清 /speckit.clarify 补充 spec 消解歧义(建议在 plan 之前)
技术方案 /speckit.plan plan.md 此阶段才决定 how
拆任务 /speckit.tasks tasks.md 有序、可勾选、标依赖
一致性检查 /speckit.analyze 分析报告 跨工件覆盖度检查
实现 /speckit.implement 代码 按 tasks 逐条执行
收敛 /speckit.converge 追加任务 循环直至 Converged

3.2 为什么「写规格时不准谈技术栈」

这是 SDD 最重要的一条纪律:把「要什么」和「怎么做」彻底分开。

  • 如果在 spec 阶段就写「用 Redis 做缓存」,等于提前锁死了方案,探索其他解的空间被关闭;
  • 分开之后,同一份 spec 可以生成多套 plan(性能优先版、成本优先版、可维护优先版),对比后再选。

这条纪律的价值在于:需求是稳定的,实现是可替换的。混在一起写,需求变更会污染方案,方案变更会污染需求。


四、规格的分层结构

实践中团队收敛出的四层结构:

文本
specs/001-feature/├── spec.md            # 需求:用户可见行为、验收标准、non-goals├── plan.md            # 方案:架构、数据模型、关键权衡├── data-model.md      # 数据模型细节├── tasks.md           # 有序任务清单└── contracts/         # 契约:OpenAPI / JSON Schema / Gherkin

4.1 spec.md 必备要素

要素 说明 反例
目标 一句话说明这个功能解决什么问题 「做一个收藏功能」(太泛)
用户可见行为 用户能看到、能操作什么 「后端存到 Redis」(用户不可见)
验收标准 逐条可测试的检查项 「体验流畅」(不可测)
Non-goals 明确不做什么 缺失 → AI 会自行扩大范围
约束 技术栈、需遵循的既有模式、禁止改动的文件 缺失 → AI 动不该动的代码
Open questions 未决问题集中列出 缺失 → AI 悄悄替你决定

Non-goals 是 spec 里最容易被忽略、又最有价值的一节。它直接封住了 AI「顺手多改一点」的倾向。

4.2 验收标准的写法

好的验收标准是可机械验证的:

markdown
## 验收标准- [ ] 已登录用户在详情页点击「收藏」,按钮变为「已收藏」- [ ] 未登录用户点击收藏,跳转登录页并携带 redirect 参数- [ ] 重复点击收藏返回 code=1001(已收藏),不产生重复记录- [ ] 收藏列表按收藏时间倒序,分页每页 20 条- [ ] 取消收藏后,详情页按钮恢复为「收藏」

坏的例子:

markdown
- [ ] 收藏功能好用       ← 不可测- [ ] 性能良好           ← 不可测,应改为「列表接口 P95 < 300ms」

4.3 契约层

契约是「规格 → 代码」之间可被机器校验的桥梁:

类型 用途
OpenAPI 3.1 HTTP 接口结构与 Schema
JSON Schema 请求/响应体校验
Protobuf gRPC 接口
Gherkin / Cucumber 行为场景
Pact 消费者驱动的契约测试

五、工具生态(2026)

工具 形态 特点
GitHub Spec Kit 开源工具包(MIT) 13 万+ stars,38 个 Agent 集成(Copilot / Claude Code / Cursor / Codex / Gemini / Kiro / Zed…),157 个社区扩展;核心流程开箱可用
Amazon Kiro Agentic IDE 规格原生,自动产出 requirements / design / tasks;用 EARS 语法写验收标准
Tessl 规格注册表 + 工具链 用 @test 注解从规格直接生成测试套件

5.1 Spec Kit 安装与初始化

bash
# 依赖:Python 3.11+、uvuv tool install specify-cli# 初始化项目(以 Copilot 为例)specify init my-project --integration copilotcd my-project# 查看所有可用集成specify integration list

换成 --integration 后面的值即可切换 Agent(claude / cursor / codex / gemini 等), 规格工件与 Agent 无关,换工具不用重写规格——这是 Spec Kit 的核心卖点(无锁定)。

5.2 Spec Kit 的三种流程入口

Spec Kit 并非只有 SDD 一条路,它提供三个独立的入口(不是三个必走的阶段):

流程 用途 命令序列
规格驱动开发 开发新功能/应用 constitution → specify → plan → tasks → implement → converge
Bug 修复 诊断与修复缺陷 bug-assess → bug-fix → bug-test
想法评估 判断一个想法值不值得投入 assess-intake → research → define → shape → decide

Bug 修复流程值得单独说明——它刻意把「诊断」「修复」「验证」三步分开,避免 Agent 直接改代码而不查根因:

bash
specify extension add bug/speckit-bug-assess "提交空密码时登录页崩溃" slug=login-crash/speckit-bug-fix slug=login-crash/speckit-bug-test slug=login-crash

最终判定为 verified / partial / failed 三档——缺少验证不算修复成功。


六、实战示例:走一遍完整流程

以「旅游线路收藏」功能为例(多端项目场景)。

6.1 阶段一:项目宪法

markdown
/speckit.constitution制定以下项目原则:- 代码质量:遵循项目既有分层(Controller → Service → Repository),不跨层调用- 测试:新增业务逻辑必须有单元测试;接口必须有契约测试- 一致性:所有接口返回统一格式 { code, message, data },错误码集中定义- 安全:所有写操作必须鉴权;用户只能操作自己的数据- 可维护性:单函数不超过 50 行;不新增依赖需说明理由

产出 constitution.md,后续所有功能都受它约束。

6.2 阶段二:写规格(只谈 what & why)

markdown
/speckit.specify为线路详情页增加「收藏」能力。## 目标让用户能把感兴趣的线路存起来,稍后在「我的收藏」里查看。## 用户可见行为- 线路详情页显示「收藏」按钮,已收藏时显示「已收藏」- 点击收藏/取消收藏后,按钮状态即时变化- 「我的收藏」页面按收藏时间倒序展示线路卡片- 收藏列表支持分页## 验收标准- [ ] 已登录用户点击收藏 → 按钮变为「已收藏」,再次点击恢复- [ ] 未登录用户点击收藏 → 跳转登录页,登录后回到原页面- [ ] 重复收藏同一线路不会产生重复记录- [ ] 「我的收藏」列表按收藏时间倒序,每页 20 条- [ ] 取消收藏后,该线路从列表移除## Non-goals(本次不做)- 不做收藏分组 / 标签- 不做收藏数展示与排行- 不做收藏分享- 不改动现有线路列表与下单流程## 约束- 遵循既有分层结构与统一响应格式- 不得修改 `OrderService` 相关代码- 移动端与 PC 端表现一致## Open questions- 收藏上限是否需要限制?(暂定不限,待产品确认)

6.3 阶段三:澄清

markdown
/speckit.clarify

Agent 会追问,例如:「收藏是否需要软删除?」「列表接口是否需要返回线路的实时价格?」——这些答案回填进 spec,而不是让模型自行决定。

6.4 阶段四:技术方案

markdown
/speckit.plan技术选型:- 新增 line_favorite 表:id, user_id, line_id, created_at,user_id+line_id 建唯一索引- 新增 FavoriteController / FavoriteService / FavoriteRepository,遵循现有分层- 接口:POST /api/favorites、DELETE /api/favorites/:lineId、GET /api/favorites?page=1- 收藏状态在详情页接口中附带返回 isFavorited 字段- 前端:复用现有卡片组件;Vue 端用 Pinia 管理收藏状态,uni-app 端用同一套 API 封装

产出 plan.md + data-model.md。

关键点:同一份 spec 可以产多套 plan。比如还可以生成一套「用 Redis 缓存收藏状态降低详情页延迟」的性能优先方案,对比后择优。

6.5 阶段五:拆任务

markdown
/speckit.tasks

产出示例([P] 表示可并行):

markdown
- [ ] T1 创建 line_favorite 表与迁移脚本- [ ] T2 [P] 定义 Favorite 实体与 Repository- [ ] T3 实现 FavoriteService(收藏 / 取消 / 列表 / 批量查状态)- [ ] T4 [P] 实现 FavoriteController 与路由注册- [ ] T5 详情页接口附带 isFavorited 字段- [ ] T6 [P] 前端 API 封装(favorites.ts)- [ ] T7 PC 端详情页收藏按钮- [ ] T8 [P] uni-app 端详情页收藏按钮- [ ] T9 「我的收藏」列表页(分页)- [ ] T10 单元测试:Service 层收藏去重逻辑- [ ] T11 契约测试:三个接口的响应结构

6.6 阶段六:实现与收敛

markdown
/speckit.implement

Agent 按 T1 → T11 顺序执行,每个任务完成即打勾。执行完后:

markdown
/speckit.converge

converge 会拿代码库对照 spec / plan / tasks,找出遗漏项并追加为新任务,循环直到报告 Converged。

这一步是 SDD 相对纯 Prompt 开发的关键差异:它有一个独立的"自查差距"环节,而不是靠人肉眼比对。


七、三个失败模式(比宣传材料更重要)

这是实践者跑了一个月真实产品后总结的教训。

7.1 Spec drift(规格漂移)

现象:代码往前走了,规格没跟上。两周后规格开始主动误导人——新人和 AI 都会相信它。

对策:

  • 功能上线后若不再维护,直接删除规格;
  • 陈旧的规格比没有规格更糟;
  • 或用 CI 强制规格与代码对齐(契约测试失败即构建失败)。

7.2 Over-specifying(过度规格化)

现象:规格写得细到成了「散文版实现」,等于把代码写了两遍。

对策:

  • 规格应约束解空间,而不是画完整张图;
  • 一个自检信号:规格比它产出的 diff 还长,就是坏味道。

7.3 Review fatigue(审查疲劳)

现象:审规格 → 审方案 → 审 diff,三轮。大改动值得,中等改动会开始「盖章通过」,而盖章通过的规格会给你虚假的安全感。

对策:

  • 完整仪式只留给值得的变更(大、贵、不熟悉);
  • 中等改动可只做 spec + diff 两轮。

7.4 判断准则

变更超出你的脑容量时写规格;装得下就不写。

场景 是否写规格
单文件小修、错别字、样式微调 ❌ 不写,写规格只是抄写
探索性试验(还不知道要做什么) ❌ 不写,先做原型
新功能(跨多文件、跨端) ✅ 写
大规模重构(行为不能变) ✅ 写,重点写「必须保持不变的行为」
高风险改动(支付、权限、数据迁移) ✅ 必须写
接手陌生代码库的改动 ✅ 写,spec 本身就是理解过程

八、与 TDD / BDD / MDD 的关系

实践 核心 与 SDD 的关系
TDD 测试先行,验证函数级计算 互补:SDD 定边界(输入输出、错误码、验收标准),TDD 验内部逻辑
BDD 行为场景(Given-When-Then) 可作为 SDD 的契约层(Gherkin)
MDD 模型驱动,从模型生成代码 理念相近,但 SDD 面向 AI Agent 而非代码生成器
瀑布 阶段严格串行 不同:SDD 的规格是活文档,代码可从规格重新生成,不是一次性签字

成熟架构里的分工

文本
SDD:定义边界 —— 契约、输入输出、错误码、验收标准TDD:验证中间 —— 领域逻辑、算法、边界条件

两层配合,既保证「做的是对的东西」,也保证「东西做对了」。


九、渐进式落地路径

不要一上来全面铺开。五个层级,按需爬升:

层级 做法 时间 价值
L1 规格即文档 用 OpenAPI 描述现有接口,不改任何代码,生成文档 第 1 周 消除「文档在哪」的问题;AI 很擅长从旧代码反推第一版规格
L2 规格即检查关卡 CI 加 Spectral / Redocly,强制命名规范、必填描述与示例 第 2-3 周 规格质量提升,工作流不变
L3 规格即契约 引入契约测试(Schemathesis / Pact)跑在 CI 第 1-2 月 第一次因「改字段没改规格」而构建失败时,团队才真正理解价值
L4 新服务规格先行 新服务强制 spec PR 先于实现 PR 合并 第 2 月起 从源头保证一致性
L5 规格驱动 Agent 选一个工具(Spec Kit / Kiro / Tessl)接入 Agent 工作流 第 3 月起 本次讨论的完整形态

落地建议

  1. 从窄开始:挑一个绿地功能或一个高风险变更,不要给每个 CRUD 都写规格。
  2. 规格进仓库、进 CI:与代码同仓,用 PR 评审规格,用 CI 校验契约。
  3. 先评审规格:把资深工程师的注意力从 diff 上移到 spec 上——错规格早发现的成本远低于错合并。
  4. ADR 写短:每个决策一页纸,胜过一份被遗忘的 wiki。

十、常见问题(FAQ)

Q1:写规格会不会拖慢进度?

不会,只是把决策提前到成本更低的时候。设计决策本来就要做,SDD 只是把它从「代码评审或线上排障时才发现」变成「规格评审时就定下」。在 Agent 工作流里这个交换更划算:30 分钟写规格,常能省下几小时反复重问与返工。

Q2:我们的 API 变化很快,规格跟不上怎么办?

如果接口变化快到规格无法维护,那是设计稳定性问题,不是规格问题。SDD 的作用恰恰是把这种不稳定暴露出来。

Q3:生成的代码质量差怎么办?

质量杠杆在规格本身:

  • 模糊的规格 → 模糊的代码
  • 结构化的验收标准 → 可验证的代码

另外要区分两类生成:样板代码生成(路由、校验、类型定义)质量通常很好;业务逻辑仍需人把关。

Q4:这不就是瀑布 / MDD 回归吗?

不是。区别在于:

  • 瀑布:一次性签字,文档冻结,变更代价高;
  • SDD:规格是活文档,随功能演进,代码可随时从规格重新生成;规格变更的代价很低。

Q5:小团队值得吗?

值得,但要选择性使用。两人团队在绿地功能和大规模多文件重构上收益明显;对一行修复和探索性试验,写规格反而更费时间。

Q6:遗留系统能用吗?

能,而且 L1 就是为遗留系统设计的:先让 AI 从现有代码反推出一版规格,人工校正后作为基线,再逐步升级到契约与规格驱动。

Q7:Agent 说它满足了规格,怎么确认?

必须有可执行校验。「满足规格」只有在有验收测试、契约测试或 schema 校验通过时,才是一个机械可验证的事实,否则只是模型的自述。


十一、最佳实践清单

写规格时

  • 只写 what & why,技术栈留到 plan 阶段
  • 写明 Non-goals(不做什么)
  • 验收标准逐条可测试,禁止「体验流畅」这类描述
  • 未决问题集中放 Open questions,不让模型替你决定
  • 规格短于它将要产出的 diff(长度是自检信号)

做方案时

  • 明确列出不允许改动的文件/模块
  • 关键权衡记录成 ADR(一页纸)
  • 重要功能可生成多套 plan 做对比

实现与验收

  • 任务拆到「一次能审查完」的粒度
  • 每个任务完成即打勾,避免批量完成
  • 跑 converge 做差距自查
  • 验收标准逐条用测试或手工验证过,不采信 Agent 的自我声明

长期维护

  • 规格与代码同仓、同 PR 评审
  • 契约进 CI,spec 与代码不一致时构建失败
  • 功能稳定后若不再维护规格,主动删除而不是留着误导人

十二、总结

SDD 的本质是一次重心转移:

文本
过去:程序员的价值 = 会写代码现在:程序员的价值 = 会定义清楚要写什么

三条核心认知:

  1. 规格是源头,代码是产物——把「要什么」和「怎么做」分开,需求才能稳定、方案才能替换。
  2. 只有可执行校验才算合规——没有测试的「已满足规格」是自述,不是事实。
  3. SDD 是给大变更用的工具,不是普适流程——「变更超出脑容量才写规格」是最实用的判断标准。

对你当前的场景(多端项目 + AI 协作开发),最值得落地的两点是:

  • 把已有的「先方案后改代码」规则固化成 spec / plan 工件,从口头约定升级为可追溯的文档;
  • 用一份 spec 驱动多端实现(PC / H5 / 小程序 / App),从「每端分别对齐」变为「规格统一、实现分头」。

完

前端、后端、部署、客服都是我一个人。写这里的东西都是真踩过的坑,不是抄来的教程。