
1. 从“想到哪写到哪”到“先想清楚再动手”SDD 解决的真实痛点我最早接触 SDDSpecification-Driven Development规格驱动开发并不是因为它时髦而是被逼的。当时团队在做一个人工智能辅助专利检索的系统代码写了大概两万行结果产品经理一句话“检索结果的排序逻辑不对”我盯着满屏的 if-else 看了整整一个下午愣是没敢动手改。那种感觉就像你在一团乱麻里找线头每一根都像是真的但拉一下就会打一个死结。后来我开始尝试把“开发前先写清楚要做什么、怎么判断做对了”这件事当成第一优先级才发现这其实正是 SDD 的核心思想。简单说SDD 不是让你多写文档而是让你在动手写代码之前先把“需求是什么、系统应该怎么表现、边界在哪里、怎么验证”这些事用结构化的方式写清楚。它和我们常说的 TDD测试驱动开发不一样TDD 关注的是“代码层面的行为验证”SDD 关注的是“整个系统层面的规格定义”。用一句大白话总结TDD 是让你先写测试再写代码SDD 是让你先写清楚“这玩意儿到底是干嘛的”再碰键盘。真正让我下定决心系统梳理 SDD 方法论的文章是 Thoughtworks 杰出工程师 Birgitta Böckeler 提出的一套三级分类框架。她把 SDD 分成三个层级这个框架对我的启发很大。她说 SDD 不是一种单一的做法而是三种不同粒度的实践的组合第一级Specification by Example面向示例的规格—— 用具体的输入输出例子来描述需求相当于给需求“拍照片”第二级Executable Specification可执行的规格—— 把规格文档变成计算机能理解的断言或测试相当于给需求“做体检”第三级Living Documentation鲜活的文档—— 让文档和代码同源实现“文档即代码”相当于给项目“装监控”。这三个层级不是互斥的你完全可以根据项目的实际情况混用。但我个人的经验是哪怕只做到第一级也就是把“示例化需求”这件事做扎实收益也已经非常可观了。这套方法论适用于几乎所有软件项目——无论是个人项目、初创团队、还是大型企业里的复杂系统只是实施的深度和形式不一样。下文我会用自己完整实践过的一个项目作为例子一步步拆解 SDD 的完整落地过程包括需求拆解、规格撰写、验证设计、AI 辅助编程的协作方式以及过程中踩过的所有坑。这篇内容既是给想入门 SDD 的朋友的路线图也是给我自己的复盘笔记。2. 需求拆解用“三级分类”把模糊想法变成可执行规格2.1 从一个模糊的项目需求开始先交代一下项目背景。当时我们接到一个内部工具的开发需求做一个“AI 辅助生成项目周报”的系统。需求描述非常模糊输入一段本周工作流水账让大模型帮忙生成一份结构化的周报并且能区分“本周完成”“下周计划”“风险与求助”几个板块。这种需求听起来简单但真的做起来你会发现到处都是坑。比如什么叫做“结构化”的周报是固定模板还是自由格式大模型输出的内容要不要保证百分百准确如果它编造了一个根本不存在的工作项怎么办用户输入的是口语化的流水账是否需要先做意图识别或者实体抽取周报生成完之后需不需要支持人工编辑编辑后的内容要不要回流给模型做二次训练如果直接撸起袖子开始写代码我大概率会做出一个表面上能“生成周报”但处处难用的半成品。有了 SDD 的框架之后我的第一步就变成了写文档。2.2 第一级用“面向示例的规格”敲定需求细节我做的第一件事是和产品经理、还有两个核心用户开发团队里的技术组长和运营同学坐在一起让他们各自给出 3 到 5 个他们心目中“理想周报”的输入输出示例。比如我们收集到的其中一组输入是输入这周主要做了三件事第一修复了登录模块的 session 失效 bug用户反馈很多第二和设计同学对了一下新版首页的交互稿基本定了第三帮忙 review 了同事的订单导出功能 PR。另外下周要开始做支付模块的重构风险是第三方支付回调经常超时。对应的理想输出是【本周完成】 1. 修复登录模块 Session 失效问题解决了大量用户反馈提升系统稳定性。 2. 完成新版首页交互方案评审与设计团队达成一致确定最终方案。 3. 参与订单导出功能代码评审保证代码质量。 【下周计划】 启动支付模块重构制定详细实施方案。 【风险与求助】 第三方支付回调存在超时现象可能影响重构进度需协调后端及运维资源联合排查。我总共收集了大概 15 组类似的输入输出示例然后把它们打印出来贴在白板上。注意这一步非常关键。在做任何技术方案之前先用示例把需求锚定住这样才能避免后续开发中“搞出来的东西不是用户想要的”这种大坑。2.3 第二级把示例转化成可执行的验证标准有了示例之后就把它们写成可验证的测试用例。不是说非要马上写代码自动化测试可以先写成表格。比如这样的测试用例表编号输入特征期望输出特征验证方式TC-01输入包含“修复了 bug”输出归类到“本周完成”且包含“修复”语义检查输出结构/关键词TC-02输入包含“下周要开始”或“计划”输出归类到“下周计划”检查输出结构/关键词TC-03输入包含“风险”“阻塞”“超时”输出归类到“风险与求助”检查输出结构/关键词TC-04输入包含多条不同类别的事项输出按类别分组且不重不漏检查输出的分组结果这些用例看起来很简单但它们其实是在定义需求的最小验收标准。有了这套标准后续开发就变成了“让程序通过这些测试用例”而不是“让程序员猜需求”。2.4 第三级让文档、代码和验证一体化第三级是最理想的状态也是最难一步到位的。我当时的做法是折中的先把需求和测试用例写进一个 Markdown 文件叫 requirement.md再在代码注释里引用这个文件的章节。后续当代码变动导致测试用例失效时我会强制要求自己同步更新 requirement.md。这就形成了文档和代码的联动。虽然没有做到“文档即代码”那种极致状态但至少不会出现“代码已经改了好几版文档还停留在当初”的情况。提示对于小团队和个人项目第三级不必追求“自动化生成文档”这种重武器。用 Git 提交信息绑定需求文档的变更记录性价比最高。3. 规格落地的关键技术选择提示词设计、模型选型与结构化输出3.1 为什么不能用“最贵的模型”一劳永逸需求定义了之后最核心的技术决策来了选什么大模型怎么设计提示词怎么处理模型的输出。很多人第一反应是“直接调 GPT-4o 或者 Claude 的最强模型把需求文本塞进去让它生成周报”。但实测下来直接这么干有几个问题成本高团队内每天可能有上百人使用周报生成功能每次都调用最强模型费用非常吓人延迟高最强模型响应时间通常要 3 到 5 秒对于“生成周报”这种高频操作太慢了输出不稳定大模型的自由发挥会让同样的输入在多次调用后产生完全不同格式的周报很难做后续的自动化处理。所以我最后的方案是用中等能力的模型比如 GPT-4o-mini 或 Claude Haiku 级别配合强约束的提示词并且要求模型输出严格的 JSON 结构。3.2 结构化输出的提示词设计为了让模型输出稳定的 JSON我在提示词里做了三件事。第一给出明确的输出 Schema 定义第二给出少样本示例few-shot examples第三在提示词里加入“思维链”约束让模型先思考分类再生成内容。我最终的提示词模板大致长这样有删减你是一个项目周报生成助手。请根据用户输入的流水账生成结构化周报。 输出必须使用以下 JSON 格式不要输出任何其他内容 { completed: [事项1, 事项2], nextWeek: [事项1], risks: [风险描述] } 分类规则 - 表示已经完成的工作放到 completed。 - 表示未来计划、下一步行动放到 nextWeek。 - 表示风险、阻塞、超时、资源不足等放到 risks。 - 如果一条描述同时包含完成和风险拆分成两个条目分别归入对应分类。 示例输入 这周修了登录 bug下周准备搞支付。 示例输出 {completed: [修复登录 bug], nextWeek: [准备支付模块工作], risks: []} 现在请处理以下输入 {user_input}这里的关键是“不要输出任何其他内容”和明确的 JSON Schema。加上少样本示例之后模型的输出基本能做到百分百可解析。实测下来在 GPT-4o-mini 上 JSON 解析失败率低于 0.5%完全可接受。3.3 处理模型输出的边界情况的技巧当然模型总会有出意外的时候。我的处理方式是加了一层“下游容错”在解析 JSON 时做三个策略如果 JSON 解析成功直接使用如果解析失败尝试用正则抽取completed、nextWeek、risks里数组内容如果还失败直接返回“生成失败”让用户重新提交一次。这里给一个 Python 解析函数的简化版本import json import re def parse_llm_response(response_text): 尝试解析 LLM 输出的 JSON带降级策略 # 策略 1标准 JSON 解析 try: data json.loads(response_text) if all(k in data for k in (completed, nextWeek, risks)): return data except json.JSONDecodeError: pass # 策略 2正则抽取 try: completed re.findall(rcompleted:\s*\[(.*?)\], response_text, re.S) next_week re.findall(rnextWeek:\s*\[(.*?)\], response_text, re.S) risks re.findall(rrisks:\s*\[(.*?)\], response_text, re.S) if completed or next_week or risks: return { completed: _extract_items(completed), nextWeek: _extract_items(next_week), risks: _extract_items(risks), } except Exception: pass raise ValueError(无法解析模型输出)注意设计提示词时不要写“请生成一份周报”这种太过开放的要求。凡是要程序自动处理的内容都必须限定输出格式凡是自由发挥的余地都会变成后续解析和处理的成本。4. 从“规格”到“代码”AI 辅助开发中的角色重分配4.1 有了规格AI 编程才能发挥真正价值跑题跑得有点远了回到开发本身。为什么说 SDD 和 AI 编程是天作之合因为 AI 编程的痛点从来不是“代码写不出来”而是“代码写出来不符合要求”。我以前做 AI 编程的时候经常会有这种体验让 AI 帮忙写一个接口它写得又快又工整但往往不是我想要的逻辑。问题出在哪出在给 AI 的需求本身就不够具体。你如果说“帮我写一个函数把用户数据存进数据库”AI 会给你一个最普通的实现。但如果你在规格里写清楚“用户数据包含 name、email、age 三个字段email 格式必须校验重复 email 返回 409 错误”AI 就能给你一份几乎和需求完全对齐的代码。SDD 本质上是在给 AI 编程“投喂高质量的上下文”。规格文档写得越清晰AI 生成的代码越精准。这也是很多人说的“vibe coding 到 harness × SDD 全栈开发实战”的核心思路用规范约束 AI 的发挥而不是让 AI 随性挥洒。我测试过一种工作流把需求规格 Markdown 文件、当前项目代码结构说明、以及一个目标函数的详细描述一起放进上下文里然后让 AI 给出实现方案。这种方式生成出来的代码质量通常比我口头描述需求让 AI 生成的代码高一个量级。核心变量就是规格的清晰度。4.2 AI 在 SDD 不同阶段可以扮演的角色顺着这个思路往下推我开始把 SDD 六个步骤里的每一个环节都尝试引入 AI 辅助阶段AI 可以帮忙做的事我的建议需求收集根据原始描述生成更多的输入输出示例推荐能大幅提高示例覆盖度规格编写把示例转化成 Gherkin 语法或测试用例表推荐但要人工校对语义测试设计根据规格生成边界测试用例推荐AI 很擅长发现边界情况代码实现根据规格直接生成目标代码强烈推荐这是 AI 最擅长的验证审查生成测试报告检查当前实现和规格的差距可用但严格审查需人工维护迭代根据代码变更自动更新规格草稿谨慎使用防止规格失真我自己实际偷偷用了一个小技巧把测试用例表复制给 AI让它给出“这些用例对应的代码实现”。AI 会逐条对照用例去写代码覆盖率和准确率比我盲写要高很多。4.3 关于“无限制 AI”类工具的技术选型建议这里要特别提醒一下技术选型问题。有一些团队的开发人员在找 AI 辅助工具时很在意“无限制、不审核”这些卖点。但我强烈不建议在生产环境使用这类没有安全边界的工具尤其是涉及企业内部数据、专利相关内容、或者用户隐私信息的时候。工具选型的核心原则是模型的输出质量和服务稳定性以及数据合规性而不是它有多“放得开”。我在实际工作中更推荐使用 OpenAI、Anthropic、百度文心、通义千问这类有明确数据使用政策的主流大模型服务。特别是涉及企业核心项目代码时最好通过内部私有的 API 网关来调用确保代码不会流入第三方训练集。实操心得如果你的项目包含专利、法务、金融等敏感领域一定要在选型清单上增加“数据隔离”和“审计日志”两项硬性指标。不要因为一时方便用了一个来路不明的“无限制”服务等出了事故再补救代价太大了。5. SDD 六步实践指南从零到一的操作手册5.1 我的六步落地流程从第一个 SDD 项目到现在我逐渐把整个流程沉淀成了固定的六个步骤。这套步骤也叫“SDD 六步实践指南”其实核心思想非常简单但如果你想直接套用可以按照下面的顺序来执行。第 1 步澄清战略意图先问清楚我们为什么要做这个功能它解决什么问题为谁服务优先级多高这些内容不写进技术文档也行但要在团队内部达成一致。在我周报生成器项目中战略意图就是“减少开发团队每周花在写周报上的时间目标是把平均耗时从 30 分钟降到 5 分钟以内”。第 2 步寻找锚定示例收集 5 到 20 组真实输入输出示例。注意这里的企业示例一定来自真实用户而不是我们想象出来的。示例的价值在于“锚定”它给整个团队提供了参考标准。第 3 步按模块拆分需求规格不要试图一次写完整个系统规格。按模块拆输入清洗模块、分类模块、周报生成模块、输出格式化模块。每个模块单独写一两页的规格描述包含输入、输出、边界、异常处理。第 4 步建立可执行的验证基准把示例转化成可运行的测试用例。如果项目允许用 Cucumber 或 Pytest 写自动化如果时间紧至少用表格维护一份“测试用例清单”。第 5 步与 AI 结对实现这一步是 AI 时代的特色。把规格、测试用例、项目结构说明放进 AI 编程工具的上下文让 AI 生成初步实现再人工审查和修改。审查的关键不是看代码风格而是看实现是否“忠于规格”。第 6 步让文档成为“活文档”代码变更后同步更新规格文档和测试用例。我个人的方式是每次 commit 时在 commit message 里加上需求文档编号比如feat: 支持风险识别 #REQ-003。后续做文档回溯就非常方便。5.2 一个完整的规格文档骨架为了让这套流程更可复制我给出一个我在实际项目中使用的 Markdown 规格模板可以直接拷贝改# 需求标识REQ-003 ## 战略意图 背景、痛点、目标 ## 功能范围 输入描述、输出描述 ## 核心场景示例 ### 示例 1常规周报生成 - 输入... - 期望输出... ### 示例 2包含风险提示的周报 - 输入... - 期望输出... ## 边界条件 - 输入为空时如何处理 - 输入超过 5000 字时如何处理 - 模型不可用时的降级策略 ## 验收标准 - Given 用户输入... When 调用生成接口 Then 返回... - Given 模型输出非法格式 When 调用解析器 Then 返回友好错误 ## 相关测试用例 - TC-01TC-02...有了这个模板即使团队里来了新同学他也能在十分钟内对项目要做什么、做到什么程度算完成有一个清晰精确的认知。6. AI 时代的新角色边界产品负责人、开发者与智能体的协作模型6.1 人机协作中的角色定义SDD 不只是“写写文档”这么简单它还会深刻改变团队的协作模式。尤其是当 AI 智能体AI Agent开始参与代码生成之后团队里每个人、每个工具的角色必须重新定义。我个人总结了一个三角色协作模型产品负责人负责第 1 步的战略意图和第 2 步的锚定示例。他输出的不是 PRD 文档而是“需求示例集”。开发者负责把示例转化为规格第 3 步并且编写自动化验证用例第 4 步。在 AI 编程越来越强的背景下开发者的核心产出不再是代码而是“问题定义”和“验收标准”。AI 智能体负责把规格翻译成具体实现第 5 步并主动发现规格中的矛盾或遗漏。比如你给 AI 输入规格文档后它可以反向提问“如果用户输入同时包含完成事项和风险需要拆分输出吗”——这是 AI 在做需求澄清而不是在写代码。这种模型下人不再是唯一的“需求翻译器”AI 也不仅仅是“代码生成器”两者成了互相校验的搭档。这也是我从“vibe coding”进化到“harness × SDD 全栈开发”的核心转变vibe coding 是让 AI 带着感觉飞奔harness 则是用 SDD 给 AI 装上方向盘和刹车。6.2 一个真实协作场景的复盘有一次产品负责人给了一个新需求“在周报生成器中增加对上周计划的回顾功能”。按照直觉大家可能会直接改提示词让模型在生成新周报之前先对比上一周的 nextWeek 列表然后把完成情况标成“已完成/未完成”。但用 SDD 的方法我们先写了一个测试用例Given 上周周报中 nextWeek 包含“完成支付模块重构” When 用户生成本周周报且输入中描述“支付模块重构完成” Then 周报的 completed 分组中对应事项应标记为“已完成”并自动关联上周计划结果这个测试用例一写出来产品负责人自己就发现问题了如果用户输入里根本没有提到“支付模块重构”那程序是应该自动认为“未完成”还是应该什么都不写这个边界不定义清楚AI 就会“自由发挥”而不同用户得到的结果就可能完全不一样。最后我们在规格里补了一条规则“当上周计划事项未在本周输入中被明确提及且未出现在已完成列表中时系统不自动输出‘未完成’只在风险栏提示‘存在未明确的计划事项’。”这个细节如果没有 SDD 流程十有八九会被忽略。但正是因为这一条让最终的用户体验稳定性提升了一个档次。7. 文档不是负担是 AI 时代开发者的核心杠杆7.1 很多人对 SDD 的误解我经常听到一种论调“SDD 不就是写文档吗太浪费时间了。”或者“现在都 AI 编程了AI 直接能写代码要文档干嘛”说这些话的人大概率没有真正在一个复杂项目里被需求反复变更逼疯过。实际上文档不是写给人类看的更是写给 AI 看的。在传统开发时代写文档的收益可能要在几个月后需求变更时才体现出来但在 AI 时代一份精确的规格文档带来的收益是即时可见的——因为 AI 直接使用文档来生成代码、生成测试、生成部署配置文档就是 AI 的“输入数据”。从投资回报率来看每花 1 小时写规格文档至少能节省 3 到 5 小时的无效开发和返工时间。我自己在周报生成器项目里做过粗略统计规格化的需求编写投入约 6 小时但因为需求清晰带来的返工减少、测试效率提升本来就预计要 2 周完成的项目最终 5 个工作日就交付了节省的时间非常可观。7.2 我的个人体会与扩展方向写到这里SDD 从理论到实战的完整脉络已经分享完了。这半年多实践下来我最深的体会是SDD 不是一个“文档管理方法论”而是一个“复杂度控制系统”。它把最大的复杂度从“写代码时”转移到了“写规格时”而写代码恰恰是现在的 AI 最擅长的事情写规格则是最需要人类经验、判断力和领域知识的事情——两者恰好形成了最优分工。最后再分享一个小技巧我在完成每个需求文档时都会在结尾加一个“开放问题”区把当时没有结论、需要继续探索的点全部列进去。这个区域不需要有答案但它会在几周后帮我快速回忆起当时的思考脉络。这个方法让我在和 AI 协作时永远知道哪些地方应该由我拍板哪些地方可以放手让 AI 去试。如果你正在寻找一种让 AI 编程更可控、让需求更清晰、让团队协作更有章法的方式SDD 值得你花一周时间认真试一次。