用同一個 AI,為什麼有些專案跑得很順,有些跑到一半卻開始改 A 壞 B?
問題有可能出在模型或 Prompt,但當 AI 開始擁有更多執行權之後,我發現真正難解決的,反而是專案的規格、邊界與驗證。
所以今天想從我自己實際遇到的三個問題開始,聊聊為什麼 AI Coding 做到後面容易越來越歪,以及 Spec-Driven Development 可以怎麼處理這些問題。
AI-DLC 給了一個完整的開發流程:每個階段由 AI 提案、人來確認,確認沒問題之後才繼續往下走。
但問題是,那我們到底要確認什麼?仔細想想,其實就是「規格」。
這也剛好接回昨天最後留下的問題——我們到底要怎麼把「我要做什麼」這件事,清楚地告訴 Claude?
我把 AI Coding 過程中遇到的問題歸納起來,就是以下三件事:
1. 沒有一份「共同依據」的規格
需求散在每段對話裡,AI 每次只看得到當下的 Context,當一個專案沒有明確的共同依據,最後大家只能靠自己的記憶理解需求。
2. 沒有邊界
你請它改 A,它順手把 B 一起「優化」了。
在單次對話裡,這看起來很貼心,但在一個持續開發的專案裡,這將會是個災難,因為我們不會每次都去 review 它多動的那部分。等到發現的時候,那些「順手的優化」已經讓專案偏離當初的設計了。
所以除了告訴 AI「要做什麼」,還需要慢慢把邊界講清楚:
3. 沒有驗證
沒有測試、沒有 CI,判斷「這樣對不對」的唯一方法就是自己手動測試,但問題是,AI 產出的速度可能是人的好幾倍,當產出速度超過驗證速度,錯誤就會開始累積。
所以問題慢慢從:
「AI 能不能寫對?」
變成:
「我們有沒有一個能跟上 AI 產出速度的 Feedback Loop?」
AI 協作我自己分成三層,而「提示詞重不重要」在每一層的答案不一樣。
1. Autocomplete 層
AI 補完一行程式,你立刻看得到對不對 → 人即時驗證
2. Chat 層
AI 沒有寫入權限 → 人複製貼上前驗證
3. Agent 層不一樣
AI 直接改檔案、跑指令、開分支,它自己決定要動哪些地方,在它做完之後才看到結果 → 沒有人在中間驗證
Prompt 解決的是「這一次怎麼告訴 AI」,Spec 解決的是「這一次的決定,要怎麼影響後面的每一次執行」。
三個問題剛好可以對應到 Spec-Driven 的三個核心:
| 我遇到的問題 | Spec-Driven 對應 |
|---|---|
| 沒有一份共同依據的規格 | Spec:定義要做什麼 |
| 沒有邊界 | Plan:定義怎麼做,以及這次不做什麼 |
| 沒有驗證 | Test:定義怎麼知道做對了 |
1. Spec:要做什麼
它的角色是成為這個功能的主要事實來源,讓 AI 不需要依賴某一次對話中的記憶來理解需求。
2. Plan:怎麼做、做到哪裡
把規格拆成有邊界的工作單元,每個單元講清楚這次要動哪些地方。Plan 裡最重要的一段其實是「不做什麼」,沒寫「這次不要碰註冊流程」,AI 有可能就會順手幫你加一個。
3. Test:怎麼知道做對了
測試在這裡不只是開發完成後的驗收清單,而是把 Spec 裡的要求轉成可以被程式反覆驗證的規則。例如你寫在 Spec 裡的「密碼連續錯三次要鎖定帳號」,只有變成一條測試之後,才真的有東西可以持續檢查它。
三件事要合起來才完整。
只有 Spec 沒有 Test,你有一份漂亮但沒人驗證的文件;只有 Test 沒有 Spec,你有一堆測試卻說不出為什麼這樣設計。
以我的實作經驗來說,不管前面的規格寫得多完整,真正開始寫 Code 之後,還是會冒出原本沒想到的事情。
但我後來覺得,這不一定代表流程有問題,因為做系統本來就是這樣:
在真正實作之前,很多事情都還只是我們的推測。
所以我現在比較習慣把實作發現的問題分成兩種。
1. 實作前不可能知道的
例如:
這些事情在還沒有實際碰到之前,本來就很難完全知道,因此,實作之後回頭修改是很正常的。
2. 實作前可以想到的
例如:
這部分就是 Spec-Driven 最能幫上忙的地方:把這些原本可以提前發現的問題,盡量擋在真正開始寫 Code 之前。
所以 Spec-Driven 並不是要做到:
「規劃得夠完整,以後就不用改。」
而是:
「把能提前知道的事情先講清楚,讓實作階段留下真正需要探索的新問題。」
這是我目前對 Spec-Driven 最實際的理解。
明天:知道「要怎麼做」之後,下一個問題就是「怎麼讓 Claude 照著做」。從 Claude Code 開始,先建立我們的第一個 AI 開發環境,以及第一份 CLAUDE.md。