> ## Content Index
> Fetch the complete content index at: https://www.hubwiz.com/blog/llms.txt
> Use this file to discover other available public pages before exploring further.

# 为什么我不认同规格驱动设计
- URL: https://www.hubwiz.com/blog/why-i-dont-buy-spec-driven-design/
- Published: 2026-05-21T11:38:01.000Z
- Updated: 2026-10-13T16:02:54.000Z
- Description: 规格驱动开发（SDD）是新的炒作。总体承诺很诱人：你用AI规划智能体写一个详细的规格说明，交给AI开发智能体，然后看着它完美地构建你的功能。
- Author: admin
- Tags: VIBE CODING, SDD, #Import 2026-10-14 14:41

这听起来像捷径吗？对我来说是的。在这个行业工作了25年多，它确实让我联想到一些东西。它看起来与瀑布方法如此相似，只是现在有了AI的帮助。但我认为今天它与30年前的瀑布方法有着一些相同的缺陷。

在Martin Fowler的一篇经典文章《设计已死？》中，他讨论了"计划设计"和"演化设计"之间的区别。SDD感觉像是回到了计划设计。它假设我们可以在构建系统之前了解关于它的一切。

在任何规模可观的项目中，你只有开始编码时才会发现真正的障碍。如果你的项目小到可以放入LLM的上下文窗口，SDD可能有效。对于其他一切，详细的规格说明最终会撞上未预见的技术现实的墙壁。

> 免责声明：我在一些评论之后添加了这些内容。当我在本文中谈论规格说明时，我主要指的是技术规格，而不是功能规格。功能规格很少因技术问题而改变，需求拆分则是一个完全不同的话题。在本文中，我主要关注的是技术规格，即如今在AI"计划模式"中构建的那种。

## 1、"简单"功能的陷阱

当我在2000年开始工作时，敏捷正在兴起。它教会我们一个残酷的真相：短迭代是捕获错误假设的唯一方法。SDD假设我们可以在构建功能之前了解关于它的一切。

让我们想象一个我们系统中非常常见的任务：处理一个新的支付webhook。

它看起来很简单。你为你的AI智能体写一个清晰、精确的规格说明。以下是我们可以写的一个简短摘要：

> *\- 创建一个POST端点 `/webhook`* 
> *\- 从JSON负载中提取 `order_id`，否则返回400 Bad Request。* 
> *\- 在数据库中查找订单，如果不存在则返回404 Not Found。* 
> *\- 将其状态更新为'PAID'（pay\_type\_id = 3）——触发'ReceiptEmail'类。*

AI完全按照你的要求做了。它写出了干净的代码，遵循你的AGENTS.md和测试。你将其部署到你的预发布环境。你感觉非常高效。

然后，现实打击了你。

你做一个手动集成测试，立刻注意到客户收到了三封收据邮件。发生了什么？你调试代码并意识到支付提供商期望在500毫秒内收到 `200 OK` 响应。如果没有收到，它会重试。你的端点花费了600毫秒，因为它是同步发送邮件的，或者因为预发布服务器很小，被其他开发人员的工作挤满了。

完美的规格说明没有考虑到网络延迟、重试或竞态条件。为了修复它，你现在需要转向。你意识到你需要一个完全不同的流程：

- 一个可以存储负载以便稍后处理的队列，并立即返回 `200 OK`。
- 一个后台进程来异步更新和发送邮件。
- 一个幂等键来防止重复。

你原来的规格说明现在没用了。初始代码必须被抛弃。你只有通过与环境的实际交互才发现了真正的架构需求。

当然，这只是一个例子，但它展示了一个简单的任务如何容易变得复杂。是的，我知道你们中一些读者会认为自己会做得更好，觉得自己应该了解架构，经典的"你做错了"。好吧，让我告诉你，没有人知道一切，连LLM也不知道。你的团队也不是充满了能预测每个可能边缘情况的高级工程师。

## 2、Token税 vs. 重构税

有了AI，预先设计引入了一个新的经济问题：**Token税。**

你花了token来解释Webhook规格说明。你花了token来生成有缺陷的代码。当现实迫使你转向时，你又付了一次税，向AI解释队列、后台工作者和幂等性。这是低效的。

我更喜欢将这些token投资于 **重构税。**从小处开始。让AI构建一个简单的概念验证（POC），只记录传入的负载。运行它。观察提供商的实际行为。一旦你了解了现实，使用AI来持续重构——提取邮件逻辑、添加队列并在过程中清理代码。这保持代码库健康，并让架构自然地涌现。

## 3、地图，而不是蓝图

当我写设计文档时，我喜欢Simon Brown（以C4模型闻名，这是一种友好的软件架构图表方法）的Google Maps类比。

你需要缩小来看上下文。你不需要一张显示每一根草的详细地图。

**糟糕的设计文档（SDD风格）：**

> `status`

**好的设计文档（Fluid风格）：**

> 支付事件通过webhook接收并放置在队列上。后台工作者处理订单履行和邮件分发，以确保幂等性。

关注重要的决策。为什么我们使用队列？这些模块如何解耦？将逐行实现留给代码。

## 4、使用适应度函数，而不是规则

如果你没有详细的规格说明，如何防止AI制造混乱？你使用适应度函数。

适应度函数是自动化的治理。你不是在文本提示中要求AI"请保持HTTP层与领域解耦"。你写一个强制执行此要求的架构测试。我以前谈论过这个，比如在这篇文章中。

我们如何防止前面的情况发生？我们写一个快速测试，当像 `ReceiptEmail` 这样的慢速服务直接在HTTP控制器中使用时立即失败（可选地，我们可以在服务层本身进行快速检查，要求在后台任务中才能继续）。

你不是在写规格说明；你是在设置一个硬边界。未来的规格说明不再需要担心这个问题。AI可以在这些墙壁内自由探索和编写代码；当其POC中抛出适当的错误消息时，它会自动转向。

> *注意：有些人认为测试驱动开发可以用于这些场景。我不太同意。我发现TDD过早地固定了你的实现；它非常适合小型bug修复，但在探索新功能并需要喘息空间时就不那么好了。但那是另一个话题。*

## 5、我目前的答案：Fluid Design

那么，SDD的替代方案是什么？我喜欢称之为**Fluid Design。**

- **设计文档，而不是规格说明：** 只记录高层决策、边界和模式。
- **主动原型设计：** 不要规定解决方案。向AI询问实现选项。构建小的POC来测试未知因素（如webhook延迟），然后再承诺于某个架构。
- **实时更新：** 将你的设计文档视为活记录。每次你在代码中发现新的约束时，更新文档。
- **你是船长：** 你掌舵。你不是把地图交给AI然后去睡觉。你根据代码告诉你的信息实时调整航向。

归根结底，唯一重要的规格说明就是代码。其他一切都只是猜测。从简单开始，持续重构，让你的架构自然演化。

---

原文链接: [The Spec is the Code: why I don't buy Spec-Driven Design](https://medium.com/dev-genius/the-spec-is-the-code-why-i-dont-buy-spec-driven-design-f75c784f7b46?ref=hubwiz.com)

汇智网翻译整理，转载请标明出处

> **这是「AI 编程 / Vibe Coding」专题的一部分。**完整地图见：[AI 编程 / Vibe Coding 完全指南](https://www.hubwiz.com/blog/vibe-coding-stack/)