AI 會寫程式之後,軟體工程真正變貴的是什麼
很多人很容易把這一輪 AI 寫程式的進展,詮釋成「模型正在取代軟體工程師」,甚至「模型正在取代軟體工程」。
這個說法只碰到了表面,卻沒有碰到核心。軟體工程沒有消失,它的重心正在上移。過去 SDLC 昂貴的部分,多半落在撰寫程式碼、處理低階細節、人工重構;現在,既然模型能迅速產生候選實作,昂貴的環節也跟著換了位置。就像高德拉特的 Theory of Constraints 所說,瓶頸會轉移。
問題是,轉移到哪裡?相對於以前,新的瓶頸比較容易處理,還是比較困難?
軟體工程的典範確實在變。變化的重點,是抽象層的提升、驗證負擔的轉移,以及治理形式的重組;工程紀律本身並沒有因此終結。
一、LLM 不是編譯器
軟體工程史上反覆出現的一個主題,是抽象層不斷上升。
早期程式設計高度依賴機器碼與組合語言,人類必須直接處理硬體細節、暫存器配置與控制流程。高階語言與編譯器出現後,指令最佳化能力強,甚至在大多數情況下強過人類,工程師的注意力才逐步從「這些指令怎麼排列」轉向「這個邏輯怎麼表達」。寫法變方便,人機分工更是被徹底重構。
從這個角度看,今天的 LLM 編程確實像是另一輪抽象層提升。人類不再只寫語法層面的指令,更常以自然語言、規格、測試與約束來描述意圖,再由模型生成候選實作。意圖導向、規格導向的開發方式,之所以現在重新變得可行,不是因為理念突然變新,而是因為技術與工具終於開始撐得住。
但這個歷史類比只能用來說明方向,還不足以替後面的結論背書。很多人看到這裡,下一步就想說:既然高階語言取代了低階語言,今天 LLM 也會像編譯器一樣,成為新的工程基礎設施。這個推論太快了。編譯器之所以能成為工程基底,關鍵不在於它很強,而在於它可預期:同樣的合法輸入,在同樣條件下,應該得到語意一致的輸出。
類比的作用,主要是幫你看清「抽象層又上升了一層」。一旦把它延伸成「LLM 已經等同於編譯器」,這個類比就走得太遠了。真正需要記住的差異很簡單:編譯器可以默認信任,LLM 不能。
二、語意層的不確定性
一個常見說法是,現代系統本來就充滿不確定性:快取未命中、垃圾回收時機、JIT 最佳化、多執行緒交錯,哪一個不是非決定性的?既然工程師早就習慣和這些東西共處,那麼 LLM 的不穩定似乎也只是另一種可管理的系統特性。
這種說法最大的問題,是沒有分清楚不確定性發生在哪一層。
傳統系統的非決定性(nondeterminism),大多發生在執行路徑、資源調度與效能表現層面;在設計得當的前提下,系統的語意正確性仍可透過型別系統、同步模型、測試與形式方法加以分析與約束。LLM 的不穩定則更常直接出現在語意建構本身:同樣一個提示,可能對應不同的實作策略、不同的邊界條件假設、不同的錯誤處理方式,甚至引入安全弱點、違反隱含限制,或偏離原始需求。12
這不單純只是「跑法有點抖」而已,而是「你得到的東西本身可能已經換了意思」。
但把話說到這裡,也不能滑向另一個極端,好像 LLM 完全不可工程化。那也不對。在任務範圍受限、提示結構清楚、工具介面穩定、測試充分的條件下,的確可以明顯收斂模型輸出。Anthropic 對 workflow 與 agent 的區分,本身就說明了一件事:工程上真正重要的,是你到底授予了多少自主性,又用什麼外部機制把這種自主性給框限起來。3
更準確的理解方式,是把 LLM 看成候選實作產生器,並且用規格、測試、權限與審計把它包起來。它可以很強,但不能裸奔。45
三、AI 擅長封閉問題
要理解 AI 為什麼能在某些問題上表現驚人,最好的科普其實不是寫程式,而是下棋。
2016 年,AlphaGo 贏了頂尖棋士李世乭固然很了不起,更深遠的意義是,它讓很多人第一次親眼看到:只要規則固定、目標清楚、勝負可判定,而且系統可以大量自我對弈,AI 就能在封閉問題裡快速逼近甚至超過人類。 圍棋雖然複雜,但它仍然是一個封閉世界:棋盤有限,合法動作明確,輸贏標準預先給定。這種問題的難,主要是搜尋空間巨大,不是目標函數模糊。AlphaGo 與後續 AlphaGo Zero 的關鍵,就是把策略學習、價值評估與搜尋結合起來,並透過大量自我對弈持續優化。67
幾年後,AlphaDev 把同一種邏輯用在程式世界。它把「尋找更好的小型排序程式」表述成一個可搜尋的問題:每一步都是組合更好的指令序列,目標函數則相對明確,例如正確性與效能。也正因為目標清楚、評估穩定、搜尋空間可封裝,AlphaDev 才能在某些小型排序問題上找到優於既有人類基準的方案。8
這裡最值得講清楚的一點是:AlphaGo 和 AlphaDev 的勝利,主要來自 AI 在規則封閉、回饋明確、可大量試錯的任務裡,對搜尋的高效率利用。
這也是為什麼它們不能被直接外推到一般企業軟體工程。企業工程面對的通常不是單一且乾淨的目標函數,而是一組彼此牴觸的要求:可維護性、模組邊界、法規遵循、事故可追溯性、部署風險、團隊交接成本、長期總持有成本。這些維度很難被壓成一個簡單分數。局部效能最優,往往不等於系統治理最優。
不同層級的問題,適合不同程度的自動化。 AI 未必能接管所有工程決策。
四、審查重心轉移
代理式工作流的真正衝擊,在於它暴露了一個現實問題:當模型生成候選實作的速度遠快於人工閱讀速度,傳統以逐行 diff 為核心的審查方式,開始難以擴展。
近年來,部分開發者與團隊開始嘗試一種更激進的工作流:人類主要提供需求、規格與目標,模型或代理則負責撰寫程式碼、執行測試、修復錯誤,甚至在一定範圍內自動迭代。如果用更通俗的話來說,人的角色開始有點像導演,而不再只是親自下場逐鏡頭剪片的剪輯師。
這類工作流中,OpenClaw 作者 Peter Steinberger 最具代表性。他讓模型在一個帶有工具、上下文與回合控制的環境裡,自己跑完一段工作流。這時候,人類審查的焦點就可能從逐行閱讀程式碼,轉向評估需求表述是否清楚、系統意圖是否被正確理解、代理執行路徑是否合理、測試結果是否可信,以及最終行為是否真的滿足目標。9
這裡最容易產生的誤解是,以為「不 review code」等於「不再審查」。其實更準確的理解是:審查沒有消失,改變的是審查的對象。 當 AI 能在短時間內產生大量候選實作時,人類不可能再用老的方式逐行追蹤每一段程式;於是,較合理的做法是:把更多信任建立在規格、測試、靜態分析、語意差異辨識與執行證據之上,而不是只建立在肉眼閱讀程式文字之上。
不過,我們不要把 OpenClaw 或 Steinberger 當成普遍結論。它們比較像 F1 賽車:不代表所有人明天都要照那樣開車,但它會提前暴露未來工程可能面對的結構性問題。這些案例的價值,不在於證明「未來所有工程團隊都會這樣工作」,而在於它們把某些本來還不明顯的壓力,提早推到了檯面上。
更值得注意的,其實不是某一個 demo 跑得多炫,而是不同團隊在實作代理式流程時,最後都會收斂到一個很務實的原則:先把能確定、能驗證、能回退的部分做好,再去談更高程度的自治。 Anthropic 在與多個團隊合作建置 agent 的經驗中,也反覆看到這個傾向。真正比較穩的系統,往往不是一開始就追求「讓模型自己決定一切」,而是先把任務切清楚,把工具介面縮小,把失敗後的回收方式設計好,然後再視情況逐步放寬模型可自行決定的範圍。3
這個觀察的意義不只是「先從簡單開始」這種老生常談,而是它揭露了代理式工程的成本函數:自主性不是免費的。 每多給模型一層循環控制、多一個外部工具、多一次可自行決策的機會,就同步提高觀測、驗證、審計與回溯的要求。所謂成熟,不是把 agent 權限一次拉滿,而是知道哪一些判斷值得交給模型,哪一些邊界必須牢牢握在人類手上。
這才是代理式軟體工程真正有趣、也真正讓人不安的地方。工程師沒有突然失業,但未來高價值的審查能力,未必是看得出每一行 code 怎麼寫,而更可能是看得出這套系統的規格是否清楚、證據是否充分、風險是否被控制、責任是否能被追溯。
五、規格開始卡住
如果開發越來越依賴對話、提示與逐步澄清,那麼上下文管理就不再只是使用技巧,而會成為真正的工程問題。
原因很簡單。多輪代理式互動,不是把同一句話反覆說,而是不斷增加限制、修正假設、引用先前輸出、放棄失敗路徑。系統不只要記住內容,還要知道哪些前提已經失效,哪些推論應該撤回,哪些局部探索不應污染全局。10
模型並不是因為「對話變長」才變笨,而是:模型在多輪互動裡,常常不擅長處理自己先前留下來的推論痕跡。 一旦早期對問題的理解有偏差,後面的回合就很容易不是重新定義問題,而是在錯的前提上繼續修修補補。Laban 等人的研究可被理解為對這個現象的系統化描述:對話越長,真正危險的往往不是記不住資訊,而是捨不得放掉先前已經形成的錯誤解釋。10
也因此,後續像 Context Branching 這類做法才有意義。它的重點不是把 prompt 包裝得更花俏,而是把「探索不同解法」這件事,從一條連續對話改成可分支、可切換、可捨棄的工作流。11 這其實是在把版本控制的觀念搬進規格管理:不是所有嘗試都值得留在主線,也不是每一次失敗都應該污染後續推理。
請記住,LLM 的限制不只出現在單次生成的正確率,也出現在規格如何隨著回合演化、修正與隔離。 未來越重要的能力,可能越不是「問得更長」,而是「把探索過程切得更乾淨」。
六、測試開始立法
如果 LLM 與代理式系統開始承擔更多實作、重構與局部迭代工作,那麼測試策略就不能只是沿用舊習慣,而必須重新回答一個問題:測試的作用,到底只是查錯,還是同時負責規定 AI 可以怎麼改、不能怎麼改。
要談這個問題,先得把經典的兩個測試流派講清楚。
所謂 Detroit school,也常被稱為 Chicago school 或 classicist TDD,核心想法是:測試應盡量從系統的外部行為與狀態變化來驗證,而不是過度關注物件之間的互動細節。這一派通常偏好經過真實組合的物件,較少使用 mock;如果某個功能完成後,系統狀態正確、輸出正確、公開介面行為正確,那麼內部到底是怎麼協作的,不一定需要在測試裡寫死。這種思路的好處,是測試通常比較耐重構;只要外部契約沒變,內部怎麼調整,測試不必跟著大改。12
相對地,London school,也就是常說的 mockist TDD,更強調從物件協作與互動設計出發。這一派常採取 outside-in 的開發方式:先從外部需求開始,逐層往內設計物件之間如何分工,並在過程中大量使用 mock 來驗證「誰應該呼叫誰、何時呼叫、帶什麼參數」。這種做法的優點,是它把設計問題提早暴露出來。當你在寫測試時就必須明確定義各個元件如何互動,很多模糊的責任分配會被迫提前釐清。因此,London school 的支持者常認為,測試不只是驗證工具,也是設計工具。13
把兩者壓縮成一句話,可以這樣理解。Detroit / Chicago school 關心的是:最後系統有沒有做對事。 London school 關心的是:系統是不是用我預期的協作方式做對事。
這裡沒有誰對誰錯。它們對應的是兩種不同的風險感知。
如果你最擔心的是重構成本、測試脆弱性、內部設計被過早綁死,那你會更偏向 Detroit。因為它保留了較大的內部實作自由,只要外部結果沒變,系統就能持續演化。 如果你最擔心的是依賴邊界不清、責任分工混亂、元件互動失控,那你會更偏向 London。因為它要求你把協作契約提前講清楚,藉由 mock 讓設計更早成形。
問題在於,到了 AI 參與開發的場景,這兩派的權重會變。
在代理式重構或生成場景中,模型很可能會調整控制流程、替換內部實作、重新切分模組,甚至用一種人類原本沒想到的方式達成同樣的外部行為。如果這時候測試過度綁定方法呼叫次序、參數傳遞路徑與物件互動細節,那麼大量本來有效、甚至更好的重構,都可能被測試判定為失敗。換句話說,過度 London 化的測試,在 AI 場景裡特別容易把「設計選擇」誤寫成「功能規格」。
這正是 AI 時代需要重新審視這場舊爭論的原因。問題已經不只是「哪一派更優雅」,而是「哪一種測試更能區分:什麼是系統真正不能變的東西,什麼只是暫時的實作路徑。」
第一層,對於 AI 需要自由探索、自由重構的區域,測試應更接近 Detroit school 的精神。也就是盡量用公開 API、可觀察狀態、整體行為與高階不變量來定義正確性,而不要過早把內部協作方式寫死。這一層的目的,是替模型保留足夠的搜尋空間,讓它能在不破壞外部契約的前提下,自主改進實作。
第二層,對於那些真的不能亂動的區域,例如對外協定、錯誤處理流程、安全檢查、高成本依賴呼叫、金流與審計事件,London school 的精神仍然有價值。因為在這些地方,我們在意的本來就不只是結果對不對,也在意它是否以正確、可追溯、可受控的方式發生。這時互動測試不是多餘,而是在保護關鍵邊界。
第三層,則是傳統 TDD 爭論較少正面處理、但在 AI 場景中特別重要的一件事:測試不只要檢查答案,還要提供足夠抽象的驗證標準。 只靠單一輸入對單一輸出的例子,對人類手寫程式有時還勉強夠用;對生成式系統來說,這種驗證往往太窄,容易讓模型學會的是「迎合測試」,不是「滿足規格」。也因此,property-based testing 這類方法會變得更重要,因為它驗證的不是個別樣本,而是程式在一整類情境下是否維持某些不變條件。14
所以,比起問「Detroit 還是 London 哪個對」,更值得問的是:哪些測試是在保護真正的外部契約?哪些測試其實只是把歷史實作偶然性誤寫成規格?哪些互動細節真的是安全或合規要求?哪些地方其實應該交給模型自由重構?
AI 時代比較合理的方向,不是在 Detroit 和 London 之間二選一,而是把不同測試放回它們各自最適合的層級。對可自由重構的內部邏輯,應優先保護外部結果與高階不變量;對不能出錯的依賴互動、權限流向與副作用,再用更嚴格的互動驗證去守邊界;至於生成式系統特有的風險,則要再往上補一層,利用 property-based 或 differential testing 去檢查「不同實作是否其實破壞了同一個規格」。15
測試不再只是查錯工具,更像是一套治理語言:一方面給模型留出探索空間,另一方面清楚告訴它,哪裡可以動,哪裡絕對不能動。
七、Clean Code 變了
關於「乾淨程式碼」(clean code),過去最常見的說法是:它能降低人類工程師的理解成本,讓維護、交接與重構變得比較容易。這個說法當然沒有錯。但到了 LLM 參與開發的時代,這套論述還得再往前走一步。今天的問題已經不只是「人看不看得懂」而已,更是:模型能不能穩定理解你給它的程式。
對人類來說,命名差一點、函式大一點,也許還能硬讀;對模型來說,這些東西會直接改變它如何切分問題、辨認模式、推測哪裡是主幹、哪裡只是雜訊。
這裡最容易被低估的一點是,對模型來說,程式碼不是單純的執行對象,也是上下文材料,要根據這些材料去推斷命名意圖、模組邊界、控制流程與可重用模式。程式越雜亂,模型越難分辨什麼是核心結構,什麼只是歷史殘留;越容易把偶然寫法誤判成必要約束,把局部噪音誤當成系統規律。於是,所謂 clean code 在 AI 時代的意義就變了:它不只是讓人比較好維護,也是在替模型降低語意負擔。
Clean code 真的可能有幫助嗎?
Jain 等人的研究,把這件事變成了一個可以測量的假設 16 :如果不急著增加資料量,而是先改善程式碼本身的可讀性與結構性,模型會不會學得更穩?他們不是去改善演算法本身,而是改善模型接觸這段程式時所看到的認知表面。整體方向是:先讓程式的命名更有語意、讓結構更容易分段理解、讓高階步驟更容易被看見。
而結果也很清楚:在程式生成任務上,資料整理得更好,確實能帶來可觀提升;甚至在某些設定下,少量但較乾淨的資料,會比大量但混亂的資料更有價值。這個結論對工程實務非常重要,因為它說明了一件常被忽略的事:在 AI 時代,很多時候真正拉開差距的,不是你餵了模型多少東西,而是你餵進去的材料到底有多容易被正確理解。
這個發現替 clean code 提供了一個新的經驗支持,也改變了我們對工程價值的理解。過去談工程紀律,常常像是在談一種類似「童子軍規則 (The Boy Scout Rule)」的道德心:今天命名清楚、模組分明,未來團隊比較好維護。這當然成立。但在 AI 時代,這些做法不只服務未來的人,也立刻服務當下的模型。你把程式整理得越清楚,模型越容易在較小的語意空間裡工作;上下文噪音越少,生成就越穩定;結構越清楚,幻覺風險和誤解成本就越低。也就是說,傳統工程紀律沒有因 AI 而過時,反而第一次在「機器可理解性」上得到了很強的操作性理由。
在 LLM 時代,乾淨程式碼正在從人類維護性的美德,變成模型可生成性的基礎設施。 對我們這些有品質執念的資深程式設計師來說,真是個好消息。
下一次再談 clean code,不要只問「這樣別人看不看得懂」。還要多問一句:這樣的結構,模型能不能穩定理解、穩定延續、穩定驗證。 這不是審美問題。這是生成條件問題。
八、可治理的程式碼
一旦接受前面的判斷,工程問題就會改寫成另一句話:不是能不能生成 code,而是能不能生成可被安全吸收、可被驗證、可被審計的 code。
這至少包含三層要求。
第一層是執行隔離。未經驗證的 AI 輸出,不應直接跑在高權限、真實資料或可對外互動的環境中。候選實作的執行,本身就是安全決策,而不是普通的開發便利功能。17
第二層是語意審查與變更理解。當產出速度遠超過人工閱讀速度,人類不可能只靠文字 diff 理解變更影響。未來的審查機制勢必更依賴語意差異分析、結構化重構辨識、靜態檢查與契約違反提示,協助人類把注意力集中在真正改變業務邏輯、權限流向與風險邊界的地方。18
第三層是高保證驗證。對多數一般系統來說,單元測試、整合測試與模擬環境已足夠吸收大部分風險;但在安全關鍵、金流、基礎設施與高合規場景,這些往往不夠。這時更形式化的狀態建模、模型檢查與規格驗證方法,就可能成為必備品。19
這一切都指向同一個事實:生成加速了,但驗證不會因此自動變簡單。很多時候,它只會變得更重要。
九、樂觀主義的邊界
坊間流傳很多樂觀派說法。像「AI 明天就會取代工程師」這種口號不必認真對待,真正需要認真回應的,是它的強化版本:真實軟體工程 benchmark 確實在快速進步,代理式 coding 正在逼近大規模可用門檻。
的確,以 Copilot 的實驗來看,生成式工具已經能在受控任務中帶來明顯的速度提升。20 而從 SWE-bench 這類更貼近真實 issue resolution 的 benchmark 來看,代理式 coding 也確實已經跨過了早期那種「只能做玩具題」的階段。21
但也正因為能力上升得夠快,benchmark 本身開始暴露出另一層問題。OpenAI 在 2026 年不再把 SWE-bench Verified 視為前沿能力的好指標,並不是因為它不重要了,而是因為模型越接近高分,測試設計缺陷、資料污染與任務定義模糊,就越會主導最後的評估結果。22
所以,這不是一份單純的捷報,而更像是一份壓力測試報告:當模型還不夠強時,大家關心的是它會不會做;當模型開始會做時,大家才突然發現,真正決定結果是否可信的,是測試到底有沒有設計好、規格到底有沒有寫清楚、驗證到底有沒有跟上。
因為它真正說明的,不是「工程快要不重要了」,而是「當模型更強時,規格、測試與 benchmark 設計反而變得更重要」。一旦能力上來,先暴露出來的不是工程不再需要,而是驗證與治理的缺口被照得更亮。這恰恰回到本文的中心命題:能力提升,沒有讓治理退場,反而把治理的必要性放大了。
你的治理能力,有跟著提升上來嗎?這才是值得擔心的。
結論
歷史是良師。當年從組合語言過渡到 C 語言,人類並沒有完全放手,而是在更高的抽象層級上重新建立了約束體系:結構化程式設計、模組化、型別系統。這些約束不是為了限制編譯器,而是為了確保人類仍然能在必要時理解和控制系統。
LLM 時代的轉折也很類似。「把邊界限縮到可掌握的顆粒度」這個原則沒有消失,只是往上遷移到更高的抽象層級:從「人類要看懂每一行程式碼」,遷移到「人類要看懂每一個模組的意圖與契約」,再到「人類要看懂系統的架構決策與約束框架」。
想把這一輪變化看清楚,要先問對問題。不要再問「AI 會不會取代程式設計」——那是一個太粗、太淺、也太容易把討論帶偏的問題;真正值得問的是:誰在定義規格?誰在驗證結果?誰在控制權限?誰在承擔後果?
如果這四件事沒有被設計好,模型越強,風險只會越大。 如果這四件事被設計好了,模型越強,工程收益才可能真正放大。
至於將來是否會出現像 AlphaGo 那樣徹底超越人類認知框架的時刻?也許會。但在那之前,我們需要的不是盲目的信任,或盲目的不信任,而是像編譯器時代一樣,在新的抽象層級上,重新建立一套人類能夠理解和掌控的約束體系。只是這次,那套約束體系的名字可能叫做 harness、validation loop、architectural guardrails,而不是 structured programming 和 SOLID。
-
Liu, Fang, et al. “Exploring and Evaluating Hallucinations in LLM-Powered Code Generation.” 2024. ↩︎
-
Zhang, Ziyao, et al. “LLM Hallucinations in Practical Code Generation: Phenomena, Mechanism, and Mitigation.” 2024. ↩︎
-
Anthropic. “Building Effective AI Agents.” 2024/2025. ↩︎ ↩︎
-
Shavit, Yonadav, et al. Practices for Governing Agentic AI Systems. OpenAI, 2023. ↩︎
-
Google DeepMind. Frontier Safety Framework 2.0, 2025. ↩︎
-
Silver, David, et al. “Mastering the game of Go with deep neural networks and tree search.” Nature 529 (2016): 484–489. ↩︎
-
Silver, David, et al. “Mastering the game of Go without human knowledge.” Nature 550 (2017): 354–359. ↩︎
-
Mankowitz, Daniel J., et al. “Faster Sorting Algorithms Discovered Using Deep Reinforcement Learning.” Nature 618 (2023): 257–263. ↩︎
-
Steinberger, Peter. “Shipping at Inference-Speed.” 2025. ↩︎
-
Laban, Philippe, C.-S. Wu, et al. “LLMs Get Lost In Multi-Turn Conversation.” 2025. ↩︎ ↩︎
-
Nanjundappa, Bhargav Chickmagalur, and Spandan Maaheshwari. “Context Branching for LLM Conversations: A Version Control Approach to Exploratory Programming.” 2025. ↩︎
-
Fowler, Martin. “Mocks Aren’t Stubs.” 2007. ↩︎
-
Freeman, Steve, and Nat Pryce. Growing Object-Oriented Software, Guided by Tests. Addison-Wesley, 2009. ↩︎
-
He, Lehan, et al. “Use Property-Based Testing to Bridge LLM Code Generation and Validation.” 2025. ↩︎
-
“Differential Testing with LLMs using Natural Language Specifications and Code Artifacts.” 2025. ↩︎
-
Jain, Naman, et al. “LLM-Assisted Code Cleaning For Training Accurate Code Generators.” 2023 / ICLR 2024. ↩︎
-
Perrone, Giuseppe, et al. “WebAssembly and Security: A Review.” 2024. ↩︎
-
Tsantalis, Nikolaos, Ameya Ketkar, and Danny Dig. “RefactoringMiner 2.0.” IEEE Transactions on Software Engineering 48, no. 3 (2022): 930–950. ↩︎
-
Lamport, Leslie. Specifying Systems: The TLA+ Language and Tools for Hardware and Software Engineers. Addison-Wesley, 2003. ↩︎
-
Peng, Sida, et al. “The Impact of AI on Developer Productivity: Evidence from GitHub Copilot.” 2023. ↩︎
-
SWE-bench. Official Leaderboards. ↩︎
-
OpenAI. “Why SWE-bench Verified no longer measures frontier coding capabilities.” 2026. ↩︎