☰
规范驱动开发(SDD):让AI编码从抽卡变成可控交付
2026/10/29 17:56:03 网站建设 项目流程

上个月在群里帮一个朋友看问题,他们团队用AI写一个订单状态筛选的功能,来来回回改了七八轮。每一轮的新提示词都写得很“专业”,把需求、格式、边界都列了个遍,但生成结果不是漏了取消订单的状态,就是把时间字段的时区改了。最后朋友无奈地跟我说:这哪是写代码,这是抽卡。

我回了一句:你现在用的就是典型的“提示与祈祷”,你以为你在控制AI编码,其实你只是把提示词扔进去,然后在心里默念“这次应该能行吧”。

这就是规范驱动开发(SDD,Specification-Driven Development)想要解决的问题。它不是让你换一个更好的提示词模板,而是让你把整套开发流程翻过来:先写清楚规格,再让AI照着规格实现。这篇文章我会把这个思路、完整落地步骤、实测效果和几个最容易翻车的坑全部讲一遍,适合那些已经用AI写了不少代码、但发现结果越来越不可控的团队和个人开发者。

1. 为什么“提示与祈祷”注定让AI编码不可控

1.1 提示词是命令,不是契约

很多人以为AI编码不可控是因为“提示词写得不够好”,于是不停地在提示词上做文章。这个方向从根上就错了。提示词本质上是个命令——“给我写一个函数,做某某事情”——它描述的只是你想要的最终结果,而不是中间必须遵守的约束。

这就跟你在工地上跟施工队说“给我盖栋楼”一样,施工队盖出来的可能是个能住的平房,也可能是个没有楼梯的三层楼。你气急败坏地补充:“要有窗户!要刷外墙!”但每补充一句,只是多了一个命令,仍然没有形成一份图纸和规范。

真正的规划应该是:“这里是什么用途、面积多大、承重结构是什么、验收标准是什么、哪些东西绝对不能做。”AI需要的不是更多命令,而是一份可验证的约束集合。提示词是点状的,规格是面状的。

1.2 上下文污染:每一次失败的反馈都在给下一轮埋雷

“提示与祈祷”还有一个非常隐蔽的代价,就是上下文污染。你看到生成结果不对,很自然地会在下一轮提示词里追加一句“注意订单状态应该包含cancelled”“返回字段不要用null要用空数组”。问题是,大模型会平等地记住你的原始需求、前五轮的修改意见,以及上一轮生成的那段错误代码。

到了第三轮以后,AI的注意力已经被大量“救火式修改”占据,原始需求反而成了背景噪声。我见过最夸张的情况是,AI因为在某一轮被告知“不要用null”,结果把所有字段都强行套上了空字符串,连数字类型的金额都变成了字符串,整个接口的契约直接崩了。

这就是“提示与祈祷”的恶心之处:每一次失败反馈都在污染下一轮的生成分布,你不是在往确定性方向收敛,而是在往复杂度方向发散。

1.3 可控性的真正含义:可预测、可验证、可回滚

那“可控的AI编码”到底是什么意思?我觉得就三条。

可预测:同样的输入、同样的规则,AI生成的代码在行为上是一致的,不会今天返回空数组、明天返回null。

可验证:每个生成结果都有明确的标准去检查,不是靠人肉review“看着差不多”。

可回滚:当某一轮的实现有问题时,能明确知道是哪一个规格条目没满足,而不是推倒重来、再赌一轮prompt。

对照这个标准,“提示与祈祷”三条全不满足。而规范驱动开发(SDD)的做法,本质上就是先把这三条用文档固定下来,再让AI去做实现。

2. 规格驱动开发(SDD)的本质:把“施工蓝图”递给AI

2.1 一份能直接喂给AI的最小规格长什么样

我在项目里用SDD时,一份规格文档通常不是长篇大论的PRD,而是极度结构化的“施工图”。我用一个实际案例说明。假设我要让AI实现一个“订单导出CSV”的功能,一份最小规格长这样:

功能:订单导出CSV 输入: - 时间范围: startDate, endDate,均为YYYY-MM-DD - 订单状态: status,可选值为created/paid/shipped/completed/cancelled,不传代表全部 输出: - CSV文件,字段顺序为:订单号,下单时间,客户名,金额,状态 - 金额单位为元,保留两位小数,CSV用UTF-8编码并带BOM 行为约束: - 时间范围超过90天时直接返回错误码:RANGE_TOO_LARGE - 导出数据量超过1万行时,拆分为多个文件并返回文件列表 - 不得修改数据库中的任何数据 验收标准: 1. 当endDate早于startDate时,返回400 + INVALID_DATE_RANGE 2. 当查询结果为空时,返回空列表而不是报错 3. CSV字段必须与给定顺序完全一致 4. 状态为cancelled的订单必须包含在导出行中 5. 金额字段不得出现浮点精度误差

这份规格看起来很简单,但注意几个关键点:输入和输出被明确限定,行为约束直接写死了“不能改数据”,验收标准给出了具体断言。不要小看第四条“状态为cancelled的订单必须包含”,真实项目里AI很容易默认过滤掉已取消的订单,因为产品需求里没强调,但它恰恰是用户最需要的。

2.2 为什么规格比提示词更符合大模型的生成逻辑

大模型的训练任务本质上是“根据前文预测下一个token”,它天然擅长“在约束条件下填空”,而不是“凭空构建你的意图”。提示词更像是让AI做一道开放性作文题,它写得再漂亮,也未必是你的意思。规格则像是一道有标准答案的填空题,每个约束都在限制解空间。

你写“帮我写个导出功能”,AI的解空间是无限大的,它可以自由选择字段顺序、时间格式、编码方式。你写“字段顺序必须为订单号/下单时间/客户名/金额/状态,金额保留两位小数”,AI的解空间就被压缩到了一小块区域,它的每个token生成都更可能落在正确范围内。

另一个容易被忽略的点是,大模型对“确定性表述”比对“愿望描述”更敏感。你告诉它“这个导出可能有点慢,最好别超时”,它不知道该怎么办。你告诉它“超过1万行时拆分文件”,它就知道这是个具体分支,可以写出对应的判断逻辑。

2.3 SDD不是文档驱动,也不是TDD替补

很多人听到“先写文档再做开发”,第一反应是“这不就是文档驱动开发吗,流程更重了”。这里要区分清楚。

传统文档驱动是给“人”看的,写需求、写设计、写接口文档,目的是降低团队沟通成本。SDD的规格文档是给“AI”看的,它同时承担了你的意图表达、约束定义和验收依据三重角色。换句话说,SDD的文档不是挂在Wiki里的摆设,而是每一段都会被AI直接读取并执行的工作指令。

TDD(测试驱动开发)关注的是“代码应该怎样被验证”,它是在实现之后或者实现的同时去写测试。SDD关注的是“需求边界是什么”,它是在实现之前把业务规则、行为约束、错误路径、边界条件全部显式化。SDD写出来的规格可以直接转化成TDD的测试用例,但两者层级不同。

我经常用的一个比喻是:TDD是给代码装质检仪,SDD是先把产品说明书定义清楚。没有产品说明书,质检仪也不知道该测什么。

3. 我的SDD五步落地法:从需求到AI实现的全流程

3.1 第一步:用“边界问题清单”把模糊需求问清楚

SDD落地的第一件事不是写文档,而是把需求访谈变成边界确认。经验不足的人在这里会直接动手写规格,结果写出来的东西跟PRD没有任何区别。

我每次接到一个需求,会先列一个边界问题清单:

  • 这个功能的核心输入是什么,取值范围是什么?
  • 输出给谁看,格式有没有硬性要求?
  • 数据为空时应该是什么行为?
  • 数据量超出预期时应该怎么处理?
  • 有没有绝对不能做的事情(不能改数据、不能调外部接口、不能删索引)?
  • 错误情况下要返回什么,是静默处理还是抛出异常?

这些问题看起来基础,但每一条都能帮你筛掉大量“AI自由发挥”的空间。拿上面那个订单导出来说,“数据量超出预期时怎么办”就是最容易漏问的,因为需求方一开始只会说“把订单导出来”,根本不会想到90天这个限制。

3.2 第二步:用结构化格式写规格,坚持“验收标准优先”

规格文档的格式我建议用YAML或JSON,而不是纯文本。因为大模型对结构化格式的解析能力非常强,同样的语义,YAML呈现的约束比大段文字醒目得多。而且结构化格式天然能强制你把“输入”“输出”“约束”“验收”分门别类,防止写成一团浆糊。

写规格时我坚持一个原则:验收标准先写,行为约束后写。为什么?因为验收标准是驱动AI行为的核心信号。你把验收标准放在前面,AI生成代码时会把每条标准对应到实现上。你把验收标准藏在最后面,AI的注意力已经分散了,可能写完了都没有认真看。

一份完整的规格,验收标准的粒度要细到能直接转成代码断言。比如“时间范围超过90天时返回错误码RANGE_TOO_LARGE”,这可以直接变成一行代码。如果你的验收标准还停留在“性能要好”“用户体验要流畅”这种层面,说明你还没想清楚自己要什么。

3.3 第三步:把规格拆成独立单元,一次只喂一段

很多人在“提prompt”时犯的最大错误,就是把整份规格一次性全部丢给AI,指望它一口气生成几千行代码。结果AI确实生成了几千行,但前半部分符合规格、后半部分开始飘。这不是AI不听话,而是注意力窗口有限,规格量太大时,前面的约束会被后面的信息挤掉。

我的做法是把功能拆成多个独立单元,每个单元对应一份子规格,每次只让AI实现一个单元。比如“订单导出”我会拆成三个单元:

  • 单元A:参数校验和时间范围检查
  • 单元B:查询订单数据并组装CSV行
  • 单元C:文件拆分与结果返回

每个单元六七行规格,AI实现起来压力很小,出错率也低。单元内部的实现细节我也不关心,AI用循环还是用map都行,只要行为符合规格。

拆单元的标准是:每个单元都可以独立验收,单元与单元之间通过明确的接口衔接。如果你的某个“单元”还需要跟别的单元共享内部状态,那就是拆得不够干净。

3.4 第四步:让AI先交实现计划,再动代码

这是我用SDD之后新增的一步,效果异常好。在让AI写代码之前,先让它根据规格输出一份“实现计划”,内容包括:它打算分几个函数、每个函数做什么、边界条件怎么处理。

这一步的作用相当于让AI“先复述一遍需求再动手”,可以提前暴露对规格的误解。有一次我让AI实现权限判断逻辑,它的计划里写“如果用户角色为guest,直接拒绝所有操作”,但我的规格写的是“guest只能访问公开接口”。这就是一个典型的理解偏差,如果它直接动手写代码,我肯定要到代码review或者测试阶段才发现,但提前走一步实现计划,几秒钟就暴露了。

实现计划不需要多详细,三五条要点就够了。关键是让AI把它准备怎么做说出来,你确认之后再说“开始写代码”。

3.5 第五步:按验收标准逐条测试,不靠肉眼review

最后一步是整个SDD流程里最关键的,也是很多人会偷懒的一步。AI把代码写完了,你不能看一眼觉得“差不多”就收工,而是要拿着规格里的验收标准逐条去验证。

我的做法是给每个验收标准写一个对应的测试脚本。如果规格有5条验收标准,我就要求AI同时生成5个测试用例,并保证跑通。这一步就是把SDD和TDD衔接起来:规格负责定义标准,测试负责执行检查。

以“订单导出”为例,验收标准第二条“当查询结果为空时,返回空列表而不是报错”,对应的测试就是构造一个查不到任何订单的时间范围,然后断言接口返回200和空数组。

有一点需要提醒:有些验收标准AI自己是测不全的,比如“金额字段不得出现浮点精度误差”,AI生成的测试用例很可能只测了整数金额。这种情况你要自己补一个边界测试,比如传一个0.1+0.2的场景。规格流程只能保证有验证机制,不能保证验证完备,最终还是要人来补关键断言。

4. 实测数据:SDD把返工率降到了什么程度

4.1 对照实验:同一个功能,两种方式的真实差异

我大概在一个月前做了一次对照实验,连续两周,挑了5个中等复杂度的功能,每个功能都用“提示与祈祷”方式写一遍,再用SDD方式写一遍。这5个功能分别是:列表查询、状态机流转、数据导入校验、权限点判断、定时任务重试。

结果对比非常明显。

纯提示词方式下,单个功能平均要迭代6.2轮才能达到“看起来能用”的状态,而且有3个功能在“看起来能用”之后,过了两周又被发现边界漏洞。SDD方式下,单个功能平均1.8轮就通过验收,5个功能里只有1个在上线后发现边界情况没有覆盖到位。

最有意思的是,SDD模式下那唯一一个漏掉的边界,其实规格里写了,但我忘记把这个规格条目写进测试脚本,AI实现的时候也没处理。这说明SDD不是银弹,流程里任何一个环节偷懒,都会漏。

4.2 时间成本要算总账:写规格的时间没有“浪费”

有人会担心SDD前期要写规格,太浪费时间。但我算完总账之后发现,这是最划算的投入。

5个功能加起来,纯提示词方式的总耗时是大概14个小时。SDD方式前期写规格花了大概5个小时,听起来很吓人,但后面AI生成和调试的时间大幅缩短,总耗时只有8个小时左右。换句话说,多花35%的时间在规格上,总时间节省了约43%。

而且这只是明面上的时间账。暗面上,纯提示词方式留下了3个上线后才被发现的漏洞,每个漏洞平均要花2-3个小时去定位和修复,这部分成本没算进上面的时间。SDD方式虽然也有1个漏网之鱼,但因为它有规格文档和测试用例,定位问题只花了20分钟。

4.3 什么指标变得明显可控

除了时间和轮次,我更关注的是三个质量指标。

第一是“行为一致性”。SDD模式下,相同的输入、相同的规格,AI在不同轮次生成的代码在行为上保持一致的比率非常高。纯提示词模式下,AI很可能这轮用空数组、下轮用null,搞得前端对接的人欲哭无泪。

第二是“回归风险”。因为验收标准是文档化的,每次改动规格后都可以重新跑一遍全部测试用例,回归风险从“靠记忆力”变成了“靠脚本”。

第三是“AI自作主张的概率”。纯提示词模式下,AI非常容易“好心办坏事”,比如自动拼接字段、自动加个排序、自动把返回结构改了。SDD模式下,因为行为约束写在前、验收标准写得细,AI的“自由发挥空间”被压制得很低。

5. SDD落地最容易翻车的五个地方

5.1 把规格写成了PRD摘抄

我第一次带团队推行SDD的时候,有同事写的规格大概是这样的:“用户希望可以方便地导出订单,导出过程要流畅,数据要准确。”这种规格扔给AI,它唯一的结局就是继续抽卡。

规格不是需求描述,是行为定义。“流畅”是主观感受,“准确”是废话。合格的规格要么是一段可执行的条件判断,要么是一组可枚举的输入输出映射。如果一句话没法被测试脚本验证,它就不应该出现在规格文档里。

5.2 验收标准写得太弱,等于交给AI“良心”

还有一类规格,约束写得还行,但验收标准写成了“程序可以正常运行,无报错”。这等于根本没有标准。

AI生成的代码当然不会在它自测的时候报错,因为它的自测用例是你描述的那个“正常情况”。真正的验收标准应该针对危险情况。我总结了一个经验法则:一条验收标准里,至少要有一个“反例”在里面。比如“当查询结果为空时返回空列表”“当时间范围超过90天时返回错误码”。验收标准里如果没有“当什么什么时”这种反例句式,那就说明你又在写需求描述了。

5.3 单次上下文过大,规格反成噪音

规格写得太长也会出问题。我之前试过把一个中大型模块的完整规格(大概五千字)一次性丢给AI,让它“按照规格实现”,结果它只认真实现了前三分之一,后面的功能全部默认简化处理。

这不是AI偷懒,而是注意力机制决定的。规格越长,每条约束的权重就越低。现在我的经验是,单次交给AI的规格控制在800字以内,一个功能模块拆成多个单元,每个单元单独生成。宁可多做几次交互,也不要一次塞太多。

如果你实在有很长的全局约束,比如“本项目的错误码规范统一为XXX”,可以在每个单元规格里都重复一遍这条约束。重复不是冗余,是对注意力机制的尊重。

5.4 只改规格不重跑验证,循环断裂

SDD流程里最重要的一条闭环是:改规格 → 重跑全部测试。但实际操作中,很多人改完规格,就只想让AI“只改那一个地方”,不想重新验证其它部分是否被影响。这个想法在传统开发里可能是合理的,在AI编码里非常危险。

因为AI在修改某段代码时,很可能顺手改坏一个原本正确的分支。如果你没有在所有改完后重跑一遍完整验收标准,这个回归问题可能直接流到线上。所以我现在的规则是:只要规格文档有任何一条变更,AI的代码改动完成后,必须把该单元全部测试用例重新执行一遍,任何依赖它的相邻单元也要一起跑。

5.5 团队协作里规格没人维护

个人项目用SDD很简单,因为规格是我自己写的,我清楚每一句话背后的意图。但到了多人协作的场景,规格文档很容易变成没人维护的僵尸文件。

最常见的情况是,产品说“需求变了,取消订单也要出现在导出里”,开发觉得“这只是加个过滤条件而已”,直接在代码里改了,没有回头去更新规格。等下一次AI重新生成这段代码时,用的还是旧规格,于是“取消订单被过滤掉”这个问题又复现了。

解决办法是让代码生成流程强制依赖规格文件。在我现在的工作流里,不允许任何团队成员绕过规格直接跟AI对话改代码。所有变更必须先改规格,再由AI基于新规格重新生成或修补代码。这个过程把规格变成了单一事实源,而不是可有可无的参考文档。

6. 边界判断:什么时候必须SDD,什么时候别折腾

6.1 适合SDD的任务画像

我用一个四象限来判断,横轴是“业务规则的明确度”,纵轴是“回归风险”。

业务规则越明确,越适合SDD。比如订单状态流转、导入校验、权限判断、报表计算,这些场景的规则是完全可枚举的,每条规则都可以转成验收标准。回归风险越高,也越适合SDD。比如核心交易流程、对外API合同、数据迁移脚本,这些代码一旦出错代价极高,靠“提示与祈祷”就是在赌运气。

具体来说,我建议以下类型的任务必须用SDD:接口开发、批量数据处理、数据库迁移、状态机实现、权限模型落地。这些任务有个共同点:行为可以被清晰地描述和执行,且错误代价高。

6.2 不适合SDD的场景

相应的,有些场景硬套SDD会非常痛苦。最典型的是探索性原型开发。你连需求都没想清楚,需要靠AI帮你头脑风暴、快速验证方案的可行性,这时候写规格就是本末倒置。原型阶段就应该用宽松的提示词,目的是快速试错,不是稳定交付。

还有一个不适合的是UI视觉效果。AI生成的页面布局、颜色搭配,很难用“验收标准”去约束,因为审美是主观的。这种场景更适合用截图反馈,循环调样式,而不是写规格。

一次性工具脚本也不适合。比如我要临时把某个JSON文件转成CSV,用完就删,写一份规格的时间可能比手写代码还长。SDD的收益来自复用和回归,一次性的东西根本不具备这个基础。

6.3 不想一步到位的渐进过渡法

你不需要第二天就把所有AI编码流程切换成SDD。我推荐的路径是:先挑一个你最近要做的小功能,按照第三部分的五步法走一遍。哪怕你这个功能只需要AI写两百行代码,也要把规格、验收标准、测试脚本全套走完。走完这个流程之后,你会对“规格要写到什么粒度”有切身体感,这种体感是看再多文章也学不来的。

然后逐步扩展到核心模块。当你发现SDD写出来的代码在后续改动中几乎不用返工,就会自然形成路径依赖。我自己就是这么过来的:刚开始只在导出功能上用SDD,后来扩展到所有接口开发,再后来连数据库迁移脚本也用规格约束。

如果团队里有人觉得写规格太麻烦,我的建议是让他们先统计一下自己在“提示与祈祷”上浪费了多少时间。大多数人对返工时间是麻木的,因为他们把“和AI反复沟通”当成了工作常态,而不是一种可避免的浪费。

最后再分享一个我自己的小技巧:在每份规格的末尾,加一节“常见误解与禁止行为”。比如“不要修改数据库结构”“不要引入额外依赖”“不要重排输出字段顺序”“不要对金额做四舍五入以外的处理”。这一节相当于给AI戴上了一副“紧箍咒”,专门压制它自作主张的冲动。实践下来,这一步对降低返工率的效果,有时比主规格里的验收标准还明显。你可以先试一个小功能,看看加了这一节之后,AI是不是变得更老实了。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询