
1. 先别急着关页面SDD 到底卡在哪儿了如果你点开这篇文章大概率是因为搜过“SDD 是什么”“SDD 和 TDD 区别”“SDD 程序员怎么上手”这类问题然后被一堆术语砸得有点懵。我先说结论SDDSpecification-Driven Development规格驱动开发不是又一个新瓶装旧酒的缩写词它真正想解决的问题是“代码写完了才发现做错了东西”这个老毛病。你不需要先成为架构师才能理解它你只需要承认一件事——大多数返工不是因为程序员不会写代码而是因为写代码之前没人把“要做什么”说清楚。我见过太多团队需求文档是一句话设计文档是几张图然后直接开干。等到提测那天产品说“这不是我要的”开发说“你当初就是这么说的”测试说“我按文档测的没问题”。三方都没撒谎问题出在中间那层“规格”从来没被认真对待过。SDD 就是把这一层拎出来当成一等公民来对待先写规格再写代码规格是唯一的事实来源。这篇文章适合谁看如果你是刚工作一两年的程序员被各种开发方法论绕晕了如果你是带小团队的技术负责人想找一套能落地的流程而不是 PPT 上的口号如果你只是好奇“AI 编程时代为什么又冒出来一个 SDD”那这篇就是写给你的。我会用大白话把 SDD 拆开讲清楚它的核心逻辑、和 TDD/DDD 的区别、实际怎么落地、以及我在真实项目里踩过的坑。不堆概念不画大饼只讲能用的东西。2. 把 SDD 翻译成人话规格不是文档是契约2.1 为什么“写文档”这三个字劝退了那么多人一提到“先写规格”很多程序员第一反应是抗拒的。原因很实在过去十几年里“写文档”这件事在大多数团队里就是走形式。需求文档写完没人看设计文档写完就过期接口文档靠 Swagger 自动生成但字段含义全靠猜。久而久之大家形成了一个条件反射——文档等于浪费时间代码才是真相。这个反射不能怪程序员。它是在无数次“写了也没人维护”的教训里练出来的。所以当你听到 SDD 说“规格优先”的时候本能地会觉得这又是哪个咨询公司编出来卖课的概念。但 SDD 里的“规格”和你理解的“文档”有一个本质区别文档是给人看的参考材料规格是给人和机器共同执行的契约。参考材料可以模糊、可以过期、可以没人看契约不行契约一旦定下来代码必须符合它测试必须验证它变更必须走流程。这个区别听起来只是措辞上的但它决定了整套方法能不能落地。打个比方。你装修房子设计师给你画了一张效果图这是文档——好看就行施工队不一定完全照着做。但如果设计师给你出的是一份带尺寸、带材料标号、带水电点位的施工图那就是规格——工人照着做监理照着验改一个插座位置都要重新出图。SDD 要的就是后面这种。2.2 规格的最小可用形态三件事说清楚就够了很多人以为写规格就是要写几十页 Word其实不是。一个能用的规格最少只需要说清楚三件事输入是什么这个功能接收什么数据、什么触发条件、什么前置状态。输出是什么成功时返回什么、失败时返回什么、边界情况怎么处理。约束是什么性能要求、安全要求、兼容性要求、不能碰的红线。就这三件事。你把它写成表格也好写成结构化文本也好写成带注释的接口定义也好形式不重要重要的是这三件事必须明确到“没有第二种解释”的程度。我举个真实的例子。之前有个需求叫“用户下单后发送通知”。这句话作为需求是合格的作为规格是灾难。因为“通知”可以是短信、邮件、站内信、推送“下单后”可以是支付成功后、订单创建后、库存扣减后“发送”可以是同步、异步、重试三次。你不把这些说清楚五个程序员能写出五种东西。改成规格之后是这样的项目内容触发条件订单状态变更为“已支付”通知渠道站内信主 邮件备发送时机异步订单状态变更后 5 秒内失败处理重试 3 次间隔 10 秒仍失败则记录告警日志不发送场景用户已关闭通知开关、订单金额为 0你看还是那一页纸但歧义消失了。这就是 SDD 说的“规格”。2.3 规格和代码谁先谁后一个容易被绕晕的问题有人会问那是不是必须先写完所有规格才能写代码不是。SDD 不要求你一次性把整个系统的规格写完它要求的是在你动手写某一块代码之前先把这一块的规格定下来。粒度可以很细细到一个函数、一个接口、一个状态机。这就像盖楼你不需要把整栋楼的施工图全部画完才开始打地基但你要打地基的那块地方图纸必须先有。SDD 反对的是“边写边想”支持的是“想清楚一块写一块”。这里有个实操上的判断标准如果你发现自己写代码的时候在纠结“这里到底该返回什么”说明规格没写够。纠结的那一刻就是规格缺失的信号。停下来把规格补上再继续写。这个习惯养成了返工率会肉眼可见地下降。3. SDD、TDD、DDD 到底是不是一家人3.1 一张表看清三个缩写的分工这三个词经常被放在一起比较但它们其实不在一个层面上。我用一张表说清楚维度TDDDDDSDD全称测试驱动开发领域驱动开发规格驱动开发关注点代码正确性业务建模需求到实现的契约核心动作先写测试再写代码先划分领域再写代码先写规格再写代码产出物测试用例领域模型规格说明解决的问题代码有没有写对业务有没有建对东西有没有做对适用场景逻辑复杂的模块业务复杂的系统协作复杂的需求看明白了吗TDD 管的是“实现层”DDD 管的是“建模层”SDD 管的是“需求层”。它们不是互相替代的关系而是可以叠加的。一个成熟的团队完全可以先用 SDD 把需求变成规格再用 DDD 把规格变成领域模型最后用 TDD 把模型变成有测试保障的代码。3.2 为什么 SDD 在 AI 编程时代突然火了这两年 AI 编程工具爆发Cursor、Windsurf、Copilot、各种 Agent 满天飞。很多人发现一个尴尬的事实AI 写代码很快但 AI 不知道你要什么。你给它一句模糊的需求它给你一段能跑但不对的代码你给它一段详细的规格它给你的代码质量立刻上一个台阶。这就是 SDD 重新被提起的直接原因。AI 编程的瓶颈从来不是“写代码的速度”而是“表达需求的精度”。SDD 恰好就是训练你表达需求精度的工具。你写规格的能力越强AI 帮你写代码的效率越高。反过来你规格写得含糊AI 只会把你的含糊放大成 bug。我自己的体会是用 AI 编程工具之前先花十分钟把规格写清楚比事后花一小时 debug 划算得多。这十分钟不是浪费是投资。而且规格写多了之后你会发现自己对需求的理解速度也变快了因为你的大脑已经习惯了“输入-输出-约束”这个思考框架。3.3 别把 SDD 当成宗教它只是一个工具我特别怕看到有人把 SDD 当成信仰逢人就说“你不写规格就是不合格的程序员”。这就走极端了。SDD 是一个工具工具有适用场景也有不适用场景。适合用 SDD 的场景多人协作、需求频繁变更、对接方多、AI 辅助编程、长期维护的项目。不太需要 SDD 的场景一次性脚本、个人小工具、探索性原型、需求极其稳定的老系统维护。判断标准很简单如果“做错了”的代价大于“写规格”的成本就值得写规格。反过来如果改一行代码就能试错那直接试比写规格快。工具是拿来用的不是拿来供的。4. 落地 SDD 的完整路径从一句话需求到可执行规格4.1 第一步把需求拆成“可验证的句子”需求文档里最常见的一句话是“系统要支持用户管理”。这句话没法验证因为“支持”是个模糊动词。SDD 的第一步就是把它拆成可验证的句子。拆法是这样的把每个模糊动词换成具体动作把每个名词换成具体对象把每个形容词换成具体数值。“系统要支持用户管理”拆完变成管理员可以创建用户必填字段为用户名、邮箱、初始角色。管理员可以禁用用户禁用后该用户无法登录。管理员可以重置用户密码重置后系统生成临时密码并通过邮件发送。普通用户只能查看和修改自己的信息不能查看他人信息。每一句都能写测试每一句都能判断对错。这就是“可验证”。提示拆需求的时候遇到“等等”“类似”“其他”这类词要特别警惕。这些词背后往往藏着没想清楚的需求不拆出来就是定时炸弹。4.2 第二步给每条规格定义验收标准规格写完了怎么知道代码有没有符合规格靠验收标准。验收标准就是“满足什么条件算通过”。继续用上面的例子。“管理员可以创建用户”这条规格验收标准可以写成提交合法数据时用户创建成功返回用户 ID。用户名重复时返回错误码 409提示“用户名已存在”。邮箱格式非法时返回错误码 400提示“邮箱格式不正确”。缺少必填字段时返回错误码 400并列出缺失字段。创建成功后用户状态默认为“启用”。这五条写出来开发知道怎么写测试知道怎么测AI 知道怎么生成代码。三方对齐返工概率大幅下降。这里有个经验验收标准要写成“给定-当-则”的结构。给定什么前置条件当发生什么操作则得到什么结果。这个结构强迫你把边界情况想清楚而不是只写 happy path。4.3 第三步把规格变成代码骨架规格和验收标准都有了接下来才是写代码。但 SDD 建议你不要一上来就写业务逻辑而是先把骨架搭出来。骨架是什么就是函数签名、接口定义、数据结构、状态枚举。这些东西直接对应规格里的输入输出和约束。比如“创建用户”这条规格骨架可以是class CreateUserRequest: username: str email: str role: str class CreateUserResponse: user_id: str status: str def create_user(request: CreateUserRequest) - CreateUserResponse: # 规格校验用户名唯一性 # 规格校验邮箱格式 # 规格校验必填字段 # 规格创建用户状态默认启用 pass你看函数体还是空的但规格已经以注释的形式嵌进去了。接下来无论你自己写实现还是让 AI 补全都有明确的靶子。这就是 SDD 说的“规格驱动”——规格不是写完就扔的文档而是贯穿到代码里的骨架。4.4 第四步用规格反推测试用例骨架搭完测试用例其实已经呼之欲出了。因为验收标准本身就是测试用例的雏形。“用户名重复时返回 409”这条验收标准直接翻译成测试就是def test_create_user_duplicate_username(): # 给定已存在用户名为 alice 的用户 create_user(CreateUserRequest(alice, aexample.com, admin)) # 当再次创建用户名为 alice 的用户 result create_user(CreateUserRequest(alice, bexample.com, user)) # 则返回 409 错误 assert result.error_code 409这就是 SDD 和 TDD 的衔接点。SDD 负责把需求变成规格TDD 负责把规格变成测试。两者配合代码质量有双重保障。4.5 第五步规格变更管理规格不是刻在石头上的。需求变了规格就要变。但 SDD 要求规格变更必须显式、可追溯。什么叫显式就是不能偷偷改代码不改规格。代码和规格不一致的时候以规格为准要么改代码要么改规格不能两边各说各话。什么叫可追溯就是每次规格变更都要记录谁改的、为什么改、影响哪些代码、影响哪些测试。这个记录不需要多正式一个变更日志文件就够了。我见过最离谱的情况是规格文档还是三个月前的版本代码已经改了八轮测试用例还是按老规格写的。这种状态下规格不但没起到契约作用反而成了误导。所以规格变更管理不是可选项是必选项。5. 真实项目里的 SDD一个订单模块的完整拆解5.1 项目背景和初始需求假设你接到一个需求给电商系统加一个“订单取消”功能。原始需求描述只有一句话“用户可以取消未发货的订单。”这句话如果直接开干你会遇到一堆问题什么叫“未发货”已支付未发货能取消吗取消后钱怎么退部分商品已发货怎么办取消次数有限制吗取消后库存怎么处理用 SDD 的方式第一步就是把这些问号变成规格。5.2 规格拆解过程我先列出所有需要明确的点然后逐个定义状态定义订单状态分为待支付、已支付待发货、已发货、已完成、已取消。只有“已支付待发货”状态可以取消。取消条件订单未发货、订单未完成、订单未取消、用户是订单所有者。退款规则取消成功后支付金额原路退回退款到账时间以支付渠道为准。库存处理取消成功后订单内商品库存加回。取消次数同一订单只能取消一次。并发处理同一订单同时发起多次取消请求只有第一次成功其余返回“订单已取消”。把这些写成规格表规格项定义可取消状态已支付待发货取消发起人订单所有者退款方式原路退回库存处理加回可用库存幂等性同一订单取消操作幂等并发控制乐观锁版本号校验5.3 从规格到代码的映射规格定完代码结构基本就出来了。你需要一个状态机管理订单状态流转。一个取消服务处理取消逻辑。一个退款服务处理退款。一个库存服务处理库存加回。一个幂等控制防止重复取消。每个服务对应一条或几条规格。写代码的时候你不需要再想“这里该做什么”因为规格已经告诉你了。你只需要想“怎么做得更好”。这就是 SDD 带来的心智负担转移把“想做什么”和“怎么做”分开。想做什么在规格阶段解决怎么做在编码阶段解决。两个阶段混在一起就是 bug 的温床。5.4 踩坑记录规格写太细和写太粗都出事我在实际项目里踩过两个方向的坑。第一个坑是规格写太细。有一次我把一个接口的规格写到了字段级别连每个字段的长度限制、正则表达式都写进去了。结果需求一变规格要改代码要改测试要改三处同步改累得半死。后来我学乖了规格写到“行为”层面就够了不要写到“实现”层面。字段长度这种细节放在代码里定义规格里只说“用户名长度符合系统约束”。第二个坑是规格写太粗。另一个项目里规格只写了“取消订单要退款”没写退款失败怎么办。结果上线后遇到支付渠道超时退款失败订单状态卡在中间用户既没收到退款也不能重新取消。后来补了规格退款失败时订单状态置为“取消失败”允许用户重试并记录告警。这两个坑的教训是一样的规格的粒度要刚好覆盖“会出错的边界”不多不少。怎么判断问自己一句如果这里出错了代码知道怎么处理吗不知道就是规格没写够。6. 让 AI 编程工具真正听懂你SDD 提示词实战6.1 为什么直接让 AI 写代码效果差很多人用 AI 编程工具的方式是打开对话框输入“帮我写一个订单取消功能”然后期待 AI 给出完美代码。结果往往是一段能跑但不符合业务逻辑的代码然后你开始一轮一轮地改改到最后发现还不如自己写。问题不在 AI在输入。AI 不是读心术它只能根据你给的信息推理。你给的信息越模糊它的推理空间越大跑偏的概率越高。SDD 提供的规格恰好就是 AI 最需要的输入。6.2 把规格改写成 AI 能吃的提示词规格是给人看的提示词是给 AI 看的。两者内容一样但表达方式要调整。给 AI 的提示词要更结构化、更明确、更少歧义。一个基于规格的提示词模板角色你是一名后端工程师使用 Python 和 FastAPI。 任务实现订单取消接口。 规格 1. 接口路径POST /orders/{order_id}/cancel 2. 前置条件订单状态为“已支付待发货”发起人为订单所有者 3. 成功行为订单状态改为“已取消”触发退款库存加回 4. 失败行为 - 订单不存在返回 404 - 订单状态不允许取消返回 409提示“当前状态不可取消” - 非订单所有者返回 403 5. 幂等性同一订单重复取消第二次返回成功但不重复退款 6. 并发控制使用乐观锁版本号不匹配时返回 409 约束 - 退款和库存操作必须异步执行 - 所有状态变更必须记录日志 - 不允许在接口层直接操作数据库 请先输出接口定义和数据结构等我确认后再输出实现。这个提示词和直接说“帮我写订单取消”的区别就像施工图和口头描述的区别。AI 拿到这个提示词输出的代码质量会稳定得多。6.3 用规格约束 AI 的“自由发挥”AI 有个特点你不管的地方它会自己补。补得好是惊喜补得不好是惊吓。SDD 的作用就是划定边界告诉 AI 哪些地方可以发挥哪些地方必须按规格来。我的做法是在提示词里明确写“不允许”清单。比如“不允许引入新的第三方库”“不允许修改现有接口签名”“不允许在业务逻辑里写 SQL”。这些约束写进去AI 就不会乱来。还有一个技巧让 AI 先输出规格理解再输出代码。你可以这样问“请先用你自己的话复述一遍你对规格的理解确认无误后再写代码。”这一步能提前发现 AI 的理解偏差避免写完一大段代码才发现方向错了。6.4 实测对比有规格和没规格的差距我在同一个需求上做过对比测试。需求是“实现一个带重试的 HTTP 请求封装”。没规格的提示词“帮我写一个带重试的 HTTP 请求封装。”AI 给了一个基础版本重试三次固定间隔没有区分错误类型没有超时控制。有规格的提示词写清楚了重试次数、重试间隔策略指数退避、哪些错误码重试、哪些不重试、超时时间、最大重试总时长、日志要求。AI 给的版本直接可用只需要微调。两次对比有规格的版本节省了大约 70% 的调试时间。这个投入产出比值得每个用 AI 编程的人认真对待。7. 团队推行 SDD 时最容易翻车的几个地方7.1 把规格写成没人看的八股文最常见的翻车方式是把 SDD 执行成了“写文档运动”。规格写得又长又正式格式漂亮但没人看没人维护写完就归档。这种规格还不如不写因为它给了团队一种“我们在做规范”的错觉实际上什么都没改变。避免这个坑的关键是规格要短、要活、要跟代码在一起。短是指一页纸能说完活是指随需求更新跟代码在一起是指放在代码仓库里而不是放在某个文档系统里吃灰。我推荐的做法是把规格写成 Markdown 文件和代码放在同一个仓库用 Pull Request 管理变更。这样规格变更和代码变更在同一个流程里不会脱节。7.2 规格和代码不一致时没人管第二个坑是规格和代码各走各的。代码改了规格没改规格改了代码没改。时间一长没人知道哪个是对的。解决办法是加一道检查在代码审查清单里加一条“规格是否同步更新”。如果代码变更涉及行为变化规格必须同步改。这条规则执行几次之后就会变成肌肉记忆。更严格的做法是用工具做一致性检查。比如接口规格可以用 OpenAPI 描述代码实现必须通过 OpenAPI 校验。这样规格和代码不一致的时候CI 直接报错想偷懒都偷不了。7.3 规格粒度失控有人写太细有人写太粗团队里每个人对“规格”的理解不一样有人写得像需求文档有人写得像设计文档有人写得像测试用例。粒度不统一协作就乱。我的建议是给团队定一个规格模板明确哪些必须写、哪些不用写。模板不用复杂包含这几块就够了功能描述一句话输入输出表格边界条件列表验收标准给定-当-则变更记录日期变更内容模板定下来之后新写的规格都按这个来慢慢就统一了。7.4 把 SDD 当成考核指标最怕的是管理层把“规格覆盖率”当成 KPI。一旦变成考核大家就会为了写规格而写规格质量反而下降。SDD 的价值在于减少返工不在于产出多少文档。衡量 SDD 是否有效的指标应该是返工率有没有下降、需求理解偏差有没有减少、AI 生成代码的可用率有没有提升。这些才是真正有意义的指标。8. 我个人的 SDD 实践心得8.1 规格写不出来往往是需求没想清楚这是我最大的体会。很多时候我坐下来准备写规格写着写着发现写不下去不是因为不会写是因为需求本身有矛盾或者有空白。规格就像一面镜子照出需求的漏洞。所以我现在把写规格当成需求评审的一部分。规格写不顺的地方就是需要找产品对齐的地方。与其等到代码写完才发现问题不如在规格阶段就把问题暴露出来。8.2 规格是给未来的自己写的很多人觉得写规格是给别人看的其实最大的受益者是三个月后的自己。三个月后你回头看代码如果没有规格你得重新读一遍代码才能想起当初为什么这么写。如果有规格五分钟就能恢复上下文。我现在维护的项目每个模块目录下都有一个SPEC.md。新同事入职先读规格再读代码上手速度快很多。这个习惯坚持下来收益是复利的。8.3 从最小的模块开始试如果你之前没接触过 SDD不要一上来就在核心项目上全面推行。找一个边缘模块或者一个新启动的小功能先试一个月。试的过程中记录哪些地方有用、哪些地方多余然后调整。SDD 不是一套必须完整执行的仪式它是一组可以按需取用的实践。你可以只用它的“验收标准”部分也可以只用它的“规格提示词”部分。怎么用取决于你的场景没有标准答案。8.4 一个实用的小技巧规格先行五分钟最后分享一个我每天都在用的小技巧。每次开始写一个新功能之前先花五分钟写一段规格不用很正式就用大白话写清楚“这个功能接收什么、返回什么、出错怎么办”。五分钟写不完说明这个功能比你想的复杂需要更多时间想清楚。这五分钟的投入通常能省下半小时以上的调试时间。而且写多了之后你会发现自己对需求的敏感度提高了很多以前会忽略的边界情况现在一眼就能看出来。这个技巧不需要任何工具不需要团队配合今天就能开始用。如果你觉得 SDD 这个概念太大不好落地那就从这个五分钟开始。