什么是 Spec-Driven Development
Spec-Driven Development(SDD,规格驱动开发) 是一种 AI 辅助开发方法论:开发者在让 AI 写代码之前,先把需求、边界和验收标准写成结构化的规格说明(Spec),AI 再依据 Spec 生成、修改或引导实现。
Spec 可以是自然语言文档,也可以带接口签名、数据模型、约束条件等结构化片段。核心不是格式,而是 先定义「完成」长什么样,再让 AI 动手。
典型 Spec 会回答:
- 要做什么、不做什么
- 输入输出与接口契约
- 边界条件与错误处理
- 验收标准(怎样算通过)
SDD 与 Vibe Coding 的关系
SDD 和 Vibe Coding 关联很强,但方向相反——它们描述的是同一条 AI 协作光谱的两端。
| 维度 | Vibe Coding | SDD |
|---|---|---|
| 输入方式 | 口语化、即兴描述 | 结构化 Spec |
| 意图传递 | 让 AI 猜 | 显式定义边界 |
| 可追溯性 | 低,依赖对话历史 | 高,Spec 可版本管理 |
| 适合场景 | 原型、探索、一次性脚本 | 功能迭代、协作、长期维护 |
| 出错模式 | 方向对但细节偏、隐性假设 | 前期写 Spec 有成本 |
Vibe Coding 指用自然、随意的语言驱动 AI 写代码,强调「跟着感觉走」——描述大概想要什么,让模型自行补全细节。Andrej Karpathy 在 2025 年推广了这个说法。它上手快,适合快速验证想法。
SDD 则是把 Vibe Coding 里隐含在对话中的假设,提前外化成可审查的文档。不是否定 Vibe Coding,而是在需要 可重复、可验收、可交接 时,把协作方式从「猜」升级为「对齐」。
更实用的做法不是二选一,而是分阶段组合——中间有一层 Vibe-to-Spec:用 Vibe Coding 的方式和 AI 一起把 Spec 写出来。
Vibe-to-Spec:用 Vibe 写 Spec,再按 Spec 编码
需求一开始往往是模糊的。如果直接让 AI 写代码,隐性假设会立刻变成代码里的默认值;如果一开始就要求完整 Spec,又容易卡在「不知道该怎么写」。
更好的实践是 三阶段:
Vibe 探索 → Vibe-to-Spec(协作写 Spec)→ SDD 编码
- Vibe 探索(可选):快速原型或对话,确认方向可行、边界大致在哪
- Vibe-to-Spec:用口语和 AI 多轮对话,把模糊需求逐渐细化、固化成一份 Spec
- SDD 编码:Spec 经 review 稳定后,再让 AI 严格按 Spec 实现
第 2 步是关键。此时你和 AI 讨论的对象是 Spec 文档本身,不是代码。AI 可以帮你补全边界 case、列出接口字段、起草验收清单;你负责纠正方向、删掉不该有的范围、确认最终口径。对话可以 vibe,产出必须是结构化的。
什么时候 Spec 算「稳定」
可以开始编码的信号:
- 目标、范围、不包含项三者不再来回改
- 接口或行为描述足够具体,能写出测试用例
- 你自己通读一遍,没有「这里 AI 可能理解错」的歧义
- 如有协作者,对方 review 过(或至少你刻意用「fresh eyes」再过一遍)
未稳定前,继续 Vibe-to-Spec,不要开写实现。
和「Vibe 直接写代码」的区别
| Vibe 直接编码 | Vibe-to-Spec → SDD 编码 | |
|---|---|---|
| 对话对象 | 代码 | Spec 文档 |
| 模糊需求的代价 | 立刻固化进实现,改起来贵 | 改 Spec 便宜,编码前对齐 |
| AI 的角色 | 猜意图 + 写代码 | 先协助澄清意图,再按契约写代码 |
| 适合 | 一次性脚本、15 分钟验证 | 要进主分支、要维护的功能 |
一句话:Vibe Coding 解决「想法从哪来」;Vibe-to-Spec 解决「想法怎么对齐」;SDD 解决「对齐后怎么可靠交付」。
为什么 AI 时代更需要 SDD
LLM 没有持久记忆,每次对话上下文有限,且倾向于「补全一个看起来合理的答案」。在这种特性下:
- 口语描述里的省略,会被 AI 用默认值填充——而这些默认值往往不是你想要的
- 多轮对话后,早期约束容易被稀释
- 没有 Spec,很难判断生成物是「做对了」还是「看起来对了」
SDD 把 隐性意图变成显性契约,让人和 AI 在同一份文本上对齐,而不是各自脑补。
Spec 写什么
复杂任务才需要完整 Spec;小改动可以只用几段文字。一个够用的 Task Spec 通常包含:
## 目标
实现用户登录 API,支持邮箱 + 密码。
## 范围
- 包含:POST /api/login、JWT 签发、错误码
- 不包含:注册、OAuth、刷新 token
## 接口
POST /api/login
Body: { "email": string, "password": string }
200: { "token": string }
401: 凭证无效
## 约束
- 密码不得明文记录
- 响应时间 P99 < 200ms(单实例)
## 验收
- [ ] 正确凭证返回 JWT
- [ ] 错误凭证返回 401
- [ ] 单元测试覆盖边界 case
Spec 里的接口契约、边界条件,可以直接转化为测试用例——这也是 SDD 与 Harness Engineering 衔接的地方。
基本工作流
Vibe 探索(可选)→ Vibe-to-Spec → Review → AI 按 Spec 实现 → 测试验收 → 下一轮
- Vibe-to-Spec:和 AI 对话,把需求收敛成 Spec(目标、范围、验收清单)
- Review:确认 Spec 稳定;不稳定就继续改 Spec,不写代码
- AI 实现:把 Spec 作为 prompt 或项目文档提供给 AI
- 验证:用测试或 checklist 对照 Spec,不接受「看起来差不多」
- 记录进度:哪些 Spec 已实现、哪些在进行中(可配合状态锚点)
- 迭代:下一个 Spec 基于当前稳定基线继续
这与 TDD 有相似之处:都是先定义「完成」的标准。差别在于 SDD 的「测试」往往是自然语言规格 + 自动化测试的组合,且 Spec 同时服务于人和 AI。
与 Harness Engineering 的分工
SDD 和 Harness Engineering 覆盖 AI 辅助开发闭环的不同侧:
- SDD(输入侧):用 Spec 告诉 AI「要做什么、边界在哪」
- Harness Engineering(验证侧):用测试套件、状态锚点、项目约定确认「做得对不对、能不能安全演进」
完整闭环:
Spec(SDD)→ AI 生成实现 → Test Harness 验证 → 状态锚点记录进度 → 下一轮 Spec
何时用哪种方式
| 场景 | 建议 |
|---|---|
| 15 分钟的小脚本、一次性数据处理 | Vibe Coding 足够 |
| 新功能、多人协作、要进主分支 | Vibe-to-Spec → Review → SDD 编码 |
| 需求模糊、方案未定 | Vibe 探索 → Vibe-to-Spec,稳定后再编码 |
| 需求清晰、边界明确 | 直接写 Spec 或小幅 Vibe-to-Spec |
| 已有测试和文档的成熟项目 | SDD + Harness,Spec 粒度可以更小 |
不必教条。关键是分清当前在做什么:探索想法、对齐 Spec,还是按 Spec 交付——三者对应 Vibe、Vibe-to-Spec、SDD 编码。
与博客「文章 SDD」的区别
本仓库还有一套 文章 SDD(Spec-Driven Writing):作者在 .ai/specs/ 写文章 Spec,AI 润色后输出 content/post/ 下的交付物。那是 写作流程,不是软件开发方法论。
| 软件开发 SDD | 文章 SDD | |
|---|---|---|
| 对象 | 代码、功能、接口 | 博客文章 |
| Spec 位置 | 项目内 docs/tasks/ 等 |
.ai/specs/ |
| 交付物 | 可运行的实现 + 测试 | Hugo 文章 |
名字相同,思路相通(先 Spec、后产出),但场景和工具链不同。
总结
SDD 和 Vibe Coding 不是非此即彼。日常更顺的路径往往是:用 Vibe 和 AI 一起把 Spec 写清楚,Review 稳定后再编码。Vibe 负责降低起步摩擦和对齐成本;SDD 负责把对齐结果变成可验收的交付。配合 Harness Engineering 的验证侧,形成 探索 → Vibe-to-Spec → 实现 → 验证 的完整链路。