不再追著 AI 的改動跑:我用 OpenSpec 把需求先鎖起來,再讓它寫程式
我用 AI 寫程式最快,但也最容易失控。OpenSpec 讓我先把需求寫成可審的規格(proposal/apply/validate/archive),再讓 AI 照 tasks 實作,最後甚至把 validate 放進 CI,顯著降低返工。
不再追著 AI 的改動跑:我用 OpenSpec 把需求先鎖起來,再讓它寫程式
我用 AI 寫程式的體感一直很矛盾:它可以快到離譜,也能在 10 分鐘內把一個「小改動」膨脹成「半個系統重構」。我真正痛的不是它寫不出來,而是我很難確定——它到底有沒有理解我。需求散在聊天裡、決策散在多次 commit 裡,最後我花最多時間的地方不是實作,而是「釐清需求」與「收斂範圍」。
OpenSpec 改變我工作方式的關鍵很簡單:先把需求寫成可以被審查的規格,再開始改程式碼。它不是一個「更會寫程式」的工具,而是一個「讓 AI 依規格做事」的流程工具。當我願意在最開始多花 10 分鐘把需求鎖定,後面就少掉大量「追著 AI 改動跑」的時間。
我遇到的三個痛點,OpenSpec 對症下藥
痛點 1:需求只在聊天裡,驗收條件不穩
我最常踩雷的是:我以為我講清楚了,但 AI 其實只抓到關鍵字。結果它補上了一堆我沒要的東西,或漏掉我以為「理所當然」的部分。這種情況下再去改 code,很容易變成無止盡的來回。
我喜歡 OpenSpec 的地方在於它逼我把需求寫成「可驗收」:至少要有一個 scenario,告訴大家什麼叫成功、什麼叫失敗。需求一旦有了驗收情境,AI 的自由發揮空間就會縮小很多。
痛點 2:改動擴散,review 變考古
AI 一次動多檔案時,我看 diff 常常像在考古:我知道它改了什麼,但不知道為什麼要改、應該改到哪裡就停。更麻煩的是,當需求其實還沒定稿,review code 只會把大家的注意力拉進細節,而不是先對齊方向。
OpenSpec 的做法讓我能先 review「意圖」:先看規格差異(spec delta)與任務清單(tasks),確認「要做哪些、不做哪些」,再讓 AI 去改 code。這種順序對我來說非常關鍵。
痛點 3:多人/多工具協作,流程容易碎裂
今天我用 A 工具、明天同事用 B 工具,如果我們沒有共同的「需求落點」,最後就會回到聊天記錄與口頭共識。OpenSpec 用檔案與資料夾結構把流程固定下來,讓「需求」不再依賴某個人或某個工具的記憶。
安裝與初始化:我會先把「規格層」裝起來
我會先安裝 OpenSpec CLI,讓我在任何專案都能用一致方式初始化與驗證:
npm install -g @fission-ai/openspec@latest然後在專案根目錄執行:
openspec init初始化後,我通常會先確認 openspec/ 的結構是否建立完成,並把它當成「需求的單一真相來源」。這一步做完,後面不管換什麼 agent,我至少有同一套規格流程可以依循。
我實際怎麼用:proposal → apply → validate → implement → archive
我現在使用 OpenSpec 時,會把它當作「需求的 CI」。流程我會固定成這樣:
1) /openspec:proposal:先把需求寫清楚
我會用一句話描述需求,然後要求它產出 proposal、tasks、spec deltas。這一步我會特別強調三件事:
- 我想解決的痛點是什麼(避免變成大雜燴)
- 明確列出「不做什麼」(防止 scope creep)
- 最少要有哪些驗收 scenario(避免最後才吵)
2) /openspec:apply:把草稿變成正式變更
對我來說 apply 是關鍵門檻:它代表「這份 proposal 已經可以被當成正式工作項」。沒有 apply,就很像只是把計畫寫在聊天裡;apply 之後,整個變更會落進 openspec/changes/<change-id>/,變成 repo 裡可 review、可追溯的內容。
3) openspec validate <change-id> --strict:先把規格驗證過
我會在寫任何程式碼之前先跑 validate。原因很務實:規格格式或 scenario 寫法如果不對,後面 AI 會照錯的規格做事,返工成本更高。我寧願先修 spec,也不要先產出一堆可能要丟掉的 code。
4) implement:照 tasks 逐條完成
通過 validate 後,我才讓 AI 開始改 code,而且我會要求它逐條完成 tasks.md,完成一條就回報改了哪些檔案、如何驗證。這一步我會刻意壓住「一次做太多」的衝動,因為 AI 越是大改,越容易把你拖回 review 地獄。
5) /openspec:archive:把變更回寫成系統真相
我最喜歡的一步其實是 archive。很多專案做完功能後,規格文件會落後;但 OpenSpec 的設計是把這次變更整理後歸檔,並把該更新的規格合併回 openspec/specs/。這讓我下次再改同一塊時,不用翻聊天記錄,只要看 specs 就知道系統現在應該怎麼運作。
我會怎麼把 openspec validate 放進 CI(避免規格先壞掉才發現)
我後來的做法是:把 openspec validate 當成「規格層的 lint」,跟 eslint/typecheck 一樣,在 PR 就擋掉規格不合格的變更。原因很現實:如果規格格式壞了、scenario 沒寫、變更結構不完整,AI 後面就會照錯的規格做事,返工會更大。
最簡單版本:CI 直接跑全量檢查
如果你的 repo 變更數量不大,我會先用最直覺的方式:每次 CI 都跑一次(跑久一點但最穩)。
openspec validate --strict更實務版本:只驗證這次 PR 相關的 change
如果你們 changes 很多,我會改成「只驗證這次 PR 變到的 change-id」。我的原則是:
- CI 先找出
openspec/changes/底下這次 PR 有變動的資料夾(通常就是 change-id) - 對每個 change-id 跑:
openspec validate <change-id> --strict這樣跑得快,而且錯誤訊息也會更聚焦。
我最想用 CI 擋掉的錯
我會一律開 --strict,因為我最怕的是「規格看起來有寫,實際 parser 沒吃到」:
- requirement 缺 scenario(等於沒有驗收條件)
- scenario 標題格式不對(導致解析失敗但你不一定立刻發現)
- spec delta 的 MODIFIED 沒貼完整 requirement block(需求上下文遺失)
我寧願 CI 先 fail,也不要讓 AI 帶著一份壞掉的 spec 去實作。
我給工程師的導入建議:先挑一個「最常返工」的功能
如果你問我怎麼導入,我不建議一開始就想把整個系統規格化。那太重,也很容易失敗。我會挑一個最常返工的改動類型先試:
- 權限/登入流程的小變更
- API 回傳欄位或行為調整
- UI 流程改動但需求常被誤解的功能
跑一輪完整流程,你會很快感受到「返工變少」:不是因為 AI 變聰明,而是因為你把需求對齊的成本,提前付在最便宜的位置。
參考資料