Journal
AI 協作系列|第 4 篇:AI 協作開發的複雜度問題
承接 第 0 篇 的脈絡。系列的最後一篇。
一個我越來越在意的擔心
我有一個擔心,說出來之前我自己也不確定有多真實:AI 協作開發,會不會讓 codebase 越來越複雜?
不是因為需求複雜,而是因為 Agent 在設計上傾向往複雜的方向走。
說「傾向」是因為這不是必然的,而是一個我觀察到的模式。Agent 看到一個問題,容易想到的解法常常包含:加一個抽象層、抽一個 utility、新增一個 config option、引入一個 pattern。這些做法本身不是錯的,問題是:它做這些的觸發條件,比人低很多。
人有摩擦成本,Agent 沒有
一個工程師在寫 code 的時候,「多加一層抽象」是有摩擦成本的。要新建一個檔案、想命名、寫 interface、更新引用、補測試。這個摩擦成本不是壞事——它會讓人在抽象之前先問:「這個真的值得抽嗎?以後真的會重用嗎?」
Agent 沒有這個成本。對它來說,抽一個 utility 和不抽,工作量差不多。所以它傾向做得更多——因為「多做」在它的視角裡,等於「做得更完整」。
問題是,很多時候「多做」等於「引入了不需要的複雜度」。
複雜度是怎麼悄悄累積的
幾個常見的模式:
為未來預備。「這個功能以後可能要支援多種格式,所以先把 parser 做成可插拔的。」但那個「以後」不一定會來,而「先做可插拔」的代價是現在的代碼多了一層間接。
同功能多個實作。每次改動,Agent 可能用稍微不一樣的方式解同樣的問題。一段時間後,codebase 裡有三種日期格式化的方法、兩種 API error 處理的方式,各自都沒錯,但它們不一致,維護的人要記三件事而不是一件事。
有 native 解法但選了外部套件。原生的 fetch 其實就夠,但 Agent 提議用某個 HTTP library,因為它有更多功能。多了一個依賴,為了一個用不到的功能。
抽象了只用一次的邏輯。一個 function 只在一個地方被呼叫,但 Agent 把它獨立出來,因為「這樣可讀性更好」或「日後可以複用」。結果是多了一個 function,但閱讀的時候需要多跳一層。
每一個單獨看都有它的道理,累積起來,就是一個比需求複雜得多的系統。
「簡單性」是要刻意設計的
這個問題讓我意識到一件事:在 AI 協作開發的脈絡裡,「簡單」不是預設值,是要主動選擇的。
對人來說,摩擦成本自然會推向簡單。對 Agent 來說,需要明確的規則才會推向簡單。
於是我定了一個原則,現在寫在規則系統的 Spec 先行那條規則裡:
在所有能完整滿足驗收條件的方案中,選擇複雜度最低的那個,並說明為何需要這個複雜度。
這個原則的重點在「完整滿足驗收條件」——這不是讓 Agent 做少一點,而是在「同樣可以做到正確」的前提下,選最簡單的那條路。
最重要的一個邊界
定這個原則的時候,我擔心一件事:Agent 會不會用「保持簡單」當藉口,跳過錯誤處理或省略邊界條件?
這個擔心是真實的。如果原則沒有寫清楚,「保持簡單」很容易被誤解成「少做事」。
所以原則裡有一條明確的邊界:簡單性適用於設計選擇,不適用於正確性要求。
設計選擇:用 useState 還是 Zustand、要不要獨立出一個 service、用哪個 library——這些有簡單和複雜之分。
正確性要求:完整的 error handling、所有 non-happy path 都有對應邏輯、邊界條件有處理——這些不受簡單性原則影響,該做就要做。
用一個具體的例子說:
「付款 API 只處理了成功的回應,沒有處理 timeout 和 duplicate charge 的情況」——這不是「複雜」,這是正確性問題,簡單性原則管不到這裡。
「為了應對未來可能有的多貨幣支援,現在先把金額計算抽成一個可插拔的 Calculator class」——這是設計選擇,現在沒有多貨幣需求的情況下,這個選擇增加了不必要的複雜度。
review 框架的對應
有了這個原則,review 的時候也需要對應的 checklist。
在 delivery-review 框架裡,over-abstraction 的定義除了「wrapper 套 wrapper」、「為假設需求預先抽象」這些常見型態,今天新增了兩個更具體的情況:
- 有更簡單的 native / built-in 方案存在,卻選用了外部 library 或自訂抽象
- 實作複雜度明顯超出需求實際規模(一個 checkbox 的狀態用了 state machine;一個靜態清單上了分頁和虛擬化)
後者的「明顯超出」這個表述是刻意的。不是「有複雜度就報」,而是「複雜度和需求規模不成比例」才報。這需要判斷,不是核對 pattern。
複雜度是在哪裡決定的
想清楚這些之後,我意識到一件事:複雜度其實不是 review 階段的問題。
Review 是事後的動作。但「這個方案是不是比需求複雜太多」這個問題,只有在計畫還沒有落地之前,你才有辦法問到。等 Agent 已經寫完,才去找「哪裡抽象過頭」,等於是在問事後有沒辦法修——不是在問「一開始要不要這樣設計」。
簡單性偏好原則的真正意義在這裡:它不只是 review 時的一條 checklist,它是計畫審查時應該問的問題——「這樣設計是因為需求需要,還是因為 Agent 覺得這樣比較完整?」把這個問題帶進計畫的評估,比在事後 review 找多餘的抽象層有效得多。
規則能做的是讓這個標準明確,讓這個問題有辦法被問出來。複雜度在哪裡被決定,這個問題是在計畫還可以改的時候。
系列結尾
這個系列記錄的是一整天的反省。從想大掃除、到發現問題比清垃圾更根本、到試著把幾件事想清楚、寫進規則。
有些事現在更清楚了:我想要的協作方式是什麼、規則系統要怎麼設計、review 要做什麼和不做什麼、複雜度的邊界在哪裡。
有些事還沒有答案:這些規則真的會改變 Agent 的行為嗎?複雜度問題靠規則能解多少?「參與決策」這個目標,執行起來會是什麼樣子?
我打算繼續觀察。
本文是系列的第 4 篇,也是最後一篇。從 第 0 篇 開始閱讀。