炮轰Spec驱动开发:为何不适合大多数项目
Spec驱动开发混淆Spec-first、Spec-anchored、Spec-as-source,带来长期治理成本。自然语言Spec难成单一事实来源,易致认知洗白和文档周转税,不适合多数历史及新项目。
SDD 是什么,它为什么突然火了
早期的AI编程,大家习惯性往对话框里扔一句“给登录页加个验证码”,然后等着模型开干。快是真快,刺激是真刺激,于是有了个说法叫Vibe Coding。可项目一复杂,问题就现形了:模型压根不知道哪些行为不能碰,不记得十轮前确认过什么,也分不清你是在说业务目标还是在暗示技术方案。它可能飞快地给你一套完整实现,但实现的可能是错误的东西。

SDD就是冲着这种失控感来的。它的主张不复杂:别让Agent收到一句模糊指令就动手写代码,先把要做什么写清楚。典型的流程长这样:
- 把产品目标、用户场景、需求边界和验收条件,整理成一份Spec。
- 让Agent根据Spec调研代码库,生成技术设计。
- 把设计拆成可执行的任务列表。
- Agent逐项实现,再根据Spec检查结果是否符合预期。
- 有些流派甚至在交付后继续保留Spec,后续功能变化时先更新Spec,再改代码。
不同工具给这些文件起了不同名字,但结构大同小异。Kiro常见的是requirements.md → design.md → tasks.md;GitHub spec-kit会生成Spec、计划、研究和任务等一组文件;OpenSpec则用proposal、delta spec、design、tasks组织一次变更,并在归档时把增量需求合并进长期Spec。
出发点很合理。Coding Agent能力越强,理解偏差的破坏力也越大。人手写错十行代码,评审时往往能看出来;Agent在错误前提上一次生成几十个文件,表面上却可能结构完整、测试齐全。先明确目标、约束和验收条件,可以让人和模型在付出实现成本之前发现分歧。
SDD也顺应了一个很有吸引力的想象:既然大模型已经能把自然语言翻译成代码,开发者是不是可以从代码细节中抽身,转而维护更高层的业务意图?Spec成为人和AI的共同语言,代码退化为可生成的“最后一公里”。需求变了就改Spec,Agent自动传播到设计、任务、测试和实现。开发不再围绕代码展开,而是围绕意图展开。
这套叙事确实击中了AI编程的几个真实痛点:聊天上下文会丢失,模糊Prompt会产生随机结果,复杂任务需要拆解,多人协作需要评审,Agent的实现需要验收。随着GitHub spec-kit、AWS Kiro、OpenSpec、Tessl等工具相继出现,SDD很快从一种提示词组织方式,被包装成了AI时代的新开发范式。
问题也恰好出在这里。“编码前把需求写清楚”是一个朴素而正确的建议,但它并不能自然推出“Spec应该成为长期事实来源”,更不能推出“多数项目都需要一套SDD工作流”。从一份任务说明,跨越到一套需要持续维护的平行知识系统,中间隔着所有传统软件工程都没能轻易解决的问题。
每隔一段时间,软件行业都会重新发明一次“只要把需求写得足够清楚,代码就会自然出现”。以前叫CASE、MDD、DSL、低代码,现在叫Spec-Driven Development。新故事里的关键角色从确定性代码生成器换成了大模型,旧问题却一个没少:谁来保证描述正确,谁来维护描述与实现的一致,需求变化后谁负责同步,以及这份描述究竟给谁看。
SDD最诱人的承诺,是把Spec设为“单一事实来源”,再让Coding Agent按Spec生成代码。听起来像是消除了需求和实现之间的鸿沟。实际情况恰恰相反:自然语言经过一个非确定性模型变成代码,中间的解释过程更长、更隐蔽,也更难复现。SDD没有消灭鸿沟,只是给鸿沟铺了一层Markdown,让人误以为下面已经是路。
直接说结论:Spec-first在部分任务中有价值;Spec-anchored需要极强的治理能力;Spec-as-source对多数业务项目仍接近一场昂贵的信仰实验。把三者统称为SDD,再把最理想化的收益宣传给所有项目,这才是问题所在。
一、SDD 连自己是什么都没说清楚
Birgitta Böckeler是Thoughtworks的杰出工程师,拥有二十多年的软件开发、架构与技术领导经验。2025年10月,她在Martin Fowler的个人网站发表《Understanding Spec-Driven-Development: Kiro, spec-kit, and Tessl》,结合对Kiro、spec-kit和Tessl的实际试用,对SDD的定义与现实适用性提出了系统质疑。她把当前所谓SDD分成了三层:
- Spec-first:编码前先写一份当前任务的Spec,任务结束后可以删除。
- Spec-anchored:Spec在功能交付后继续保留,后续演进持续更新。
- Spec-as-source:Spec才是主要源文件,人只修改Spec,代码只是生成物。
这三层看起来只是程度不同,实际上是三种完全不同的工程契约。
Spec-first是一种上下文组织技巧,类似一份结构清楚的长提示词。Spec-anchored是一套长期文档治理制度。Spec-as-source则接近模型驱动开发和生成式编程,要求团队改变代码所有权、调试方式、评审对象和发布流程。前者可以在一个下午试用,后两者却会引入长期治理成本。
可SDD的传播经常把它们揉在一起:用Spec-first的低门槛吸引团队,再用Spec-as-source的宏大收益证明价值。今天说“不过是先把需求写清楚”,明天就说“以后维护软件就是维护Spec”。这不是渐进式采用,而是概念滑坡。
甚至“Spec”本身也没有稳定定义。它可能是用户故事、验收标准、PRD、技术设计、接口契约、任务清单、领域规则,或者这些东西的混合物。一个词同时装下“为什么做、做什么、怎么做、如何验证、实施到哪一步”,得到的不是统一语言,而是一只没有所有者的文档泥潭。
一个合格的工程产物至少要回答这些问题:
- 谁编写,谁审批,谁维护?
- 它描述意图、当前行为,还是目标行为?
- 它对人、对模型,还是对自动化工具负责?
- 与代码、测试、PRD、ADR冲突时,谁有裁决权?
- 哪类变更必须更新它,哪类变更不需要?
- 它什么时候失效,什么时候应该删除?
- 如何证明它是完整、最新且内部一致的?
如果这些问题没有答案,“Spec是单一事实来源”就不是工程规则,只是一句品牌口号。
二、它卡在上下文工程与传统产出物之间,两边都不讨好
在coding agent出现之后,代码库中新增的内容大部分是为上下文工程服务的,之前的内容我称之为传统产出物。
如果Spec是上下文工程,它本质上仍是提示词
一份只服务于当前Coding Agent、在任务完成后即可丢弃的Spec,本质上就是经过模板化、版本化的Prompt。结构化当然有价值:它能固定目标、约束、验收标准和未决问题,也比散落在十几轮对话中的要求更容易审查。
但别把格式上的庄重误认为方法论上的突破。给提示词加上requirements.md、design.md和tasks.md三个文件,并不会自动提升其中事实的可信度;把“prompt”命名为“spec”,也不会让模型突然获得业务判断力。
在这个层面,planning-with-files往往更诚实,也更实用。task_plan.md回答接下来做什么,findings.md保存带证据的发现,progress.md记录已经做了什么。它们明确是任务状态,不冒充系统的永久真相;任务结束后可以归档或删除,也不要求团队为整个代码库建立第二套模型。
这种做法尤其适合历史项目,因为调查结论会随着证据变化。计划可以改,候选假设可以被推翻,错误上下文可以丢弃。它承认模型正在工作,而不是假装模型已经掌握了需求。
当然,planning-with-files也不是SDD的万能替代品。它解决的是Agent的工作记忆和长任务恢复,不负责跨团队需求确认、合规审计或稳定接口契约。计划文件同样可能漏更、过时甚至污染后续上下文;它胜出的地方不是天然更正确,也不是简单的“文件更少”,而是职责更窄、生命周期更清楚、退出机制更明确。即使腐化,影响半径通常也被限制在一个任务内。
如果Spec是传统研发产出物,它多半只是PRD的再包装
如果一份Spec要长期存在、供产品与研发共同评审、定义业务行为和验收标准,那么它已经进入PRD或需求规格说明书的职责范围。如果它记录技术方案和关键取舍,那是设计文档或ADR;如果它约束接口,那是OpenAPI、Protobuf、JSON Schema或类型定义;如果它定义可验证行为,那是自动化测试或契约测试。
SDD并没有凭空创造一种缺失的产物。它更常做的是把这些已有产物重新打包,再额外要求一份Agent友好的Markdown投影。
于是问题来了:这份Spec到底给谁看?
- 给人看,就应该短、稳定、聚焦决策,不能堆满模型生成的实现细节。
- 给模型看,就要显式、冗余、上下文自足,往往会变得又长又机械。
- 给机器执行,就必须有形式化语法、校验器和确定性语义,自然语言又不够可靠。
试图用同一份Markdown同时服务三类读者,通常只能得到三边都将就的产物。没有明确读者的文档,不是共享知识,而是共享负担。
三、“单一事实来源”最容易制造多个事实来源
一个成熟代码库已经存在许多知识载体:PRD说明产品意图,ADR记录架构决策,代码体现当前实现,测试保护部分行为,Schema约束边界,监控和日志反映运行事实,Issue与Git历史解释变化原因。
SDD再加入一套长期Spec后,并没有自动替代上述任何一项。现实更可能从六份材料变成七份材料。每次变更都要判断更新哪些文件,并承担漏更其中一个的风险。
所谓“一致性”也不能靠Agent自动维护来解决,因为这会形成一个循环论证:
- 我们需要Spec,是因为代码和需求之间存在理解鸿沟。
- 手工维护的Spec容易与代码失同步,因此有人希望让Agent自动生成或维护它。
- 但如果Agent同时负责理解代码、维护Spec、再依据Spec修改代码,那么Spec只是Agent自己判断的中间产物,不能作为独立证据。
一旦第一轮理解有误,错误就会在Spec与代码之间自我强化。文档未必是独立证据,也可能只是模型上一次推断的沉淀;下一轮模型却会把它当成高优先级指令。普通的过时文档可能被工程师怀疑,挂着“Source of Truth”牌子的过时Spec反而更危险。
SDD的标准回答是“人要逐阶段审查”。这当然必要,却也恰好暴露了成本并未消失:模型负责批量生产文档,人负责逐条验证事实。生成变便宜后,审查反而成为瓶颈。如果团队原本就没有能力持续维护PRD、设计文档和测试,再新增一个要求更高频同步的Spec层,不会凭空长出治理能力。
这就是上下文腐化:错误信息因为被反复引用而获得权威,模型在错误前提上生成越来越完整、越来越自洽的实现。代码至少还能被编译器、类型系统、测试和线上行为反驳;自然语言Spec往往连“完整”都无法被机器判定。
SDD常把自然语言Spec称为“可执行规格”,这个说法也值得警惕。只要从Spec到代码仍要经过概率模型,它就不是传统意义上的可执行规格,而是可再次解释的规格。同一输入可能生成不同实现,遗漏同一约束,甚至在不同上下文中给出相反选择。真正可执行的部分,最终仍然来自测试、Schema、编译器、模型检查器和运行时验证,而不是Markdown的标题层级。
四、历史项目不是SDD的沃土,而是它最危险的压力测试
历史项目的难点从来不是“没有一份足够长的说明”,而是现存材料互相冲突。代码可能实现了旧需求,测试可能保护偶然行为,注释可能三年没更新,线上配置可能改变实际路径,老同事记得的则是某次事故后的例外规则。
这时让Agent反向生成Spec,首先碰到一个无法靠语法解决的问题:它生成的是业务意图,还是当前行为?
从代码反推,只能得到当前实现的近似描述,无法判断其中哪些是业务规则,哪些是Bug,哪些是临时兼容,哪些是无人敢删的死分支。把这些内容整理成格式漂亮的Spec,很容易完成一次“认知洗白”:原本值得怀疑的历史偶然,被重新命名为正式需求。
如果要求先补齐整个项目的Spec,成本接近重新理解一遍系统。对于几十万行代码、多个上下游、复杂开关和隐含运营规则,这不是“补文档”,而是一场没有明确回报的数字考古。更糟的是,补齐那天就是它开始过期的第一天。
这里也需要公允地修正一个常见批评:当前OpenSpec明确不要求为历史代码一次性补齐全部Spec。它主张从正在发生的变更开始写delta,归档时再把增量合并到openspec/specs/,让主Spec随改动逐步生长。它甚至直接警告,大规模回填会产生没人信任的过时Spec。
这比“先给遗留系统写完百科全书再开工”现实得多,但没有消除核心矛盾,只是改变了矛盾的形态:
- 主Spec被称为“当前行为的事实来源”,实际却只覆盖被变更触碰过的切片。
- 同一领域中,一部分行为有Spec,一部分只能读代码,使用者很难知道缺失意味着“未覆盖”还是“不允许”。
- delta合并可以减少编辑冲突,不能证明基线理解正确,更不能保证实现、测试和主Spec同步。
- 随时间自然生长的Spec不是天然完整,只是天然不均匀;热点模块越来越详细,沉默但关键的旧逻辑仍然是黑箱。
所以,OpenSpec的delta-first是一种不错的变更组织策略,却不足以证明长期统一Spec可以成为事实来源。局部增量解决了录入成本,没有解决权威性、覆盖率和真实性。
历史项目真正需要的是证据工程:先固定业务目标,再沿生产、传递、消费和用户可观察行为追链路;用运行结果、日志、Git历史、现有测试与Owner确认交叉验证。调查结论在得到证据前应该保持临时身份,而不是急着晋升为Spec。
五、新项目也未必适合:不确定性最高时,文档最容易贬值
SDD的演示偏爱新项目,因为从零生成Todo App最容易显得流程完整。现实中的新项目往往处于另一种状态:问题尚未找准,用户反馈不足,技术路线未验证,原型随时推翻,产品决策每周都在变化。
此时最重要的是低成本试错,不是尽早生产一套看似完整的需求、设计与任务文档。模型尤其擅长把模糊想法扩写成完整文本,这种能力很容易制造“已经想清楚”的错觉。十六条验收标准不代表需求更成熟,可能只代表模型更能写。
如果一个决策下周大概率变化,今天为它写proposal、spec、design、tasks,再在实现后同步主Spec,得到的不是严谨,而是文档周转税。团队最终会走向两个结局之一:认真维护,速度被流程拖住;停止维护,Spec迅速失去信用。
这也是SDD的尴尬区间:
- 任务很小,完整流程是拿大锤砸坚果。
- 任务很大但问题不清楚,Spec只是在规模化记录猜测。
- 任务清楚且边界稳定,传统PRD、ADR、契约测试和实现计划通常已经够用。
SDD当然存在适用区域,但这个区域远比宣传口径窄。
六、更多Markdown不等于更多控制
SDD工具喜欢用模板、检查表、阶段和追踪关系制造秩序感。问题在于,文件数量增加的是可见产出,不一定是有效控制。
每一份AI生成的文档都需要人审。审查者不仅要判断它写得通不通,还要核对它是否忠于业务、是否重复已有能力、是否与代码事实一致。阅读一份流畅但暗含错误前提的长文,往往比审查一段可运行的代码更累,因为自然语言没有编译错误,只有被人漏掉的歧义。
Birgitta Böckeler在试用Kiro与spec-kit后给出的评价相当直接:它们都不适合多数真实编码问题;小Bug被扩写成四个用户故事和十六条验收标准;一个普通功能产生大量重复Markdown,审查这些文件的时间足以直接完成实现。她还观察到Agent把“现有类的调研记录”误当成新需求,再生成了一批重复类。
这正说明了一个反直觉事实:上下文越正式,不代表模型越听话;上下文越多,也不代表模型越理解。大窗口提高了可输入的信息量,没有提高每条信息的真实性,也没有保证模型会正确处理冲突。模板可以规范输出形状,不能替代事实调查。
SDD最危险的副作用不是写了几份没人看的文档,而是制造虚假的掌控感。团队看到了完整目录、勾选框和需求追踪矩阵,于是误以为风险已经被管理。实际上,风险可能只是从代码里搬进了更难验证的自然语言。
七、真正值得长期维护的,不是“统一Spec”,而是少量高价值事实
软件项目确实存在一些不应随任务任意漂移的内容:架构边界、数据所有权、兼容承诺、安全约束、合规要求、不可逆技术选择。这些内容应该被有意维护,但不该混进一份无限膨胀的统一Spec。
更稳妥的做法,是按生命周期和验证方式拆分知识:
| 内容 | 合适载体 | 原因 |
|---|---|---|
| 当前任务目标、计划、发现、进度 | planning-with-files 或同类任务文件 | 服务当前执行,可恢复、可删除,不冒充永久真相 |
| 产品目标与验收边界 | PRD、Issue、用户故事 | 有明确业务Owner,允许随产品决策演进 |
| 重要且长期的技术决策 | ADR | 记录背景、选择、代价和替代方案,强调“为什么” |
| API、数据与跨服务契约 | OpenAPI、Protobuf、Schema、类型 | 可被工具解析、校验和生成 |
| 稳定业务行为 | 自动化测试、契约测试、示例 | 能够执行,失败时给出明确反馈 |
| 当前实现与真实调用链 | 代码、运行结果、日志、Tracing | 用于证明系统现在实际做了什么 |
| 临时假设与探索结论 | 对话、草稿、findings.md | 在证据不足时保留可撤销性 |
ADR尤其重要,因为大模型对业务的理解有限,而许多关键决策无法仅从代码恢复。代码可以告诉后来者“现在用了事件驱动”,却未必能告诉他“同步方案曾因跨地域超时被否决”;这类原因值得以高写入门槛长期保存。
反过来,能从代码、类型或生成配置稳定恢复的信息,不必再手抄一遍。文档的价值不在覆盖面积,而在保存那些重要、稳定、无法从现状可靠推导的知识。
八、什么时候可以用SDD
批判SDD的滥用,不等于任何Spec都不该写。下面几类场景可能值得采用轻量或严格程度不同的SDD:
- 需求边界已经较稳定,失败代价高,必须在编码前对齐验收条件。
- 多团队、跨仓库协作,需要共同审查某项行为契约。
- 受监管、审计或安全要求约束,需要保存意图到验证结果的追踪链。
- 同一稳定规格需要生成多种实现,并且拥有强测试、确定性校验和再生成机制。
- 大型变更涉及大量步骤,任务上下文确实超出一次对话可可靠承载的范围。
即使在这些场景,也应该先回答三个问题:这份Spec的唯一职责是什么,谁负责维护,它如何被验证。回答不出来,就先不要创建。
一个简单的采用原则是:短期信息进入任务上下文,长期决策进入ADR,可执行约束进入测试和Schema,产品意图留给有Owner的需求系统。不要因为AI喜欢Markdown,就让Markdown接管软件工程。
结论:SDD最大的问题,是把“写清楚”偷换成了“写完整”
写清楚当然重要,但清楚不等于冗长,结构化不等于真实,版本化不等于有人维护,“Source of Truth”也不等于事实真的住在那里。
对多数项目,尤其是历史项目,SDD很容易变成一项文档扩张运动:把Prompt写成Spec,把Spec当成PRD,把PRD当成代码的上级,再让Agent负责维护它们之间的一致。最后团队多维护了一套没人能说清读者、边界和权威性的文档,而Agent得到了一份比普通旧文档更有指令权的旧文档。
这不是上下文工程的胜利,而是上下文腐化的制度化。
好的上下文工程追求的是:当前任务需要什么事实,证据在哪里,哪些结论仍可撤销,什么时候应该忘掉。好的传统工程产出物追求的是:谁拥有它,服务什么决策,如何验证,何时失效。SDD如果不能回答这些问题,就只是夹在两者之间的一层昂贵介质。
Spec可以是工具,但不该成为宗教。对历史项目而言,先调查事实,再记录决策;先验证行为,再谈统一真相。否则你得到的不是specification-driven development,而是specification-driven delusion。
参考资料
- Birgitta Böckeler, Understanding Spec-Driven-Development: Kiro, spec-kit, and Tessl, 2025-10-15。
- GitHub spec-kit, Specification-Driven Development。
- OpenSpec, Core Concepts。
- OpenSpec, Using OpenSpec in an Existing Project。
游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。
同类文章
CAD零基础入门教程:坐标输入、图层管理与基础绘图命令
本文面向CAD零基础学习者,系统讲解坐标输入、图层管理与基础绘图命令的核心用法。通过分步实操与常见问题排查,帮助新手建立精确绘图习惯,掌握规范出图的基础能力。
CAD从入门到项目交付:绘图、标注、图块与实战工作流
掌握CAD的核心在于建立“画得准、标得清、复用快、交付稳”的工作流。本文提供从环境设置、高频命令组合、标注规范、图块标准化到项目分阶段交付的完整路径,帮助初学者避免常见返工陷阱,独立完成可检查、可复用、可打印的工程图纸。
Claude Code 登录指南:个人、Teams 与企业账号区分与授权步骤
本文详细解析 Claude Code 登录前的账号类型区分方法,涵盖个人订阅、Teams 席位与企业 Enterprise 席位的授权路径差异。提供终端登录命令、环境变量排查及常见异常处理步骤,帮助用户快速完成正确授权并避免登录路径混淆。
Claude Code 文件修改前的权限模式配置与命令审批指南
本文详细介绍Claude Code在修改文件前的权限模式配置方法,包括defaultMode可选值、permissions allow与deny规则设置、多层级配置文件管理以及 status验证技巧,帮助开发者安全高效地使用AI编程助手。
Claude Code接入VS Code后先测扩展和终端命令
在VS Code中接入Claude Code后,建议优先验证扩展面板与集成终端两条入口。本文提供标准检查顺序、关键命令与常见故障排查路径,帮助你快速确认环境就绪,避免后续开发受阻。
- 热门数据榜
1
2
3
4
5
6
7
8
9
10
相关攻略
2026-09-01 16:53
2026-09-01 16:52
2026-09-01 14:27
2026-09-01 14:12
2026-09-01 14:10
2026-09-01 14:07
2026-09-01 13:55
2026-09-01 13:47
热门教程
- 游戏攻略
- 安卓教程
- 苹果教程
- 电脑教程

