這是很多人第一次看到 AI 生出的過度設計程式碼時的直覺反應:明明只交代了一句話,AI 卻自己加了一堆 Repository、Event、Cache 後端,錯的是 AI 想太多,又不是我沒講清楚。
但如果我們换個角度想:AI 沒有讀心術,你沒講的每一個細節,它都得自己填一個答案。 你說「幫我做一個新聞發佈系統」,這句話裡沒有講的東西太多了——會不會有排程發佈?要不要多語系?瀏覽數要不要即時更新?AI 不會把這些留白,它會用它認為「專業」「完整」的預設值去填。今天要示範的,就是這個「填空過程」實際上長什麼樣子。
ai-news-test 的過度設計版本)示範 AI 腦補出的東西長什麼樣假設你給 AI 的需求是:「做一個新聞發佈系統,文章可以草稿、發佈、下架,發佈後不能重複發佈,已發佈的文章要先下架才能編輯。」
這句話對人類工程師來說已經算清楚了——四條業務規則,聽起來就是這樣。但對 AI 來說,這句話沒講的東西包括:
沒有人跟 AI 說「不要」,AI 就會傾向「都做」——尤其現在的 coding agent 很擅長把一個需求「專業化」,用它訓練資料裡看過的各種模式(Repository、CQRS、Event-Driven)把系統包起來,這些模式本身沒有錯,錯的是沒有驗收依據支撐它們存在的必要性。
在我實際做的示範專案 ai-news-test(recca0120/ai-news-test)裡,我用同一組 10 個 Given-When-Then 驗收測試,餵給兩種寫法:一種是遵循 Outside-In TDD 紀律、只在測試逼出需求時才新增類別;另一種模擬「AI 拿到模糊需求後自由發揮」。兩者都 100% 通過同一組測試,一行都沒改。
結果:遵循 TDD 紀律的版本是 3 個檔案、249 行;自由發揮的版本是 745 個檔案、21,727 行。業務規則數量完全相同——都是 4 條。
自由發揮版本裡,真正會被入口點呼叫到、對測試結果有影響的程式碼只有 62 個檔案、1,738 行。剩下的 683 個檔案、約 92% 的程式碼,是預先建好、從來沒有被任何測試或執行路徑碰過的部分,包括:
❌ 沒有驗收依據、純粹「以防萬一」的假設:
「這個系統以後可能需要多語系,先把 LocaleAwareTitle 這個 Value Object 建起來。」
「排程發佈是常見功能,先把 ScheduledPublishCommand 跟對應的 Handler 建好。」
✅ 有驗收依據才存在的東西:
Given 一篇已發佈的文章
When 嘗試再次發佈
Then 應該回傳「文章已發佈」的錯誤
→ 只有這條測試逼出來的規則,才需要一個對應的類別去實現它。
驗收測試沒有要求的東西,不該只因為「看起來專業」就存在。 這句話聽起來像常識,但在 AI 產出速度下,它變成一條容易被忽略的防線——因為 AI 寫出這些「假設性功能」的速度太快,快到你甚至沒有機會意識到自己從沒要求過它們。
一句模糊需求給人類工程師,頂多讓他多問幾個問題再動工;同一句話給 AI,它會在幾秒鐘內把所有沒問清楚的地方,用一整套看起來很完整的架構填滿。這正是本系列的主題句第一次具體示範:AI 沒有發明過度設計,它只是讓過度設計的速度追上了你按下 Enter 的速度;Review 要跟得上,審的就不能再是程式碼本身,而是產生程式碼的規則。
很多人(包含資深工程師)看到一份程式碼裡有清楚的分層、Repository、Command/Query 分離,第一反應是「這寫得蠻專業的」。但「專業樣式用得對不對」跟「這個樣式在這裡有沒有必要」是兩件事。看起來完整的架構,如果沒有驗收測試在背後撐著它存在的理由,本質上只是換了一種形式的意外複雜度。
回想你最近一次交給 AI 的需求描述:裡面有哪些細節你自己也沒想清楚?如果拿掉「AI 自由發揮」這個選項,換成你自己接手這句需求,你會不會先反問清楚,而不是直接動工?
ai-news-test 的示範:同一組 10 個驗收測試,自由發揮版本比遵循 TDD 紀律的版本多了 248 倍的檔案數Day 3 要拆解一個更根本的問題:既然兩個版本都通過同一組測試,為什麼「測試都綠燈」不能拿來證明程式碼設計沒問題?測試到底驗證了什麼、沒驗證什麼。
我以前 review 資淺工程師的程式碼時,常常會被「這人寫得好講究」唬住——多加了一層抽象、多包了一個介面,直覺上覺得是加分。這幾年帶著 AI 一起寫程式碼之後,我才慢慢改掉這個反射動作:先問「這是驗收條件要求的嗎」,再問「寫得好不好」。順序反過來,就很容易被 AI 生成的「看起來很專業」的架構唬住,因為它真的很擅長把不必要的東西包裝成必要的樣子。