OpenSpec 使用教學手冊

版本:3.1
更新日期:2026-03-23
適用版本:OpenSpec v1.2.0(含 Profiles、OPSX 工作流程、動態指令架構與語義規格同步)
適用對象:新進軟體工程師、系統分析師、尚未接觸過 SDD 或 OpenSpec 的同仁
官方網站openspec.dev


目錄


前言

為什麼需要這份手冊?

在 AI 輔助開發的時代,許多團隊開始使用 GitHub Copilot、Claude、ChatGPT 等工具來加速開發。然而,AI 助手在沒有明確規格的情況下,容易產生不符合需求的程式碼,或是理解偏差導致返工。

OpenSpec 是一套 Spec-Driven Development(SDD,規格驅動開發) 的方法論與工具,它讓「規格」成為開發的唯一真實來源(Single Source of Truth),確保人類與 AI 在同一個頁面上。OpenSpec 是目前最受歡迎的規格框架(GitHub ★ 33.2k、MIT 授權),支援 24 個 AI 編程助手(包含 Claude Code、GitHub Copilot、Cursor、Windsurf、Gemini CLI、Pi、Kiro 等),並提供靈活的 OPSX 工作流程、Profiles 設定檔系統動態指令架構(Dynamic Instructions),以及語義規格同步(Semantic Spec Syncing),讓開發者可以自由迭代而非被瀑布式流程鎖住。

OpenSpec 的核心哲學:

  • 流動而非剛性(fluid not rigid)
  • 迭代而非瀑布(iterative not waterfall)
  • 簡單而非複雜(easy not complex)
  • 為既有專案而建(built for brownfield not just greenfield)
  • 可從個人專案擴展至企業級(scalable from personal projects to enterprises)

💡 v1.2.0 新功能:新增 Profiles 系統core / custom)、/opsx:propose 一鍵提案指令AI 工具自動偵測、以及 Pi 與 Kiro 工具支援。

本手冊的目標

  1. 讓新進同仁理解 為什麼要用 OpenSpec
  2. 學會 如何在日常專案中正確使用 OpenSpec
  3. 掌握 如何與 AI 協作產出高品質、可落地的系統規格

閱讀建議

  • 第一次接觸:建議從頭到尾閱讀,搭配實作練習
  • 已有經驗:可直接跳到第五章的實作範例
  • 快速查閱:使用附錄的檢查清單

第一章:OpenSpec 是什麼?

1.1 為什麼會有 OpenSpec

傳統開發的痛點

在傳統開發流程中,需求往往以下列形式存在:

  • 📧 Email 往來中的討論
  • 💬 會議記錄中的口頭確認
  • 📝 Word 文件中的需求規格書
  • 🗒️ 便利貼或白板上的筆記

這些分散的資訊導致:

問題影響
需求散落各處開發時難以追溯完整需求
版本不一致不同人看到的需求可能不同
AI 無法理解AI 助手無法有效利用這些資訊
變更難追蹤需求變更後難以確認影響範圍

AI 時代的新挑戰

當我們使用 AI 助手開發時,問題更加明顯:

❌ 傳統方式:需求在聊天歷史中
You: 幫我寫一個用戶登入功能
AI: *產生一段程式碼*
You: 不對,我要的是用 JWT
AI: *重新產生*
You: 還要支援 2FA
AI: *再次重新產生*
...反覆修改,最終結果可能仍然不符合需求

OpenSpec 的解決方案

OpenSpec 透過結構化的規格文件,在實作前鎖定需求:

✅ OpenSpec 方式:規格先行
1. 撰寫 Spec → 明確定義「要做什麼」
2. AI 與人共同審閱 → 確保理解一致
3. 依據 Spec 實作 → 產出符合預期的程式碼

💡 銀行系統實務:在金融業,需求變更必須經過嚴格審批。OpenSpec 的規格版本控管機制,正好符合金控稽核對於「需求追溯」的要求。


1.2 與傳統 PRD / SRS / 設計文件的差異

傳統文件類型

文件類型全名用途
PRDProduct Requirements Document產品需求文件,描述商業目標與功能
SRSSoftware Requirements Specification軟體需求規格書,詳細的技術需求
SDDSoftware Design Document軟體設計文件,系統架構與設計

OpenSpec 的不同之處

graph LR
    subgraph 傳統方式
        A[PRD] --> B[SRS]
        B --> C[SDD]
        C --> D[Code]
        D --> E[Test]
    end
    
    subgraph OpenSpec 方式
        F[Spec<br/>規格] --> G[Proposal<br/>變更提案]
        G --> H[Tasks<br/>工作項目]
        H --> I[Implementation<br/>實作]
        I --> J[Archive<br/>歸檔更新 Spec]
    end
比較項目傳統 PRD/SRSOpenSpec
格式Word、Confluence、Wiki結構化 Markdown
版本控管手動管理版本號Git 版本控管
AI 可讀性低(自然語言散文)高(結構化格式)
變更追蹤透過文件對比透過 Delta 差異檔
與程式碼關聯分離同一 Repository
即時性可能過時持續更新(活文件)
工作流程線性階段式OPSX 流動式迭代(含 Profiles)
AI 工具支援24 個 AI 助手原生整合
指令架構靜態提示詞動態指令(Context + Rules + Template)
規格同步手動合併語義規格同步(ADDED/MODIFIED/REMOVED/RENAMED)

關鍵差異說明

  1. AI 可理解:OpenSpec 的格式讓 AI 能精確理解需求
  2. 與程式碼共存:Spec 放在專案中,與程式碼一起版本控管
  3. 增量更新:透過「變更(Changes)」機制,追蹤每次修改
  4. 語義同步:Delta Spec 使用 ADDED/MODIFIED/REMOVED/RENAMED 語義標記,而非脚本式文字合併

與其他 SDD 工具的比較

比較項目OpenSpecspec-kit (GitHub)Kiro (AWS)
設計理念輕量、靈活迭代嚴謹、階段門控IDE 整合
工作流程流動式,不鎖定階段剛性階段門固定流程
AI 工具支援24+ 工具有限僅 Claude
IDE 要求無(任何 IDE)鎖定 Kiro IDE
既有專案支援✅ 強(brownfield-first)偏向新專案偏向新專案
自訂 Schema✅ 可自訂工作流程
Profiles✅ core / custom
安裝npm/pnpm/yarn/bun/nixPythonIDE 內建

⚠️ 注意事項:OpenSpec 不是要取代所有文件,而是作為「開發期間的規格真實來源」。高層次的商業需求文件(如 BRD)仍然需要。


1.3 OpenSpec 在 SDD 中扮演的角色

SDD(Spec-Driven Development)概述

SDD 是一種開發方法論,核心理念是:

「先有規格,再有程式碼」

flowchart TD
    A[需求想法] --> B[撰寫 Spec]
    B --> C{Spec 審核}
    C -->|通過| D[建立 Tasks]
    C -->|修改| B
    D --> E[AI/人員 實作]
    E --> F[驗證符合 Spec]
    F -->|通過| G[歸檔 Spec]
    F -->|不符| E
    G --> H[Spec 成為系統文件]

OpenSpec 在 SDD 中的定位

OpenSpec 是實踐 SDD 的工具與框架

角色說明
規格管理者管理所有 Spec 的結構與版本
變更追蹤者追蹤每個功能變更的提案、任務、實作
AI 指導者提供 AI 助手明確的上下文與指令
文件保管者歸檔完成的變更,維護系統文件

目錄結構

OpenSpec 初始化後會建立以下結構:

專案根目錄/
├── openspec/
│   ├── config.yaml             # 專案配置(schema、context、rules)
│   ├── schemas/                # 自定義工作流程 schema(可選)
│   ├── specs/                  # 當前的規格(真實來源)
│   │   ├── auth/
│   │   │   └── spec.md         # 認證模組規格
│   │   └── user/
│   │       └── spec.md         # 用戶模組規格
│   ├── changes/                # 進行中的變更
│   │   └── add-2fa/            # 某個功能變更
│   │       ├── .openspec.yaml  # 變更的 schema 設定
│   │       ├── proposal.md     # 變更提案
│   │       ├── design.md       # 技術設計決策
│   │       ├── tasks.md        # 工作項目
│   │       └── specs/          # 規格差異(Delta)
│   └── changes/archive/        # 已完成的變更
│
│   # 以下為 AI 工具整合檔案(依工具而異,openspec init 自動產生)
├── .claude/                    # Claude Code 整合
│   ├── skills/openspec-*/SKILL.md   # 技能檔(動態指令)
│   └── commands/opsx/              # OPSX 指令檔
├── .cursor/                    # Cursor 整合
│   ├── skills/openspec-*/SKILL.md
│   └── commands/opsx-*.md
├── .github/                    # GitHub Copilot 整合
│   ├── skills/openspec-*/SKILL.md
│   └── prompts/opsx-*.prompt.md
├── .windsurf/                  # Windsurf 整合
│   ├── skills/openspec-*/SKILL.md
│   └── workflows/opsx-*.md
└── .gemini/                    # Gemini CLI 整合
    ├── skills/openspec-*/SKILL.md
    └── commands/opsx/*.toml

💡 實務建議:建議在專案初期就導入 OpenSpec,這樣可以從第一天就建立完整的規格歷史。

ℹ️ 備註config.yaml 取代了舊版的 project.md,提供更結構化的專案配置方式。每個 AI 工具的檔案位置依工具而異,例如 Claude Code 使用 .claude/skills/ + .claude/commands/,Cursor 使用 .cursor/skills/ + .cursor/commands/,GitHub Copilot 使用 .github/skills/ + .github/prompts/,Windsurf 使用 .windsurf/skills/ + .windsurf/workflows/ 等。執行 openspec init 時會自動偵測你專案中已存在的 AI 工具目錄並預先選取。在 core profile 下產生 4 個指令檔(propose、explore、apply、archive),在 custom profile 下可產生最多 11 個指令檔。

第二章:Spec-Driven Development(SDD)核心概念

2.1 規格優先(Spec First)

什麼是「規格優先」?

規格優先意味著在寫任何程式碼之前,先完成並確認規格。

sequenceDiagram
    participant PM as 產品經理
    participant SA as 系統分析師
    participant AI as AI 助手
    participant Dev as 開發人員

    PM->>SA: 提出需求想法
    SA->>SA: 撰寫 Spec
    SA->>AI: 請 AI 審閱 Spec
    AI->>SA: 提出問題與建議
    SA->>SA: 修正 Spec
    SA->>PM: Spec 確認
    PM->>SA: 核准 Spec
    SA->>Dev: 依據 Spec 開發
    Dev->>AI: 請 AI 依 Spec 產生程式碼
    AI->>Dev: 產生符合 Spec 的程式碼

為什麼要「規格優先」?

原因說明
減少返工事先確認需求,避免開發後才發現理解錯誤
提高 AI 效能AI 有明確規格可依循,產出更準確
便於審核先審規格再審程式碼,效率更高
降低溝通成本所有人看同一份規格,減少誤解

實務範例

❌ 不好的做法(Code First)

開發人員:我先寫一版看看
(寫完後)
PM:這不是我要的
開發人員:那你要什麼?
PM:要能支援多種付款方式
開發人員:好,我改
(改完後)
PM:不對,每種付款方式要有不同的手續費計算
開發人員:😫

✅ 好的做法(Spec First)

系統分析師:我先寫規格

## 付款模組規格

### Requirement: 多元付款支援
系統 SHALL 支援以下付款方式:
- 信用卡
- 銀行轉帳
- 電子錢包

### Requirement: 手續費計算
每種付款方式 SHALL 有獨立的手續費計算規則

#### Scenario: 信用卡付款
- GIVEN 付款方式為信用卡
- WHEN 交易金額為 1000 元
- THEN 手續費為 25 元(2.5%)

(PM 審閱後確認,開發人員依規格開發)

💡 銀行系統實務:金融業的每個功能變更都需要經過「需求確認 → 設計審查 → 程式審查」流程。Spec First 的做法正好對應這個流程,讓需求確認更加結構化。


2.2 規格即合約(Spec as Contract)

什麼是「規格即合約」?

Spec 不只是文件,而是開發團隊與 AI 之間的合約

  • 對人類:這份 Spec 描述了系統應該做什麼
  • 對 AI:這份 Spec 定義了你應該產生什麼樣的程式碼
graph TB
    subgraph 合約內容
        A[輸入條件<br/>GIVEN/WHEN] --> B[預期行為<br/>THEN]
        B --> C[驗收標準<br/>Acceptance Criteria]
    end
    
    subgraph 約束力
        D[人類<br/>依規格審核] 
        E[AI<br/>依規格產出]
        F[測試<br/>依規格驗證]
    end
    
    合約內容 --> D
    合約內容 --> E
    合約內容 --> F

合約的關鍵要素

要素說明範例
SHALL必須實作的功能系統 SHALL 驗證密碼長度
MUST強制要求密碼 MUST 至少 8 個字元
SHOULD建議實作密碼 SHOULD 包含特殊字元
MAY可選功能系統 MAY 提供密碼強度提示

規格合約範例

# 用戶認證規格

## Purpose
管理用戶身份驗證與會話管理

## Requirements

### Requirement: 密碼驗證
系統 SHALL 在用戶登入時驗證密碼

#### Scenario: 密碼正確
- GIVEN 用戶帳號存在且為啟用狀態
- WHEN 用戶輸入正確的帳號密碼
- THEN 系統核發 JWT Token
- AND Token 有效期為 30 分鐘

#### Scenario: 密碼錯誤
- GIVEN 用戶帳號存在
- WHEN 用戶輸入錯誤密碼
- THEN 系統回傳 401 Unauthorized
- AND 記錄失敗登入次數

#### Scenario: 帳號鎖定
- GIVEN 用戶連續 5 次登入失敗
- WHEN 用戶再次嘗試登入
- THEN 系統回傳帳號已鎖定訊息
- AND 帳號鎖定 15 分鐘

⚠️ 注意事項:規格中的情境(Scenario)應該要能直接轉換為測試案例。如果無法測試,代表規格不夠具體。


2.3 規格可被 AI 理解與執行

為什麼 AI 可讀性很重要?

AI 助手的能力取決於提供給它的上下文(Context)。結構化的規格讓 AI 能:

  1. 理解需求意圖:知道要實作什麼功能
  2. 遵循設計約束:了解系統的技術限制
  3. 產生一致的程式碼:依據統一的規格格式
flowchart LR
    subgraph 輸入
        A[模糊的聊天訊息]
        B[結構化的 Spec]
    end
    
    subgraph AI 處理
        C[AI 助手]
    end
    
    subgraph 輸出
        D[不確定的程式碼]
        E[符合規格的程式碼]
    end
    
    A --> C --> D
    B --> C --> E
    
    style A fill:#ffcccc
    style D fill:#ffcccc
    style B fill:#ccffcc
    style E fill:#ccffcc

OpenSpec 如何提升 AI 可讀性

特性說明
標準格式使用固定的 Markdown 結構
關鍵字標記SHALL、MUST、GIVEN、WHEN、THEN
情境導向每個需求都有具體的情境描述
檔案組織清晰的目錄結構,便於 AI 定位

與 AI 對話的 Prompt 範例

建立新 Spec 的 Prompt

請依據 OpenSpec 格式,為「用戶密碼重設」功能建立 Spec。

需求摘要:
- 用戶透過 Email 申請密碼重設
- 系統發送重設連結,有效期 24 小時
- 新密碼不能與最近 5 組相同

請產出:
1. proposal.md - 變更提案
2. specs/auth/spec.md - 規格差異(Delta)
3. tasks.md - 工作項目

審閱 Spec 的 Prompt

請審閱以下 Spec,檢查:
1. 是否有遺漏的情境(邊界條件、錯誤處理)
2. 是否有模糊不清的描述
3. 是否符合 OpenSpec 格式規範

[貼上 Spec 內容]

💡 實務建議:在與 AI 對話時,明確告訴它要遵循 OpenSpec 格式。這樣 AI 產出的內容會更符合團隊規範。


第二章小結

核心概念重點
規格優先先寫 Spec,再寫 Code
規格即合約Spec 是人與 AI 共同遵守的約定
AI 可讀結構化格式讓 AI 更能理解與執行

本章練習

  1. 找一個你最近開發的功能,嘗試用「GIVEN-WHEN-THEN」格式描述一個情境
  2. 思考:這個功能如果有 Spec,開發過程會有什麼不同?

第三章:OpenSpec 文件結構說明

3.1 常見 Spec 類型

OpenSpec 支援多種規格類型,適用於不同的開發階段與需求層級:

graph TB
    subgraph 規格層級
        A[Product Spec<br/>產品規格] --> B[System Spec<br/>系統規格]
        B --> C[API Spec<br/>介面規格]
        B --> D[Data Spec<br/>資料規格]
    end
    
    subgraph 輔助文件
        E[Proposal<br/>變更提案]
        F[Tasks<br/>工作項目]
        G[Design<br/>設計決策]
    end
    
    A -.-> E
    B -.-> E
    C -.-> E

主要 Spec 類型

類型用途適用場景
Product Spec描述產品功能與商業價值新功能規劃、產品討論
System Spec描述系統行為與業務規則系統分析、功能設計
API Spec描述介面契約與資料格式API 設計、前後端整合
Data Spec描述資料模型與關聯資料庫設計、資料流

輔助文件類型

類型檔名用途
Proposalproposal.md說明「為什麼要做這個變更」
Taskstasks.md列出「需要完成的工作項目」
Designdesign.md記錄「技術決策與架構選擇」
Deltaspecs/*/spec.md描述「規格的差異與變更」

3.2 每一種 Spec 的用途與撰寫原則

Product Spec(產品規格)

用途:從商業角度描述功能需求

撰寫原則

  • 聚焦於「使用者能做什麼」
  • 包含商業價值說明
  • 避免技術細節

範例

# 密碼重設功能 - Product Spec

## 商業價值
減少客服處理忘記密碼案件的人力,提升用戶自助服務體驗

## 功能描述
用戶可透過 Email 自助重設密碼,無需聯繫客服

## 使用者故事
作為一個忘記密碼的用戶
我想要透過 Email 重設密碼
以便能夠重新登入系統

## 成功指標
- 密碼重設成功率 > 95%
- 平均重設時間 < 3 分鐘
- 客服密碼重設案件減少 50%

System Spec(系統規格)

用途:描述系統應有的行為與規則

撰寫原則

  • 使用 SHALL/MUST 明確要求
  • 包含所有情境(正常、異常、邊界)
  • 可直接作為測試依據

範例

# 密碼重設 - System Spec

## Purpose
提供用戶透過 Email 自助重設密碼的功能

## Requirements

### Requirement: 申請密碼重設
系統 SHALL 允許用戶申請密碼重設

#### Scenario: 成功申請
- GIVEN 用戶帳號已註冊且為啟用狀態
- WHEN 用戶輸入正確的 Email 申請重設
- THEN 系統發送重設連結至該 Email
- AND 連結有效期為 24 小時

#### Scenario: 帳號不存在
- GIVEN Email 未在系統中註冊
- WHEN 用戶輸入該 Email 申請重設
- THEN 系統仍顯示「重設連結已發送」訊息
- AND 不實際發送任何郵件
- NOTE 此設計為防止帳號探測攻擊

#### Scenario: 重複申請
- GIVEN 用戶已有未過期的重設連結
- WHEN 用戶再次申請重設
- THEN 系統發送新的重設連結
- AND 舊連結立即失效

API Spec(介面規格)

用途:定義 API 的輸入、輸出與錯誤處理

撰寫原則

  • 明確定義 Request/Response 格式
  • 列出所有可能的狀態碼
  • 包含欄位驗證規則

範例

API Spec 範例:密碼重設 API

POST /api/v1/auth/password-reset/request

Description:用戶申請密碼重設

Request Body

{
  "email": "user@example.com"
}

Request Validation

欄位類型必填驗證規則
emailstringYes有效 Email 格式

Response - Success (200)

{
  "message": "若帳號存在,重設連結已發送至您的信箱",
  "requestId": "req_abc123"
}

Response - Error (400)

{
  "error": "INVALID_EMAIL_FORMAT",
  "message": "Email 格式不正確"
}

Response - Error (429)

{
  "error": "TOO_MANY_REQUESTS",
  "message": "請求過於頻繁,請稍後再試",
  "retryAfter": 60
}

Data Spec(資料規格)

用途:定義資料結構與關聯

範例

# 密碼重設 - Data Spec

## Entity: PasswordResetToken

### Description
儲存密碼重設令牌

### Fields
| 欄位 | 類型 | 說明 | 限制 |
|------|------|------|------|
| id | UUID | 主鍵 | PK |
| userId | UUID | 關聯用戶 | FK → User.id |
| token | VARCHAR(64) | 重設令牌 | UNIQUE, NOT NULL |
| createdAt | TIMESTAMP | 建立時間 | NOT NULL |
| expiresAt | TIMESTAMP | 過期時間 | NOT NULL |
| usedAt | TIMESTAMP | 使用時間 | NULLABLE |

### Indexes
- UNIQUE INDEX on (token)
- INDEX on (userId, createdAt)
- INDEX on (expiresAt) - 用於清理過期資料

### Retention
- 已使用或過期的 Token 保留 7 天後自動刪除

💡 銀行系統實務:金融業的 API 規格特別重視錯誤處理與安全性。建議在 API Spec 中明確定義所有可能的錯誤碼,並說明是否需要記錄審計日誌。


3.3 好的 Spec 與壞的 Spec 範例比較

比較表

項目壞的 Spec好的 Spec
清晰度模糊、籠統具體、明確
完整性只有正常情境包含異常與邊界
可測試性無法寫測試每個情境可測試
格式一致格式混亂遵循標準格式

壞的 Spec 範例 ❌

# 登入功能

用戶可以登入系統,登入成功後可以使用各種功能。
如果密碼錯誤要給錯誤訊息。
記得要安全一點。

問題

  • ❌ 沒有具體的驗收條件
  • ❌ 「安全一點」太模糊
  • ❌ 沒有定義什麼是「登入成功」
  • ❌ 沒有考慮邊界情況(如:帳號鎖定)

好的 Spec 範例 ✅

# 用戶登入 - System Spec

## Purpose
驗證用戶身份並建立會話

## Requirements

### Requirement: 帳號密碼驗證
系統 SHALL 驗證用戶提供的帳號密碼

#### Scenario: 登入成功
- GIVEN 帳號存在且密碼正確
- AND 帳號狀態為「啟用」
- WHEN 用戶提交登入請求
- THEN 系統回傳 JWT Token
- AND Token 包含 userId 與 role
- AND 記錄登入成功審計日誌

#### Scenario: 密碼錯誤
- GIVEN 帳號存在但密碼錯誤
- WHEN 用戶提交登入請求
- THEN 系統回傳 401 Unauthorized
- AND 回應訊息為「帳號或密碼錯誤」
- AND 增加失敗登入次數
- AND 記錄登入失敗審計日誌

#### Scenario: 帳號不存在
- GIVEN 帳號不存在
- WHEN 用戶提交登入請求
- THEN 系統回傳 401 Unauthorized
- AND 回應訊息為「帳號或密碼錯誤」
- NOTE 訊息與密碼錯誤相同,防止帳號探測

#### Scenario: 帳號已鎖定
- GIVEN 帳號連續失敗 5 次登入
- WHEN 用戶嘗試登入
- THEN 系統回傳 403 Forbidden
- AND 回應訊息包含鎖定解除時間

### Requirement: 暴力破解防護
系統 MUST 防止暴力破解攻擊

#### Scenario: 帳號鎖定機制
- GIVEN 同一帳號連續 5 次登入失敗
- WHEN 失敗次數達到閾值
- THEN 帳號鎖定 15 分鐘
- AND 發送異常登入通知 Email

#### Scenario: IP 限制
- GIVEN 同一 IP 在 1 分鐘內嘗試 10 次登入
- WHEN 達到限制
- THEN 該 IP 被暫時封鎖 5 分鐘

## Security Considerations
- 密碼不得以明文傳輸或儲存
- 所有登入請求 MUST 透過 HTTPS
- Token 有效期不得超過 30 分鐘
- 支援 Refresh Token 機制延長會話

優點

  • ✅ 每個情境都有明確的前提、動作、結果
  • ✅ 包含正常、異常、邊界情境
  • ✅ 考慮安全性需求
  • ✅ 可以直接轉換為測試案例
  • ✅ 使用標準關鍵字(SHALL、MUST、GIVEN、WHEN、THEN)

第三章小結

重點說明
多種 Spec 類型Product、System、API、Data Spec 各有用途
標準格式使用固定的格式與關鍵字
完整情境涵蓋正常、異常、邊界條件
可測試性每個情境都能轉換為測試

本章練習

  1. 選擇一個你熟悉的功能,分別用 Product Spec 和 System Spec 的格式描述
  2. 檢查你的 Spec 是否包含了異常情境

第四章:使用 OpenSpec 的標準工作流程

4.1 從需求想法到 Spec

完整工作流程

flowchart TD
    A[需求想法] --> B[建立變更提案<br/>Proposal]
    B --> C[撰寫規格差異<br/>Spec Delta]
    C --> D[定義工作項目<br/>Tasks]
    D --> E{審核}
    E -->|通過| F[實作]
    E -->|修改| C
    F --> G{驗證}
    G -->|通過| H[歸檔<br/>Archive]
    G -->|不符| F
    H --> I[更新主規格<br/>Source of Truth]

Step 1: 建立變更提案(Proposal)

當收到新需求時,首先建立變更提案:

使用 OPSX 指令(推薦)

# 建立新變更(AI 會引導你填寫細節)
You: /opsx:new add-2fa

# 或者一次快速產生所有規劃文件
You: /opsx:ff add-2fa

CLI 方式

# 如果尚未初始化
openspec init

# 建立新變更
openspec new change "add-2fa"

與 AI 對話方式

You: 建立一個 OpenSpec 變更提案,功能是「新增用戶雙因素認證」

AI: 我將建立 OpenSpec 變更提案...
    *建立 openspec/changes/add-2fa/ 目錄*
    *建立 proposal.md、tasks.md、specs/auth/spec.md*

Proposal 內容範例

# 變更提案:新增雙因素認證

## 變更編號
CHG-2024-001

## 變更摘要
新增基於 TOTP 的雙因素認證(2FA),提升帳戶安全性

## 變更原因
- 符合金管會資安規範要求
- 降低帳戶被盜風險
- 客戶反映需要更高安全性

## 影響範圍
- 用戶認證模組
- 用戶設定頁面
- 登入 API

## 預計完成時間
2 週

## 風險評估
| 風險 | 機率 | 影響 | 緩解措施 |
|------|------|------|---------|
| 用戶不會設定 | 中 | 中 | 提供圖文教學 |
| 手機遺失 | 低 | 高 | 提供備用碼機制 |

Step 2: 撰寫規格差異(Spec Delta)

Spec Delta 描述「這次變更會如何改變現有規格」:

# Delta for Auth

## ADDED Requirements

### Requirement: 雙因素認證設定
系統 SHALL 允許用戶啟用雙因素認證

#### Scenario: 成功啟用 2FA
- GIVEN 用戶已登入
- WHEN 用戶掃描 QR Code 並輸入驗證碼
- THEN 系統啟用該用戶的 2FA
- AND 產生並顯示 10 組備用碼

### Requirement: 雙因素認證驗證
系統 SHALL 在啟用 2FA 的用戶登入時要求驗證

#### Scenario: 2FA 驗證成功
- GIVEN 用戶已啟用 2FA 且密碼驗證通過
- WHEN 用戶輸入正確的 TOTP 碼
- THEN 系統核發 JWT Token

#### Scenario: 使用備用碼
- GIVEN 用戶無法使用 TOTP App
- WHEN 用戶輸入有效的備用碼
- THEN 系統核發 JWT Token
- AND 該備用碼標記為已使用

## MODIFIED Requirements

### Requirement: 帳號密碼驗證(原有)
*修改說明:密碼驗證通過後,需檢查是否啟用 2FA*

#### Scenario: 登入成功(已修改)
- GIVEN 帳號存在且密碼正確
- AND 帳號狀態為「啟用」
- WHEN 用戶提交登入請求
- THEN 若未啟用 2FA:回傳 JWT Token
- OR 若已啟用 2FA:回傳 2FA 挑戰,等待驗證碼

Step 3: 定義工作項目(Tasks)

將規格拆解為可執行的工作項目:

# Tasks for add-2fa

## 1. 資料庫設計
- [ ] 1.1 建立 user_2fa_settings 表
- [ ] 1.2 建立 backup_codes 表
- [ ] 1.3 修改 users 表,新增 2fa_enabled 欄位

## 2. 後端實作
- [ ] 2.1 建立 TOTP 產生器服務
- [ ] 2.2 實作 2FA 設定 API(GET /api/v1/user/2fa/setup)
- [ ] 2.3 實作 2FA 啟用 API(POST /api/v1/user/2fa/enable)
- [ ] 2.4 實作 2FA 驗證 API(POST /api/v1/auth/2fa/verify)
- [ ] 2.5 修改登入流程,加入 2FA 檢查
- [ ] 2.6 實作備用碼產生與驗證

## 3. 前端實作
- [ ] 3.1 建立 2FA 設定頁面
- [ ] 3.2 建立 QR Code 掃描元件
- [ ] 3.3 建立 2FA 驗證輸入畫面
- [ ] 3.4 建立備用碼顯示與管理頁面

## 4. 測試
- [ ] 4.1 單元測試:TOTP 產生器
- [ ] 4.2 整合測試:2FA 設定流程
- [ ] 4.3 整合測試:登入 + 2FA 驗證流程
- [ ] 4.4 E2E 測試:完整用戶流程

## 5. 文件與部署
- [ ] 5.1 更新 API 文件
- [ ] 5.2 撰寫用戶操作手冊
- [ ] 5.3 準備部署腳本與資料庫遷移

4.2 OPSX 工作流程與 Profiles 系統(v1.2.0)

💡 重要更新:OpenSpec v1.2.0 引入了 Profiles 系統/opsx:propose 一鍵提案指令,大幅簡化了預設工作流程。以下是你需要了解的核心改變。

Profiles 設定檔系統(v1.2.0 新功能)

OpenSpec v1.2.0 新增了 Profiles 概念,讓你控制安裝哪些工作流程指令:

Profile包含指令適用情境
core(預設)proposeexploreapplyarchive大多數場景,簡單快速
custom可從全部 11 個指令中自由選取需要精細控制的進階使用者

設定 Profile

# 互動式設定
openspec config profile

# 快速切換為 core(預設)
openspec config profile core

# 套用至專案
openspec update

💡 建議:初次使用建議先用 core profile,熟悉後再視需要切換至 custom 以啟用更多指令。

從舊版到新版的轉變

graph LR
    subgraph 舊版工作流程
        A1["/openspec:proposal"] --> A2["/openspec:apply"]
        A2 --> A3["/openspec:archive"]
    end

    subgraph "v1.2.0 Core 預設流程"
        B1["/opsx:propose"] --> B2["/opsx:apply"]
        B2 --> B3["/opsx:archive"]
    end

    subgraph "v1.2.0 Expanded 擴展流程"
        C1["/opsx:explore"] --> C2["/opsx:new"]
        C2 --> C3["/opsx:continue<br/>或 /opsx:ff"]
        C3 --> C4["/opsx:apply"]
        C4 --> C5["/opsx:verify"]
        C5 --> C6["/opsx:archive"]
    end

核心理念差異

舊版OPSX 新版
線性階段門(Phase Gates)流動式動作(Fluid Actions)
一次建立所有文件/opsx:propose 一鍵產生 或 逐步建立
無法回頭修改任何時候都可以修改任何文件
3 個指令4 個 core 指令 + 7 個擴展指令

三大架構革新(v1.0.0 起)

OpenSpec 1.0 進行了從底層開始的重建。以下三個架構革新是理解 OPSX 工作流程的關鍵:

1. 動態指令架構(Dynamic Instructions)

舊版:AI 每次都收到相同的靜態指令,不論專案狀態如何。

新版:指令由三層動態組裝而成:

graph TB
    subgraph 動態指令三層架構
        A[Context<br/>專案背景 — 來自 config.yaml<br/>技術棧、慣例、業務領域] 
        B[Rules<br/>Artifact 專屬約束<br/>如:propose 必須含回滾計畫]
        C[Template<br/>輸出結構模板<br/>如:proposal.md 的標準格式]
    end
    
    A --> D[AI 助手]
    B --> D
    C --> D
    D --> E[即時狀態查詢<br/>哪些 artifact 存在?<br/>哪些可以建立?<br/>下一步是什麼?]

config.yaml 範例

# openspec/config.yaml
schema: spec-driven    # 使用的工作流程 schema

context: |
  Tech stack: TypeScript, React, Node.js, PostgreSQL
  API style: RESTful
  Testing: Jest + React Testing Library
  業務領域: 銀行核心系統

rules:
  proposal:
    - 必須包含回滾計畫
    - 必須標示影響的團隊
  specs:
    - 使用 Given/When/Then 格式
    - 優先參考現有模式
  design:
    - 列出技術選型的替代方案

💡 關鍵優勢:AI 不再只是「讀指令」,而是能查詢 CLI 取得即時狀態——哪些 artifact 已存在、哪些準備好可以建立、相依性是否滿足、每個動作解鎖什麼。這讓 AI 的決策更智能、更貼合專案當前狀態。

2. 語義規格同步(Semantic Spec Syncing)

舊版:規格更新需要手動合併或整個檔案覆蓋,容易出錯。

新版:Delta Spec 使用 AI 可理解的語義標記:

語義標記用途說明
## ADDED Requirements新增需求完整加入主規格
## MODIFIED Requirements修改需求局部更新(可新增情境而不複製既有的)
## REMOVED Requirements移除需求刪除時附帶原因與遷移說明
## RENAMED Requirements重新命名更名但保留內容

語義同步範例

# Delta for Auth

## ADDED Requirements

### Requirement: 雙因素認證設定
系統 SHALL 允許用戶啟用雙因素認證
...(完整定義)

## MODIFIED Requirements

### Requirement: 帳號密碼驗證(修改既有)
*僅新增 2FA 檢查情境,不影響既有登入情境*

#### Scenario: 需要 2FA 驗證(新增)
- GIVEN 帳號存在且密碼正確
- AND 帳號已啟用 2FA
- WHEN 用戶提交登入請求
- THEN 系統回傳 2FA 挑戰

## REMOVED Requirements

### Requirement: 安全問答驗證
*原因:已被 2FA 取代*
*遷移說明:既有使用安全問答的用戶需先綁定 TOTP*

💡 Archive 過程在 requirement 層級(而非脆弱的標題匹配)解析這些標記,確保合併的正確性。

3. Agent Skills 統一格式

舊版:8+ 設定檔散落在專案根目錄,21 個工具需要不同格式的 slash command。

新版:統一使用 YAML frontmatter 的 Markdown 技能檔。每個 AI 工具有專屬的目錄,但技能內容格式一致:

.claude/skills/openspec-propose/SKILL.md      # Claude Code
.cursor/skills/openspec-propose/SKILL.md      # Cursor
.windsurf/skills/openspec-propose/SKILL.md    # Windsurf
.github/skills/openspec-propose/SKILL.md      # GitHub Copilot

ℹ️ 這些 skill 檔案由 openspec initopenspec update 自動產生與維護,開發者通常不需要手動編輯。

OPSX 完整指令一覽

Core 指令(預設 core profile)

指令用途說明
/opsx:propose一鍵提案建立變更並產生所有規劃文件(proposal、specs、design、tasks)
/opsx:explore探索想法在開始變更前,與 AI 討論問題、比較方案
/opsx:apply實作任務依據 tasks.md 逐一實作並勾選完成
/opsx:archive歸檔變更移動至 archive 目錄,更新主規格

擴展指令(需透過 openspec config profile 選取)

指令用途說明
/opsx:new建立新變更建立變更目錄,選擇 workflow schema
/opsx:continue逐步建立依據相依圖一次建立一個 artifact
/opsx:ff快速建立一次產生所有規劃文件(Fast-Forward)
/opsx:verify驗證實作檢查實作是否符合 spec 與 design
/opsx:sync同步規格將 delta spec 合併回主規格
/opsx:bulk-archive批量歸檔一次歸檔多個已完成的變更
/opsx:onboard互動教學引導新手完成一個完整的工作流程

常見工作流程模式

模式 0:最快路徑(core profile 預設,推薦)

/opsx:propose ──► /opsx:apply ──► /opsx:archive
You: /opsx:propose add-logout-button
AI:  Created openspec/changes/add-logout-button/
     ✓ proposal.md — 變更原因與範圍
     ✓ specs/       — 需求與情境
     ✓ design.md    — 技術方案
     ✓ tasks.md     — 工作項目清單
     Ready for implementation!

You: /opsx:apply
AI:  Implementing tasks...
     ✓ 1.1 新增登出按鈕到 header
     ✓ 1.2 實作 session 清除邏輯
     ✓ 1.3 新增確認對話框
     All tasks complete!

You: /opsx:archive
AI:  ✓ Archived to openspec/changes/archive/2026-02-26-add-logout-button/
     Specs updated. Ready for the next feature.

💡 /opsx:propose 等同於舊版的 /opsx:new + /opsx:ff,一個指令完成所有規劃文件的建立。

模式 1:快速功能(擴展模式,清楚知道要做什麼)

/opsx:new add-logout ──► /opsx:ff ──► /opsx:apply ──► /opsx:archive
You: /opsx:new add-logout-button
AI:  Created openspec/changes/add-logout-button/

You: /opsx:ff
AI:  ✓ proposal.md — 變更原因與範圍
     ✓ specs/       — 需求與情境
     ✓ design.md    — 技術方案
     ✓ tasks.md     — 工作項目清單
     Ready for implementation!

You: /opsx:apply
AI:  Implementing tasks...
     ✓ 1.1 新增登出按鈕到 header
     ✓ 1.2 實作 session 清除邏輯
     ✓ 1.3 新增確認對話框
     All tasks complete!

You: /opsx:archive
AI:  ✓ Archived to openspec/changes/archive/2026-02-26-add-logout-button/
     Specs updated. Ready for the next feature.

模式 2:探索式開發(需要先釐清需求)

/opsx:explore ──► /opsx:propose ──► /opsx:apply ──► /opsx:archive
You: /opsx:explore
AI:  我是你的思考夥伴。想討論什麼?

You: 我們的登入系統需要更安全,但不確定用什麼方案

AI:  我們可以分析幾個選項:
     1. TOTP 雙因素認證
     2. WebAuthn/Passkey
     3. SMS OTP
     ...讓我們逐一比較...

You: TOTP 方案聽起來不錯,開始吧

You: /opsx:propose add-totp-auth
AI:  Created openspec/changes/add-totp-auth/
     ✓ proposal.md
     ✓ specs/
     ✓ design.md
     ✓ tasks.md
     Ready for implementation!

模式 3:多變更並行

You: /opsx:apply add-dark-mode     # 繼續實作 A
...
You: /opsx:new fix-login-redirect   # 中途處理 B 
You: /opsx:ff
You: /opsx:apply                    # 實作 B
You: /opsx:archive                  # 歸檔 B
You: /opsx:apply add-dark-mode      # 回到 A

流動式迭代(Fluid Iteration)

OPSX 最大的優勢是不被階段鎖定。實作過程中發現設計有問題?直接修改 design.md 然後繼續:

You: /opsx:apply
AI:  Working on task 3/7...
     Issue: The design.md specifies Redux but this is a Vue project.

You: 更新 design.md 使用 Pinia 替代 Redux

AI:  ✓ Updated design.md
     Continuing implementation...

自訂 Schema

OpenSpec 支援自訂工作流程 schema,團隊可以定義自己的 artifact 順序與規則。自訂 schema 放在 openspec/schemas/ 目錄中,透過版本控管與團隊共享:

# openspec/config.yaml(config.yaml 完整範例參見上方「動態指令架構」段落)
schema: spec-driven    # 預設 schema,可改為自訂 schema 名稱

Schema 管理 CLI 指令

openspec schemas                   # 查看可用的工作流程 schema
openspec schema list               # 列出所有 schema(含自訂)
openspec schema show <name>        # 查看特定 schema 的 artifact 定義
openspec schema export <name>      # 匯出 schema 為檔案
openspec schema validate           # 驗證 schema 格式正確性

💡 自訂 schema 無需修改 OpenSpec 套件程式碼,團隊可透過 Git 版本控管共享自訂的工作流程 schema。

新手上路:使用 /opsx:onboard

如果你是第一次使用 OpenSpec,強烈建議執行互動教學:

You: /opsx:onboard

AI:  Welcome to OpenSpec!
     我會帶你完成一個完整的工作流程,使用你的實際程式庫...
     
     Phase 1: 分析你的 codebase
     Phase 2: 找到一個改進機會
     Phase 3: 建立變更 (/opsx:propose)
     Phase 4: 審閱規劃 artifact
     Phase 5: 實作變更
     ...
     Phase 11: 總結與下一步

⚠️ Legacy 指令說明/openspec:proposal/openspec:apply/openspec:archive 為舊版「一次建立所有文件」的工作流程。根據官方文件,這些指令仍可使用(作為 legacy 相容),但 OPSX 指令才是推薦的標準做法。既有使用舊版指令的專案可直接用 OPSX 指令接續操作,artifact 結構是相容的。

各 AI 工具的指令語法差異

不同 AI 工具使用略有不同的指令語法。核心意圖相同,但語法格式依工具整合方式而異:

AI 工具指令格式範例說明
Claude Code/opsx:propose, /opsx:apply冒號分隔格式
Cursor/opsx-propose, /opsx-apply連字號格式
Windsurf/opsx-propose, /opsx-apply連字號格式
GitHub Copilot (IDE)/opsx-propose, /opsx-apply連字號格式(僅 IDE 擴充套件支援)
Trae/openspec-propose, /openspec-apply-change技能導向呼叫(無產生指令檔)

ℹ️ GitHub Copilot CLI 注意:GitHub Copilot prompt 檔案(.github/prompts/*.prompt.md)目前僅在 IDE 擴充套件(VS Code、JetBrains、Visual Studio)中可用。Copilot CLI 尚不支援自訂 prompt 檔案。


4.3 與 AI 互動修正 Spec 的方式

AI 協作的最佳實踐

sequenceDiagram
    participant You as 你
    participant AI as AI 助手
    participant Spec as Spec 文件

    You->>AI: 建立 Spec 初稿
    AI->>Spec: 產生初始 Spec
    You->>AI: 審閱並提出問題
    AI->>You: 解釋或提出建議
    You->>AI: 要求修改特定部分
    AI->>Spec: 更新 Spec
    You->>AI: 請補充遺漏的情境
    AI->>Spec: 新增情境
    You->>Spec: 最終確認

Prompt 範例集

1. 請 AI 建立初稿

請依據 OpenSpec 格式,為以下功能建立 Spec:

功能:用戶密碼強度檢查
需求:
- 密碼至少 8 字元
- 必須包含大小寫字母
- 必須包含數字
- 建議包含特殊字元

請產出完整的 System Spec,包含所有可能的情境。

2. 請 AI 審閱 Spec

請審閱以下 Spec,檢查:
1. 是否有遺漏的邊界條件?
2. 錯誤處理是否完整?
3. 是否有安全性考量未涵蓋?

[貼上 Spec 內容]

3. 請 AI 補充情境

這份 Spec 似乎缺少以下情境,請補充:
- 併發操作的處理
- 網路逾時的處理
- 資料不一致的處理

原有 Spec:
[貼上 Spec 內容]

4. 請 AI 優化格式

請將以下需求描述轉換為 OpenSpec 標準格式:

原始描述:
「用戶登入時如果輸入錯誤密碼超過5次就要鎖定帳號,鎖定15分鐘後自動解鎖」

請使用 GIVEN-WHEN-THEN 格式。

5. 請 AI 檢查一致性

請檢查以下三份文件是否一致:
1. Proposal(變更提案)
2. Spec Delta(規格差異)
3. Tasks(工作項目)

確認:
- 所有提案中提到的功能是否都在 Spec 中定義
- 所有 Spec 中的需求是否都有對應的 Task

常用的 AI 指令(Slash Commands)

若你使用支援 OpenSpec 的 AI 工具,可使用以下 OPSX 指令:

Core Profile 指令(預設):

指令功能
/opsx:propose <名稱>🆕 建立變更並一次產生所有規劃 artifact
/opsx:explore探索想法,與 AI 討論問題
/opsx:apply <名稱>開始實作指定的變更
/opsx:archive <名稱>歸檔已完成的變更

Expanded Profile 額外指令:

指令功能
/opsx:new <名稱>建立新的變更(不自動產生 artifact)
/opsx:continue建立下一個 artifact
/opsx:ff <名稱>快速產生所有規劃文件
/opsx:verify <名稱>驗證實作是否符合規格
/opsx:sync同步 delta spec 到主規格
/opsx:bulk-archive🆕 批次歸檔多個已完成的變更
/opsx:onboard互動式新手教學

ℹ️ Profile 切換:使用 openspec config profile 可在 core 與 custom profile 之間切換。舊版 /openspec:* 指令仍然有效,但建議使用 OPSX 指令。

CLI 指令

# 列出所有進行中的變更
openspec list

# 列出所有規格
openspec list --specs

# 查看特定變更的詳情
openspec show add-2fa

# 查看變更狀態(含 artifact 進度)
openspec status --change add-2fa

# 驗證 Spec 格式
openspec validate add-2fa

# 互動式 Dashboard
openspec view

# 歸檔已完成的變更
openspec archive add-2fa --yes

# 更新 AI 助手設定檔(含 Profile 同步)
openspec update

# Profile 管理(v1.2.0 新增)
openspec config profile              # 互動式切換 core/custom profile

# Schema 管理
openspec schema list                  # 列出所有可用 schema(含自訂)
openspec schema show <name>           # 查看特定 schema 的 artifact 定義
openspec schema export <name>         # 匯出 schema 為檔案
openspec schema validate              # 驗證 schema 格式

# 查看/修改全域配置
openspec config list                  # 查看所有配置(含 config drift 警告)
openspec config set telemetry.enabled false
openspec config path                  # 查看配置檔路徑

# Shell 自動完成
openspec completion                   # 產生 shell completion 腳本

# 回饋
openspec feedback                     # 提交使用回饋

4.4 Spec 如何驅動設計、程式碼與測試

Spec → 設計

flowchart LR
    A[Spec] --> B[架構設計]
    A --> C[API 設計]
    A --> D[資料模型]
    A --> E[UI 設計]

Spec 中的需求直接對應設計決策:

Spec 內容設計決策
「系統 SHALL 在 3 秒內回應」需要快取機制、效能優化
「支援 10,000 併發用戶」需要負載平衡、水平擴展
「密碼 MUST 加密儲存」使用 bcrypt 或 Argon2

Spec → 程式碼

Spec 情境

#### Scenario: 密碼錯誤
- GIVEN 帳號存在但密碼錯誤
- WHEN 用戶提交登入請求
- THEN 系統回傳 401 Unauthorized
- AND 增加失敗登入次數

對應程式碼(Java/Spring Boot):

@PostMapping("/login")
public ResponseEntity<?> login(@RequestBody LoginRequest request) {
    User user = userRepository.findByEmail(request.getEmail())
        .orElseThrow(() -> new UnauthorizedException("帳號或密碼錯誤"));
    
    if (!passwordEncoder.matches(request.getPassword(), user.getPassword())) {
        // 增加失敗登入次數
        loginAttemptService.loginFailed(request.getEmail());
        throw new UnauthorizedException("帳號或密碼錯誤");
    }
    
    // ... 登入成功邏輯
}

Spec → 測試

Spec 情境直接轉換為測試案例

@Test
@DisplayName("Scenario: 密碼錯誤")
void testLoginWithWrongPassword() {
    // GIVEN 帳號存在但密碼錯誤
    User user = createTestUser("test@example.com", "correctPassword");
    
    // WHEN 用戶提交登入請求
    LoginRequest request = new LoginRequest("test@example.com", "wrongPassword");
    ResponseEntity<?> response = authController.login(request);
    
    // THEN 系統回傳 401 Unauthorized
    assertEquals(HttpStatus.UNAUTHORIZED, response.getStatusCode());
    
    // AND 增加失敗登入次數
    assertEquals(1, loginAttemptService.getFailedAttempts("test@example.com"));
}

追溯矩陣

建立需求追溯矩陣,確保每個規格都有對應實作與測試:

Spec ID需求描述程式模組測試案例狀態
AUTH-001帳號密碼驗證AuthServiceAuthServiceTest#testLogin*
AUTH-002帳號鎖定機制LoginAttemptServiceLoginAttemptTest#testLock*
AUTH-0032FA 驗證TwoFactorServiceTwoFactorTest#*🔄

💡 銀行系統實務:金融業常要求「需求追溯」,確保每個需求都有對應的設計、程式碼與測試。OpenSpec 的結構化格式讓這個追溯工作變得更容易。


第四章小結

流程步驟產出負責人
建立變更提案proposal.mdSA/PM
撰寫規格差異specs/*/spec.mdSA
定義工作項目tasks.mdSA/Dev Lead
審核審核通過Tech Lead/PM
實作程式碼Dev + AI
驗證測試通過QA/Dev
歸檔更新主規格SA

本章練習

  1. 使用 Prompt 範例,請 AI 幫你建立一份簡單功能的 Spec
  2. 練習使用 openspec listopenspec show 指令

第五章:新進同仁實作範例

💡 本章將透過一個完整的實例,示範從「需求描述」到「可開發規格」的完整過程。

5.1 案例說明:帳戶餘額查詢 API

業務背景

某銀行核心系統需要提供「帳戶餘額查詢」功能,供網銀與行動銀行 App 使用。

原始需求

用戶需要能查詢自己的帳戶餘額,包括:
- 活存帳戶的可用餘額與帳面餘額
- 定存帳戶的本金與到期金額
- 外幣帳戶要顯示各幣別餘額
- 要有適當的權限控制

目標

將這段原始需求轉換為符合 OpenSpec 格式的規格文件。


5.2 從需求描述到 OpenSpec 文件

Step 1: 建立變更目錄結構

openspec/
└── changes/
    └── account-balance-query/
        ├── proposal.md
        ├── tasks.md
        ├── design.md
        └── specs/
            └── account/
                └── spec.md

Step 2: 撰寫 Proposal(變更提案)

# 變更提案:帳戶餘額查詢 API

## 變更編號
CHG-2024-002

## 變更摘要
提供帳戶餘額查詢 API,支援活存、定存、外幣帳戶的餘額查詢

## 變更原因
- 網銀系統需要顯示用戶帳戶餘額
- 行動銀行 App 需要同樣功能
- 現有舊系統 API 即將汰換

## 商業價值
- 每日預估查詢量:50,000 次
- 支援用戶自助查詢,減少臨櫃作業

## 影響範圍
- 帳戶核心模組
- 用戶認證模組(權限驗證)
- 外幣匯率模組(匯率換算)

## 相依性
- 需要 AUTH-001(用戶認證)規格
- 需要 FX-001(外幣匯率)規格

## 時程預估
- 開發:1 週
- 測試:3 天
- 部署:1 天

Step 3: 撰寫 System Spec(系統規格)

# 帳戶餘額查詢 - System Spec

## Purpose
提供用戶查詢自有帳戶餘額的功能,支援活存、定存、外幣等帳戶類型

## Scope
- 包含:餘額查詢、多帳戶彙總、幣別顯示
- 不包含:交易明細、轉帳功能

## Requirements

### Requirement: 單一帳戶餘額查詢
系統 SHALL 允許用戶查詢指定帳戶的餘額

#### Scenario: 查詢活存帳戶餘額成功
- GIVEN 用戶已通過身份驗證
- AND 用戶持有帳號 "1234567890"
- AND 該帳戶為活存帳戶
- WHEN 用戶查詢該帳戶餘額
- THEN 系統回傳以下資訊:
  - 帳號:1234567890
  - 帳戶類型:活存
  - 幣別:TWD
  - 可用餘額:實際可動用金額
  - 帳面餘額:含圈存的總金額
  - 查詢時間:系統時間戳記

#### Scenario: 查詢定存帳戶餘額成功
- GIVEN 用戶已通過身份驗證
- AND 用戶持有定存帳號
- WHEN 用戶查詢該帳戶餘額
- THEN 系統回傳以下資訊:
  - 帳號
  - 帳戶類型:定存
  - 本金金額
  - 到期金額(含利息)
  - 存入日期
  - 到期日期
  - 年利率

#### Scenario: 查詢外幣帳戶餘額成功
- GIVEN 用戶已通過身份驗證
- AND 用戶持有外幣帳號
- WHEN 用戶查詢該帳戶餘額
- THEN 系統回傳以下資訊:
  - 帳號
  - 帳戶類型:外幣
  - 各幣別餘額清單(幣別、金額)
  - 換算台幣總值(依即時匯率)

#### Scenario: 查詢非本人帳戶
- GIVEN 用戶已通過身份驗證
- AND 帳號 "9999999999" 非該用戶所有
- WHEN 用戶查詢該帳戶餘額
- THEN 系統回傳 403 Forbidden
- AND 記錄異常查詢審計日誌

#### Scenario: 查詢不存在的帳戶
- GIVEN 用戶已通過身份驗證
- AND 帳號 "0000000000" 不存在於系統中
- WHEN 用戶查詢該帳戶餘額
- THEN 系統回傳 404 Not Found

#### Scenario: 帳戶狀態異常
- GIVEN 用戶已通過身份驗證
- AND 帳戶狀態為「凍結」或「結清」
- WHEN 用戶查詢該帳戶餘額
- THEN 系統回傳餘額資訊
- AND 包含帳戶狀態警示

---

### Requirement: 全部帳戶餘額彙總
系統 SHALL 允許用戶一次查詢所有帳戶的餘額

#### Scenario: 查詢所有帳戶餘額成功
- GIVEN 用戶已通過身份驗證
- AND 用戶持有 3 個帳戶(活存、定存、外幣各一)
- WHEN 用戶查詢所有帳戶餘額
- THEN 系統回傳所有帳戶的餘額清單
- AND 計算總資產(換算為台幣)

#### Scenario: 用戶無任何帳戶
- GIVEN 用戶已通過身份驗證
- AND 用戶名下無任何帳戶
- WHEN 用戶查詢所有帳戶餘額
- THEN 系統回傳空清單
- AND 總資產為 0

---

### Requirement: 權限控制
系統 MUST 確保用戶只能查詢自己的帳戶

#### Scenario: Token 過期
- GIVEN 用戶的 JWT Token 已過期
- WHEN 用戶嘗試查詢帳戶餘額
- THEN 系統回傳 401 Unauthorized
- AND 提示重新登入

#### Scenario: 無效的 Token
- GIVEN 用戶提供的 Token 格式不正確或被竄改
- WHEN 用戶嘗試查詢帳戶餘額
- THEN 系統回傳 401 Unauthorized
- AND 記錄安全事件日誌

---

## Non-Functional Requirements

### 效能需求
- 單一帳戶查詢 SHOULD 在 500ms 內回應
- 所有帳戶查詢 SHOULD 在 2s 內回應

### 可用性需求
- API 可用性 MUST ≥ 99.9%

### 安全性需求
- 所有查詢 MUST 透過 HTTPS
- 所有查詢 MUST 記錄審計日誌
- 敏感資訊(如完整帳號)SHOULD 遮罩處理

---

## API Definition

### GET /api/v1/accounts/{accountNo}/balance

查詢單一帳戶餘額

**Request Headers:**

```text
Authorization: Bearer <JWT Token>
X-Request-ID: <UUID>

Path Parameters:

參數類型說明
accountNostring帳號

Response - Success (200):

{
  "accountNo": "123456****",
  "accountType": "SAVINGS",
  "currency": "TWD",
  "availableBalance": 50000.00,
  "ledgerBalance": 52000.00,
  "status": "ACTIVE",
  "queryTime": "2024-01-15T10:30:00Z"
}

Response - Error (403):

{
  "error": "ACCESS_DENIED",
  "message": "您無權查詢此帳戶"
}

GET /api/v1/accounts/balances

查詢所有帳戶餘額

Response - Success (200):

{
  "accounts": [
    {
      "accountNo": "123456****",
      "accountType": "SAVINGS",
      "currency": "TWD",
      "availableBalance": 50000.00
    },
    {
      "accountNo": "789012****",
      "accountType": "TIME_DEPOSIT",
      "currency": "TWD",
      "principal": 100000.00,
      "maturityAmount": 102500.00,
      "maturityDate": "2024-12-31"
    }
  ],
  "totalAssetsTWD": 152500.00,
  "queryTime": "2024-01-15T10:30:00Z"
}

Step 4: 撰寫 Tasks(工作項目)

# Tasks for account-balance-query

## 1. 資料庫與基礎架構
- [ ] 1.1 確認帳戶資料表結構,建立必要的 View
- [ ] 1.2 建立餘額查詢審計日誌表
- [ ] 1.3 設定 Redis 快取(餘額資料 TTL: 30 秒)

## 2. 核心服務實作
- [ ] 2.1 建立 AccountBalanceService 介面
- [ ] 2.2 實作活存帳戶餘額查詢
- [ ] 2.3 實作定存帳戶餘額查詢
- [ ] 2.4 實作外幣帳戶餘額查詢
- [ ] 2.5 實作帳戶權限驗證邏輯
- [ ] 2.6 整合外幣匯率服務

## 3. API 層實作
- [ ] 3.1 建立 AccountBalanceController
- [ ] 3.2 實作 GET /accounts/{accountNo}/balance
- [ ] 3.3 實作 GET /accounts/balances
- [ ] 3.4 實作統一錯誤處理
- [ ] 3.5 實作審計日誌攔截器

## 4. 測試
- [ ] 4.1 單元測試:AccountBalanceService(各帳戶類型)
- [ ] 4.2 單元測試:權限驗證邏輯
- [ ] 4.3 整合測試:完整 API 流程
- [ ] 4.4 效能測試:確認回應時間符合 SLA

## 5. 文件與交付
- [ ] 5.1 更新 Swagger/OpenAPI 文件
- [ ] 5.2 撰寫 API 使用說明
- [ ] 5.3 更新系統架構圖

5.3 示範如何向 AI 詢問與優化 Spec

對話範例 1:請 AI 建立初稿

You: 
我有一個「帳戶餘額查詢」的需求,請依據 OpenSpec 格式建立 System Spec。

需求摘要:
- 用戶可查詢單一帳戶或所有帳戶的餘額
- 支援活存、定存、外幣帳戶
- 需要權限控制,只能查自己的帳戶
- 這是銀行系統,需要考慮安全性

AI:
我將依據 OpenSpec 格式為您建立「帳戶餘額查詢」的 System Spec。

[產生 Spec 內容...]

請問這份 Spec 是否涵蓋了您的需求?是否有需要補充的情境?

對話範例 2:請 AI 審閱與補充

You:
請審閱這份 Spec,檢查是否有遺漏的情境:

[貼上 Spec]

AI:
我檢查了這份 Spec,發現以下可能遺漏的情境:

1. **系統層面**
   - 核心系統連線失敗時的處理
   - 資料庫查詢逾時的處理
   - 快取與資料庫資料不一致的處理

2. **業務層面**
   - 帳戶有圈存款項時的顯示
   - 定存提前解約的餘額計算
   - 外幣帳戶有多種外幣時的顯示順序

3. **安全層面**
   - 短時間內大量查詢的限制
   - 查詢日誌的保存期限

是否需要我補充這些情境到 Spec 中?

對話範例 3:請 AI 協助優化

You:
以下這個情境描述不夠清楚,請幫我改寫成更具體的 GIVEN-WHEN-THEN 格式:

「外幣帳戶要顯示各幣別餘額」

AI:
我將這個需求拆解為更具體的情境:

#### Scenario: 查詢外幣帳戶餘額成功
- GIVEN 用戶已通過身份驗證
- AND 用戶持有外幣帳號 "FX-001"
- AND 該帳戶包含 USD 1000.00、JPY 50000、EUR 500.00
- WHEN 用戶查詢該帳戶餘額
- THEN 系統回傳以下資訊:
  - 帳號:FX-001
  - 幣別餘額清單:
    - USD: 1,000.00
    - JPY: 50,000
    - EUR: 500.00
  - 換算台幣總值:依即時匯率計算
  - 匯率更新時間:顯示匯率資料時間

#### Scenario: 外幣帳戶無餘額
- GIVEN 用戶已通過身份驗證
- AND 用戶持有外幣帳號但所有幣別餘額為 0
- WHEN 用戶查詢該帳戶餘額
- THEN 系統回傳空的幣別餘額清單
- AND 換算台幣總值為 0

這樣的描述是否符合您的需求?

對話範例 4:從 Spec 產生程式碼

You:
請依據以下 Spec 情境,產生對應的 Java 程式碼:

#### Scenario: 查詢非本人帳戶
- GIVEN 用戶已通過身份驗證
- AND 帳號 "9999999999" 非該用戶所有
- WHEN 用戶查詢該帳戶餘額
- THEN 系統回傳 403 Forbidden
- AND 記錄異常查詢審計日誌

AI:
依據這份 Spec,我產生以下程式碼:

// Service 層
@Service
public class AccountBalanceServiceImpl implements AccountBalanceService {
    
    @Autowired
    private AccountRepository accountRepository;
    
    @Autowired
    private AuditLogService auditLogService;
    
    @Override
    public AccountBalance getBalance(String accountNo, String userId) {
        Account account = accountRepository.findByAccountNo(accountNo)
            .orElseThrow(() -> new AccountNotFoundException(accountNo));
        
        // 驗證帳戶所有權
        if (!account.getOwnerId().equals(userId)) {
            // 記錄異常查詢審計日誌
            auditLogService.logSecurityEvent(
                AuditEventType.UNAUTHORIZED_ACCESS_ATTEMPT,
                userId,
                "Attempted to access account: " + accountNo
            );
            throw new AccessDeniedException("您無權查詢此帳戶");
        }
        
        return buildAccountBalance(account);
    }
}

// Controller 層
@GetMapping("/accounts/{accountNo}/balance")
public ResponseEntity<AccountBalanceResponse> getBalance(
        @PathVariable String accountNo,
        @AuthenticationPrincipal UserDetails userDetails) {
    try {
        AccountBalance balance = accountBalanceService
            .getBalance(accountNo, userDetails.getUsername());
        return ResponseEntity.ok(toResponse(balance));
    } catch (AccessDeniedException e) {
        return ResponseEntity.status(HttpStatus.FORBIDDEN)
            .body(new AccountBalanceResponse(e.getMessage()));
    }
}

第五章小結

步驟產出物重點
建立提案proposal.md說明變更原因與影響
撰寫規格spec.md完整情境、標準格式
定義任務tasks.md可執行的工作項目
AI 協作優化後的 Spec審閱、補充、優化

本章練習

  1. 選擇一個你熟悉的銀行功能(如:轉帳、對帳單查詢),嘗試用 OpenSpec 格式撰寫 Spec
  2. 使用 AI 助手審閱你的 Spec,看看它會發現哪些遺漏

第六章:常見錯誤與反模式(Anti-Patterns)

⚠️ 本章列出新手常見的錯誤,幫助你避免踩坑。

6.1 規格寫得像程式碼

錯誤示範 ❌

### Requirement: 登入驗證
- 系統接收 POST /api/login 請求
- 從 request body 取得 email 和 password
- 用 SELECT * FROM users WHERE email = ? 查詢用戶
- 如果 user == null,return 401
- 用 BCrypt.check(password, user.passwordHash) 驗證密碼
- 如果驗證失敗,loginAttempts++
- 如果 loginAttempts >= 5,設定 lockedUntil = now + 15 minutes
- 驗證成功則用 JWT.sign({userId: user.id, role: user.role}) 產生 token

問題

  • ❌ 包含具體的實作細節(SQL、BCrypt、JWT)
  • ❌ 像是虛擬碼而非規格
  • ❌ 限制了實作的彈性

正確示範 ✅

### Requirement: 登入驗證
系統 SHALL 驗證用戶的登入憑證

#### Scenario: 登入成功
- GIVEN 用戶帳號存在且密碼正確
- AND 帳號未被鎖定
- WHEN 用戶提交登入請求
- THEN 系統核發包含用戶身份的存取令牌

#### Scenario: 密碼錯誤
- GIVEN 用戶帳號存在但密碼錯誤
- WHEN 用戶提交登入請求
- THEN 系統回傳驗證失敗
- AND 記錄失敗次數

#### Scenario: 帳號鎖定
- GIVEN 用戶連續登入失敗達到閾值
- WHEN 達到鎖定條件
- THEN 帳號暫時鎖定一段時間

改進

  • ✅ 描述「做什麼」而非「怎麼做」
  • ✅ 不綁定特定技術
  • ✅ 關注業務行為

6.2 規格過於抽象或過度細節化

過於抽象 ❌

### Requirement: 安全的登入機制
系統應該要有安全的登入機制,保護用戶資料。

問題

  • 什麼是「安全」?沒有具體定義
  • 無法測試
  • 不同人有不同理解

過度細節化 ❌

### Requirement: 密碼輸入欄位
- 密碼欄位使用 <input type="password">
- 欄位寬度為 280px
- 欄位高度為 40px
- 邊框顏色為 #CCCCCC
- 聚焦時邊框顏色變為 #0066CC
- 字型為 Arial, 14px
- 佔位符文字為「請輸入密碼」
- 欄位下方間距為 16px

問題

  • 這是 UI 設計稿,不是規格
  • 過於細節會限制設計彈性
  • 規格應該聚焦在行為而非外觀

正確的平衡 ✅

### Requirement: 密碼輸入安全性
系統 SHALL 保護密碼輸入的安全性

#### Scenario: 密碼遮罩
- GIVEN 用戶在密碼欄位輸入
- WHEN 輸入字元
- THEN 顯示遮罩字元(如 ●)而非明文

#### Scenario: 防止密碼洩漏
- GIVEN 用戶輸入密碼
- THEN 密碼不會被瀏覽器自動儲存(除非用戶明確同意)
- AND 密碼不會出現在網址列或 JavaScript 日誌中

6.3 把 AI 當成自動寫 Code 工具

錯誤心態 ❌

flowchart LR
    A[模糊的需求] --> B[AI]
    B --> C[程式碼]
    C --> D[Bug!]
    D --> E[再叫 AI 修]
    E --> F[更多 Bug!]

常見錯誤做法

You: 幫我寫一個登入功能

AI: [產生一段程式碼]

You: 不對,要用 JWT

AI: [重新產生]

You: 錯誤處理不對

AI: [再次修改]

... 無限循環

正確心態 ✅

flowchart LR
    A[需求] --> B[與 AI 協作撰寫 Spec]
    B --> C[審核 Spec]
    C --> D[依 Spec 實作]
    D --> E[驗證符合 Spec]

正確做法

You: 我需要實作登入功能,請先幫我用 OpenSpec 格式撰寫規格

AI: 好的,讓我先確認需求...
    [產生 Spec]

You: 請補充「帳號鎖定」的情境

AI: [更新 Spec]

You: Spec 看起來完整了,請依據這份 Spec 產生程式碼

AI: 依據 Spec 的以下情境,我產生對應的程式碼...
    [產生符合規格的程式碼]

關鍵差異

錯誤做法正確做法
直接要程式碼先要規格
口頭修改需求更新 Spec 文件
AI 猜測需求AI 依據 Spec 實作
結果不可預測結果符合規格

常見反模式總覽

graph TB
    subgraph 反模式
        A[Code as Spec<br/>把程式碼當規格]
        B[Vague Spec<br/>規格太模糊]
        C[Over-detailed Spec<br/>規格太細]
        D[AI as Magic<br/>把 AI 當魔術師]
        E[No Review<br/>不審閱 Spec]
        F[Outdated Spec<br/>不更新 Spec]
    end
    
    subgraph 正確做法
        G[行為導向的規格]
        H[具體可測試的規格]
        I[適當抽象層級]
        J[Spec 先行的協作]
        K[Spec 審核流程]
        L[Spec 持續更新]
    end
    
    A --> G
    B --> H
    C --> I
    D --> J
    E --> K
    F --> L
反模式症狀解決方法
Code as Spec規格中有 SQL、API 路徑聚焦於業務行為
Vague Spec無法寫測試案例加入具體情境
Over-detailed包含 UI 細節、顏色值只描述行為規則
AI as Magic反覆修改、結果不穩定Spec First
No Review實作後發現需求錯誤建立審核流程
Outdated SpecSpec 與程式碼不一致變更時更新 Spec

第六章小結

反模式避免方法
規格像程式碼描述「做什麼」而非「怎麼做」
規格太抽象加入具體的 GIVEN-WHEN-THEN 情境
規格太細節只描述行為規則,不描述 UI 細節
AI 當魔術師Spec First,先有規格再寫程式

本章練習

  1. 檢視你過去寫的文件,是否有上述反模式?
  2. 嘗試改寫一份「過於抽象」的規格,使其更具體

第七章:導入 OpenSpec 的最佳實務(Best Practices)

7.1 團隊協作方式

角色與職責分工

graph TB
    subgraph 角色分工
        PM[產品經理/PM<br/>定義需求優先級]
        SA[系統分析師/SA<br/>撰寫詳細 Spec]
        TL[技術主管<br/>審核 Spec 技術可行性]
        DEV[開發人員<br/>依 Spec 實作]
        QA[測試人員<br/>依 Spec 撰寫測試]
    end
    
    PM --> SA
    SA --> TL
    TL --> DEV
    SA --> QA
角色職責OpenSpec 相關任務
產品經理 (PM)定義業務需求、優先級審核 Proposal、確認商業價值
系統分析師 (SA)將需求轉換為規格撰寫 Spec、定義情境
技術主管 (Tech Lead)技術決策、架構審核審核 Spec 技術面、核准實作
開發人員 (Dev)程式實作依 Spec 開發、回報問題
測試人員 (QA)品質保證依 Spec 撰寫測試案例

協作流程

sequenceDiagram
    participant PM as PM
    participant SA as SA
    participant TL as Tech Lead
    participant Dev as 開發人員
    participant QA as QA
    
    PM->>SA: 1. 提出需求
    SA->>SA: 2. 撰寫 Spec 初稿
    SA->>PM: 3. 業務面審核
    PM->>SA: 4. 回饋/核准
    SA->>TL: 5. 技術面審核
    TL->>SA: 6. 回饋/核准
    SA->>Dev: 7. 發布 Spec
    SA->>QA: 7. 發布 Spec
    Dev->>Dev: 8. 依 Spec 實作
    QA->>QA: 8. 依 Spec 撰寫測試
    Dev->>QA: 9. 提交程式碼
    QA->>QA: 10. 執行測試
    QA->>SA: 11. 回報結果
    SA->>SA: 12. 歸檔 Spec

團隊溝通建議

階段會議/儀式參與者頻率
需求確認Spec Review MeetingPM, SA, TL每個需求
開發中Daily StandupDev, SA每日
整合前Spec CheckSA, QA每個 Sprint
交付後Retrospective全員每個 Sprint

💡 銀行系統實務:金融業通常有「需求確認會」與「設計審查會」的流程。OpenSpec 的 Proposal + Spec 正好可以作為這兩個會議的輸入文件。


7.2 Spec Review 重點

Review 檢查清單

業務面檢查

  • 需求是否完整?沒有遺漏的功能?
  • 情境是否涵蓋正常、異常、邊界條件?
  • 商業價值是否清楚說明?
  • 優先級是否合理?

技術面檢查

  • 效能需求是否可實現?
  • 安全性需求是否足夠?
  • 是否與現有系統相容?
  • 是否考慮擴展性?

格式檢查

  • 是否使用標準 OpenSpec 格式?
  • GIVEN-WHEN-THEN 是否清楚?
  • 是否使用正確的關鍵字(SHALL、MUST)?

Review 會議範例

會議議程(30 分鐘):

時間項目說明
0-5 min背景說明SA 簡報變更背景
5-15 minSpec 走讀逐一檢視情境
15-25 min討論提問與釐清
25-30 min結論核准/修改/駁回

常見問題範例

審核者:「查詢逾時的情況有處理嗎?」
SA:「目前沒有,我補充到 Spec 中。」

審核者:「用戶連續查詢 100 次會怎樣?」
SA:「好問題,我加入 Rate Limiting 的情境。」

審核者:「這個 API 的回應時間 SLA 是多少?」
SA:「我會在 Non-Functional Requirements 補上。」

Review 常見問題與處理

常見問題處理方式
Spec 不夠具體要求補充 GIVEN-WHEN-THEN
遺漏錯誤處理列出需要補充的異常情境
效能要求不清要求定義具體 SLA
安全考量不足要求加入安全相關情境

7.3 如何版本控管 Spec(搭配 Git)

分支策略

gitGraph
   commit id: "初始提交"
   branch feature/add-2fa
   checkout feature/add-2fa
   commit id: "建立 Spec 初稿"
   commit id: "審核後修改"
   commit id: "開始實作"
   commit id: "完成實作"
   checkout main
   merge feature/add-2fa id: "合併 + 歸檔"

建議的分支命名

  • feature/add-xxx - 新功能
  • fix/issue-xxx - 修復問題
  • refactor/xxx - 重構

Commit 訊息規範

使用 Conventional Commits 格式:

# Spec 相關
spec(auth): add 2fa requirement scenarios
spec(auth): update login scenarios for lockout
docs(spec): fix typo in proposal

# 實作相關
feat(auth): implement 2fa verification
fix(auth): correct token expiry logic
test(auth): add 2fa integration tests

目錄結構建議

專案根目錄/
├── openspec/
│   ├── config.yaml             # 專案配置(schema、context、rules)
│   ├── schemas/                # 自定義 schema(可選)
│   ├── specs/                  # 主規格(Source of Truth)
│   │   ├── auth/
│   │   │   └── spec.md
│   │   ├── account/
│   │   │   └── spec.md
│   │   └── transaction/
│   │       └── spec.md
│   ├── changes/                # 進行中的變更
│   │   └── add-2fa/
│   │       ├── .openspec.yaml  # 變更的 schema 設定
│   │       ├── proposal.md
│   │       ├── design.md
│   │       ├── tasks.md
│   │       └── specs/
│   │           └── auth/
│   │               └── spec.md  # Delta
│   └── changes/archive/        # 已完成的變更
│       └── 2026-01-15-add-profile-search/
│           ├── proposal.md
│           ├── tasks.md
│           └── specs/
├── .github/prompts/            # GitHub Copilot 技能檔
├── src/                        # 程式碼
├── test/                       # 測試
└── ...                         # 其他專案檔案

Pull Request 流程

PR 範本

## 變更類型
- [x] Spec 變更
- [ ] 程式碼變更
- [ ] 文件變更

## 相關 Spec
- openspec/changes/add-2fa/

## 變更摘要
新增雙因素認證的 Spec,包含設定、驗證、備用碼等情境

## 審核確認
- [ ] Spec 格式正確
- [ ] 情境完整
- [ ] 已通過 PM 確認
- [ ] 已通過技術審核

💡 實務建議:建議在 CI/CD 中加入 openspec validate 檢查,確保每次提交的 Spec 格式正確。


第七章小結

最佳實務說明
角色分工明確定義誰寫、誰審、誰實作
Review 流程業務面 + 技術面雙重審核
版本控管使用 Git 分支,Spec 與程式碼一起管理
命名規範統一的分支、目錄、Commit 命名

第八章:給新進同仁的學習建議

8.1 上手順序

學習路徑

flowchart LR
    A[1. 理解概念<br/>1-2 天] --> B[2. 閱讀範例<br/>1 天]
    B --> C[3. 模仿撰寫<br/>2-3 天]
    C --> D[4. 獨立撰寫<br/>1 週]
    D --> E[5. 審核他人<br/>持續]

第一週:理解概念

天數任務產出
Day 1閱讀本手冊第 1-2 章理解 SDD 核心概念
Day 2閱讀第 3-4 章理解 Spec 格式與流程
Day 3閱讀專案中現有的 Spec熟悉團隊風格
Day 4跟著第 5 章實作一遍完成第一份 Spec
Day 5Review + 修改根據回饋改進

第二週:實戰練習

天數任務說明
Day 1-2選一個小功能撰寫 Spec如:修改密碼、查詢記錄
Day 3參與 Spec Review學習審核要點
Day 4-5依自己寫的 Spec 實作驗證 Spec 的可實作性

持續精進

  • 每週至少寫/審一份 Spec
  • 收集好的 Spec 範例
  • 參與團隊 Spec Review 討論

8.2 常見卡關點

卡關點 1:不知道情境要寫多細

症狀

  • 寫太少:只有 happy path
  • 寫太多:連 UI 顏色都寫

解決方法

問自己三個問題:

  1. 這個情境能不能寫成一個測試案例?
  2. 如果交給另一個人看,他能不能實作?
  3. 這是「行為」還是「實作細節」?

經驗法則

應該寫不該寫
系統回傳 401 Unauthorized用 Spring Security 的 @PreAuthorize
密碼至少 8 個字元密碼欄位寬度 280px
查詢結果分頁顯示用 PageRequest.of(0, 10)

卡關點 2:不確定用 SHALL 還是 MUST

解答

關鍵字意義使用時機
SHALL必須實作一般功能需求
MUST強制要求安全性、合規性要求
SHOULD建議實作最佳實務、非必要功能
MAY可選未來擴展、可選功能

範例

系統 SHALL 提供密碼登入功能(功能需求)
密碼 MUST 使用 bcrypt 或更強的演算法加密(安全要求)
系統 SHOULD 提供密碼強度提示(最佳實務)
系統 MAY 支援指紋登入(可選功能)

卡關點 3:AI 產出的 Spec 不符合團隊風格

解決方法

  1. 提供範例
請參考以下範例格式撰寫 Spec:
[貼上團隊的 Spec 範例]
  1. 明確要求
請使用以下規則:
- 標題用 ### Requirement: 開頭
- 情境用 #### Scenario: 開頭
- 使用 GIVEN-WHEN-THEN 格式
  1. 迭代修改
請把這段改成團隊的標準格式:
[貼上需要修改的內容]

卡關點 4:不知道從哪裡開始

快速起步模板

# [功能名稱] - System Spec

## Purpose
[一句話說明這個功能的目的]

## Requirements

### Requirement: [主要需求名稱]
系統 SHALL [做什麼事情]

#### Scenario: 成功情境
- GIVEN [前提條件]
- WHEN [用戶執行的動作]
- THEN [預期的結果]

#### Scenario: 失敗情境 - [失敗原因]
- GIVEN [導致失敗的條件]
- WHEN [用戶執行的動作]
- THEN [錯誤處理方式]

8.3 如何從「會寫」進階到「寫得好」

進階技巧

1. 思考邊界條件

每個功能都問:

  • 輸入值為空會怎樣?
  • 輸入值為 null 會怎樣?
  • 輸入值超出範圍會怎樣?
  • 併發操作會怎樣?
  • 網路中斷會怎樣?

2. 考慮非功能性需求

## Non-Functional Requirements

### 效能
- 查詢回應時間 SHOULD < 500ms (P95)
- 系統 SHOULD 支援 1000 TPS

### 安全性
- 所有 API MUST 透過 HTTPS
- 敏感操作 MUST 記錄審計日誌

### 可用性
- 服務可用性 MUST ≥ 99.9%
- 計劃性維護時間 SHOULD < 4 小時/月

3. 使用表格整理複雜邏輯

### 手續費計算規則

| 交易類型 | 金額範圍 | 手續費 |
|---------|---------|--------|
| 同行轉帳 | 任意 | 0 |
| 跨行轉帳 | ≤ 500 | 10 |
| 跨行轉帳 | 501-10,000 | 15 |
| 跨行轉帳 | > 10,000 | 交易金額 × 0.1% |

4. 建立自己的 Checklist

## 我的 Spec 檢查清單

撰寫完成後確認:
- [ ] 有 Purpose 說明
- [ ] 有成功情境
- [ ] 有失敗/錯誤情境
- [ ] 有邊界條件情境
- [ ] 有權限控制情境(如需要)
- [ ] 有效能需求(如需要)
- [ ] 有安全需求(如需要)
- [ ] 格式符合團隊規範
- [ ] 可以直接轉換為測試案例

學習資源

類型資源說明
官方OpenSpec GitHub官方文件與範例
官方Workflows 工作流程工作流程詳細說明
官方CLI 參考文件完整 CLI 指令說明
官方Commands 文件完整指令參考
官方Concepts 概念核心概念說明
社群OpenSpec Discord討論與問答
社群@0xTab on X官方更新動態
相關spec-kit另一個 SDD 工具
方法論BDD (Behavior-Driven Development)GIVEN-WHEN-THEN 的來源

💡 推薦 AI 模型:根據 OpenSpec 官方建議,使用 Claude Opus 4.5GPT 5.2 等高效能模型可獲得最佳的 Spec 生成與審閱品質。建議在處理 Spec 撰寫與審閱任務時,優先選擇這些模型。

⚠️ Context 衛生建議:為獲得最佳 AI 協作體驗,建議在開始新的 OPSX 工作流程前清理 AI 對話的 context(例如開啟新對話),避免前一個任務的殘餘 context 影響 Spec 品質。


第八章小結

階段重點
初期閱讀範例、模仿撰寫
中期獨立撰寫、接受 Review
進階考慮邊界、非功能需求、審核他人

附錄:檢查清單(Checklist)

A. OpenSpec 環境設定檢查清單

  • Node.js >= 20.19.0 已安裝(node --version 確認)
  • OpenSpec CLI 已安裝(以下任一方式):
    • npm install -g @fission-ai/openspec@latest
    • pnpm add -g @fission-ai/openspec@latest
    • yarn global add @fission-ai/openspec@latest
    • nix run github:Fission-AI/OpenSpec -- init
  • 驗證安裝:openspec --version 顯示版本號
  • 專案已初始化 (openspec init,支援自動偵測已安裝的 AI 工具)
  • 已選擇要整合的 AI 工具(init 過程中會提示)
  • 已設定 Profile(openspec config profile,預設為 core)
  • openspec/config.yaml 已填寫專案 context 資訊
  • 驗證 AI 工具整合:在 AI 助手中嘗試 /opsx:onboard

B. Spec 撰寫檢查清單

  • 有 Purpose 說明
  • 每個 Requirement 使用 SHALL/MUST/SHOULD/MAY
  • 每個 Requirement 至少有一個 Scenario
  • Scenario 使用 GIVEN-WHEN-THEN 格式
  • 包含成功情境
  • 包含失敗/錯誤情境
  • 包含邊界條件情境
  • 包含權限驗證情境(如適用)
  • 包含非功能性需求(效能、安全、可用性)
  • API 定義完整(如適用)

C. Spec Review 檢查清單

業務面

  • 需求是否完整?
  • 情境是否涵蓋所有可能?
  • 商業價值是否清楚?
  • 優先級是否合理?

技術面

  • 效能需求是否可實現?
  • 安全性需求是否足夠?
  • 是否與現有系統相容?
  • 是否考慮擴展性?

格式面

  • 格式是否符合團隊規範?
  • 關鍵字使用是否正確?
  • 情境描述是否清楚?

D. 變更完成檢查清單

  • 所有 Tasks 已完成(tasks.md 中的 checkbox 全部勾選)
  • 程式碼已提交並審核
  • 測試已通過
  • 文件已更新
  • 已執行 /opsx:verifyopenspec validate 驗證實作完整性
  • 已執行 /opsx:archiveopenspec archive 歸檔
  • Delta spec 已同步至主規格(archive 過程會提示)

E. 常用 CLI 指令速查

# 初始化
openspec init                      # 初始化並選擇 AI 工具(自動偵測已安裝工具)
openspec init --tools claude,cursor # 非互動式指定工具

# 查看狀態
openspec list                      # 列出所有進行中的變更
openspec list --specs              # 列出所有規格
openspec show <change>             # 查看特定變更詳情
openspec status --change <change>  # 查看 artifact 狀態
openspec view                      # 互動式 Dashboard

# 工作流程
openspec new change <name>         # 建立新變更
openspec validate <change>         # 驗證 Spec 格式
openspec archive <change> --yes    # 歸檔已完成的變更

# Profile 管理(v1.2.0 新增)
openspec config profile            # 互動式切換 core/custom profile

# Schema 管理
openspec schema list               # 列出所有可用 schema(含自訂)
openspec schema show <name>        # 查看特定 schema 的 artifact 定義
openspec schema export <name>      # 匯出 schema 為檔案
openspec schema validate           # 驗證 schema 格式

# 配置管理
openspec config list               # 查看所有配置(含 config drift 警告)
openspec config set <key> <value>  # 設定配置值
openspec config path               # 查看配置檔路徑

# 更新與維護
openspec update                    # 更新 AI 助手設定(含 Profile 同步)
openspec schemas                   # 查看可用的工作流程 schema

# 其他
openspec completion                 # 產生 shell 自動完成腳本
openspec feedback                   # 提交使用回饋

F. 與 AI 對話 Prompt 範本

建立新 Spec

請依據 OpenSpec 格式,為以下功能建立 System Spec:

功能:[功能名稱]
需求摘要:
- [需求 1]
- [需求 2]
- [需求 3]

請包含成功情境、失敗情境和邊界條件。

審閱 Spec

請審閱以下 Spec,檢查:
1. 是否有遺漏的情境?
2. 是否有模糊不清的描述?
3. 是否符合 OpenSpec 格式?
4. 是否有安全性考量?

[貼上 Spec 內容]

優化 Spec

請將以下需求描述轉換為 OpenSpec 的 GIVEN-WHEN-THEN 格式:

[貼上需求描述]

G. 支援的 AI 工具清單

OpenSpec v1.2.0 支援 24 個 AI 編程助手,在執行 openspec init 時可選擇要整合的工具(支援自動偵測已安裝工具)。

每個工具安裝時會包含兩類檔案:

  1. Skills(技能檔):.../skills/openspec-*/SKILL.md — 動態指令的核心
  2. Commands(指令檔):工具特定格式的 opsx-* 指令檔案
工具IDSkills 路徑Commands 路徑
Amazon Q Developeramazon-q.amazonq/skills/openspec-*/SKILL.md.amazonq/prompts/opsx-<id>.md
Antigravityantigravity.agent/skills/openspec-*/SKILL.md.agent/workflows/opsx-<id>.md
Auggie (Augment CLI)auggie.augment/skills/openspec-*/SKILL.md.augment/commands/opsx-<id>.md
Claude Codeclaude.claude/skills/openspec-*/SKILL.md.claude/commands/opsx/<id>.md
Clinecline.cline/skills/openspec-*/SKILL.md.clinerules/workflows/opsx-<id>.md
CodeBuddycodebuddy.codebuddy/skills/openspec-*/SKILL.md.codebuddy/commands/opsx/<id>.md
Codexcodex.codex/skills/openspec-*/SKILL.md$CODEX_HOME/prompts/opsx-<id>.md*
Continuecontinue.continue/skills/openspec-*/SKILL.md.continue/prompts/opsx-<id>.prompt
CoStrictcostrict.cospec/skills/openspec-*/SKILL.md.cospec/openspec/commands/opsx-<id>.md
Crushcrush.crush/skills/openspec-*/SKILL.md.crush/commands/opsx/<id>.md
Cursorcursor.cursor/skills/openspec-*/SKILL.md.cursor/commands/opsx-<id>.md
Factory Droidfactory.factory/skills/openspec-*/SKILL.md.factory/commands/opsx-<id>.md
Gemini CLIgemini.gemini/skills/openspec-*/SKILL.md.gemini/commands/opsx/<id>.toml
GitHub Copilotgithub-copilot.github/skills/openspec-*/SKILL.md.github/prompts/opsx-<id>.prompt.md**
iFlowiflow.iflow/skills/openspec-*/SKILL.md.iflow/commands/opsx-<id>.md
Kilo Codekilocode.kilocode/skills/openspec-*/SKILL.md.kilocode/workflows/opsx-<id>.md
Kiro 🆕kiro.kiro/skills/openspec-*/SKILL.md.kiro/prompts/opsx-<id>.prompt.md
OpenCodeopencode.opencode/skills/openspec-*/SKILL.md.opencode/commands/opsx-<id>.md
Pi 🆕pi.pi/skills/openspec-*/SKILL.md.pi/prompts/opsx-<id>.md
Qoderqoder.qoder/skills/openspec-*/SKILL.md.qoder/commands/opsx/<id>.md
Qwen Codeqwen.qwen/skills/openspec-*/SKILL.md.qwen/commands/opsx-<id>.toml
RooCoderoocode.roo/skills/openspec-*/SKILL.md.roo/commands/opsx-<id>.md
Traetrae.trae/skills/openspec-*/SKILL.md無(使用技能導向 /openspec-* 呼叫)
Windsurfwindsurf.windsurf/skills/openspec-*/SKILL.md.windsurf/workflows/opsx-<id>.md

* Codex commands 安裝在全域 Codex home($CODEX_HOME/prompts/~/.codex/prompts/),不在專案目錄中。
** GitHub Copilot prompt 檔案僅在 IDE 擴充套件(VS Code、JetBrains、Visual Studio)中可用,Copilot CLI 尚不支援。

產生的 Skill 名稱

依據 profile/workflow 選擇,OpenSpec 會產生以下 skill:

Core Profile(預設)Custom Profile(擴展)
openspec-proposeopenspec-new-change
openspec-exploreopenspec-continue-change
openspec-apply-changeopenspec-ff-change
openspec-archive-changeopenspec-sync-specs
openspec-verify-change
openspec-bulk-archive-change
openspec-onboard

非互動式安裝

# 指定特定工具
openspec init --tools claude,cursor,github-copilot

# 安裝所有工具
openspec init --tools all

# 跳過工具配置
openspec init --tools none

# 指定 profile(覆蓋全域設定)
openspec init --profile core

所有可用 Tool IDamazon-qantigravityauggieclaudeclinecodexcodebuddycontinuecostrictcrushcursorfactorygeminigithub-copilotiflowkilocodekiroopencodepiqoderqwenroocodetraewindsurf

💡 Skill/Command 的數量取決於 profile 選擇與 delivery mode,並非固定數量。在 core profile 下產生 4 組 skill + command,在 custom profile 下依選擇可產生最多 11 組。

ℹ️ 使用 openspec update 更新時,會自動移除已取消選擇的工作流程檔案(sync prune)。openspec config list 會在全域配置與專案配置不同步時顯示 config drift 警告。


H. 疑難排解(Troubleshooting)

問題原因解決方法
「Change not found」指令無法識別要操作的變更明確指定變更名稱:/opsx:apply add-dark-mode;確認變更目錄存在:openspec list
「No artifacts ready」所有 artifact 已完成或被相依性阻擋執行 openspec status --change <name> 查看阻擋原因;先建立缺少的前置 artifact
「Schema not found」指定的 schema 不存在列出可用 schema:openspec schemas;確認拼寫;若為自訂 schema 則需先建立
指令未被辨認AI 工具未載入 OpenSpec 技能檔確認已初始化:openspec init;重新產生技能檔:openspec update;重啟 AI 工具
Artifact 產出不完整AI 缺乏足夠的專案上下文openspec/config.yaml 補充 context 資訊;為特定 artifact 新增 rules;改用 /opsx:continue 逐步產生
Windows 相容性問題路徑分隔符號差異OpenSpec v1.0.2+ 已修正跨平台路徑處理;確認使用最新版
Archive 中途停止跨裝置或限制路徑導致 rename 失敗v1.1.0+ 已修正:自動回退為 copy+remove

💡 更多疑難排解請參閱 Commands 指令參考 中的 Troubleshooting 區段。


參考資源

官方資源

資源連結
OpenSpec 官方網站https://openspec.dev/
OpenSpec GitHubhttps://github.com/Fission-AI/OpenSpec
OpenSpec npmhttps://www.npmjs.com/package/@fission-ai/openspec
OpenSpec Discordhttps://discord.gg/YctCnvvshC
CHANGELOGhttps://github.com/Fission-AI/OpenSpec/blob/main/CHANGELOG.md
Getting Started 入門https://github.com/Fission-AI/OpenSpec/blob/main/docs/getting-started.md
Workflows 工作流程https://github.com/Fission-AI/OpenSpec/blob/main/docs/workflows.md
OPSX 指令說明https://github.com/Fission-AI/OpenSpec/blob/main/docs/opsx.md
Concepts 概念說明https://github.com/Fission-AI/OpenSpec/blob/main/docs/concepts.md
Commands 指令參考https://github.com/Fission-AI/OpenSpec/blob/main/docs/commands.md
CLI 參考https://github.com/Fission-AI/OpenSpec/blob/main/docs/cli.md
Supported Tools 支援工具清單https://github.com/Fission-AI/OpenSpec/blob/main/docs/supported-tools.md
Installation 安裝指南https://github.com/Fission-AI/OpenSpec/blob/main/docs/installation.md
Multi-Language 多語言https://github.com/Fission-AI/OpenSpec/blob/main/docs/multi-language.md
Customization 自訂https://github.com/Fission-AI/OpenSpec/blob/main/docs/customization.md
@0xTab on Xhttps://x.com/0xTab
團隊版 Slack 頻道寄信至 teams@openspec.dev 申請

相關工具

工具說明連結
spec-kitGitHub 的 SDD 工具(較重量級、有階段門)https://github.com/github/spec-kit
KiroAWS 的規格管理工具(鎖定 IDE 與 Claude 模型)https://kiro.dev

延伸閱讀

主題說明
BDD (Behavior-Driven Development)GIVEN-WHEN-THEN 的來源
ATDD (Acceptance Test-Driven Development)驗收測試驅動開發
Domain-Driven Design領域驅動設計
Context Engineering上下文工程——如何有效構建 AI 的提示上下文
Spec-Driven Development (SDD)規格驅動開發方法論

文件資訊

項目內容
文件名稱OpenSpec 使用教學手冊
版本3.1
建立日期2025-12-30
更新日期2026-03-23
適用版本OpenSpec v1.2.0
維護者[Eric Cheng]
適用對象新進軟體工程師、系統分析師

📝 回饋與改進:如果您在使用本手冊過程中發現任何問題或有改進建議,歡迎提出!