當 AI 寫完所有程式碼,工程師還要看什麼?Uncle Bob 與 Matt Pocock 的回答
當 Uncle Bob 用工程指標重構對 AI 的信任,Matt 則反問:當戰術實作交給 AI,工程師真正的戰略價值為何?
最近看了 Matt Pocock 與 Robert C. Martin,也就是「Uncle Bob」的對談。
最令我意外的,不是這位寫出《Clean Code》的資深工程師已經開始大量使用 AI Agent,而是他正在努力讓自己完全不必閱讀 Agent 寫出的程式碼。
一位長年提倡程式碼品質的人,最後竟然選擇不看程式碼,聽起來多少有些矛盾。
不過,仔細聽完整場對談就會發現,Bob 並不是不在乎程式碼,也不是把工作丟給 Agent 後就放任不管。他真正做的,是把品質保證從「人工逐行閱讀」,轉移到一套可以重複執行、產生明確結果的驗證系統。
而 Matt 在這場對談裡,也不只是負責提問。
他從多 Agent、Context Trajectory、Deep Module、開發成本與新人養成切入,不斷追問同一件事:
當程式碼的生產不再稀缺,軟體工程真正困難的部分會移到哪裡?
寫《Clean Code》的人,真的完全不看程式碼了嗎?
「Bob 已經完全不看 AI 寫的程式碼」是一句很吸引人的說法,但若仔細還原他的描述,會發現實際情況更細緻。
Bob 的目標,是讓自己盡可能不必逐行檢查 Agent 的實作。他會查看 CRAP 分數、執行各種自動化測試、觀察模組與依賴關係,也會偶爾抽查程式碼。
所以,他不是對 Agent 產生了無條件的信任。
他只是認為,當 Agent 寫程式碼的速度遠遠超過人類,如果每一行仍然要由人類重新閱讀,AI 帶來的速度優勢最後就會卡在人類身上。
他不是取消 Review,而是重新設計 Review 發生的位置與形式。
過去,工程師透過閱讀程式碼判斷成果是否值得信任;Bob 現在嘗試做的,是讓工具、測試、架構與驗收結果共同提供證據。
人類不必看完所有實作,但必須知道應該看哪些訊號。
Agent 寫得愈快,混亂也可能累積得愈快
Bob 一開始使用 Agent 的經驗,跟許多人很像。
Agent 可以快速完成一項功能,卻也會留下重複邏輯、複雜函式、不完整的測試,以及各種沒有清理乾淨的程式碼。當 Bob 繼續交付下一個任務,這些問題便逐漸累積。
一開始,Agent 仍然可以繼續工作。
但隨著程式碼愈來愈混亂,它開始為了修正一個問題而破壞另一個地方;修好第二個問題後,又讓第一個問題重新出現。整個過程不斷繞圈,速度愈來愈慢,最後甚至無法完成任務。
這個現象其實不陌生。
人類工程師面對充滿耦合、命名混亂、責任不清的系統時,也會遇到相同問題。每次修改都必須同時記住大量隱含關係,任何小變更都可能引發意料之外的連鎖反應。
Agent 或許可以承受比人類更高的複雜度,但它仍然存在極限。
一旦超過那個門檻,生成速度再快,也只是在更快地累積問題。
這也解釋了為什麼 Clean Code 在 AI 時代並沒有失去意義。
整潔的程式碼不只是為了讓人讀起來舒服,而是為了控制系統複雜度。
只要 Agent 還需要理解既有程式碼、追蹤依賴並持續修改系統,它就同樣需要清楚的結構。
真正的轉折:從閱讀程式碼,改成閱讀證據
遇到 AI 產生品質不佳的程式碼,多數人的第一個反應,是繼續增加提示詞規則:
函式不可以太長
必須遵守 Clean Code
所有功能都要有測試
不可以破壞原有架構 Bob 也曾經這麼做。
他的初始提示詞一度累積到五頁、十頁,詳細描述 TDD、Clean Code 與各種開發規範。問題是,這些規則對模型而言,可能只是一種「建議」。
隨著工作持續,Context 不斷增長,原本重要的規則逐漸被推到上下文中間。Agent 對這些內容的注意力開始降低,最後變成選擇性遵守。
Bob 因此採取另一條路。
他將初始提示詞縮減到最小,只留下真正重要的任務方向;至於程式碼品質,則交給具有確定性結果的工具。
提示詞可能被忽略,但檢查失敗就是失敗。
這套方法的關鍵,不是設法寫出一段永遠不會失效的完美 Prompt,而是把模糊的品質期待轉換成 Agent 必須通過的機械化關卡。
CRAP 分數:讓「程式碼太複雜」不再只是一種感覺
Bob 重新採用的第一項工具,是 CRAP(Change Risk Anti-Patterns)分數。
CRAP 會綜合循環複雜度與測試覆蓋率,判斷一個函式是否過於複雜,卻又缺乏足夠的測試保護。
如果函式太複雜,Agent 就必須拆分它;如果測試覆蓋不足,就必須補上測試。
這比在提示詞裡寫一句「請保持函式簡潔」明確得多。因為不管 Context 累積了多少內容,檢查工具都會按照相同標準執行。
有意思的是,Bob 沒有直接照搬過去為人類設定的門檻。
他原本希望人類撰寫的函式將 CRAP 分數控制在 4 以下,但面對 Agent 時,則嘗試放寬到 6,甚至考慮繼續調整。
這代表 Clean Code 背後的價值沒有改變,但實際門檻可以依 Agent 的能力重新校準。
突變測試:測試通過,不代表測試值得信任
只有 Code Coverage 還不夠。
測試可能執行了每一行程式碼,卻沒有真正確認結果。即使把條件判斷寫反、移除重要呼叫,整套測試仍然可能保持綠燈。
突變測試(Mutation Testing)會刻意修改正式程式,例如反轉條件、替換運算子或移除方法呼叫,再重新執行測試。
如果測試沒有失敗,代表這項錯誤沒有被偵測到,也就是出現了「存活的突變」。
Agent 接下來必須找出測試缺口、補上有效的驗證,直到這些突變都能被測試抓出來。
Bob 早在多年前就嘗試過這項技術,但當時執行成本太高,很難放進日常開發流程。如今,Agent 不怕枯燥、重複又耗時的工作,反而讓這些過去太昂貴的品質技術重新變得實用。
AI 帶來的價值,因此不只是更快產生功能。
它也提供了足夠便宜的執行能力,讓團隊可以把品質檢查做得更加徹底。
不是一個超級 Agent,而是一條品質生產線
Bob 沒有要求同一個 Agent 從需求分析、程式撰寫、重構一路負責到最終驗收,而是將工作拆成幾個角色:
規格定義 Agent
→ 程式撰寫 Agent
→ 程式清理 Agent
→ 品質強化 Agent
→ QA Agent 規格定義 Agent 先把人類描述的需求,轉換成 Gherkin 驗收條件與 QA 操作程序。
程式撰寫 Agent 負責單元測試、正式程式與功能實作;清理 Agent 執行 CRAP 分析與一般程式碼檢查;品質強化 Agent 使用突變測試找出測試缺口;最後,QA Agent 從使用者角度操作系統,產生可驗證的結果。
這套流程不一定比單一 Agent 快。
一項原本幾分鐘就能完成、但品質未知的任務,經過完整流程可能需要一小時。Bob 接受這個取捨,因為他要的不是最快產生程式碼,而是在仍然保有速度優勢的前提下,提高成果的可信度。
不過,Matt 對多 Agent 並非全盤接受。
他對「建立一整間 AI 公司」、替數十個 Agent 設計職稱,甚至讓它們彼此通訊的做法有所懷疑。他認為,多 Agent 真正有價值的地方,不在角色數量,而在能否把認知負擔不同的工作分開。
例如,實作 Agent 只需要讓功能運作;Review Agent 已經有明確的 Diff,可以直接針對變更內容檢查,不必重新探索整個問題。
多 Agent 的重點不是模仿人類的組織架構,而是讓每個 Context 只承擔一種清楚的責任。
角色如果只是名稱不同,實際上卻讀取相同資料、執行相似工作,就只是增加溝通成本。
Agent 不只會忘記,也會被自己的歷史綁住
Bob 關注的是 Lost in the Middle。
當 Context 愈來愈長,開頭的重要規則會被推到中間,逐漸失去影響力。Matt 則補上另一個很值得注意的概念:Context Trajectory。
Context 不只是裝了哪些資訊,也會累積一條思考軌跡。
如果 Agent 在工作初期選擇了某個方向,後續判斷往往會繼續沿著相同路徑前進。即使人類不斷修正,它也可能只是站在原有假設上補洞,而沒有真正重新思考問題。
例如,Agent 一開始認為某個問題應該從 UI 測試處理,後續每次修改便可能持續回到 UI。對話中愈來愈多內容支持這條路徑,其他可能性則愈來愈難進入它的判斷。
有時候,繼續在原本的 Session 裡糾正,並不能真正改變方向。
結束這個 Context,將清楚的產出交給新的 Agent,反而比較有效。
因此,Bob 的多 Agent 流程也可以理解成:
接受一項明確任務
→ 產生可交付結果
→ 結束目前 Context
→ 由下一個角色重新檢查 工作交接不只是分工,也是在切斷可能已經偏離目標的思考慣性。
好的模組化,也是在替 Agent 節省 Context
談到架構時,Matt 引入 John Ousterhout 的 Deep Module 概念。
Deep Module 透過小而簡單的介面,隱藏內部較多的實作複雜度。使用者只需要理解模組提供什麼能力,不必知道所有內部細節。
Matt 認為,這種設計特別適合 Agent。
如果模組具有清楚、穩定的介面,Agent 只要理解介面與相關測試,就能使用這項能力,不必每次都把底層實作全部載入 Context。
對人類而言,抽象可以降低理解成本;對 Agent 而言,抽象同時也是一種 Context 管理技術。
Bob 也從自己的實驗補充了這個觀點。
他讓 Agent 建立架構檢視工具,以類似 UML 的方式呈現模組與依賴關係;同時使用確定性檢查,定義哪些模組可以互相依賴、依賴方向應該如何流動。
只要 Agent 違反架構規則,就必須反轉依賴、插入介面或重新拆分模組。
這也揭露了「不看程式碼」真正的邊界。
Bob 可以減少閱讀個別函式,但他並沒有放棄觀察系統結構。他仍然關心:
- 系統被切成哪些模組
- 模組的責任是否清楚
- 模組之間如何互動
- 依賴方向是否正確
- 測試是否能偵測行為改變
- Agent 是否開始反覆修改、原地打轉
人類並沒有離開開發流程,而是從檢查每一段實作,轉向管理整個系統如何組織複雜度。
保留工程價值,不必複製人類的工作儀式
另一個令我印象深刻的觀點,是 Bob 對 TDD 的重新思考。
他仍然是 TDD 的支持者,卻不認為應該強迫 Agent 完全遵循人類的 Red、Green、Refactor 節奏。
TDD 的操作方式,是針對人類的注意力、短期記憶與行為弱點所設計。先寫一個失敗測試,再撰寫最少量的程式使它通過,可以限制人類一次處理的範圍,避免在腦中同時承載太多問題。
但 Agent 的能力與限制不同,未必需要採用一模一樣的工作節奏。
Bob 因此做出一個很重要的區分:
不應放棄人類重視的品質價值,但不必強迫 Agent 模仿人類實踐價值的每一個動作。
測試仍然重要,可維護性仍然重要,低複雜度也仍然重要。
至於 Agent 是先寫一個函式再補測試,還是嚴格按照人類的 TDD 節奏逐步執行,則可以根據實際效果調整。
我們真正需要管理的是結果、證據與風險,而不是要求 AI 表演一套看起來像專業工程師的工作儀式。
AI 降低了修改成本,卻沒有消除做錯事情的成本
AI Agent 很喜歡寫計畫。
只要提出需求,它就能產生條理完整、細節豐富,看起來近乎完美的規格。但計畫寫得漂亮,不代表實際執行時不會崩潰。
Bob 因此對 Spec-Driven Development(SDD,規格驅動開發)抱持懷疑。
他特別警惕的,是企圖在開發前就把所有細節定義完整,再期待 Agent 一次實作成功的做法。這很可能讓軟體業重新走回重型前期規劃的瀑布式思維。
Bob 用一棟房子做比喻。
假設蓋地基、改屋頂或移動樓梯,每次變更都只需要一美元,我們還會先花一千美元請建築師設計一份不容更動的完美藍圖嗎?
還是先蓋出一部分,實際走過一次,再根據結果調整?
當 Agent 大幅降低修改成本,快速迭代可能比預測所有細節更有價值。
但 Matt 也補上一個必要的限制。
AI 大幅壓縮的主要是實作時間。需求判斷、前期規劃、完成後的 Review,以及決定「這是不是我們真正要做的東西」,並沒有按照相同比例縮短。
修改做錯的東西變便宜,不代表做錯的東西沒有成本。
此外,Matt 也指出,SDD 這個詞的範圍非常模糊。只要在實作前與 Agent 對齊方向,也可以被稱為規格驅動;甚至每一段 Prompt,都可以視為一種規格。
因此,真正需要區分的可能不是「有沒有 Spec」,而是團隊如何看待 Spec:
- 它是這次工作的短期對齊工具嗎?
- 它會隨著實作與回饋持續調整嗎?
- 還是被當成完整定義整個系統的永久藍圖?
Bob 的流程本身仍然會產生 Gherkin 與 QA 程序。他反對的不是「說清楚這次要完成什麼」,而是相信一份龐大規格可以在開發開始以前,就消除後續所有未知。
比較合理的節奏仍然是:
完成少量功能
→ 取得實際回饋
→ 檢查程式與架構
→ 重新整理
→ 再完成下一小段 規格用來引導下一步,不是用來假裝未來已經完全可知。
Agent 會讀人類的規格,人類卻讀不完 Agent 的輸出
Matt 在對談中還指出一個很有趣的不對稱關係。
人類收到一份冗長規格,不一定真的會讀完;Agent 收到文件,至少會把它放進 Context。
反過來,Agent 產生大量計畫、說明、測試與程式碼後,人類通常也不會全部閱讀。
這表示未來人機協作的問題,不只是「如何讓 Agent 聽懂人類」,還包括:
當 Agent 產生的內容遠遠超過人類的閱讀能力,人類要靠什麼掌握結果?
如果答案仍然是把所有內容重新看過一次,人類就會成為無法擴充的瓶頸。
Bob 的確定性工具、架構圖、測試結果與 QA 流程,可以視為這個問題的一種回答。
人類不需要消化 Agent 的所有輸出,而是需要一套能夠壓縮結果、呈現風險並提供可信證據的介面。
從這個角度來看,未來的工程工具不只要幫 Agent 寫得更快,也必須幫人類看得更高。
Agent 擅長戰術,人類必須學會戰略
對談後半段,Matt 引入戰術程式設計與戰略程式設計的區分。
戰術程式設計是完成眼前的函式、測試與功能;戰略程式設計則是判斷系統如何演進、複雜度應該放在哪裡,以及今天的選擇會在幾個月後帶來什麼代價。
Agent 很擅長戰術,卻不擅長戰略。
這也帶來一個棘手的人才問題。
新人過去正是透過大量戰術工作,逐漸學會辨識架構問題與長期代價。如果這些任務都被 Agent 接走,公司只想留下能夠管理 Agent 的資深工程師,那麼下一代資深工程師又要從哪裡出現?
Bob 的答案,並不是讓新人跳過程式碼。
他認為新人仍應花一段時間親自寫程式,理解 Agent 實際面對的問題。從二進位、組合語言、C,到更高階的語言與 Agent 工作流,這些基礎能幫助工程師理解每一層抽象背後究竟發生了什麼。
進入大量使用 Agent 的團隊後,新人甚至可以先像 Agent 一樣接受範圍明確的小型任務,通過相同的測試、品質工具與資深工程師監督。
一開始的產出可能很低,但目的不是和 Agent 比速度。
目的是透過親手實作、除錯、失敗與修正,建立辨識問題的能力。只有自己曾經在混亂的系統裡受挫,才比較有機會看出 Agent 何時正在重演相同的錯誤。
Matt 則提出另一個可能性。
AI 雖然拿走了一部分傳統練習機會,卻也大幅縮短開發與回饋週期。過去一項錯誤的架構決策,可能九個月後才出現後果;工程師甚至可能在看見結果以前就已經離開專案。
當 Agent 加快系統演進,同樣的問題也可能更早暴露。
新人或許失去了一部分手動撰寫程式碼的機會,卻有機會在更短時間內觀察更多決策、結果與修正。
AI 一方面抽走傳統的學習階梯,另一方面也可能建立更快速的經驗回饋迴路。
真正的問題,不只是新人還要不要寫程式,而是團隊能否重新設計一條讓新人取得經驗、看見後果並逐步承擔策略責任的路徑。
不看程式碼,其實需要更多工程能力
Bob 可以不把時間花在逐行閱讀 AI 產生的程式碼,不是因為他對 AI 有無條件的信任,而是因為他知道信任必須建立在哪些證據上。
他把模糊的品質期待轉換成可以執行的檢查,把不同工作交給具有明確責任的 Agent,再由人類負責架構、回饋與策略判斷。
Matt 的追問則讓這套方法不只停留在工具層次。
Context 會形成軌跡,多 Agent 不一定愈多愈好;好的抽象可以降低 Agent 的理解成本;AI 只壓縮了部分開發成本;而新人取得工程經驗的方式,也必須跟著改變。
「Human in the Loop」不代表人類必須閱讀每一行輸出。
當程式碼生成速度超過人類閱讀速度,硬要維持相同的 Review 方式,只會讓人類成為整條流程最慢的一環。
更合理的方向,是重新思考人應該在哪些位置介入。
工程師真正需要負責的,將逐漸從「親手產生每一行程式碼」,轉向:
- 定義什麼叫正確
- 建立能夠證明正確的工具
- 設計清楚的模組與抽象
- 觀察 Agent 是否開始失去方向
- 判斷目前做的是不是正確的事情
- 為系統的長期演進承擔責任
軟體工程的基本功並沒有因為 AI 而過時。
正好相反。
當程式碼變得便宜,真正昂貴的就不再是把功能寫出來,而是控制複雜度、辨識錯誤方向,以及建立一套讓快速產出仍然值得信任的系統。
這或許才是 Bob 能夠不看 AI 程式碼的真正原因。
不是他不再需要 Clean Code,而是他已經把 Clean Code 背後的價值,從個別程式碼搬進整套工作流程裡。
