1. 先别急着关页面:SDD 到底卡在哪儿了
如果你点进这篇文章,大概率是搜过“SDD 看不懂”“SDD 入门”“SDD 和 TDD 区别”这类词,然后被一堆论文、规范文档、或者满屏术语的博客劝退了。我特别理解这种感觉——SDD 这个词,全称是 Specification-Driven Development,中文一般叫“规范驱动开发”。听起来好像很学术,但它本质上就是一件事:先把“要做什么”写清楚,再让代码去实现它。
你可能会说,这不就是写需求文档吗?还真不是。传统需求文档是写给人看的,而 SDD 的核心是:规范本身要足够精确,精确到能直接驱动开发、甚至驱动 AI 编程工具生成代码。这就是为什么最近 SDD 突然又火了——AI 编程助手越来越强,但如果你给它的指令含糊不清,它生成的代码就是一团浆糊。SDD 解决的正是这个问题。
这篇文章适合谁看?如果你是那种“一看规范就头疼、宁愿直接写代码”的程序员,或者你正在用 Cursor、Windsurf、Copilot 这类 AI 编程工具但总觉得生成结果不稳定,再或者你听说过 SDD 但一直没搞懂它和 TDD、DDD 到底什么关系,那这篇就是写给你的。我会用最直白的话,把 SDD 拆开揉碎,配上可以直接抄的操作步骤和踩坑记录。
2. SDD 到底是什么:用“装修图纸”来理解它
2.1 一句话说清 SDD 的核心逻辑
我试过很多种解释方式,最后发现最有效的类比是装修。你找装修队来家里干活,有两种方式:
第一种,你口头说“我想要一个温馨一点的客厅”,然后工人凭感觉给你装。结果大概率是:你觉得颜色不对,他觉得你要求不明确,来回扯皮,工期拖长,预算超支。
第二种,你先出一套图纸:哪里是插座、哪里是承重墙、电视墙多宽、灯光色温多少。工人照着图纸施工,验收也照着图纸来。出了问题,大家对着图纸说话。
SDD 就是第二种方式。规范就是图纸,代码就是施工。图纸画得越精确,施工返工的概率就越低。在软件里,这份“图纸”不是随便写写的 Word 文档,而是一种结构化、可验证、甚至机器可读的规范描述。
2.2 SDD 和 TDD、DDD 到底什么关系
很多人卡在这里。我用一张表说清楚:
| 概念 | 核心关注点 | 产出物 | 典型使用场景 |
|---|---|---|---|
| TDD | 测试先行,用测试驱动代码 | 单元测试用例 | 代码级质量保障 |
| DDD | 领域模型驱动,业务语言统一 | 领域模型、聚合根 | 复杂业务系统建模 |
| SDD | 规范先行,用精确描述驱动实现 | 结构化规范文档 | 需求到代码的转化、AI 编程 |
它们不是互斥的。实际项目里,我经常这样组合:SDD 定上层规范,DDD 拆领域边界,TDD 保底层质量。SDD 管的是“从想法到可执行描述”这一段,它不替代 TDD,而是把 TDD 的“测试先行”思想往前推了一步——变成“规范先行”。
2.3 为什么现在 SDD 突然重要了
因为 AI 编程工具改变了游戏规则。以前你写代码,规范模糊一点没关系,你自己脑子里有数。现在你把任务交给 AI 助手,它没有你的“脑补”能力。你写“做一个用户登录功能”,它可能给你生成一个明文存密码的版本。你写“做一个安全的用户登录功能”,它可能给你加个 MD5——也不对。
AI 编程的上限,取决于你给它的规范精度。这就是 SDD 在 AI 编程时代重新被重视的根本原因。你去看那些 AI 编程助手大比拼的测评,Cursor、Windsurf、Copilot、Trae 谁更强,其实差距不在模型本身,而在使用者能不能把需求写成精确规范。同一个工具,有人用得出神入化,有人用得一塌糊涂,差别就在这儿。
3. 一份能用的 SDD 规范长什么样
3.1 规范的最小结构:输入、行为、输出、边界
我踩过最大的坑,就是一开始把 SDD 规范写成了“小作文”。洋洋洒洒几百字,结果 AI 读完还是不知道要干什么。后来我总结出一个最小可用结构,四个部分:
- 输入:这个功能接收什么数据?格式、类型、来源、约束条件。
- 行为:拿到输入后,系统要做什么?步骤、规则、优先级。
- 输出:返回什么?成功什么样,失败什么样。
- 边界:什么情况下不处理?异常怎么抛?极限值是多少?
举个例子。假设你要做一个“用户注册”功能。模糊写法是:“用户输入邮箱和密码,系统验证后创建账号。”这种写法给 AI,它生成的代码大概率缺校验、缺异常处理。
精确写法应该是:
输入: - email: 字符串,必须符合 RFC 5322 邮箱格式,最大长度 254 - password: 字符串,长度 8-64,必须包含至少一个大写字母和一个数字 行为: 1. 校验 email 格式,不合法返回错误码 AUTH_001 2. 校验 password 强度,不合法返回错误码 AUTH_002 3. 查询 email 是否已存在,存在返回错误码 AUTH_003 4. 对 password 进行 bcrypt 哈希(cost=12) 5. 写入数据库,返回用户 ID 输出: - 成功:{ userId: string, createdAt: timestamp } - 失败:{ errorCode: string, message: string } 边界: - 数据库连接失败:返回 AUTH_500,不暴露内部错误 - 并发注册同一邮箱:依赖数据库唯一索引,捕获冲突异常返回 AUTH_003你看,同样一个功能,第二种写法给 AI,它生成的代码质量完全不一样。规范不是写给人看的文档,是写给“执行者”看的指令——这个执行者可能是人,也可能是 AI。
3.2 规范的语言选择:自然语言 vs 结构化格式
有人问,SDD 规范必须用特定格式吗?比如 Gherkin、OpenAPI、JSON Schema?我的经验是:看你的执行者是谁。
如果执行者是人,自然语言加结构化列表就够了,重点是消除歧义。如果执行者是 AI 编程助手,那结构化程度越高越好。我实测下来,给 Cursor 或 Windsurf 喂规范时,用 Markdown 的标题加列表格式,比纯段落效果好很多。因为 AI 对层级结构敏感,它能清楚知道哪部分是输入、哪部分是行为。
如果执行者是自动化工具链,那就需要机器可读格式,比如 OpenAPI 描述 API、JSON Schema 描述数据结构、Gherkin 描述行为场景。这些格式的好处是可验证——你可以写脚本检查规范本身有没有矛盾。
3.3 规范写多细才够:一个判断标准
这是最常被问到的问题。写太粗,AI 瞎猜;写太细,写规范的时间比写代码还长。我的判断标准是:如果换一个完全不了解这个项目的人来执行,他能不能不问你任何问题就做对。
如果答案是“能”,规范就够了。如果答案是“他可能会问……”,那你就把那个“可能会问”的点补上。
但注意,这个标准是针对“执行者”的。如果执行者是 AI,你还要考虑 AI 的“知识盲区”。比如你写“用标准加密方式存密码”,AI 可能选 MD5。你得写“用 bcrypt,cost=12”。这不是啰嗦,这是把隐含知识显式化。
4. 实操:从零写一份 SDD 规范并驱动 AI 生成代码
4.1 准备工作:选工具、定模板、建目录
先说工具。我目前主力用 Cursor 加 Claude 模型,偶尔用 Windsurf 做交叉验证。VS Code Copilot 适合补全,不适合从零生成完整模块。Trae 我用得少,但社区反馈不错。工具选择不是关键,关键是你怎么组织规范文件。
我的项目目录里有一个specs/文件夹,结构如下:
specs/ features/ user-register.md user-login.md order-create.md schemas/ user.json order.json glossary.md每个功能一个 Markdown 文件,用统一模板。glossary.md放术语定义,避免同一个词在不同规范里含义不同。这个习惯是从 DDD 的“统一语言”借鉴来的,但用在 SDD 里同样有效。
4.2 第一步:写清楚“不做什么”比“做什么”更重要
新手写规范,容易只写正向流程。但实际开发中,边界和异常才是 bug 重灾区。我写规范时,会强制自己回答三个问题:
- 输入为空、超长、格式错误时怎么办?
- 依赖的外部服务超时、返回错误时怎么办?
- 并发、重复请求、部分成功时怎么办?
这三个问题的答案,往往比正向流程更能决定代码质量。比如“用户注册”那个例子,如果你不写“并发注册同一邮箱”的处理方式,AI 生成的代码可能先查再写,存在竞态条件。你写了“依赖数据库唯一索引”,它就知道要用INSERT ... ON CONFLICT或者捕获唯一约束异常。
4.3 第二步:把规范喂给 AI 编程助手的正确姿势
很多人用 AI 编程助手的方式是:打开对话框,输入“帮我写一个用户注册功能”,然后等结果。这种方式在 SDD 框架下是低效的。正确的姿势是:
- 先把规范文件在编辑器里打开,让 AI 读取上下文。
- 在对话框里明确说:“根据
specs/features/user-register.md的规范,生成对应的实现代码。使用 TypeScript,框架是 NestJS,数据库是 PostgreSQL。” - 生成后,不要直接接受。先对照规范逐条检查:输入校验有没有?错误码对不对?边界处理有没有?
我实测下来,这种方式的首次生成可用率能从 30% 提升到 70% 以上。剩下的 30%,通常是规范本身有歧义,或者 AI 对框架的特定写法不熟悉。这时候你回去改规范,比直接改代码更划算——因为改规范是一次性的,改代码是每次生成都要改。
4.4 第三步:用规范做代码审查的 checklist
SDD 的一个隐藏好处是:规范天然就是审查清单。代码写完后,你不需要凭记忆去检查,直接对着规范一条条过:
| 规范条目 | 检查点 | 通过标准 |
|---|---|---|
| 输入 email 格式校验 | 是否有正则或验证库 | 非法邮箱返回 AUTH_001 |
| 密码强度校验 | 长度、大小写、数字 | 不满足返回 AUTH_002 |
| 邮箱唯一性 | 数据库唯一索引 | 冲突返回 AUTH_003 |
| 密码哈希 | bcrypt cost=12 | 数据库中无明文 |
| 错误不暴露内部信息 | 500 错误统一处理 | 响应中无堆栈 |
这张表可以直接贴到 PR 描述里,reviewer 照着打勾就行。团队协作时,这比“我觉得这里可能有问题”高效得多。
5. 常见问题与排查技巧实录
5.1 规范写了但 AI 不遵守怎么办
这是最高频的问题。我遇到的情况通常有三类原因:
第一,规范本身有矛盾。比如前面写“密码长度 8-64”,后面写“密码至少 12 位”。AI 会随机选一个。解决办法:写完规范后,用脚本或人工做一次一致性检查。
第二,规范太长,AI 注意力丢失。超过 2000 字的规范,AI 可能只记住开头和结尾。解决办法:拆分成多个小规范,每个规范聚焦一个功能点,用引用链接关联。
第三,AI 模型的指令遵循能力差异。同一个规范,Claude 可能遵守得很好,GPT 可能漏掉几条。解决办法:换模型试,或者在对话框里把关键约束再强调一遍。
5.2 规范更新了,代码没同步怎么办
这是 SDD 落地最大的痛点。我的做法是:把规范文件纳入版本控制,和代码在同一个仓库。每次改规范,PR 里必须同时包含规范变更和代码变更。CI 里加一个检查:如果specs/目录有变更但src/没有对应变更,就警告。
更进一步,可以用 AI 做“规范-代码一致性检查”。把规范文件和对应代码一起喂给 AI,问它:“代码是否完全实现了规范?列出所有偏差。”我试过,能抓出不少遗漏。
5.3 小项目也需要 SDD 吗
看情况。如果是一个人写的小工具,规范可以很轻,甚至就是代码注释里的几行说明。但如果是多人协作、或者你要用 AI 生成代码,那规范的价值就很大。我的经验是:当你的 AI 编程助手开始“猜”你的意图时,就是该写规范的时候了。
5.4 常见问题速查表
| 问题现象 | 可能原因 | 排查动作 | 解决方式 |
|---|---|---|---|
| AI 生成的代码缺校验 | 规范未写明校验规则 | 检查规范输入部分 | 补充格式、长度、类型约束 |
| 错误码不一致 | 规范未定义错误码表 | 检查规范输出部分 | 建立统一错误码表并引用 |
| 并发问题 | 规范未提并发场景 | 检查边界部分 | 补充并发、重复请求处理 |
| 规范与代码脱节 | 规范未纳入版本控制 | 检查仓库结构 | 规范与代码同仓库、同 PR |
| AI 忽略部分规范 | 规范过长或有矛盾 | 检查规范长度和一致性 | 拆分规范、消除矛盾 |
6. 我踩过的坑和给你的建议
第一个坑:把 SDD 当成写文档。我一开始花大量时间排版、润色,后来发现完全没必要。规范是给执行者看的,不是给领导看的。清晰、无歧义、可验证,比好看重要一万倍。
第二个坑:规范写得太细,失去灵活性。有一次我把一个算法的每一步都写死了,结果 AI 生成的代码完全没法维护。后来我学会区分“必须遵守的约束”和“建议的实现方式”。前者写死,后者留白。
第三个坑:忽略术语一致性。同一个概念,规范里叫“用户”,代码里叫“account”,数据库里叫“member”。AI 生成时就会混乱。后来我建了一个glossary.md,所有术语先定义再使用,问题少了很多。
如果你刚开始尝试 SDD,我的建议是:从一个小功能开始,写一份规范,喂给 AI,看生成结果,然后回头改规范。这个循环走三遍,你就找到感觉了。不要一上来就搞大而全的规范体系,那只会让你放弃。
SDD 不是银弹,它解决的是“意图到实现”的转化损耗问题。在 AI 编程时代,这个损耗被放大了,所以 SDD 的价值也被放大了。但它本质上还是一种沟通方式——和你自己沟通,和协作者沟通,和 AI 沟通。沟通清楚了,代码自然就清楚了。