專案實作流程

以清楚的命令引導代理生成憲章、規格、計畫與任務,再逐步實作。

SDD 完整工作流程總覽

Spec Kit 的核心理念是「先思考、再實作」。透過六個明確的命令,將一段自然語言需求轉化為可驗證、可追溯的實作成果。每個步驟都有對應的產出物,AI 代理在進入下一步之前必須確認當前步驟的品質門檻已達標。整個流程圍繞三份核心文件展開:spec.md(規格)、plan.md(計畫)、tasks.md(任務),它們共同構成功能實作的完整知識圖譜,讓人類與 AI 代理始終站在同一個認知基礎上協作。

核心原則:任何步驟都可以(也應該)在發現問題時退回上一步修正。SDD 不是線性瀑布流程,而是帶有回饋環路的迭代式工作法。每次回退都是品質提升的機會,而非失敗的標誌。回退成本在前期遠低於後期——在規格階段修正一個誤解,比在程式碼審查階段修正要節省數倍的精力。前期投入的澄清與設計時間,是整個流程最高投資報酬率的環節。

六步驟主流程

Step 1 — 撰寫規格 specify specify

這是整個工作流程的起點。你以自然語言描述功能需求,AI 代理將其轉化為結構嚴謹的 spec.md,包含使用者故事(User Story)、驗收條件(Acceptance Criteria)、邊界情境(Edge Cases)與非功能性需求(Non-Functional Requirements)四大區塊。規格文件一旦建立,即成為後續所有步驟的真相來源(Source of Truth)——計畫要引用它,任務要覆蓋它,分析要對照它。好的起點描述應清楚涵蓋「誰、做什麼、在何種條件下、預期什麼結果」,避免跳過邊界情境。切勿在規格中使用「合理」、「適當」、「業界標準」等無法量化的形容詞,這些詞語是模糊地帶的溫床,只會讓後續澄清工作加倍。

產出物:.specify/features/<feature-name>/spec.md,包含四大章節:使用者故事、驗收條件(Given/When/Then)、邊界情境、非功能性需求。
specify specify "使用者可以用電子郵件與密碼登入,
登入失敗三次後鎖定帳號 15 分鐘,
登入成功後導向儀表板"
  • 需求是否以使用者角度描述(Given / When / Then 格式)
  • 是否同時涵蓋成功路徑(Happy Path)與失敗路徑(Sad Path)
  • 邊界條件(空白密碼、超長輸入、特殊字元)是否明確列出
  • 非功能性需求(效能指標、資安要求、無障礙標準)是否已量化
  • 功能範圍是否明確,避免「鍍金」(Gold Plating)風險
  • 規格中未出現任何無法客觀驗證的模糊形容詞

Step 2 — 澄清需求 specify clarify

規格初稿完成後,AI 代理化身需求分析師,主動提出最多五個高價值的澄清問題,精準聚焦於三類風險:模糊地帶(如「合理的錯誤訊息」究竟指什麼)、遺漏情境(如多裝置同時登入的行為)與潛在衝突(如鎖定機制與忘記密碼流程的交互作用)。你的回答會被直接編碼回 spec.md,使規格精確度大幅提升。此步驟是整個流程中投資報酬率最高的環節:花五分鐘澄清,可以避免數小時的返工。每一個未澄清的模糊點,都將在後期以十倍成本現形。澄清的目標不是枚舉所有可能的情境,而是識別並消除最高風險的模糊地帶,讓計畫階段可以在清晰的前提下展開技術設計。

產出物:更新後的 spec.md(澄清內容已合併至對應章節,所有新增細節均有明確的原始問題來源標注)
specify clarify
典型澄清問題範例:「帳號鎖定期間,使用者是否可以透過『忘記密碼』流程解鎖?鎖定計數器在成功登入後是否自動重置?同一帳號從不同 IP 發起的失敗嘗試是否計入同一計數器?多裝置同時登入是否允許,Token 是否共享或各自獨立?鎖定訊息是否需要揭示剩餘鎖定時間?」這類問題在此步驟解決,遠比在 Code Review 時爭論便宜得多。
  • 所有模糊描述是否已替換為可量化、可測試的具體條件
  • 邊界情境的預期行為是否已明確(而非「視情況而定」)
  • 與既有功能的整合點是否已識別並描述
  • 澄清答案是否已回寫至 spec.md 對應章節,而非散落於對話記錄

Step 3 — 生成計畫 specify plan

基於澄清後的 spec.md,AI 代理生成 plan.md,內容包含技術架構決策、元件拆分策略、資料模型設計、API 介面定義(含輸入輸出型別)、模組依賴關係圖與主要技術風險評估。計畫層級回答「如何做」,規格層級回答「做什麼」,兩者分離使設計決策可以獨立審查與修改。當計畫與 constitution.md 的技術原則有衝突時,應在此步驟明確標注並取得確認,而不是悄悄繞過原則。計畫不是詳細的程式碼實作,而是讓整個團隊對技術方向達成共識的溝通文件。技術選型的每一個決策都應附上理由,以便未來的審計者理解當時的脈絡與取捨。

產出物:.specify/features/<feature-name>/plan.md,涵蓋架構圖、API 契約、資料模型、風險清單與技術決策理由。
specify plan
  • 技術選型是否與 constitution.md 的技術棧原則一致
  • 資料流是否清晰,外部依賴(資料庫、快取、第三方服務)是否已標注
  • API 介面是否有明確的輸入輸出型別定義與錯誤碼規範
  • 是否識別了主要技術風險(如競態條件、效能瓶頸)並提出緩解方案
  • 安全性考量(認證、授權、資料驗證)是否已明確納入設計
  • 每項技術決策是否附有選擇理由與被排除的替代方案

Step 4 — 拆分任務 specify tasks

plan.md 中的設計拆分為一系列原子化、可獨立驗證的任務,生成 tasks.md。每個任務都有明確的完成標準(Definition of Done)、預估複雜度標籤(S / M / L)與依賴關係聲明。任務的粒度設計原則是「一個任務對應一個可測試的功能單元」,確保代理可以逐一確認進度而不遺漏任何驗收條件。任務 ID(如 T-01、T-02)是後續 specify implement 與 git commit 訊息的錨點,保障整個實作歷史的可追溯性。任務過大會讓回滾範圍難以控制;任務過小則會造成管理負擔。理想的任務邊界是「一個任務的結果可以在不執行其他任務的情況下被完整驗證」。

產出物:.specify/features/<feature-name>/tasks.md,每個任務含唯一 ID、完成標準、複雜度標籤、依賴關係聲明與狀態欄位。
specify tasks
任務粒度黃金法則:一個任務的驗收條件應在三到五項之間,預計可在 30 分鐘內被獨立驗證完成。若驗收條件超過五項,或任務描述中出現「並且(and)」連接多個獨立功能,即應將其再次拆分。過大的任務會讓代理難以判斷當前進度,也會讓需要回滾時的影響範圍難以控制。反之,任務拆分過細(如「修改一行 CSS」)則會讓 tasks.md 臃腫不堪,每次狀態更新的管理成本高於實作本身。
  • 每個任務是否有唯一 ID 且完成標準可客觀驗證
  • 任務間的依賴關係是否已明確聲明(避免循環依賴)
  • 是否有覆蓋 spec.md 中所有驗收條件的對應任務
  • 測試任務(單元測試、整合測試)是否與功能任務分開列出
  • 每個任務是否可在 30 分鐘內獨立驗證,複雜度標籤是否合理

Step 5 — 執行實作 specify implement

代理依照 tasks.md 中聲明的依賴順序逐一執行任務,每完成一個任務即更新其狀態標記並執行對應的驗收檢查。此命令具備斷點續跑能力:若中途因任何原因中斷,下次執行時會自動識別最後一個已完成的任務並從下一個任務繼續,無需手動指定進度。實作過程中若發現 plan.md 的設計存在問題(如 API 型別不符、資料模型需調整),正確做法是暫停並返回 Step 3 或 Step 4 更新設計文件後再繼續,而不是直接在程式碼層面打補丁卻不更新文件。文件與程式碼的同步一致性是 SDD 可追溯性的命脈,一旦允許「暫時性不一致」出現,技術債的積累速度往往超出預期。

產出物:實際程式碼變更 + 更新後的 tasks.md(各任務標記完成狀態與完成時間戳,每個 git commit 包含對應任務 ID)
specify implement
  • 每個任務完成後是否有可見的成果(測試通過截圖、功能可手動驗證)
  • 程式碼變更範圍是否嚴格對應當前任務(無範圍蔓延 Scope Creep)
  • 依賴任務是否已先完成,後置任務才開始執行
  • 遇到設計問題時是否停止並更新上游文件,而非強行在程式碼層面繞過
  • 每次 git commit 訊息是否包含對應的任務 ID(如 feat: T-03 實作登入鎖定機制

Step 6 — 驗證分析 specify analyze

所有任務完成後,執行跨工件一致性分析,系統性地比對 spec.mdplan.mdtasks.md 與實際程式碼之間的落差。此步驟會識別並標記三類問題:一、規格中定義但程式碼未實作的驗收條件(遺漏實作);二、程式碼中存在但規格未描述的行為(隱性功能,可能是範圍蔓延);三、計畫中的設計決策與實際實作不一致(文件漂移)。分析結果生成品質報告,供人工審查後決定是否需要補充實作或更新文件。此步驟是合併前的最後品質守門,不應跳過。對於分析報告中的每一項問題,必須做出明確的書面決策——補充實作、更新文件或標記為已知差異並附上理由——不得留白忽略。

產出物:一致性分析報告(顯示於終端機或存入 .specify/features/<feature-name>/analyze.md),標注每一個差異的優先級與建議行動。
specify analyze
分析後的決策框架:對於報告中的每一個問題,你需要做出明確選擇——補充實作(讓程式碼對齊規格)、更新文件(讓規格對齊已驗證的實作決策)或標記為已知差異(附上理由)。忽略分析報告等同於放棄了 SDD 帶來的可追溯性保障。在合併前將所有高優先級問題清零,是對未來維護者與審計者最起碼的尊重。

完整範例:「登入功能」從自然語言到 tasks.md

以下示範如何將一段口語描述逐步轉化為可執行的任務清單,讓你直觀感受六步驟工作流的完整轉化過程。整個過程從一句話需求出發,歷經規格撰寫、需求澄清,最終產出五個獨立可測試的任務,每個任務都有明確的完成標準與依賴關係。這個範例也清楚展示「澄清」如何將模糊的日常語言轉化為嚴謹的工程契約,以及一句原始需求背後隱藏了多少未言明的假設。

原始需求(自然語言)

「使用者可以用電子郵件和密碼登入。輸入錯誤三次就鎖定。登入成功跳到首頁。」
這段描述包含至少五個模糊點:「鎖定」多久?「首頁」是哪個路由?鎖定期間是否允許任何操作?鎖定計數器以什麼維度計算(userId 還是 IP)?成功登入後計數器是否重置?這正是 specify clarify 要解決的問題。若不澄清直接進入計畫,AI 代理會根據自身假設填補空白,而這些假設直到實作完成後才在 Code Review 或使用者驗收測試中被發現——屆時修正成本已是澄清成本的十倍以上。

Step 1 產出:spec.md 摘要

# 功能:使用者電子郵件登入

## 使用者故事
- 身為一位已註冊使用者,我希望能以電子郵件和密碼登入,
  以便安全地存取我的帳戶資料。

## 驗收條件
- Given 使用者輸入正確的電子郵件與密碼,
  When 點擊登入按鈕,
  Then 系統建立 Session 並導向 /dashboard

- Given 使用者輸入錯誤密碼,
  When 點擊登入,
  Then 顯示「電子郵件或密碼不正確」(不區分是哪個欄位錯誤)

- Given 使用者連續輸入錯誤密碼三次,
  When 第三次失敗後,
  Then 帳號鎖定 15 分鐘並顯示「帳號已鎖定,請於 N 分鐘後再試」

- Given 帳號處於鎖定狀態,
  When 使用者嘗試登入,
  Then 直接返回鎖定訊息,不執行密碼比對

## 邊界情境
- 電子郵件格式錯誤 → 前端即時驗證,禁止送出
- 密碼欄位為空 → 禁止送出,顯示「密碼不得為空」
- 帳號不存在 → 返回與密碼錯誤相同的訊息(防帳號枚舉攻擊)
- 鎖定計數器在成功登入後重置為 0

## 非功能性需求
- 密碼以 bcrypt(cost=12)雜湊儲存,不得明文記錄於任何日誌
- 登入 API 回應時間 P99 < 300ms(不含網路延遲)
- 登入表單需通過 WCAG 2.1 AA 無障礙標準

Step 2:specify clarify 補全的關鍵細節

澄清後新增的五條規格:(1)鎖定計時從第三次失敗時刻起算,非從第一次失敗;(2)鎖定期間輸入正確密碼仍顯示鎖定訊息,不執行密碼比對;(3)/dashboard 為登入後的預設導向,若有 redirect_to 查詢參數則優先導向該路徑(需驗證白名單,防止開放重定向漏洞);(4)多裝置登入允許,各裝置 Token 獨立管理,登出只失效當前裝置的 Token;(5)鎖定計數器以 userId 為 Key,與 IP 無關,帳號不存在時不建立計數器(防帳號枚舉側信道攻擊)。這五個細節在原始需求中完全缺失,若未澄清將導致後端與前端對鎖定行為有截然不同的實作假設,而且每一個假設都有合理依據,爭論起來可能耗費數小時。

Step 4 產出:tasks.md 摘要

# 任務清單:使用者電子郵件登入

## T-01 建立登入 API 端點  [S]
- [ ] POST /api/auth/login 接受 { email: string, password: string }
- [ ] 輸入格式驗證失敗回傳 400 + 錯誤描述
- [ ] 帳號不存在時回傳 401(訊息與密碼錯誤相同)
完成標準:curl 測試可收到正確的 400 / 401 / 200 回應碼

## T-02 實作密碼驗證邏輯  [S]  依賴:T-01
- [ ] 以 bcrypt.compare 驗證密碼雜湊
- [ ] 帳號不存在時執行虛擬比對(防時序攻擊,統一回應時間)
完成標準:單元測試通過,覆蓋率 >= 90%,含虛擬比對分支

## T-03 實作登入失敗鎖定機制  [M]  依賴:T-02
- [ ] Redis 計數器記錄失敗次數(key: login_fail:{userId},TTL: 900s)
- [ ] 第三次失敗後設定鎖定旗標,後續請求直接返回 423
- [ ] 成功登入後重置計數器
完成標準:整合測試模擬三次失敗後,第四次請求應收到 423 狀態碼

## T-04 建立前端登入表單  [M]
- [ ] Email 與密碼欄位、即時格式驗證(電子郵件 Regex)
- [ ] 送出按鈕在驗證失敗時禁用
- [ ] 顯示後端回傳的錯誤訊息(含鎖定剩餘時間倒數)
- [ ] 通過 WCAG 2.1 AA:label 關聯、鍵盤可操作、錯誤訊息有 aria-live
完成標準:E2E 測試模擬正常登入流程可導向 /dashboard

## T-05 登入成功後的 Session 管理  [S]  依賴:T-01, T-02
- [ ] 生成 JWT(HS256,exp: 24h)並設定為 HttpOnly Cookie
- [ ] 登入成功後 302 導向 /dashboard(或 redirect_to 白名單路徑)
- [ ] 登出端點清除 Cookie 並使當前裝置 Token 失效
完成標準:手動測試確認 Cookie 設定正確,重新整理後仍維持登入狀態
轉化過程的關鍵觀察:原始需求僅有一句話(30 個字),經過六步驟工作流後,產出了結構化的驗收條件、邊界情境、非功能性需求與五個可獨立執行的任務。這個「資訊密度增幅」不是 AI 憑空生成的內容,而是系統性地將隱藏在人類心智模型中的假設與期望顯式化(Externalizing)的過程。SDD 的核心價值正在於此:讓隱性知識成為顯性文件,讓個人假設成為團隊共識。

常見工作流程錯誤

錯誤一:跳過 clarify 直接進入 plan
spec.md 中存在模糊描述時(如「系統應回應合理的錯誤訊息」、「效能需達到業界標準」),若未經澄清即進入計畫階段,AI 代理會根據自身假設填補空白。問題在於這些假設在 plan.md 中並不透明,直到實作完成後才在 Code Review 或使用者驗收測試中被發現。此時修正成本已是初期澄清的十倍以上。這類問題在分散式團隊中尤其致命——不同成員基於各自的合理假設各自實作,最終在整合時才發現根本性的設計衝突,而此時距離最初的模糊描述可能已過了數週。處方:每次 specify specify 完成後,養成立即執行 specify clarify 的習慣,即使你認為需求已經很清楚——正是在「覺得很清楚」的時候最容易藏著最貴的假設。
錯誤二:任務粒度過大,驗收條件超載
將「實作完整登入模組」作為單一任務,或在一個任務中同時包含 API 端點、業務邏輯、前端表單與 Session 管理,會導致代理無法在中途有效確認進度。一旦某個子功能的方向偏差,整個大任務都難以回滾到已知良好狀態。更嚴重的問題是,粒度過大的任務讓 specify implement 的斷點續跑機制失去意義——因為沒有足夠細緻的檢查點,中斷後恢復時必須人工判斷從何處繼續,而 AI 代理對大塊未完成工作的狀態感知能力遠不如對小型已定義任務可靠。處方:遵循「一任務一可測試功能單元」原則,並以「能否在 30 分鐘內獨立驗證完成」作為粒度是否合適的判斷依據。
錯誤三:在 implement 階段靜默修改設計
當代理在實作過程中發現 plan.md 的設計存在問題(如 API 回傳型別不符合前端需求、Redis Key 設計有競態條件風險),若直接在程式碼層面打補丁而不同步更新 plan.mdtasks.md,三份文件與實際程式碼就開始分裂。後續的 specify analyze 會產生大量假性警告,每次分析都需要人工逐一確認哪些差異是「已知且接受的設計變更」、哪些是真正的遺漏實作,整個 SDD 的可追溯性隨之瓦解。這個錯誤的誘惑之處在於「當下」看起來更快——暫時不更新文件可以立刻繼續寫程式——但它將複利累積的技術債轉嫁給了未來的自己和團隊成員。處方:發現設計問題立即暫停,執行 specify plan 更新計畫,必要時重新生成受影響的任務,再繼續實作。文件更新的成本永遠低於後期的困惑成本。
最佳實踐:在每次 git commit 之前,確認 tasks.md 中對應的任務已標記完成,且 commit 訊息包含任務 ID(格式:feat: T-03 實作登入失敗鎖定機制)。這樣 git log 與 tasks.md 的進度就能形成完整對應的實作歷史記錄,方便日後審計、回溯與新成員快速理解功能演進脈絡。當團隊成員離職或功能需要六個月後重新修改時,這份可追溯的歷史記錄往往是唯一能說清楚「當初為什麼這樣做」的文件。

快速參考:各步驟命令一覽

# 完整六步驟工作流(以「登入功能」為例)
specify specify "使用者可以用電子郵件與密碼登入,失敗三次鎖定 15 分鐘"
specify clarify          # 澄清模糊需求,回答問題後自動更新 spec.md
specify plan             # 生成技術架構與設計決策(plan.md)
specify tasks            # 拆分為原子化任務清單(tasks.md)
specify implement        # 逐一執行任務,支援斷點續跑
specify analyze          # 驗證工件一致性,生成品質報告