SDD的问题,以及如何修复它
我一直说规格驱动开发有问题,以及为什么有问题。这是我第一次展示修复方案,而且它在一个说出来从未到达的地方结束——客户的账单上。
SDD 之所以成型,是因为 vibe coding 行不通。你描述一个目标,得到一段代码,看起来对的,但不完全能用。GitHub 自己在 2025 年 9 月发布 spec-kit 时也这么说:模型"在模式补全方面非常出色,但不会读心术"。目标转向了规格说明。提前详细写下你想要什么,agent 就不再猜测。有人写了几个命令,GitHub 就是 GitHub,spec-kit 接管了对话,十几个其他工具紧随其后:AWS 的 Kiro、Tessl、BMAD、Agent OS。这个品类在不到一年内就成为了主流。
一个纠正,因为细心的读者会去核实。规格驱动开发并不新鲜,仔细研究过的人很早以前就说了。Larman 和 Basili 在 2003 年的 IEEE Computer 中记录了迭代开发可以追溯到 1950 年代,而单遍式、文档驱动的理想从一开始就受到质疑,甚至 Royce——通常为此背锅的人——也是如此。一年后,XP 2004 的一篇论文,Ostroff、Makalsky 和 Paige 的"敏捷规格驱动开发",不是为大型前置规格辩护,而是相反:认为"完整的"规格是一个有缺陷的理想,规格应该随着测试和契约的出现而逐步成型。他们在写"完整"这个词时不得不加上引号。现代的工业使用比 AI 浪潮早了好几年。Vibe coding 的失败没有发明 SDD。它让 SDD 成为了主流。而点燃导火索的人,Andrej Karpathy,创造的是 vibe coding,不是 SDD。他是两个时代之间的桥梁,后来他说 vibe 时代正在结束。这个故事的简单版本把两者都归功于他,那是错的。
以下是正确的版本,没有人告诉你。几乎没有人意识到这一点,因为他们还在与 SDD 挣扎。
1、SDD 留下漏洞,agent 来填补
SDD 的整个问题是人们随意写规格。它包含做什么。它包含怎么做。它包含工程师能写的任何东西。每个工程师都用那天早上脑子里的东西来填充它。然后 agent——Claude Code、Codex 和 Droids——阅读规格并做出决定,因为其中有巨大的漏洞。漏洞不是规格的缺陷。
这是两个人类差距,不是工具问题。第一:工程师不花时间去了解规格实际上是什么。我们假设我们知道,因为我们已经写了 20 年的规格。但我们没有写过这种。第二:流行的方法不是为我们大多数人工作的地方构建的。一个在绿地应用的四十分钟 YouTube 演示中完美扩展的方法,不等于一个在拥有十二个团队、十年决策积淀以及一个需要安心睡觉的合规审查员的真实企业代码库中扩展的方法。这个领域的营销层把演示当作方法来销售。它们不是一回事,它们之间的差距是由下游来买单的。
2、OpenAI 的 Symphony 规格实证明了我的观点
看看 OpenAI 在 2026 年 4 月发布的 Symphony。Symphony 是一个用于编排 agent 的开放规格,其核心是一个单一规格文件,2,169 行,十八个章节,用正式的 must 和 should 语言编写。深度水平准确展示了我们对人们的要求,也准确展示了他们做不到的。
如果任何人都能提前把所有这些写进一个 SPEC.md 中,那么是的,它有效。这不是讽刺;这是字面上的事实。一个完整的、无歧义的、两千行的规格会产生好的软件。OpenAI 花了大约六个月在一条硬规则下构建内部工具:没有人类编写的代码,每一行都由 Codex 生成。他们让它运行成功了。只有成功之后,他们才从运行系统中提炼出规格。然后他们让 Codex 在 Elixir 中一次性构建参考实现,并分别在 TypeScript、Go、Rust、Java 和 Python 中实现相同规格,目的是把歧义抖出来。这个深度的、RFC 级别的规格是已经在运行的软件的回溯性文档,这不是我的曲解;这是 OpenAI 自己对事情发生顺序的描述。
所以规格有效,如果你能提前写出来的话。这就是没有人告诉你的陷阱,因为你不能提前写出来,而唯一一个产生了这么好的规格的组织是最后产生的,而不是最先产生的——通过逆向工程已经活着的软件。行业把那个过程的产出当作方法来销售。
3、我自己给自己挖了坑
我在自己的工作中遇到了这个问题。规格是好的,但 agent 仍然漂移了,因为我退出了循环,让它填补我没有想清楚的部分。我有一段时间称它为漂移。它不是漂移。漂移是你不想说"你离开了"时用的词。我花了三天返工来撤销本不应该写的代码。我每天运行 1.5 到 2 亿个 token 与我的 agent 协作,按当前的 Opus 费率,三天的费用大约是 $985——我制造了问题然后又花了一次钱来消除它的真金白银。这是整篇文章中这种失败最便宜的版本,我自己的钱在我自己的机器上。规格好正是这件事重要的原因:好的规格不会自己撑住;它撑住是因为有人留在循环中,而那次,我没有。
4、ICE:三种技艺和它们运行的循环
框架是 ICE:Intent(意图)、Context(上下文)、Expectations(预期)。本文定义第一个,因为 Intent 是其他一切挂载的原语。Context 和 Expectations 也是真正的技艺,但它们留给后面的文章;试图一次定义三者会导致你回到这个方法要替换的那个臃肿文档。所以现在先讲 Intent,Context 和 Expectations 以后再说。
举个最简单的例子。一个商业场景:"用户想买一双 90 美元以下的红色鞋子。"意图是买一双 90 美元以下的红色鞋子,人类想要的结果,其中不包含哪个技术栈或哪个服务来构建它。Intent 是整个方法的一等原语,它不是一句话。五个要素加在一起构成一个意图:对所想要事物的描述、围绕它的约束、失败的场景、成功的场景,以及连接——指向它触及的其他意图的链接,使得这里的变更可以追溯到它影响的所有东西。缺少这五个中的任何一个,你就回到了让 agent 为你填补的坑里。
如果你周一只做一件事,就做这个。拿一个你本周要交付的真实结果,不是整个系统,只是一个结果:90 美元以下的红色鞋子。只为它写五个部分。想要什么是一双买家实际上能以 90 美元以下购买的红色鞋子。约束:尺寸、有库存、可配送。失败场景:返回 140 美元的鞋子、缺货的鞋子或非红色的鞋子。成功场景:买家将一双价格合理的红色鞋子加入购物车并结账。连接:任何涉及价格、库存或结账的东西,因为那里的变更会影响这个。然后测试:把它交给一个不在你脑子里的人,问他们 agent 在哪里仍然需要猜测。他们指出的每个地方都是你即将让它填补的漏洞。关闭这些漏洞,不是整个系统。这是第一步,花费一小时,而不是方法论推广。
4.1 Expectations(预期)
这些是人们称之为规格的部分,我故意不叫它规格。它是边界:结果算作完成的场景、失败的场景以及它必须留在的限制内,用用户能认出的术语编写,而不是用实现语言编写。将其作为独立的技艺,由拥有意图的同一个人拥有,这是整个修复方案;一旦完成的定义偏离了想要结果的人,agent 就开始替他们决定"完成了"。
4.2 Context(上下文)
是怎么做:技术、现有系统和代码库的约束,鞋子在其中被构建。它应该来自你的工具链,并根据需要渐进式地提供,而不是在一开始就倾泻成一堵墙。其他一切——模型、提示、编排、实际运行循环的工具链——都是机制。
这些技艺只是片段,直到你看到它们运动,所以这是我们必须构建的循环。
人类提供两样东西:意图和说明"完成意味着什么"以及"结果必须不是什么"的预期。它们输入到 agent 编码循环中,工具链做工作、拉取上下文、编码并根据预期进行验证;如果不符合,再来一次,直到符合。最后,一旦完成,代码合并。人类拥有意图和预期,永远不离开它们;工具链拥有循环,永远不会被要求发明人类想要什么。
这就是 ICE 的全部要点。SDD 之所以失败,是因为它要求一个文档,由拿着键盘的人以一种方式编写,同时充当意图、完成定义、工作流和上下文,它们之间的空白留给 agent 自行决定。同样值得明确的是,工具链不是方法:spec-kit、BMAD 和提示与工作流群体是工具链,有用的工具链,但仍然只是工具链,而 ICE 是在工具链处理之前决定工作内容的方法。在不采用方法的情况下采用工具链——这是今天的默认做法,因为工具链是有下载按钮的部分——你会得到和我花了三天返工支付的相同失败,只是规模更大,上面有客户的名字。
我称之为 IDSD——意图驱动软件开发,其中声明结果并让机器确定实现方式是正常的工作方式,而不是愿望。
有些人会说这仍然是换了个名字的规格,他们对文件说得对,对改变了什么说错了。它们仍然都是 markdown——意图、预期和上下文——格式从来不是问题。改变的是每个文件是什么以及谁拥有它。没有规格技艺:以前是一个庞大规格的东西现在是预期,一个由想要结果的人编写的简短边界,而不是由拿着键盘的人猜测。上下文是 agent 工具如何完成工作的;它们由工具链拥有,而不是在与用户愿望相同的段落中即兴发挥。一个文件,然而键盘持有者那天早上的感觉就是那个崩溃的东西,而意图加上一组明确的预期,交给拥有构建的工具链,完全是另一回事。
5、IDSD 至少比行业目前的水平高两个层级
我向我的团队展示了实现。不是理论,是真实的东西。我展示了如何为消费者用例编写意图,然后如何为 agent 编写意图,连同约束、失败场景以及回溯到它触及的每个其他意图的链接。我看着它着陆。你可以在第二张幻灯片就读懂一个房间,而这个房间以一种不是赞同的方式安静下来。
Ira 大声说了出来。她是我的首席顾问,十八年经验。"团队还没有采用 SDD,"她说。"它才一年,大多数人还在假装在做。现在你想让他们把意图和预期作为独立的技艺来编写,两者之间有可追溯性,而且还要为 agent 也这样做。这比团队实际水平高出两级。"
然后是 Nyra。她让房间继续前行,像她惯常做的那样。"一分钟。"很轻,像是一件小事。"团队还没准备好不是风险。风险是有一天 agent 写了一万行看起来对的代码,而没有人拥有解释'对'意味着什么的部分。我们不是让他们学一个更难的规格。我们让他们继续做这个方法很容易跳过的那个判断。"她刚刚在四句话中把整个论点说了回来,并把 Ira 的反对变成了做这件事的理由,而不是不做的理由。
这就是我走出来的综合判断。Ira 说得对,对团队的水平来说太超前了。Nyra 说得对,答案不是等到他们准备好;而是让那个不能跳过的东西变得不可能跳过。其余的就是我试图构建这个。
6、让我失眠的事
这是担忧,直白地说。这是一个真实的恐惧,我还没有完全解决。
当我的团队在项目上工作时,他们会遗漏系统的关键部分。这就是 Nyra 说的看起来对的一万行代码,她在我找到合适的词语之前就安静地指出了它。不是因为他们不好。因为现在生成大量代码变得极其容易,生成越容易,你就越能自信地在大量上出错。当 METR 在 2025 年对此进行受控试验时,有经验的开发者在 AI 辅助下可测量地更慢,但离开时确信 AI 让他们更快了。在感觉快的时出错——一句话概括了整个失败。我们将在时间和金钱上花在把错误的东西做好上。这让我害怕,而且我有收据来证明这是应得的。那又是我的三天返工,只是更大了,而且在客户的账单上。
真正的答案,我相信但不完全做到的,是你必须在每一步都参与。是团队的一部分,在工作进行时,而不是最后来祝福一个已经太大而无法真正阅读的 diff 的审查者。我把它称为一个核心指标:在循环中的存在,而不是在关卡上的批准。我做得相当好。我不能一直这样做。那个想要信任 agent 并走开的部分,就是那个买了三天返工的部分。我亲密地了解这个失败,因为我是一个回头客。
7、谁真正买单
这归根结底不是一个软件工程的故事。它是一个经济学故事,而在最底层的人一生中从未读过一份规格。
有两种构建方式,行业知道这一点,即使它不说。你写代码,编写慢但运行便宜,因为计算已经商品化多年。或者你依赖 agent,编写快但运行昂贵。不是因为 token 变贵了;每 token 价格持续下降。昂贵是因为一个被留下填补空白的 agent 每个完成的结果消耗更多 token,即使标价下降,结果的成本也在攀升,而且令人震惊数量的 token 被花在在有人注意到之前自信地出错上。
破损的规格驱动开发坐在那条线的昂贵一边,而且它不会安静地待在那里。它膨胀了构建软件的成本,而那种膨胀不是由销售方法的供应商或演示它的网红吸收的。
SDD 之所以失败,是因为我们要求人类做人类做不到的事情:在它存在之前就指定一切。它之所以失败,是因为为此销售的方法是为演示构建的。这些成本都不会消失。它沿着链条向下移动,最终落在这里。从未读过规格的客户,以及客户服务的人——他们从未选择这些,也不在它出问题时在场。
这就是我在自己的团队上做的事情。我们正在超越 SDD。我们要运行 IDSD:以真正的纪律编写意图和预期,上下文精确限制在我们想要的,然后 agent 做工作。我有点害怕。我无论如何都在做,因为这件事必须做,而且背后的原则是吃自己的狗粮。你在它到达客户的账单之前,先在自己身上运行自己的方法。飞轮只有在转动时才会复合增长,而它只有当有人愿意迈出第一步时才会转动。这就是它的开始。
所以问题不是你的 agent 能不能做这个工作。它们能。问题是你是否有纪律自己拥有意图和预期,以及是否有勇气在机器运行时留在循环中——在那一天,走出去祝福 diff 会容易得多。那一天就是整个游戏。你在那一天做什么?
原文链接:The Method That Replaces Spec-Driven Development — IDSD
汇智网翻译整理,转载请标明出处