文章封面圖: 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計畫