本文整理自 Dave Farley 的影片 I Said This Years Ago: Why Prompting AI Code Fails (And What Works)(Modern Software Engineering 頻道),並加上我的觀察。
AI 寫程式時,人類真正的工作只剩一件:把「要什麼」寫成一份會失敗的規格。
這是 Dave Farley 在影片裡的核心主張。他是《Continuous Delivery》的作者之一,推動驗收測試驅動開發(ATDD)超過二十年。
有趣的是,他發現 Bob Martin、Kent Beck、Adam Tornhill、OpenAI 的 Sean Grove、Emily Bache,甚至 Anthropic 官方的 Claude Code 指引,各自走到了同一個結論:
- 不要只給 AI 一段 prompt
- 也不要只給它一份 markdown 文件
- 要給它一份能執行、能驗證的規格
這篇文章用最白話的方式,整理他的論點。
一、寫程式從來不是最難的部分
Farley 認為,寫軟體一直有三個難題:
- 說清楚:我們到底要什麼?
- 確認對:做出來的東西,真的是我們要的嗎?
- 走小步:每一步要小到偏離方向時能馬上發現。
AI 只解決了「產出程式碼」這件事,對這三個難題完全沒幫助,甚至讓它們更難:
| AI 帶來的問題 | 結果 |
|---|---|
| Prompt 比程式碼模糊 | 更容易被誤解 |
| 模型常常改超過你要求的範圍 | 你不確定原本正常的功能是否還正常 |
| 一分鐘產出上千行 | 很容易一步跨太大,重要的變更被淹沒在雜訊中 |
有人一天用 agent 產出一萬兩千行程式碼。沒有人能認真審查這麼多。所以真正的問題不是「AI 能寫多快」,而是**「我們能多快知道它寫得對不對」**。
Kent Beck 有句話說得很好:AI 幫你完成 80% 的薪資系統,等於完成 0%。
驗證,才是瓶頸。
二、叫 AI 自己補測試?沒用
很多人的直覺是:那就讓 AI 把測試也寫一寫。
問題在於,如果 AI 是寫完程式碼之後才寫測試,測試唯一的依據就是那段程式碼。
這樣的測試只能證明「程式做了它本來就在做的事」,沒辦法告訴你「它做的是不是你要的事」。
意圖必須來自人,而且要寫成可以拿來量測結果的形式。
三、Spec-Driven Development 對了一半
2025 年,業界開始流行「規格驅動開發」(Spec-Driven Development,SDD):GitHub 推出 Spec Kit,Amazon 推出 Kiro,ThoughtWorks 也把它放上技術雷達。
Farley 同意它的診斷:不能只靠感覺指揮 AI,必須先寫清楚要什麼。
但他不同意做法,因為這些規格大多是 markdown 散文。實際用過的人遇到同樣的問題:
- Gojko Adzic(《Specification by Example》作者):markdown 規格缺少大量細節,真正的規格最後還是落在單元測試和整合測試裡。
- Birgitta Böckeler(ThoughtWorks):就算有一堆檔案、範本、檢查清單,agent 還是常常不照做。
- Colin Eberhardt(Scott Logic):程式碼是形式語言,可以推理、測試、證明對錯;markdown 規格沒有這種嚴謹性。
一句話總結:
不會變紅的規格,只是比較長的 prompt。
AI 讀完規格,做出不符合的東西,你不會知道,它自己也不會知道。因為沒有任何東西失敗,沒有任何東西變紅。你又回到逐行讀程式碼、祈禱一切順利的老路。
四、可執行規格長什麼樣子
關鍵是:寫規格和驗證規格,必須是同一份東西。 這樣規格就不可能和程式碼脫節,因為一脫節,build 就會壞。
Farley 舉的例子:
Given 一位顧客的購物車裡有一本書When 他套用折扣碼 SUMMERThen 購物車總額減少 10%
注意沒有寫出來的東西:沒有 HTTP、沒有按鈕、沒有資料表、沒有類別名稱。它只說系統該做什麼,完全不提怎麼做。
這不是寫作風格,而是重點所在。描述「怎麼做」的規格不是規格,而是設計。一旦有人(或 AI)找到更好的設計,它就會壞掉。
四層架構
為了讓這種規格真的能跑,Farley 把測試分成四層:
| 層 | 負責什麼 | 例子 |
|---|---|---|
| 1. 測試案例 | 用問題領域的語言描述行為 | 上面的 Given/When/Then |
| 2. DSL | 把行為變成可重用的操作 | 「套用折扣碼」 |
| 3. Protocol Driver | 知道怎麼跟真實系統溝通 | 透過 UI、API 操作 |
| 4. 受測系統 | 真正的程式 | 由 AI 實作 |
規格在最上層,技術細節全部壓在最下層。整個框架換掉、甚至改用另一種語言重寫,規格依然成立。
這不是新點子。Farley 2007 年在 LMAX 就這樣做,每次 commit 跑上萬條規格。新的是誰受惠:「what」和「how」分開,剛好就是 AI agent 需要的契約。
- 在怎麼做上,AI 擁有完全的自由
- 在做什麼上,AI 沒有任何自由
規格就是 AI 的評分標準,也是它必須通過的考題。
五、三條馬上能用的規則
軟體開發一直是一連串的翻譯:
模糊的願望 → User Story → 具體範例 → 可執行規格 → 可運作的軟體
AI 負責最後一步,人類擁有前面三步。Farley 說:如果你想不出例子,代表你還不夠理解問題。
具體怎麼做?三條規則:
規則 1:先寫規格,看它失敗
一次只寫一個情境(scenario),先跑,確認它是紅的,再讓 AI 去實作。
紅燈不是儀式。在 AI 時代,紅燈證明你的規格有能力抓到錯誤答案。一條從沒紅過的測試,你不知道它到底有沒有在檢查東西。
規則 2:別讓 AI 碰規格
Kent Beck 和 Emily Bache 都遇過同樣的事:AI 為了讓測試通過,直接把失敗的測試刪掉。
驗收測試就是契約。要嘛放在 AI 改不到的地方,要嘛把每一次修改都當成契約變更,由人類批准。
規則 3:一次走一小步
一個情境 → 紅 → 綠 → 檢查 → commit。
不是 AI 需要小步,而是小步才能讓我們在犯錯還很便宜的時候發現錯誤。AI 拿著模糊需求產出三千行,就是一大步。Code review 看不出那是好的一步還是一次踉蹌。
六、常見質疑,Farley 怎麼回
| 質疑 | Farley 的回應 |
|---|---|
| 這不就是瀑布式? | 一次寫完整份 markdown 規格才是瀑布。ATDD 一個情境只有幾行,寫完、變紅、變綠、再寫下一個,比多數團隊的迭代還細。 |
| 小工作包跟 SDD 的精神矛盾 | 小工作包本來就是 ATDD 的核心。 |
| 不讀程式碼會累積認知債 | 可執行規格不是叫你別讀碼,而是讓「讀不讀」變成依風險決定的選擇,而不是每一行都得讀的義務。 |
| 驗收測試又慢又脆,斷言又少 | 寫得爛的驗收測試確實如此,比沒有還糟。解法是用四層架構跟 UI 解耦,再搭配 mutation testing:變異存活下來,就代表規格有漏洞。 |
| AI 寫的測試不算 TDD | 同意。所以 AI 可以起草,但必須由懂問題的人擁有並批准,才算是規格。 |
七、Farley 沒說的事
我大致同意這支影片,但有幾個地方值得多想一層。
1. 範例從哪裡來?
Farley 說人類要擁有「願望 → 故事 → 範例」這三步,卻幾乎沒講怎麼做好。
在他的敘事裡,好像只要「懂問題的人」就能寫出規格。但實務上最難、也最有價值的,恰恰是產生範例的那段對話:業務、開發、測試坐下來,用具體例子把模糊的需求逼出邊界,發現彼此理解不同的地方。
規格要能執行,但規格也要靠對話才寫得出來。 這正是 Specification by Example 想補上的那一塊。
2. 規格只能驗證你想到的事
效能、易用性、安全性、「用起來就是怪怪的」,這些很難寫成 Given/When/Then。
可執行規格擅長確認已知,但對沒想到的事無能為力。這是探索性測試的位置,而影片完全沒有提到。兩者是互補,不是替代。
3. 細節常常在實作時才浮現
Gojko 發現 markdown 規格缺細節、真正的規格最後落在測試裡。Farley 把它解讀成「所以規格要可執行」。
但另一種讀法是:很多細節要動手做了才會出現。規格本身也需要在過程中被發現、被修正,不能假設人類事先就全部知道。
4. 留意「共識」的修辭
影片引用的人物,其實立場差異不小。例如 Bob Martin 完全不讀 AI 寫的碼,但 Emily Bache 的調查顯示多數實踐者仍然會讀。
結語
AI 讓寫程式變得很便宜,但讓「知道寫得對不對」變得更貴。
Farley 的答案很直接:Vibe coding 不是我們能做到的最好,markdown 規格也不是。規格必須能執行。
我會再補一句:規格也必須從對話中長出來,並且搭配探索去發現它沒想到的事。
三個重點帶走:
- 先寫一個情境,看它變紅,再讓 AI 實作
- 把驗收測試當契約,不讓 AI 自行修改
- 一次一小步:紅 → 綠 → 檢查 → commit
來源
- Dave Farley, I Said This Years Ago: Why Prompting AI Code Fails (And What Works), Modern Software Engineering(YouTube)
發佈留言