1986 年,Fred Brooks 在 IFIP 世界電腦大會上發表了一篇文章,隔年刊在 IEEE 的《Computer》期刊上,標題是〈No Silver Bullet〉。
開頭是一個民間傳說的比喻:所有夜裡的怪物裡,最可怕的是狼人,因為它會毫無預警地從熟悉的樣子變成恐怖的樣子,所以人們一直在找能一槍放倒它的銀子彈。軟體專案也像這樣,看起來單純無害,卻可能變成進度落後、預算爆掉、產品充滿缺陷的怪物。大家都在等一顆銀彈。
Brooks 的回答是沒有。往後十年內,不會有任何單一的技術或管理方法,能讓生產力、可靠度或簡潔程度提升十倍。
Day 5 引過他的一句話:軟體開發最難的,是決定到底要做什麼。系列的最後一天,再回來把這篇文章讀完整。
Brooks 借用亞里斯多德的分法,把軟體的困難分成兩種。一種是本質的,來自軟體本身:資料、資料之間的關係、演算法,這些概念彼此咬合成一個結構,要把它想清楚、設計好、驗證對,本來就難。另一種是偶然的,來自當下的工具:用某種語言把這個結構寫出來、塞進機器的記憶體和速度限制裡。
他接著算了一筆帳。除非偶然的工作佔了全部心力的九成以上,否則就算把它們縮短到零,也換不到十倍的提升。
過去幾次真正的突破,他認為都是在消除偶然的困難。高階語言讓人不用再管暫存器和位元。分時系統讓人不用再等批次處理,Day 29 談過的 CTSS 就是這一類;他特別寫到,批次的周轉太慢,等結果回來,人早就忘了當初在想什麼。Unix 這種整合的開發環境,用統一的檔案格式和 pipe 把工具串在一起,那是 Day 13 McIlroy 的六行 shell。
他還寫到:就算機器再快十倍,思考的時間仍然會是程式設計師一天裡最主要的活動。接著補了一句,看起來現在就已經是這樣了。
AI coding 可能是到目前為止,對偶然困難最徹底的一次攻擊。打字、查 API 的用法、寫樣板程式,這些時間都在快速趨近於零。Brooks 在 1986 年就覺得思考佔了一天的大半,到了現在,這件事只會更明顯。
剩下的,正好是 Brooks 說的那一半。回頭看這三十天,大部分篇幅其實都在處理它。
最大的一塊,是把要做什麼交代清楚,從 Day 1 的 context 到 Day 24 的說明書,系列有將近一半在處理這件事。Brooks 在文章後段寫得更直接:建構一個軟體系統,最難的單一部分,就是精確地決定要做什麼。模型寫得再快,也不會比外包廠商更知道客戶真正想要的是什麼。
另一塊是驗收,怎麼確認做出來的東西是對的。Brooks 談程式驗證時寫過,就算是完美的驗證,也只能證明程式符合規格;最難的,是得到一份完整而一致的規格,寫程式有很大一部分,其實是在幫規格除錯。Day 5 說沒有規格書的 AI 是一台隨機打字機,談的就是這件事。
其餘幾篇,權限和資安靠的是最小權限這類老原則,談人與組織的那幾篇,引的是 Bainbridge、Goodhart、Solow 幾十年前的觀察。Day 11 乾脆就是 Brooks 自己在《人月神話》裡的定律換了個場景。
先寫一份短的 CLAUDE.md,只放 Claude 讀程式碼也猜不到的事:怎麼跑測試、哪些目錄不要碰、團隊有什麼慣例。Day 3 提過,指令越多不代表越好。接著在權限設定裡把禁止清單填好,永遠不該由 agent 做的事放進去,例如讀取 .env、執行 rm -rf;推送到遠端這類動作設成每次都要確認,這是 Day 8 的內容。
交代任務之前,先把驗收條件寫成測試,讓 agent 改到測試通過為止;任務比較複雜,就先切到 plan mode,在計畫上修正方向,比改完再推翻便宜得多。讓它大範圍改動之前先 commit 一次,Day 28 說過,git 才是最可靠的那道雙向門。
發現自己一直在貼同一段交代,就存成一個 skill。開 PR 之前打 /code-review 先跑一遍,然後自己把改動看懂,Day 18 的重點在後半句。要把任務丟到雲端或 GitHub、人離開電腦之前,先把主分支設成必須經過 PR 才能合併。
這份清單裡沒有一項是新觀念,每一項都比 AI coding 老得多。
Brooks 在 1986 年也沒有把話說死。他寫道,懷疑不等於悲觀;雖然沒有驚天動地的突破,持續、有紀律地把許多小改進做好,加起來還是能換到十倍。沒有捷徑,但有一條路。
AI coding 把偶然的困難削到幾乎看不見,留下的都是老問題,前人大多已經想過答案。三十天走下來,換的是工具,路還是同一條。
延伸閱讀