从 Vibe Coding 到 SDD:规范驱动开发如何拯救 AI 编程失控
1. 引言Vibe Coding 的失控时刻Vibe Coding 这个词在 2025 年迅速走红它描述的是一种「跟着感觉写代码」的 AI 辅助编程方式开发者把需求丢给大模型让 AI 自动生成代码自己只负责「感觉对不对」。这种模式在原型验证、脚本编写、一次性工具开发中确实效率惊人但一旦进入生产环境问题就会集中爆发。典型的失控场景包括AI 在无人监督的情况下连续生成数百行未经审查的代码同一个功能反复生成却每次结构都不同代码能跑但没人说得清它为什么能跑一次「小改动」引发连锁回归却无法定位根因。这些问题的本质不是 AI 能力不足而是缺少一套可执行的规范来约束 AI 的产出。规范驱动开发Specification-Driven Development简称 SDD正是针对这一痛点提出的方法论。它的核心思想是在让 AI 写代码之前先让 AI或人机协作把「做什么、怎么做、怎么验收」写成机器可读的规范再基于规范生成代码并用规范自动验证结果。本文将从原理到实战完整演示如何用 SDD 让 AI 编程重新回到可控轨道。2. 什么是 Vibe Coding它为什么会失控Vibe Coding 并非一个严谨的学术概念它更像是对一种新兴工作方式的概括开发者用自然语言描述需求AI 生成代码开发者凭直觉判断是否可用。这种模式在以下场景中表现亮眼快速原型几天内验证一个产品想法是否可行。脚本与自动化写一次性数据处理脚本、运维工具。样板代码生成 CRUD 接口、DTO、配置文件等重复性代码。但失控往往发生在规模扩大之后。以下是 Vibe Coding 最常见的四类失控表现失控类型典型表现根因需求漂移AI 生成的功能与真实需求逐渐偏离自然语言歧义缺少可验证的验收标准结构混乱每次生成代码结构不同难以维护没有约定架构模式和代码规范回归失控修改一处引发多处故障无法定位缺少自动化测试和契约约束质量黑洞代码能运行但无人理解其内部逻辑缺少设计文档和评审机制这些问题的共同点在于AI 的输出缺少一个「锚点」。Vibe Coding 把锚点寄托在开发者的直觉上而人的直觉在复杂系统中并不可靠。SDD 则把锚点替换为「规范」——一份明确、可执行、可验证的契约。3. SDD 的核心思想与工作流程规范驱动开发并不是一个新概念它在传统软件工程中早有雏形如契约式设计、规格说明方法。SDD 在 AI 时代的特殊价值在于规范不再只是给人看的文档而是同时给 AI 看的「指令集」和给测试框架看的「验证脚本」。一个完整的 SDD 循环包含五个阶段需求澄清把模糊的自然语言需求转化为结构化描述。规范编写用机器可读的格式如 Markdown JSON Schema、Gherkin、OpenAPI描述功能、边界和验收标准。代码生成让 AI 严格依据规范生成实现代码。自动验证用规范中的验收标准驱动测试自动检查实现是否满足要求。迭代修正验证失败时把失败信息反馈给 AI让其修正代码或规范。这个循环的关键在于规范是唯一的权威来源。AI 不直接面对模糊的自然语言而是面对结构化的规范验证不依赖人的直觉而是依赖可执行的测试。这样即使 AI 生成代码有偏差也能在早期被自动捕获。4. 实战准备环境与项目结构为了让演示可运行我们选择一个贴近真实业务的场景实现一个带库存校验的订单创建接口。这个场景足够简单能完整展示 SDD 流程又包含业务规则、边界条件和错误处理能体现规范的价值。技术栈选择如下保持 Java 生态便于展示类型安全和测试能力语言Java 17框架Spring Boot 3.x测试JUnit 5 AssertJ规范格式Markdown JSON Schema GherkinCucumber项目结构如下order-service/ ├── specs/ │ ├── order-creation.md # 功能规范人机可读 │ ├── order-schema.json # 请求/响应数据结构规范 │ └── order.feature # Gherkin 行为规范可执行 ├── src/ │ ├── main/java/com/example/order/ │ │ ├── controller/OrderController.java │ │ ├── service/OrderService.java │ │ ├── repository/OrderRepository.java │ │ └── model/Order.java │ └── test/java/com/example/order/ │ ├── OrderServiceTest.java │ └── OrderSteps.java # Cucumber 步骤定义 └── pom.xml这个结构的关键在于specs/目录它是整个开发的起点也是 AI 生成代码的唯一依据。5. 第一步编写机器可读的规范SDD 的第一步是把需求写成规范。我们先用 Markdown 描述业务规则再用 JSON Schema 定义数据结构最后用 Gherkin 编写可执行的行为规范。首先是功能规范order-creation.md# 订单创建功能规范 业务规则 用户必须提供商品 ID 和购买数量。 商品必须存在且处于上架状态。 购买数量必须大于 0 且不超过库存。 创建成功后扣减库存返回订单 ID。 库存不足时返回 409 冲突错误。 商品不存在时返回 404 错误。 验收标准 输入合法时返回 201 和订单信息。 数量为 0 或负数时返回 400 错误。 库存不足时返回 409 错误。 商品不存在时返回 404 错误。然后是数据结构规范order-schema.json{ type: object, required: [productId, quantity], properties: { productId: { type: string, minLength: 1 }, quantity: { type: integer, minimum: 1 } }, additionalProperties: false }最后是可执行的行为规范order.featureGherkin 格式Feature: 订单创建 作为用户 我希望创建订单时系统校验库存 以便避免超卖 Scenario: 正常创建订单 Given 商品 P001 存在且库存为 10 When 用户购买商品 P001 数量 3 Then 返回 201 状态码 And 返回订单 ID And 商品 P001 库存变为 7 Scenario: 库存不足 Given 商品 P001 存在且库存为 2 When 用户购买商品 P001 数量 5 Then 返回 409 状态码 And 返回错误信息 库存不足 Scenario: 商品不存在 Given 商品 P999 不存在 When 用户购买商品 P999 数量 1 Then 返回 404 状态码 And 返回错误信息 商品不存在这三份规范合在一起构成了 AI 生成代码的「完整契约」。注意 Gherkin 规范中的每个场景都是可执行的——这正是 SDD 与普通文档的关键区别。6. 第二步让 AI 依据规范生成代码规范就绪后我们把规范文件作为上下文提供给 AI要求它严格按规范实现。这里的关键是提示词要明确「以规范为准」而不是让 AI 自由发挥。一个有效的提示词模板如下请严格依据 specs/ 目录下的三份规范实现订单创建功能 1. order-creation.md 定义了业务规则和验收标准。 2. order-schema.json 定义了请求数据结构。 3. order.feature 定义了可执行的行为场景。 要求 实现 OrderController、OrderService、OrderRepository 和 Order 模型。 所有业务规则必须与规范一致不得自行增减。 错误码必须与规范中的 400/404/409 对应。 不要实现规范之外的任何功能。基于上述规范AI 生成的OrderService核心逻辑如下Service public class OrderService { private final OrderRepository orderRepository; private final ProductClient productClient; public OrderService(OrderRepository orderRepository, ProductClient productClient) { this.orderRepository orderRepository; this.productClient productClient; } public Order createOrder(CreateOrderRequest request) { // 规则 1商品必须存在 Product product productClient.findById(request.productId()); if (product null) { throw new ProductNotFoundException(商品不存在); } // 规则 2商品必须上架 if (!product.isActive()) { throw new ProductNotActiveException(商品已下架); } // 规则 3数量必须大于 0由 JSON Schema 保证此处防御性校验 if (request.quantity() amp;lt; 0) { throw new InvalidQuantityException(购买数量必须大于 0); } // 规则 4库存必须充足 if (product.stock() amp;lt; request.quantity()) { throw new InsufficientStockException(库存不足); } // 规则 5扣减库存并创建订单 productClient.deductStock(request.productId(), request.quantity()); Order order new Order(request.productId(), request.quantity()); return orderRepository.save(order); } }注意这段代码的每个分支都能在规范中找到对应规则。这不是巧合而是「规范驱动」的直接结果AI 没有自由发挥的空间它只是在把规范翻译成代码。7. 第三步用规范自动验证实现代码生成后最关键的一步是验证。SDD 的验证不是「人工看一眼」而是把 Gherkin 规范直接变成自动化测试。我们用 Cucumber 实现SpringBootTest AutoConfigureMockMvc public class OrderSteps { Autowired private MockMvc mockMvc; Autowired private ProductRepository productRepository; private ResultActions result; Given(商品 {string} 存在且库存为 {int}) public void productExists(String productId, int stock) { productRepository.save(new Product(productId, stock, true)); } Given(商品 {string} 不存在) public void productNotExists(String productId) { productRepository.deleteById(productId); } When(用户购买商品 {string} 数量 {int}) public void userBuys(String productId, int quantity) throws Exception { result mockMvc.perform(post(/api/orders) .contentType(MediaType.APPLICATION_JSON) .content({productId: productId ,quantity: quantity })); } Then(返回 {int} 状态码) public void assertStatus(int status) throws Exception { result.andExpect(status().is(status)); } Then(返回订单 ID) public void assertOrderId() throws Exception { result.andExpect(jsonPath($.orderId).exists()); } Then(商品 {string} 库存变为 {int}) public void assertStock(String productId, int stock) { Product product productRepository.findById(productId).orElseThrow(); assertThat(product.stock()).isEqualTo(stock); } Then(返回错误信息 {string}) public void assertError(String message) throws Exception { result.andExpect(jsonPath($.message).value(message)); } }运行mvn test后Cucumber 会逐条执行 Gherkin 中的场景。如果 AI 生成的代码有偏差测试会明确指出哪个场景失败、期望什么、实际得到什么。这就是 SDD 的「自动验收」能力。8. 第四步迭代修正与规范演进SDD 的循环不会在第一次验证通过后结束。当业务规则变化时我们修改规范然后让 AI 依据新规范重新生成或修改代码再跑测试验证。这个迭代过程是规范驱动开发的核心价值所在。举个例子假设业务新增一条规则「单笔订单金额不能超过 10000 元」。我们只需在规范中增加一条7. 单笔订单总金额不得超过 10000 元超过时返回 400 错误。同时在 Gherkin 中增加场景Scenario: 订单金额超限 Given 商品 P001 存在且库存为 100单价为 5000 When 用户购买商品 P001 数量 3 Then 返回 400 状态码 And 返回错误信息 订单金额超限然后把更新后的规范交给 AI要求它修改OrderService。AI 会定位到金额校验逻辑新增规则分支。最后跑测试验证新旧规则都通过。整个过程不需要人工逐行审查代码规范就是评审标准。9. SDD 与 Vibe Coding 的对比为了更直观地理解 SDD 的价值我们把两种模式放在一起对比维度Vibe CodingSDD规范驱动开发需求表达自然语言存在歧义结构化规范机器可读验收标准开发者直觉可执行测试场景代码结构每次生成可能不同受规范约束保持一致回归控制依赖人工回归测试规范驱动自动化测试变更管理改需求后重新生成风险高改规范后增量修改可追踪适用场景原型、一次性脚本生产系统、核心业务逻辑需要强调的是SDD 并不是要完全取代 Vibe Coding。对于探索性、低风险的任务Vibe Coding 的灵活性仍然有价值。但对于生产级代码SDD 提供的「规范锚点」能显著降低失控风险。10. 落地 SDD 的实践建议把 SDD 引入团队并不需要推翻现有流程可以从以下三个步骤渐进落地从关键业务开始选择库存、支付、权限等核心逻辑先写规范再写代码不要一开始就覆盖所有模块。规范要可执行不要只写 Markdown 文档一定要配套 Gherkin 场景或 JSON Schema让规范能驱动自动化测试。把规范纳入代码评审评审时先看规范是否完整再看代码是否偏离规范而不是直接看代码细节。此外建议团队维护一份「规范模板库」把常见的业务规则模式如库存校验、权限控制、金额限制沉淀为可复用的规范片段。这样新项目启动时AI 可以直接基于模板生成规范再基于规范生成代码效率和质量都能得到保障。11. 总结Vibe Coding 让 AI 编程变得极其高效但也把「失控」的风险推到了台前。SDD 提供了一条务实的出路用规范约束 AI 的产出用自动化测试验证结果用迭代循环持续演进。它不是要束缚创造力而是把创造力放在正确的位置——规范本身的设计才是真正需要人类智慧的地方。当 AI 越来越擅长写代码开发者的核心价值将不再是「写代码」而是「定义什么是正确的代码」。SDD 正是这种能力的方法论载体。从今天开始在下一个 AI 辅助开发任务中先写规范再让 AI 动手你会感受到「可控的 AI 编程」带来的踏实感。