GPT-5.6 Sol 沒做錯,卻做了 7,700 行我不需要的東西
社群上有篇討論 AI 寫程式的貼文,用了一個很傳神的譬喻:原本只要求做番茄炒蛋,GPT-5.6 卻自行加了東坡肉;使用者要求拿掉後,PR 還特別標成「沒有東坡肉」,並補上一長段為什麼不需要東坡肉。
這個來自 songkeys 原貼 的觀察,剛好說中了我後來遇到的事。但當它從幾十行的程式碼修改一路發生到需求規格與架構設計的源頭,事情就沒那麼輕鬆了。
最近我在設計一個個人專案的收尾提醒工具時,就遇到同一種問題,只是規模更大。當時擔任需求規格作者與實作主導的模型是 GPT-5.6 Sol(此結論僅由當次 session 紀錄的原始模型欄位證實,不外推到其他場景)。最後產出的五個 v1 檔案合計 7,687 行,標題取近似值 7,700;內容包含 hook、測試、兩個治理檔案與設定測試。
我後來把這次事件歸為「需求層過度設計」:Sol 沿著規格把功能做完,問題是規格早已把大量不必要的複雜度列成必做。真正需要的只有提醒功能,把它做成近 7,700 行的證明與跨機治理系統則超出原始需求。
一句「提醒我收尾」,怎麼長成三態證明的系統
原始的需求其實非常單純。
agent 在個人 repo 執行工作時會開 branch 或 worktree,完成品有時留在 main 之外沒有合回去。我的需求只是一個輕量提醒:個人 repo 的完成品還留在 branch、worktree 或其他 main 外狀態時告訴我;公司 repo 完全不檢查。
這項需求既不需要證明級分類,也不需要跨機器治理。但當 GPT-5.6 Sol 開始撰寫規格時,問題的定義完全變了樣。
規格書將提醒邏輯拆解成三種 Git 狀態:能證明已進 main、能證明在 main 之外、以及無法證明。為了嚴格判定三態,規格開始追蹤同一批變更是否已用其他形式進入 main。它還建立臨時 Git 暫存索引、跨 repo 保存結果,並處理掃描期間的競態。接著,遠端狀態是否最新與多機同步處置也被打包進第一版範圍。
原本只要在終端機印出一行提示的工具,規格定稿時已經變成一套多狀態分類與跨機治理系統。
三種把事情越做越大的推導模式
事後回看整個規格制定過程,需求沿著三個前後相接的階段一路膨脹。
把提醒做成證明。 當我追問 Git 如何知道確實有東西留在 main 外,Sol 把提醒問題推成「如何證明內容已整合」。規格因此開始處理 squash 合併、手動移植、歷史改寫,以及 main 與其他分支同時改動同一段內容的情況,並加入精確的差異比對與正反向套用檢查。
選項只會加,不會減。 在釐清需求的對話中,模型拋出一輪又一輪的選擇題。這些選項幾乎只有「加強防護」與「完整支援」,完全沒有「這個情境先不做」或「遇到就直接跳過」的選項。我逐題回答後,偏向加強的選項就被寫進規格;連我沒有回答的多機方案也被升成必做。在缺乏成本煞車的情況下,需求就這樣層層疊加。
先造處置機制,再替它造安全治理。 系統原本只是一個提醒工具,但前幾輪推導又加入了讓使用者把 branch 標成保留、退役或放棄,並讓結果跨機同步的處置機制。安全檢查便立刻跟進,為這套機制建立完整威脅模型。為了防止 agent 代替人類核准處置,實作追加提案流程、逐字確認,並把核准綁定到特定 session 後一次性使用。處置紀錄則只信任已進版控的版本。光是這張安全治理工作單的 commit,就新增約 3,000 行內容。
沒有人停下來問一句:一個在本機跑的提醒工具,真的需要這套權威治理架構嗎?
測試全綠,依然回答不了「值不值得做」
這套系統寫完之後,三個 agent 分別檢查規格符合度、程式碼品質與架構設計。測試全數通過,hook 執行前後的 Git 狀態也保持一致。這些結果支持實作大致符合規格,卻回答不了整套機制值不值得存在。
在四個 repo 的一次實地驗收裡,待判斷的 branch 與 worktree 大多仍然落入「無法證明」,系統只能吐出模稜兩可的警告。每次 Bash 呼叫都會觸發狀態掃描,終端機因此多出數秒等待。那套讓使用者標記保留、退役或放棄的處置流程,在同一輪驗收裡一次也沒有被用到。
局部實作可以做對,新增的複雜度卻沒有換到足夠的判別力與使用價值。
我隨即拍板拆除 v1 的所有接線,回到最單純的目標重新實作 v2。重做後的 v2 只在個人 repo 的 session 開場提示 main 外的本機 branch、stash、非主幹上的未提交變更,以及 main 上尚未推送的 commit;公司 repo 仍然沉默。它不再做三態證明,也拿掉執行期狀態、每次 Bash 掃描與跨機同步的處置紀錄。hook 與測試最終合計 968 行,目前完成的是實作與驗收,長期使用效果仍待觀察。必須說明的是,968 行涵蓋的範圍比 v1 的五個檔案窄得多,兩者不能直接相除計算縮減比例,但這個對照已經足以說明:原始問題可以用提示等級的答案解決,不需要原先的證明與跨機治理。
復盤之後,才長出來的 YAGNI 審查
這次失敗給我最大的教訓是:測試全綠只能回答「有沒有做對」,無法回答「這東西值不值得存在」。
我拍板拆線重做後,重新讀過整個原始對話,歸納出前面提到的三種膨脹模式。這套事後復盤促使我建立 YAGNI(You Aren’t Gonna Need It,先別做還沒被證明需要的功能)審查,專門檢查新增需求值不值得進規格。
這套審查把新增需求的舉證責任反轉。需求作者要交代需求來自哪裡,問題的分母,也就是過去實際發生幾次、每次造成多少損失,以及簡單版本為什麼不夠。如果 reviewer 建議刪減而需求作者不同意,爭議必須回到使用者拍板,不能由需求作者用更完整的設計自行判定保留。
這套審查後來又實際使用一次:一份規格的 32 條待審項目中,有 11 條被延後或刪除。
這項治理機制目前仍在觀察期。現有證據只到本案以外又實際使用過一次,還不足以稱為普遍適用的萬用解法。
把深挖的能力放對席位
我真正該調整的是模型所在的席位。同一種深挖能力放在 reviewer 席,可以幫忙找出邊界;放在能直接擴寫需求的位置,卻沒有成本煞車,就會把每個想到的邊界都轉成加法。
下一次模型想替小工具加入更多治理,我會先把舉證責任丟回去。說不清楚,就先別讓它進規格。