OpenSpec SDD 規格驅動開發 AI coding Spec-Driven Development Claude Code

OpenSpec 入門:讓 AI 照規格驅動開發(SDD)寫程式

莊政哲 Peter Chuang 2026/11/02 10:43:28
10

前言

大家應該都有遇過,上週叫 AI 改的功能,這週同事跑來問:「這裡為什麼要這樣寫?」你想翻當初的對話,結果早就關掉了。再去問 AI,它也只能看著程式碼重新猜一個理由,當初真正的考量已經沒人知道。

AI 寫程式很快,但對話一關,跟它講好的事就跟著不見了。

這篇用 OpenSpec 來講,怎麼把跟 AI 講好的需求、設計、任務寫成檔案放進 repo,之後誰要查都查得到。

什麼是 OpenSpec?

OpenSpec 是讓 AI 照 SDD(Spec-Driven Development,規格驅動開發)流程做事的工具:動手前先把目標、設計、邊界寫好,做完再對照有沒有落差。

這篇會回答你三個問題:

  1. 為什麼跟 AI 講好的事,過一陣子就沒人說得出來?
  2. OpenSpec 怎麼跑一輪?跑完會留下什麼?
  3. 拿到團隊裡用,三個月後的自己、接手的同事、每個人寫的東西,能不能對得上?

為什麼講好的事會不見?

先假設一個情境。你負責一個日期選擇器,前後請 AI 改了三次:

  • 03/02:「幫我做一個日期選擇器」
  • 05/18:「改成可以選區間,報表要用」
  • 08/11:「鍵盤也要能操作喔」

每次 AI 都很乾脆地回你「好的,我會這樣設計……」,寫完、合併、關掉對話,一切看起來都很順。

直到半年後要再改,你才發現:為什麼要支援區間?鍵盤操作為什麼這樣處理?這些理由只存在當時的對話裡,現在手上只剩程式碼。

這就是 vibe coding 的代價:講個大概就開工,不對再改。做原型很好用,但要長期維護、多人一起改的東西,還是得先講清楚、寫下來。

plan mode 不是也會規劃嗎?

你可能會想說:「現在的 AI 工具都有 plan mode,開工前也會先列計畫,這跟 OpenSpec 有什麼差?」

差在計畫放在哪裡。plan mode 的計畫跟著對話走,對話一關就沒了,更別說拿到 PR 上給同事審,或是做完回頭對照。OpenSpec 則是把計畫寫成檔案放進 repo,跟程式碼一起進 PR、一起留在 git 裡。

而且 OpenSpec 的規格不只寫這次要做什麼,官方是這樣定位它的:

規格存在 git 裡,記錄系統現在該有的行為,是專案的 source of truth。

—— OpenSpec 官方文件

怎麼開始?

先裝 CLI(需要 Node.js 22.12.0 以上),然後在專案裡初始化:

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

init 會幫你建好 openspec/ 資料夾,也會替你選的 AI 工具裝好 /opsx 指令。之後每一輪變更,基本上就是這 4 個指令:

  1. /opsx:explore:想法還模糊時先聊聊,不寫程式
  2. /opsx:propose:把這次的變更寫成 4 份文件
  3. /opsx:apply:照任務清單一項一項實作
  4. /opsx:archive:把這次的需求差異合併回 specs/,變更收進 archive

還有一些進階指令(continue、ff、verify 等)預設沒開,想用的話先跑 openspec config profile 選,再跑 openspec update 套用。

一輪會留下哪些文件?

跑完 /opsx:propose,openspec/changes/<名稱>/ 底下會多出 4 份文件。拿裝潢來比喻會比較好懂:

  • proposal:變更提案,先講好要裝潢哪裡、哪些不動
  • specs:需求跟驗收標準,做完怎樣才算合格
  • design:技術方案,也就是施工圖
  • tasks:實作清單,也就是排工班

只說要裝潢成什麼樣子,問施工圖跟工班怎麼排,都回你「做了就知道」?小心,這是裝潢蟑螂(誤)。很多人叫 AI 寫程式,其實就是請了這種師傅。

那要照什麼順序寫?

specs 和 design 只依賴 proposal,可以同時寫;tasks 要等兩份都完成。依賴只決定「什麼可以開始寫」,寫完不會鎖住,發現問題可以回頭改。

—— OpenSpec 官方文件

也就是說,順序只是讓你知道下一步能寫什麼,不是寫完就不能動。

接下來用「新增深色模式」當例子,一份一份來看。

proposal:先講清楚做什麼、不做什麼

# Proposal: 新增深色模式
## Intent(目的)
## Scope(範圍)
In scope: …
Out of scope: …
## Approach(做法)

這份最重要的是 Out of scope。邊界先畫好,AI 才不會越做越多。

我自己就踩過:只講了要做什麼,沒講哪些不要動,結果 AI 順手把共用元件也改了,來回三輪才改回來。

specs:只寫這次改了什麼

## ADDED Requirements
### Requirement: 深色模式切換
系統 SHALL 提供深色模式切換。

#### Scenario: 切換到深色
- GIVEN 使用者在設定頁
- WHEN 開啟深色模式
- THEN 整個介面改用深色主題

需求用 RFC 2119 的關鍵字(SHALL、MUST)來寫,每條需求底下都附一個驗收情境,寫法借用 BDD 的 Gherkin 語法(GIVEN / WHEN / THEN),做完直接拿來對照就知道有沒有達成。

什麼是 RFC 2119?

RFC 2119 是 IETF 定義規格用詞的文件,規定 MUST、SHALL、SHOULD、MAY 這些字代表多強的要求,例如 MUST/SHALL 是一定要做到,SHOULD 是建議但有理由可以不做。

什麼是 BDD 的 Gherkin?

BDD(Behavior-Driven Development,行為驅動開發)是用「使用者會看到什麼行為」來描述需求的開發方式;Gherkin 是它常用的寫法,用 GIVEN(前提)、WHEN(動作)、THEN(結果)三段描述一個情境。

要注意的是,這裡的 specs 不是整份重寫:

變更裡的 specs 只寫差異(delta spec),用 ADDED、MODIFIED、REMOVED 標示這次動了哪些需求。

—— OpenSpec 官方文件

三種標記分別是:

  • ADDED:新增需求
  • MODIFIED:取代原本的需求
  • REMOVED:刪掉需求

把它想成 git diff 就對了:平常只看改了哪幾行,等 archive 合併回去才是完整的規格。

design:記下為什麼這樣做

## Technical Approach
## Architecture Decisions
### Decision: 用 CSS 變數,不用兩套樣式表(附理由)
## Data Flow
## File Changes
- src/theme.ts (new)
- src/App.vue (modified)

裡面最常被翻出來看的是 Decision。之後有人問「怎麼不用兩套樣式表?」,答案就寫在這裡。

tasks:拆到知道怎麼驗收

只寫「做深色模式」「補測試」是不夠的,這樣不管是你還是 AI,都不知道做到哪裡才算完成。要寫成這樣:

## 1. 主題設定
- [ ] 1.1 新增深色主題 CSS 變數
  (驗證:切換後背景色改變)
- [ ] 1.2 補上單元測試
  (驗證:測試涵蓋淺色、深色兩種狀態並通過)

## 2. 設定頁
- [ ] 2.1 加上切換開關
  (驗證:點開關後主題立即切換,重新整理後仍保留)
- [ ] 2.2 補上元件測試
  (驗證:測試涵蓋切換和重新整理後保留,並通過)

每一項都寫上怎麼驗證,每做完一組就順手補測試,不要全部堆到最後。

簡單整理一下:proposal 畫邊界、specs 定驗收、design 留理由、tasks 拆到能驗證。

三個月後,自己還記得嗎?

回到開頭那個日期選擇器。如果每次修改都走 OpenSpec,archive 裡會長這樣:

openspec/changes/archive/
├── 2026-03-02-add-date-picker/          第一版:基本日期選擇
├── 2026-05-18-add-date-range/           加上區間選擇(為什麼:報表需求)
└── 2026-08-11-modify-date-picker-a11y/  改成可用鍵盤操作(為什麼:無障礙稽核)

每個資料夾裡都留著當時的 proposal 跟 design,改了什麼、為什麼改都查得到。如果是改既有的需求,就用 MODIFIED,順便註明原本是什麼。

下次要再動這個元件,不用再猜「當初怎麼會這樣設計」,打開 archive 從上往下看一遍就知道了。對話會不見,但 archive 會把每一版的決定留下來。

協作時,同事看得懂嗎?

假設同事要接手這個日期選擇器,想知道為什麼要支援區間選擇。

沒有 OpenSpec 的話,大概會是這樣:「欸,你當初怎麼設計的?」→ 約時間 → 口頭解釋一輪 → 過陣子又忘了。

有 OpenSpec 的話,同事自己打開 2026-05-18-add-date-range/ 的 proposal 跟 design,答案就在裡面。懶得翻資料夾,也可以直接用 CLI 查:

openspec list          # 看有哪些變更
openspec show <名稱>   # 直接看內容

審 PR 的順序也可以換一下:先看 proposal,再看需求差異,最後才看程式碼。方向如果不對,看 proposal 的時候就能講,不用等 300 行程式碼都寫完了才發現。

每個人寫的,都照同一套嗎?

每個人各寫各的筆記,格式很快就亂掉了。OpenSpec 的文件結構本來就是固定的,剩下的交給兩個東西:格式讓 validate 檢查,內容規則寫進 config。

validate 擋格式

openspec validate --all --strict
# ✗ change 沒有任何需求差異
# ✗ MODIFIED 對不到現有規格

它會擋什麼?

沒有任何需求差異的 change 不會通過;MODIFIED 的需求要對得到現有規格。

—— OpenSpec 官方文件

建議直接加進 CI,沒過的 PR 就不合併。

config 告訴 AI 團隊的規矩

# openspec/config.yaml
context: |
  技術棧:TypeScript、Vue
rules:
  proposal:
    - 包含回滾計畫
  • context:每份文件生成時都會帶進去
  • rules:只套用在指定的文件上,像上面就是要求每份 proposal 都要寫回滾計畫

如果還想多加一道關卡,也可以 fork 內建的流程。官方有個範例,在 design 後面多一份 review 審查清單,tasks 要等 review 完才能寫:

openspec schema fork spec-driven with-review

團隊實際跑一輪長怎樣?

一個變更就是一個分支、一個 PR:

  1. 開分支:git switch -c add-dark-mode
  2. 想法還很模糊的話,先用 /opsx:explore 聊清楚(可跳過)
  3. 用 /opsx:propose 寫出計畫
  4. 寫程式之前,自己先把計畫讀過一遍
  5. 清空對話或開新對話,apply 會從第一個還沒勾的項目接著做
  6. 用 /opsx:apply 照計畫實作,文件跟程式碼一起改
  7. commit、開 PR,CI 跑 openspec validate --all --strict
  8. 同事審查:先看 proposal,再看差異跟程式碼
  9. 合併後跑 /opsx:archive,再補一個小 commit

為什麼要清空對話?出考卷的人自己寫考卷,當然一百分。剛寫完計畫的 AI 腦袋裡還記得很多沒寫進文件的前提,換一個乾淨的對話,它只能看文件做事,計畫哪裡沒寫清楚,馬上就會露餡。

要提醒一下,官方有特別講:

OpenSpec 不碰 git:不會幫你 commit、開分支、push 或 pull。

—— OpenSpec 官方文件

所以這些還是要你自己來。另外 validate 只看文件格式,不會去比對程式碼有沒有照規格寫。

OpenSpec 做不到什麼?

講了這麼多,它也不是萬能的。

validate 只擋格式,config 只給提示。

—— OpenSpec 官方文件

內容到底對不對,還是要有人看。AI 寫的 proposal 如果沒人審,就只是多一份文件而已。

「那改個錯字也要開 change 嗎?」不用,殺雞焉用牛刀。官方的說法是:

小改動(錯字、樣式)不必開 change,流程的成本要跟改動大小相稱。

—— OpenSpec 官方文件

OpenSpec 留給需要講清楚「為什麼」的變更就好。

總結

  • 跟 AI 的對話會關,plan mode 的計畫也會跟著消失;想留下來,就要寫成檔案放進 repo。
  • 一輪變更 4 個指令:explore → propose → apply → archive,留下 proposal、specs、design、tasks 四份文件。
  • archive 把每一版的理由留下來,三個月後的自己查得到;文件跟程式碼在同一個 PR,同事也看得懂。
  • validate 擋格式、config 定規矩,大家寫的照同一套;不過內容對不對,還是要有人審。

看完不妨挑一張需求單,實際跑一輪 propose → apply → archive 試試看。

參考

  1. OpenSpec
莊政哲 Peter Chuang