文章封面图: Spec-Driven Development实战指南:AI时代的开发方法

Spec-Driven Development实战指南:AI时代的开发方法

发布于:

阅读时间: 2 min

主题: 技术

作者: Leandro Valencia

#spec-driven development#bdd#domain-driven design#api-first#ai开发#openspec

什么是Spec-Driven Development?为什么它在AI时代重新流行?如何结合BDD、DDD、MDE和API-First落地实践,附示例、对比表和智能体工作流。

目录

先写清楚软件该做什么,然后再写代码

你肯定遇到过这种情况:客户要"一个能预约的机器人",团队马上开工写代码,三周之后,没人说得清"预约"到底是什么意思。能取消吗?时间段被占了怎么办?代码是写出来了,但当初的想法从来没被写下来。

Spec-Driven Development(SDD),即规格驱动开发,瞄准的正是这个问题。规则很简单:规格说明才是项目的核心产物,代码、测试和文档都从它派生。业务变了,先改规格;代码随后再改。

它不是单一的方法论,而是一类把规格、模型或契约放在软件开发生命周期(SDLC)中心的方法家族。本文会介绍最常用的四种——BDD、DDD、MDE/MDA和API-First——它们如何比较,以及在大量代码已经由AI来写的今天该怎么落地。

为什么SDD又火了起来:AI写代码,你来定规格

"先写规格再编码"这个想法已经有几十年历史了。新鲜的是谁来写代码。有了Copilot、Claude Code、Cursor这样的AI智能体,生成代码很便宜;真正昂贵的是知道该生成什么。

如果你对一个智能体说"给我做个登录",没有任何上下文,你得到的会是某个登录功能,而不是你的登录功能。这种凭直觉干活的方式有了一个名字:vibe coding。做原型没问题,放到真实项目里就会翻车。

因此,一批把规格放到AI协作中心位置的工具出现了:

  • OpenSpec:我的推荐。轻量,支持30多种AI助手(Claude Code、Cursor、Copilot等),专为已有项目设计,而不是只能从零开始。
  • Kiro:AWS的IDE,把每个功能拆成三个文件:requirements.md、design.md和tasks.md。
  • GitHub Spec Kit:开源工具包,流程按阶段划分、更严格;如果你用GitHub Copilot,它尤其好用。

规格说明从一份没人看的文档,变成了整个项目最重要的提示词。

1. Behavior-Driven Development(BDD):能执行的规格

BDD把TDD的思想带进业务语言。规格就是用结构化自然语言写成的行为场景,几乎总是采用Gherkin格式(Given / When / Then)。

Feature: 通过WhatsApp预约

  Scenario: 所需时间段已被占用
    Given 一位客户正在与诊所的机器人对话
    And 周二10:00已经有一条约好的预约
    When 客户预约周二10:00
    Then 机器人回复该时间段不可用
    And 推荐最近的三个空闲时间段

它在生命周期中的走法:

  • 分析与设计: 业务、开发和QA在"Three Amigos"会议上一起写场景。
  • 开发与测试: 每个场景都连接一个自动化测试(Cucumber、Behave、SpecFlow/Reqnroll),在功能实现之前它先失败。
  • 维护: .feature文件就是living documentation(活文档):一旦描述不再成立,测试就会失败。

适用场景: 项目最大的风险是误解客户的需求。

2. Domain-Driven Design(DDD):把业务模型当规格

在DDD中,规格是一个丰富的领域模型和一门通用语言(ubiquitous language):同样的词、同样的含义,出现在客户会议、看板和代码里。业务说"预约",类就叫Reservation,而不是BookingItemDTO。

它在生命周期中的走法:

  • 分析与战略: 通过Event Storming这类工作坊发现业务事件,划分成Bounded Contexts(比如日程、账单、通知),再用上下文映射图连接起来。
  • 架构与实现: 战术设计(实体、值对象、聚合、领域事件)把模型直接翻译成代码。
  • 演进: 业务规则变了,先更新模型,再更新架构和代码。

通用语言变成代码的例子:

// Bounded Context: 日程
class Reservation {
  reschedule(newSlot: TimeSlot) {
    if (this.status === "cancelled") throw new Error("已取消的预约不能改期");
    this.slot = newSlot;
    this.record(new ReservationRescheduled(this.id, newSlot));
  }
}

适用场景: 复杂度在业务规则里,而不在技术里。

3. Model-Driven Engineering(MDE)与Model-Driven Architecture(MDA):从模型到生成的代码

这里的规格是形式化模型:UML图、领域特定语言(DSL)或任何建模语言。MDA是OMG标准化的变体,它把平台无关模型(PIM)和平台相关模型(PSM)分开。

它在生命周期中的走法:

  • 设计: 构建抽象模型,不绑定某个语言或框架。
  • 构建与部署: 转换引擎把模型变成源代码、数据库schema、基础设施脚本和测试。
  • 维护: 改高层模型然后重新生成即可更新系统;生成的代码不手动改。

你用得比想象中多:生成数据库和客户端的schema.prisma,定义基础设施的Terraform文件,都是这套哲学的小例子。低代码平台则把这种思路推到极致。

适用场景: 有很多相似的系统,或高度受监管、更适合生成而不是手写的领域。要小心僵硬性:如果转换工具跟不上,团队最后会去手改生成的代码,模型也就不再是真相。

4. API-First与Contract-Driven Development(CDD):契约说了算

这是SDD在服务架构、微服务和集成中最实用的应用。规格是API契约,在编码之前用开放标准写好:REST用OpenAPI(Swagger),事件用AsyncAPI,gRPC用Protobuf。

openapi: 3.1.0
info:
  title: 预约API
  version: 1.0.0
paths:
  /reservations:
    post:
      summary: 创建预约
      requestBody:
        content:
          application/json:
            schema:
              type: object
              required: [clientId, timeSlot]
              properties:
                clientId: { type: string }
                timeSlot: { type: string, format: date-time }
      responses:
        "201": { description: 预约已创建 }
        "409": { description: 该时间段已被占用 }

它在生命周期中的走法:

  • 设计: 提供API的一方和消费API的一方共同商定契约。
  • 并行开发: 从契约可以生成mock服务器、客户端SDK和代码骨架,前后端同时推进、互不等待。
  • 集成与部署: 契约测试(用Pact这类工具做Consumer-Driven Contracts)跑在CI/CD流水线里,任何会破坏消费方的改动都会被拦下。

适用场景: 多个团队或系统依赖同一个API,比如与WhatsApp、CRM或支付网关的集成。

对比:哪种方法适合你?

它们并不互相竞争:各自针对不同的风险,而且组合得很好。

方法论 核心产物 SDLC中的主要焦点 主要解决的问题
BDD 行为场景(.feature) 业务-开发-QA对齐与验证 "我们做的东西客户根本没要"
DDD 领域模型与通用语言 架构、复杂度与业务 "业务规则散落在代码各处"
MDE / MDA 抽象模型(UML、DSL) 自动生成与抽象 "同样的东西手写了一遍又一遍"
API-First / CDD API契约(OpenAPI、AsyncAPI、Protobuf) 集成、微服务与并行开发 "每次部署都弄坏一个集成"

真实项目中常见的组合:用DDD把系统拆成上下文,用API-First定义这些上下文怎么通信,用BDD从用户视角验证每个功能。

用AI做SDD:明天就能用的流程

入门不需要四种方法论全上。这套流程对任何AI智能体都有效,只需要仓库里的几个Markdown文件;下面我会演示如何用OpenSpec把它自动化。

  1. 写规格: 在spec.md里写清楚功能要做什么、为什么,附上验收标准。BDD场景和DDD的通用语言都用在这里。
  2. 做计划: 让智能体产出plan.md,包含架构、技术栈和契约(你的OpenAPI就放在这里)。继续之前自己先审一遍。
  3. 拆任务: 把计划拆成tasks.md,每一步都小而可验证,一个commit一步。
  4. 实现: 智能体一次执行一个任务,始终把规格和计划当作上下文来读。
  5. 验证: 由规格派生的测试说了算,任务完没完成不是靠直觉。

黄金法则:需求变了,就改规格,让改动向下流动。如果直接在代码上修,规格就不再是真相,你就退回了vibe coding。

用OpenSpec具体怎么做

OpenSpec是我推荐用来落地这套流程的工具。跟Spec Kit比,它有三个实用优势:

  • 仪式感更少: 不强迫你走严格的阶段;你可以对提案反复迭代,直到清晰为止。
  • 为已有项目设计: 每个变更都待在自己的文件夹里,作为现有spec之上的delta,你不必在开工前先把整个系统文档化。
  • 不绑定某个智能体: 支持Claude Code、Cursor、Copilot、Amazon Q等几十种工具。

安装需要Node.js 20.19或更高版本:

npm install -g @fission-ai/openspec@latest
cd your-project
openspec init

之后,在你的AI智能体里,整个循环只有三个命令:

  1. /opsx:propose:在openspec/changes/里创建一个文件夹,包含提案、受影响的spec、设计和任务。你审核调整之后再继续。
  2. /opsx:apply:智能体按照规格实现任务。
  3. /opsx:archive:完成的变更被归档,它的spec进入openspec/specs/,成为项目的事实来源。

如果想法还不清晰,/opsx:explore可以让你先和智能体一起梳理需求,再创建提案。命令的具体语法可能因你使用的助手而异。

开始SDD时的常见错误

  • 规格写得太多: 40页的spec没人维护。每个功能从一页开始。
  • 写"怎么做"而不是"做什么": "用Redis"属于计划,不属于规格。
  • 从不验证的spec: 没有任何测试或契约来校验,几周内就会过时。
  • 改了代码忘了spec: 这是把SDD变成死文档的错误。

结语

Spec-Driven Development不是官僚流程:它只是先把那些反正都要解释的东西写下来。BDD、DDD、MDE和API-First是四种做法,各有各的核心产物和最擅长对付的风险。当AI智能体写的代码越来越多,规格就成了你确保结果符合需求的最好工具。

你的下一步: 拿项目的下一个功能,写出带三个Given/When/Then场景的spec.md,在要任何一行代码之前先交给你的AI智能体。评论区告诉我效果如何。

常见问题

SDD和TDD是一回事吗? 不是。TDD从开发者写的单元测试出发;SDD从更高层级的规格出发,测试、代码和文档都可以从规格派生。BDD是两者之间的桥梁。

小团队或个人项目能用吗? 能。一个spec.md加一个tasks.md,就足以让AI智能体专注得多地干活,哪怕你是一个人的团队。

四种方法论都要用吗? 不用。按你最大的风险来选:跟客户互相误解(BDD)、业务规则复杂(DDD)、重复代码多(MDE)或集成脆弱(API-First)。

开始需要什么工具? 一个编辑器、Markdown和你喜欢的AI智能体。想要现成的结构,就从OpenSpec开始:一条命令安装,跟你现在用的智能体就能配合。

参考资料

Frequently asked questions

SDD和TDD是一回事吗?

不是。TDD从开发者写的单元测试出发;SDD从更高层级的规格出发,测试、代码和文档都可以从规格派生。BDD是两者之间的桥梁。

小团队或个人项目能用吗?

能。一个spec.md加一个tasks.md,就足以让AI智能体专注得多地干活,哪怕你是一个人的团队。

四种方法论都要用吗?

不用。按你最大的风险来选:跟客户互相误解(BDD)、业务规则复杂(DDD)、重复代码多(MDE)或集成脆弱(API-First)。

开始需要什么工具?

一个编辑器、Markdown和你喜欢的AI智能体。想要现成的结构,就从OpenSpec开始:一条命令安装,跟你现在用的智能体就能配合。

相关文章

继续探索您可能感兴趣的相似内容

合作

我每天在用的工具,社区可以拿到更好的条件。

opencode5 美元免费额度先试用Z.ai首单立减 10%Eneba游戏、正版授权与礼品卡立减 5%
Amazon0 美元 · 我为设备和内容制作买的东西,你不会多花一分钱西班牙美国
含推广链接。你支付的价格不变。查看全部合作
培训项目

准备好将您的想法转化为真实项目了吗?

Transforma是一个帮助您以清晰的方法创建、执行和扩展项目的培训项目。

了解Transforma项目