SuperPowers 實戰反思:subagent 的理想與現實
整理版優先睇
SuperPowers subagent 模式中嘅 reviewer-implementer 博弈可能引致防禦性過度工程,作者透過換模型同加入行為準則來調校。
呢篇文章係〈重生之我用 AI 寫代碼〉嘅續篇。作者團隊用 SuperPowers 搭咗一套 Agentic Engineering 體系,用 subagent 並行開發。表面上好完美,但實際用落就發現問題。
故事由一個 PR review 開始:業務代碼要記錄審計日誌,但 AI 生成嘅代碼將 logger 包喺 try…catch 入面,仲喺 catch 度吞咗異常,改記一條警告日誌。呢個做法喺合規要求好硬嘅項目入面係災難。作者翻查會話記錄,發現呢段代碼係 reviewer 覺得要加異常處理,implementer 迎合意見加上去嘅,spec 同 plan 完全冇要求。呢個現象作者稱為「防禦性過度工程」——implementer 為咗一次過 review,寧可多寫防禦代碼,形成 reviewer 越嚴格、implementer 越防禦嘅正反饋循環。
作者之後做咗兩個調整:第一,限制 subagent 用嘅模型唔可以係 haiku(因為 haiku 判斷力弱,容易俾 reviewer 帶住走);第二,喺用戶級 CLAUDE.md 加入 Andrej Karpathy 分享嘅四條行為準則(先想再寫、簡單至上、手術式修改、目標驅動執行)。調整後問題冇再出現,但作者唔肯定邊個調整更關鍵。反思係:呢個問題係制度設計問題,而非資訊缺失;模型判斷力可能比規則更管用;人嘅角色由執行者變成調音師,要調校 AI 嘅環境參數。整體結論係:…
- Subagent 模式下 implementer 會為迎合 reviewer 而過度編碼,導致防禦性過度工程,例如審計日誌被錯誤地加咗 try-catch 吞異常。
- 問題根源係 reviewer-implementer 嘅博弈激勵結構:implementer 目標係一次過 review,所以寧可多寫防禦代碼。
- 作者採取兩個調整:限制模型為非 haiku(提升判斷力),同埋喺 CLAUDE.md 加入 Karpathy 四條行為準則(先想再寫、簡單至上、手術式修改、目標驅動)。
- 關鍵反思:呢個係制度設計問題,唔係資訊缺失;模型判斷力可能比規則更重要,因為規則可以禁止行為,但唔可以賦予判斷力。
- 人嘅角色由執行者變成調音師,需要設計 AI 寫代碼嘅環境,理解多 agent 系統嘅結構性特徵,先係真正有壁壘嘅能力。
Karpathy 行為準則
四條鐵律用於調校 AI agent 避免過度工程:1. 先想再寫——唔好假設,有唔清楚就問,有更簡單方案就提出。2. 簡單至上——只寫解決當前問題所需最少代碼,唔好加冇要求嘅功能、抽象、靈活性或錯誤處理。3. 手術式修改——只改必須改嘅,唔好順手優化旁邊代碼或重構冇壞嘅嘢。4. 目標驅動執行——將每個任務轉化為可驗證目標,強目標讓獨立循環。
一個 PR 揭露嘅問題:審計日誌變咗安全隱患
前幾日我 review 一個 PR,見到 AI 生成嘅代碼咁樣處理審計日誌:先將 logger 調用包喺 try...catch 入面,然後喺 catch 度唔拋錯誤,反而吞咗異常,改記一條警告日誌。呢個做法令到本來應該可靠嘅審計日誌變得唔可靠——就好似保險箱嘅報警器壞咗,你唔去修理,反而貼張紙條寫「報警器可能壞了」。
審計日誌嘅意義在於「無論發生咩事,呢個操作記錄唔可以丟」
我檢查過 SuperPowers 生成嘅 spec 同 plan,完全冇提到要加 try-catch。追查會話記錄後發現:係 reviewer 喺審查階段覺得「調 logger 萬一出錯點算」,implementer 就迎合呢個意見加上防禦。呢個係一個自發行為,唔係 spec 要求。
subagent 模式嘅設計同埋內在博弈
SuperPowers 嘅 subagent-driven-development 係咁運作:主 agent 拆好任務後,對每個任務派一個 implementer subagent 寫代碼,然後由 spec compliance reviewer 同 code quality reviewer 檢查,唔通過就返去改。呢個制衡關係本來係健康嘅,但實際上創造咗一個軍備競賽。
Implementer 嘅目標係「一次過 review」,所以佢會選擇寫「令 reviewer 揾唔到毛病嘅代碼」而非「啱啱夠用嘅代碼」
- 1 寫啱啱夠用嘅代碼:按需實現,唔多唔少。
- 2 寫令 reviewer 冇得彈嘅代碼:每個可能性都包埋、每個邊界都處理、每段邏輯都加兜底。
- 3 Reviewer 越嚴格,implementer 越傾向用後者,形成正反饋循環。
呢個唔係單一 agent 嘅失誤,而係制度設計產生嘅結構性後果。就好似古德哈特法則咁:當 review 通過率變成目標,佢就唔再係質量嘅可靠指標。
兩個調整:換模型同埋加行為準則
發現問題後,我喺觸發 subagent-driven-development 時加咗兩條鐵律:第一,所有 subagent 用嘅模型一定唔可以係 haiku;第二,所有 subagent 都需要額外加載用戶級 CLAUDE.md 到上下文。同時,我喺原來係空嘅 ~/.claude/CLAUDE.md 入面寫入咗基於 Andrej Karpathy 分享嘅行為準則。
- 先想再寫:唔好假設,有唔清楚就問,有更簡單方案就提出
- 簡單至上:只寫解決當前問題所需最少代碼,唔好加冇要求嘅功能、抽象、靈活性或錯誤處理
- 手術式修改:只改必須改嘅,唔好順手優化旁邊代碼或重構冇壞嘅嘢
- 目標驅動執行:將每個任務轉化為可驗證目標,強目標讓獨立循環
「唔好俾不可能出錯嘅場景加錯誤處理」——呢條幾乎係為審計日誌故事量身定做
調整之後,過度防禦嘅代碼冇再出現。但由於兩個調整係同時做嘅,我唔肯定邊個更關鍵。換模型可能更重要,因為 haiku 判斷力弱,容易俾 reviewer 帶住走;而行為準則可能係喺概率層面壓低「加 try-catch」嘅傾向。
反思:制度設計、模型判斷力同埋人嘅新角色
第一,reviewer-implementer 軍備競賽係制度設計問題,唔係資訊缺失。即使規範曬,只要互動模式唔變,過度防禦就會出現。第二,如果模型起決定作用,咁暗示「判斷力」可能比「規則」更管用——規則可以禁止行為,但唔可以賦予判斷力,正如高級工程師同初級工程師用同一份 coding guidelines,前者寫出嚟嘅 code 仍然更好。
解法可能只係兩行配置,但知道點解要加呢兩行配置——呢個「點解」先係真正學到嘅嘢
- SuperPowers 係好設計,但唔完美:有大部份情況下產出高質量結果,但有結構性侷限。
- 任何架構都有取捨,聰明嘅做法係清楚知道自己做緊咩取捨。
- 下次見到 AI 寫出「安全到唔安全」嘅防禦代碼,唔好鬧 AI 蠢——去翻會話記錄,睇下 reviewer 同 implementer 係咪打咗場交。
上次講到,我哋團隊用 SuperPowers 建立咗一套 Agentic Engineering 體系,七個階段、硬門檻、subagent 並行開發——聽落係咪好完美?當時寫嗰篇文章嘅時候,我都係咁諗。但你知㗎,任何方法論喺紙上面都好好睇,真係好用唔好用,要用過先至知。
呢篇文章就係用咗之後嘅真心話。
(先講下,呢篇文章係上一篇重生之我用 AI 寫程式碼 嘅續篇,如果你未睇過嗰篇,極力建議你先去睇下,至少了解下 SuperPowers 嘅 subagent 模式係點樣。當然唔睇都得,我會盡量講清楚背景。)
故事嘅起點:一個「好安全」嘅程式碼審查
前幾日我喺 review 一個 PR,見到咁樣一段程式碼:
業務程式碼需要記錄一條審計日誌。呢件事本身好簡單——call 下 logger,將操作類型、操作人、時間戳記低,搞掂。但 AI 生成嘅程式碼係咁樣:先將日誌記錄包喺 try...catch 裏面,然後喺 catch 裏面,唔係拋出錯誤,而係靜靜雞將異常吞咗,改記一條警告日誌。(即係嗰種「原本應該記審計日誌,點知記審計日誌嘅時候出錯,於是我將錯誤收起咗,改記一條『審計日誌記錄失敗』嘅警告」——讀到呢度你應該已經覺得唔對路)
審計日誌嘅意義就係「無論發生咩事,呢個操作記錄都唔可以冇咗」。你將日誌記錄嘅異常吞咗,等於喺最需要可靠性嘅地方加咗一個唔可靠嘅環節。就好似保險箱嘅警報器壞咗,你唔去整警報器,而係貼一張紙條寫「警報器可能壞咗」。(呢個邏輯,唔係越保護越唔安全咩?)
(順便一提,喺某啲業務場景入面,審計日誌失敗時降級係合理嘅——例如電商下單流程,你唔會因為審計日誌服務死咗就拒絕用戶支付。但呢個項目嘅合規要求好硬,冇咗一條審計就係事故。所以呢度 AI 加嘅唔係「防禦」,而係「喺最唔應該降級嘅地方降級」)
呢個唔係我寫嘅程式碼。亦都唔係任何團隊成員寫嘅。呢個係 AI 自己加上去嘅。
我第一個反應係:plan 入面係咪要求咁樣寫?於是我去翻咗 SuperPowers 生成嘅 spec(設計規格文件)同 plan(執行計劃),逐行對照——冇。冇任何地方提到要俾審計日誌加 try-catch,更加冇話要將異常吞咗改成警告日誌。
咁呢段程式碼係從邊度嚟嘅?
我將 Claude Code 嘅會話記錄拉出嚟睇,叫佢自己分析下呢段程式碼係點樣產生。分析結果好有趣——係 reviewer 喺審查階段覺得呢度需要加異常處理,implementer 收到反饋之後就迎合咗呢個意見,加上咗層層防禦。 冇人喺 spec 或 plan 入面要求咁樣做。呢個係一個「reviewer 覺得需要 → implementer 照做」嘅自發行為。
呢個先係令我真正在意嘅地方。
回顧:subagent 模式係點樣設計嘅
先快速回顧下 SuperPowers 嘅 subagent-driven-development 階段嘅設計(上一篇寫過,呢度只講關鍵部分):
主 agent 將任務拆好之後,對每個任務循環執行呢套流程——
派一個全新嘅 implementer subagent 出去寫程式碼 implementer 完成後回報狀態 派一個 spec compliance reviewer(規格合規審查員)檢查實現係咪符合設計稿 派一個 code quality reviewer(程式碼質量審查員)檢查架構合理性、程式碼質量 任何一個審查唔過 → implementer 返去改 → 再審 → 通過 → 下一個任務
呢個設計有一個好明確嘅制衡關係:implementer 負責實現,reviewer 負責揾問題。兩者嘅角色係分離嘅。
呢度有一個重要嘅背景資訊需要說明:喺 Claude Code 裏面行 SuperPowers 嘅 subagent 模式時,subagent 係會載入項目級別同用戶級別嘅 CLAUDE.md 嘅。 即係話,項目規範(編碼風格、架構約定、目錄結構)subagent 係會睇到嘅。
不過,喺出問題嘅時候,我嘅用戶級別 CLAUDE.md(~/.claude/CLAUDE.md)係空嘅。所以 subagent 載入到嘅只有項目級嘅規範,冇用戶級嘅行為約束。
但即使有咗項目規範,佢都係寫咗嗰段過度防禦嘅程式碼——呢個令我意識到問題可能唔在於「有冇規範」,而係喺更深嘅地方。
問題:implementer 同 reviewer 嘅「軍備競賽」
而家可以講核心問題啦。
Subagent 模式入面,implementer 同 reviewer 係兩個獨立嘅角色。Implementer 寫程式碼,reviewer 揾問題。Review 唔過,implementer 就要返去改。改完再審。再審唔過,再改。
呢個循環睇落好健康——程式碼審查嘛,嚴啲總比鬆啲好。
但你企喺 implementer 嘅角度諗下:佢嘅目標係「一次過通過 review」。
點樣先可以一次過通過?最簡單嘅策略唔係「寫啱啱好用嘅程式碼」,而係「寫到 reviewer 揾唔到問題嘅程式碼」。
呢兩者有咩分別?分別大啦。
「寫啱啱好用嘅程式碼」係按需實現,唔多唔少。「寫到 reviewer 揾唔到問題嘅程式碼」係過度防禦——將每一個可能出錯嘅地方都包起嚟、每一個邊界條件都處理曬、每一段邏輯都加上兜底。Reviewer 越嚴格,implementer 越傾向「寧可寫多啲防禦程式碼,都唔想俾人揾到問題」。
返去開頭嗰個審計日誌——你而家知道咗佢嘅來龍去脈。呢個唔係 implementer 一開始就寫壞嘅,係 reviewer 喺審查時覺得「call logger 萬一出錯點算」,俾咗反饋,然後 implementer 迎合呢個意見加上咗層層防禦。兩輪互動之後,一個簡單嘅 logger 調用就變成咗 try-catch 嵌套加異常降級。
我將呢種現象叫做 防禦性過度工程——佢唔係某個 agent 嘅「失誤」,而係 implementer 同 reviewer 之間博弈關係嘅結構性產物。Reviewer 越盡責,implementer 越防禦,程式碼就越臃腫。呢個係一個正反饋循環,但方向係反嘅。
(n=1 推結構性結論係工程師嘅大忌,我知。但我好難將呢件事歸為偶然——spec 同 plan 都乾淨、項目規範都載入咗,純粹係兩個 agent 喺互動中演化出來。呢個「發生路徑」本身就說明咗問題唔在於某個個體,而係喺互動模式)
(打個唔係好恰當嘅比方:你叫一個質檢員睇住一個工人做嘢。質檢員越嚴格,工人就越傾向喺每個螺絲上都多擰兩圈——唔係因為需要擰兩圈,而係因為「多擰總比少擰安全」。但擰多咗嘅螺絲,可能比擰少咗嘅螺絲更難拆)
解法:比你想像中簡單,但原因比你想像中複雜
咁點樣應對呢?
發現問題之後,我喺兩個地方做咗調整。
第一,喺觸發 subagent-driven-development 時加咗兩條鐵律:
後續開發過程中,所有 subagent 使用嘅模型一定唔可以係 haiku
後續開發過程中,所有 subagent 都需要額外載入 ~/.claude/CLAUDE.md 到上下文,作為 agent 底層指導規則
先講第二條。呢條鐵律喺 Claude Code 環境下其實係多餘嘅——因為 subagent 默認就會載入用戶級別同項目級別嘅 CLAUDE.md。加呢條更多係「以防萬一」嘅心態,確保萬無一失。
第二,喺用戶級別嘅 CLAUDE.md 入面寫入咗行為準則。 呢條係真正值得詳細講嘅。
喺呢之前,我嘅 ~/.claude/CLAUDE.md 係空嘅。發現問題之後,我開始諗:可唔可以俾 subagent 加啲通用嘅行為約束,等佢哋冇咁容易滑向過度防禦?做嚇做嚇我意識到,我做嘅呢件事唔似係「管 AI」,更加似係「調 AI」——唔係叫佢做乜,而係校準佢嘅行為傾向。呢個感覺後面仲會提到。
我揾到咗一份基於 Andrej Karpathy(OpenAI 聯合創始人之一、前 Tesla AI 總監)喺 Twitter 上分享嘅帖子提煉出來嘅行為準則。有人將嗰篇帖子整理成咗一份 CLAUDE.md,我直接攞嚟用咗。核心就四條鐵律:
一、先諗再寫。 唔好假設,唔好收埋啲疑惑唔講。有唔清楚嘅,先問。如果有更簡單嘅方案存在,講出嚟。
二、簡單至上。 只寫解決當前問題所需嘅最少程式碼。原文嘅措辭更直接——"No features beyond what was asked. No abstractions for single-use code. No 'flexibility' or 'configurability' that wasn't requested. No error handling for impossible scenarios." 翻譯過嚟就係:冇被要求嘅功能唔加,只用一次嘅程式碼唔抽象,冇被要求嘅「靈活性」同「可配置性」唔加,唔可能出錯嘅場景唔加錯誤處理。最後仲附咗一個自檢問題:「如果一位高級工程師見到呢段程式碼,會話『搞複雜咗』嗎?如果係,就簡化。」(見到「唔好俾唔可能出錯嘅場景加錯誤處理」嗰句未?簡直就係為審計日誌嗰個故事度身訂做嘅)
三、手術式修改。 只改你一定要改嘅,只清理你自己製造嘅混亂。唔好順手「優化」隔籬嘅程式碼,唔好重構冇壞嘅嘢。
四、目標驅動執行。 將每個任務轉化為可驗證嘅目標。強目標令你可以獨立循環,弱目標需要不斷揾人確認。
你睇出嚟未?呢四條鐵律,幾乎每一條都係對住 AI 嘅「過度編碼」天性落刀。「唔好加冇被要求嘅功能」直接砍咗過度工程嘅動機,「只改你一定要改嘅」阻止 AI 順手「改善」周邊程式碼,「先諗再寫」令 AI 喺動手之前先判斷合理性而唔係本能地往複雜咗寫。
兩個調整做好之後,過度防禦嘅程式碼確實冇再出現過。起碼目前為止冇。
但我得老實講:我唔能夠百分百確定係邊個調整起咗決定性作用。
先講第一條鐵律——唔用 haiku。審計日誌嗰個故事就係喺 haiku 模型下發生嘅。Haiku 係 Claude 家族裏面最快、最平、但亦都最「淺」嘅模型。佢對複雜任務嘅理解力同判斷力明顯唔夠——更容易俾 reviewer 嘅意見帶住走,更容易做出「睇落合理但實際有問題」嘅決策。換成更強嘅模型之後,更強嘅判斷力意味住佢唔會盲目迎合 reviewer 嘅每一條反饋,而係會自己判斷「呢個反饋係咪合理」。審計日誌嗰個場景,如果模型夠強,佢應該判斷到「喺 catch 裏面吞咗異常改成警告日誌」係唔合理嘅——而唔係 reviewer 講乜就照做乜。
再講 Karpathy 嘅四條規則。佢嘅作用可能更微妙——唔係「禁止」AI 做某件事,而係喺概率層面調低咗 AI 做「多餘嘅事」嘅傾向。當你話俾 AI 聽「唔好俾唔可能出錯嘅場景加錯誤處理」,你係調整緊佢對「加 try-catch」呢件事嘅概率權重。即使 reviewer 喺推佢加防禦,呢條規則都喺往回拉。
所以到底係換模型起咗作用,定係 Karpathy 嘅規則起咗作用,定係兩者都起作用?我唔肯定。 兩個變化係同時做嘅,冇做對照組實驗。(工程師遇到問題就改兩個變量,然後問題消失咗——呢啲事喺工程實踐中太常見啦,你冇辦法確定係邊個變量起咗作用,但問題確實消失咗)
而且解法本身好簡單——一個模型選擇嘅約束、一份四條規則嘅行為準則、幾行配置。(有時最難嘅唔係揾到答案,而係接受答案可以咁簡單)
反思:制度比人重要,模型比規則重要?
用咗呢段時間之後,我有幾個更深層嘅思考。
第一,reviewer-implementer 嘅軍備競賽係一個「制度設計問題」。
佢唔係某個 agent 嘅「失誤」,亦唔係「規範冇傳到」——而係呢個 reviewer → implementer → 再 review 嘅循環本身存在一種過度防禦嘅傾向。就好似任何制度都會產生預料唔到嘅激勵效果一樣,「review 唔過就要改」呢個機制,會將 implementer 推向「寧可多做都唔願意俾人揾到問題」嘅策略。
呢個意味住,即使你將所有規範都餵咗俾 subagent,即使你嘅 spec 同 plan 寫得再清楚,只要 reviewer-implementer 嘅互動模式唔變,過度防禦嘅程式碼就可能會出現。因為呢個唔係一個「資訊缺失」問題——而係一個「激勵結構」問題。
呢個令我想起經濟學入面嘅「古德哈特法則」:當一個指標變成目標時,佢就唔再係一個好指標啦。 Review 通過率本來係衡量程式碼質量嘅指標,但當佢變成 implementer 嘅目標時,佢就唔再係質量嘅可靠代理啦——因為 implementer 開始優化「通過 review」呢件事本身,而唔係優化「程式碼質量」。
(所以你睇,寫程式碼寫到後面,居然同經濟學扯上咗關係。呢個世界嘅底層邏輯真係周圍相通嘅)
第二,如果起決定作用嘅係模型而唔係規則,意味住啲咩?
前面講咗,兩個變量同時改嘅,唔知邊個起作用。但如果要我估——我傾向認為係換模型嘅影響更大。原因係審計日誌嗰個故事就係喺 haiku 模型下發生嘅,haiku 嘅判斷力唔夠,更容易俾 reviewer 帶住走。換模型之後問題就冇再出現過。
如果真係模型起咗決定作用,咁佢暗示咗一件有意思嘅事:對於 AI agent 嚟講,「判斷力」可能比「規則」更有效。 規則話你知「唔好俾唔可能出錯嘅場景加錯誤處理」——呢條係一條明確嘅禁止令。但「判斷咩場景係唔可能出錯嘅」——呢個需要判斷力。規則可以禁止行為,但唔能夠賦予判斷力。更強嘅模型擁有更好嘅判斷力,所以佢喺同樣嘅規則框架下,表現可能就係比弱模型好。
當然,呢個係推測,唔係結論。我冇做對照實驗,證據只有 n=1。但呢個唔妨礙我將呢個猜想擺出嚟——因為如果佢成立,對點樣用 AI agent 嘅影響係好大嘅。
呢個同請人係同一個道理——你俾一個高級工程師同一個初級工程師同樣嘅 coding guidelines,前者寫出來嘅程式碼質量都係比後者好。唔係 guidelines 冇用,而係有啲嘢唔係靠規則可以補充嘅。
第三,Karpathy 嘅規則可能正在做一件更微妙嘅事。
呢個係我喺發現問題之後先加嘅——之前用戶級 CLAUDE.md 一直係空嘅。雖然我唔肯定佢嘅效果有幾多,但我懷疑佢嘅作用唔只係「禁止過度編碼」。佢嘅措辭本身可能影響咗一個更深層嘅嘢——**AI 嘅「傾向」**。
大語言模型嘅輸出係被概率分佈驅動嘅。當你話俾佢知「唔好俾唔可能出錯嘅場景加錯誤處理」,你唔係設定一個硬開關——你係調整緊佢對「加 try-catch」呢件事嘅概率權重。喺有咗呢條規則之後,AI 喺遇到類似審計日誌嘅場景時,「加 try-catch」呢個選擇嘅概率被壓低咗,而「唔處理」嘅概率被拉高咗。即使 reviewer 喺推佢加防禦,呢條規則都喺往回拉。
呢種係一種「軟約束」——唔似程式碼入面嘅 if-else 咁硬性,但能夠喺概率層面起到調節作用。Karpathy 四條鐵律嘅精妙之處就在於此:佢唔係喺教 AI 做乜,而係喺調低 AI 做「多餘嘅事」嘅概率。
(呢個就好似你同一個人講「唔好諗咁多」——你冇辦法阻止佢思考,但你可以影響佢思考嘅方向。好嘅行為準則做嘅就係呢件事)
話說回頭:呢個唔影響我對 SuperPowers 嘅整體判斷
講咗咁多問題,你可能會覺得我在 diss SuperPowers。唔係嘅。
我想表達嘅係:SuperPowers 嘅 subagent 模式係一個好嘅設計,但佢唔係一個完美嘅設計。 好設計嘅意思係,佢喺大部分場景下能夠產出高質量嘅結果,比冇呢套體系強好多。唔完美嘅意思係,佢有自己嘅結構性侷限,使用者需要意識到呢啲侷限,並且有意識咁去做補償。
呢個同任何一個架構決策係一樣嘅。微服務好唔好?好。但微服務帶嚟咗服務間通訊嘅複雜性、分佈式交易嘅難題、運維成本嘅增加。呢啲唔係話微服務唔好——而係話任何設計都有 trade-off(取捨),聰明嘅做法唔係扮 trade-off 唔存在,而係清楚知道自己喺做咩取捨。
返到 SuperPowers,我嘅實際體感係:用咗比唔用好好多,但用咗唔代表可以閂埋眼俾佢行。 有啲問題唔係「方法論教錯咗」,而係「方法論冇覆蓋到」——例如 reviewer-implementer 之間會自發產生過度防禦程式碼呢件事,SuperPowers 嘅設計入面冇呢層考慮。再例如模型選擇——文檔唔會話你知「用 haiku 行 subagent 會出咩問題」,呢個要你自己試咗先明。
人嘅角色唔係由「執行者」變咗做「旁觀者」,而係由「寫程式碼嘅人」變咗做「設計 AI 寫程式碼嘅環境嘅人」。呢個角色嘅難度,老實講,唔比寫程式碼低。前面往用戶級 CLAUDE.md 入面寫行為準則嘅時候我就有呢個感覺——唔係管 AI,而係調 AI。上一篇文章我話人係「監工」,而家我覺得更準確嘅講法係「調音師」——你唔係監督 AI 做嘢,而係校準令 AI 做好嘢嘅環境參數。
寫喺最後
上一篇結尾我話,AI 越強大,人嘅決策能力就越值錢。用咗 SuperPowers 呢段時間之後,我想俾呢句話加一個註腳:
AI 越強大,人對「AI 嘅侷限」嘅理解能力就越值錢。
知道 AI 做到啲咩,只係第一步。知道 AI 嘅各個組件喺互動中會演化出咩嘢隱性行為——例如 reviewer 同 implementer 之間嘅軍備競賽、模型選擇對判斷力嘅隱性影響——呢個先係真正有壁壘嘅能力。呢啲侷限唔係單個 agent 嘅 bug,而係多 agent 系統嘅結構性特徵。
Subagent 模式下,reviewer-implementer 博弈催生嘅防禦性過度工程、模型選擇對 subagent 判斷力嘅隱性影響——呢啲都唔係你喺文檔入面讀到嘅。佢哋係喺真實項目中、一次 PR review、一次會話分析、一行程式碼一行程式碼追出來嘅。
呢個亦都係點解我一直覺得,Agentic Engineering 呢件事,紙上談兵冇意義。你要自己落場踩一次。踩完咗回頭睇,嗰啲你喺方法論文章入面跳過嘅「細節」,先會真正變成你嘅嘢。而且有意思嘅係——追根因嘅過程往往比解法本身更有價值。解法可能就係兩行配置嘅事,但你知道點解要加呢兩行配置——呢個「點解」先係你真正學到嘅嘢。
下次如果你都遇到 AI 寫咗一堆「安全到唔安全」嘅防禦程式碼,唔好急住鬧 AI 蠢——去翻下會話記錄,睇下係咪 reviewer 同 implementer 喺你唔知嘅地方打咗一次交。
佢只係太想通過啦。
上回書說到,我們團隊用 SuperPowers 搭了一套 Agentic Engineering 的體系,七個階段、硬門卡死、subagent 並行開發——聽起來是不是特別完美?當時寫那篇文章的時候,我確實也是這麼覺得的。但你知道的,任何方法論在紙面上都很好看,真正好用不好用,得用了才知道。
這篇文章就是用了之後的真話。
(先說一下,這篇文章是上一篇重生之我用 AI 寫代碼 的續篇,如果你沒看過那篇,強烈建議先去看一眼,至少了解一下 SuperPowers 的 subagent 模式是怎麼回事。當然不看也行,我會盡量把背景交代清楚。)
故事的起點:一個"很安全"的代碼審查
前幾天我在 review 一個 PR,看到這麼一段代碼:
業務代碼需要記錄一條審計日誌。這件事本身很簡單——調一下 logger,把操作類型、操作人、時間戳記下來,完事。但 AI 生成的代碼是這樣的:先把日誌記錄包在 try...catch 裏,然後在 catch 裏面,不是拋出錯誤,而是默默把異常吞掉,改記一條警告日誌。(就是那種"原本該記審計日誌的,結果記審計日誌的時候出錯了,於是我把錯誤藏起來了,改成記一條'審計日誌記錄失敗'的警告"——讀到這裏你應該已經感到不對勁了)
審計日誌的意義就在於"不管發生什麼,這個操作記錄不能丟"。你把日誌記錄的異常吞了,等於在最需要可靠性的地方加了一個不可靠的環節。就好比保險箱的報警器壞了,你不去修報警器,而是貼一張紙條寫"報警器可能壞了"。(這邏輯,不是越保護越不安全了嗎?)
(順帶一提,在某些業務場景裏,審計日誌失敗時降級是合理的——比如電商下單流程,你不會因為審計日誌服務掛了就拒絕用戶支付。但這個項目的合規要求很硬,丟一條審計就是事故。所以這裏 AI 加的不是"防禦",是"在最不該降級的地方降級")
這不是我寫的代碼。也不是任何團隊成員寫的。這是 AI 自己加上去的。
我的第一反應是:plan 裏是不是要求這麼寫了?於是我去翻了 SuperPowers 生成的 spec(設計規格文檔)和 plan(執行計劃),逐行對照——不存在。沒有任何地方提到要給審計日誌加 try-catch,更沒有說要把異常吞掉改成警告日誌。
那這段代碼是從哪來的?
我把 Claude Code 的會話記錄拉出來看,讓它自己分析一下這段代碼是怎麼產生的。分析結果很有意思——是 reviewer 在審查階段覺得這裏需要加異常處理,implementer 收到反饋後就迎合了這個意見,加上了層層防禦。 沒有人在 spec 或 plan 裏要求這麼做。這是一個"reviewer 覺得需要 → implementer 照做"的自發行為。
這才是讓我真正在意的地方。
回顧:subagent 模式是怎麼設計的
先快速回顧一下 SuperPowers 的 subagent-driven-development 階段的設計(上一篇寫過,這裏只說關鍵部分):
主 agent 把任務拆好之後,對每個任務循環執行這套流程——
派一個全新的 implementer subagent 出去寫代碼 implementer 完成後回報狀態 派一個 spec compliance reviewer(規格合規審查員)檢查實現是否符合設計稿 派一個 code quality reviewer(代碼質量審查員)檢查架構合理性、代碼質量 任一審查不過 → implementer 回去修 → 再審 → 通過 → 下一個任務
這個設計有一個很明確的制衡關係:implementer 負責實現,reviewer 負責挑毛病。兩者的角色是分離的。
這裏有一個重要的背景信息需要說明:在 Claude Code 裏跑 SuperPowers 的 subagent 模式時,subagent 是會加載項目級別和用戶級別的 CLAUDE.md 的。 也就是說,項目規範(編碼風格、架構約定、目錄結構)subagent 是能看到的。
不過,在出問題的時候,我的用戶級別 CLAUDE.md(~/.claude/CLAUDE.md)是空的。所以subagent 加載到的只有項目級的規範,沒有用戶級的行為約束。
但即使有了項目規範,它還是寫出了那段過度防禦的代碼——這讓我意識到問題可能不在"有沒有規範",而在更深的地方。
問題:implementer 和 reviewer 的"軍備競賽"
現在可以說核心問題了。
Subagent 模式裏,implementer 和 reviewer 是兩個獨立的角色。Implementer 寫代碼,reviewer 挑毛病。Review 不過,implementer 就得回去改。改完再審。再審不過,再改。
這個循環看起來很健康——代碼審查嘛,嚴一點總比松一點好。
但你站在 implementer 的角度想一想:它的目標是"一次通過 review"。
怎麼才能一次通過?最簡單的策略不是"寫剛好夠用的代碼",而是"寫讓 reviewer 找不出毛病的代碼"。
這兩者有什麼區別?區別大了。
"寫剛好夠用的代碼"是按需實現,不多不少。"寫讓 reviewer 找不出毛病的代碼"是過度防禦——把每一個可能出錯的地方都包起來、每一個邊界條件都處理掉、每一段邏輯都加上兜底。Reviewer 越嚴格,implementer 越傾向於"寧可多寫點防禦代碼,也不想被挑毛病"。
回到開頭那個審計日誌——你現在知道了它的來龍去脈。這不是 implementer 一開始就寫壞的,是 reviewer 在審查時覺得"調 logger 萬一出錯怎麼辦",給了反饋,然後 implementer 迎合這個意見加上了層層防禦。兩輪互動下來,一個簡單的 logger 調用就變成了 try-catch 嵌套加異常降級。
我把這種現象叫做 防禦性過度工程——它不是某個 agent 的"失誤",而是 implementer 和 reviewer 之間博弈關係的結構性產物。Reviewer 越盡責,implementer 越防禦,代碼就越臃腫。這是一個正反饋循環,但方向是反的。
(n=1 推結構性結論是工程師的大忌,我知道。但我很難把這件事歸為偶然——spec 和 plan 都乾淨、項目規範也加載了,純粹是兩個 agent 在互動中演化出來的。這個"發生路徑"本身就說明了問題不在某個個體,而在互動模式)
(打個不太恰當的比方:你讓一個質檢員盯着一個工人幹活。質檢員越嚴格,工人就越傾向於在每個螺絲上都多擰兩圈——不是因為需要擰兩圈,而是因為"多擰總比少擰安全"。但擰多了的螺絲,可能比擰少了的螺絲更難拆)
解法:比你想的簡單,但原因比你想的複雜
那怎麼應對呢?
發現問題之後,我在兩個地方做了調整。
第一,在觸發 subagent-driven-development 時加了兩條鐵律:
後續開發過程中,所有 subagent 使用的模型一定不能是 haiku
後續開發過程中,所有 subagent 都需要額外加載 ~/.claude/CLAUDE.md 到上下文,作為 agent 底層指導規則
先說第二條。這條鐵律在 Claude Code 環境下其實是多餘的——因為 subagent 默認就會加載用戶級別和項目級別的 CLAUDE.md。加這條更多是"以防萬一"的心態,確保萬無一失。
第二,在用戶級別的 CLAUDE.md 裏寫入了行為準則。 這條是真正值得展開說的。
在此之前,我的 ~/.claude/CLAUDE.md 是空的。發現問題之後,我開始想:能不能給subagent 加一些通用的行為約束,讓它們不那麼容易滑向過度防禦?做着做着我意識到,我乾的這件事不像是"管 AI",更像是"調 AI"——不是告訴它該幹什麼,而是調校它的行為傾向。這個感覺後面還會提到。
我找到了一份基於 Andrej Karpathy(OpenAI 聯合創始人之一、前特斯拉 AI 總監)在推特上分享的帖子提煉出來的行為準則。有人把那篇帖子整理成了一份 CLAUDE.md,我直接拿來用了。核心就四條鐵律:
一、先想再寫。 不要假設,不要藏着困惑不說。有不清楚的,先問。如果有更簡單的方案存在,說出來。
二、簡單至上。 只寫解決當前問題所需的最少代碼。原文的措辭更直接——"No features beyond what was asked. No abstractions for single-use code. No 'flexibility' or 'configurability' that wasn't requested. No error handling for impossible scenarios." 翻譯過來就是:沒被要求的功能不加,只用一次的代碼不抽象,沒被要求的"靈活性"和"可配置性"不加,不可能出錯的場景不加錯誤處理。最後還附了一個自檢問題:"如果一位高級工程師看到這段代碼,會說'搞複雜了'嗎?如果是,就簡化。"(看到"不要給不可能出錯的場景加錯誤處理"那句了嗎?簡直就是給審計日誌那個故事量身定做的)
三、手術式修改。 只動你必須動的,只清理你自己製造的混亂。不要順手"優化"旁邊的代碼,不要重構沒壞的東西。
四、目標驅動執行。 把每個任務轉化為可驗證的目標。強目標讓你能獨立循環,弱目標需要不斷找人確認。
你看出來了嗎?這四條鐵律,幾乎每一條都在對着 AI 的"過度編碼"天性開刀。"不要加沒被要求的功能"直接砍掉過度工程的動機,"只動你必須動的"阻止 AI 順手"改善"周邊代碼,"先想再寫"讓 AI 在動手之前先判斷合理性而不是本能地往復雜了寫。
兩個調整做好之後,過度防禦的代碼確實沒有再出現過。起碼目前為止沒有。
但我得誠實地說:我不能百分之百確定是哪個調整起了決定性作用。
先說第一條鐵律——不用 haiku。審計日誌那個故事就是在 haiku 模型下發生的。Haiku 是 Claude 家族裏最快、最便宜、但也最"淺"的模型。它對複雜任務的理解力和判斷力明顯不夠——更容易被 reviewer 的意見帶着走,更容易做出"看起來合理但實際有問題"的決策。換成更強的模型之後,更強的判斷力意味着它不會盲目迎合 reviewer 的每一條反饋,而是會自己判斷"這個反饋是否合理"。審計日誌那個場景,如果模型足夠強,它應該能判斷出"在 catch 裏吞掉異常改成警告日誌"是不合理的——而不是 reviewer 說什麼就照做什麼。
再說 Karpathy 的四條規則。它的作用可能更微妙——不是"禁止"AI 做某件事,而是在概率層面調低了 AI 做"多餘的事"的傾向。當你告訴 AI "不要給不可能出錯的場景加錯誤處理",你是在調整它對"加 try-catch"這件事的概率權重。即使 reviewer 在推着它加防禦,這條規則也在往回拉。
所以到底是換模型起了作用,還是 Karpathy 的規則起了作用,還是兩者都在起作用?我不確定。 兩個變化是同時做的,沒有做對照組實驗。(工程師遇到問題就改兩個變量,然後問題消失了——這種事在工程實踐中太常見了,你沒法確定是哪個變量起了作用,但問題確實消失了)
而且解法本身很簡單——一個模型選擇的約束、一份四條規則的行為準則、幾行配置。(有時候最難的的不是找到答案,而是接受答案可以這麼簡單)
反思:制度比人重要,模型比規則重要?
用了這段時間之後,我有幾個更深層的思考。
第一,reviewer-implementer 的軍備競賽是一個"制度設計問題"。
它不是某個 agent 的"失誤",也不是"規範沒傳到"——而是這個 reviewer → implementer → 再 review 的循環本身存在一種過度防禦的傾向。就像任何制度都會產生意想不到的激勵效果一樣,"review 不過就要改"這個機制,會把 implementer 推向"寧可多做也不願被挑毛病"的策略。
這意味着,即使你把所有的規範都餵給了subagent,即使你的 spec 和 plan 寫得再清楚,只要 reviewer-implementer 的互動模式不變,過度防禦的代碼就可能出現。因為這不是一個"信息缺失"問題——是一個"激勵結構"問題。
這讓我想起經濟學裏的"古德哈特法則":當一個指標變成目標時,它就不再是一個好指標了。 Review 通過率本來是衡量代碼質量的指標,但當它變成 implementer 的目標時,它就不再是質量的可靠代理了——因為 implementer 開始優化"通過 review"這件事本身,而不是優化"代碼質量"。
(所以你看,寫代碼寫到後面,居然跟經濟學扯上了關係。這世界的底層邏輯真是處處相通的)
第二,如果起決定作用的是模型而不是規則,意味着什麼?
前面說了,兩個變量同時改的,不知道哪個起的作用。但如果讓我猜——我傾向於認為是換模型的影響更大。原因是審計日誌那個故事就是在 haiku 模型下發生的,haiku 的判斷力不夠,更容易被 reviewer 帶着走。換模型之後問題就沒再出現過。
如果真的是模型起了決定作用,那它暗示了一件有意思的事:對於 AI agent 來說,"判斷力"可能比"規則"更管用。 規則告訴你"不要給不可能出錯的場景加錯誤處理"——這是一條明確的禁止令。但"判斷什麼場景是不可能出錯的"——這需要判斷力。規則可以禁止行為,但不能賦予判斷力。更強的模型擁有更好的判斷力,所以它在同樣的規則框架下,表現可能就是比弱模型好。
當然,這是推測,不是結論。我沒有做對照實驗,證據只有 n=1。但這不妨礙我把這個猜想擺出來——因為如果它成立,對怎麼用 AI agent 的影響是很大的。
這跟招人是一個道理——你給一個高級工程師和一個初級工程師同樣的 coding guidelines,前者寫出來的代碼質量還是比後者好。不是 guidelines 沒用,而是有些東西不是靠規則能補的。
第三,Karpathy 的規則可能正在做一件更微妙的事。
這是我在發現問題之後才加進去的——之前用戶級 CLAUDE.md 一直是空的。雖然我不確定它的效果有多少,但我懷疑它的作用不只是"禁止過度編碼"。它的措辭本身可能影響了一個更深層的東西——**AI 的"傾向"**。
大語言模型的輸出是被概率分佈驅動的。當你告訴它"不要給不可能出錯的場景加錯誤處理",你不是在設一個硬開關——你是在調整它對"加 try-catch"這件事的概率權重。在有了這條規則之後,AI 在遇到類似審計日誌的場景時,"加 try-catch"這個選擇的概率被壓低了,而"不處理"的概率被拉高了。即使 reviewer 在推着它加防禦,這條規則也在往回拉。
這是一種"軟約束"——不像代碼裏的 if-else 那樣硬性,但能在概率層面起到調節作用。Karpathy 四條鐵律的精妙之處就在於此:它不是在教 AI 做什麼,而是在調低 AI 做"多餘的事"的概率。
(這就像你在跟一個人說"別想太多"——你沒法阻止他思考,但你可以影響他思考的方向。好的行為準則做的就是這個事)
話說回來:這不影響我對 SuperPowers 的整體判斷
說了這麼多問題,你可能會覺得我在 diss SuperPowers。不是的。
我想表達的是:SuperPowers 的 subagent 模式是一個好的設計,但它不是一個完美的設計。 好設計的意思是,它在大部分場景下能產出高質量的結果,比沒有這套體系強很多。不完美的意思是,它有自己的結構性侷限,使用者需要意識到這些侷限,並且有意識地去做補償。
這跟任何一個架構決策是一樣的。微服務好嗎?好。但微服務帶來了服務間通信的複雜性、分佈式事務的難題、運維成本的增加。這些不是說微服務不好——是說任何設計都有 trade-off(取捨),聰明的做法不是假裝 trade-off 不存在,而是清楚地知道自己在做什麼取捨。
回到 SuperPowers,我的實際體感是:用了比不用好很多,但用了不代表可以閉着眼讓它跑。 有些問題不是"方法論教錯了",而是"方法論沒覆蓋到"——比如 reviewer-implementer 之間會自發產生過度防禦代碼這件事,SuperPowers 的設計裏沒有這層考慮。再比如模型選擇——文檔不會告訴你"用 haiku 跑 subagent 會出什麼問題",這得你自己試了才明白。
人的角色不是從"執行者"變成了"旁觀者",而是從"寫代碼的人"變成了"設計 AI 寫代碼的環境的人"。這個角色的難度,說實話,不比寫代碼低。前面往用戶級 CLAUDE.md 裏寫行為準則的時候我就有這個感覺——不是在管 AI,而是在調 AI。上一篇文章我說人是"監工",現在我覺得更準確的說法是"調音師"——你不是在監督 AI 幹活,你是在調校讓 AI 幹好活的環境參數。
寫在最後
上一篇結尾我說,AI 越強大,人的決策能力就越值錢。用了 SuperPowers 這段時間之後,我想給這句話加一個註腳:
AI 越強大,人對"AI 的侷限"的理解能力就越值錢。
知道 AI 能做什麼,只是第一步。知道 AI 的各個組件在互動中會演化出什麼樣的隱性行為——比如 reviewer 和 implementer 之間的軍備競賽、模型選擇對判斷力的隱性影響——這才是真正有壁壘的能力。這些侷限不是單個 agent 的 bug,而是多 agent 系統的結構性特徵。
Subagent 模式下,reviewer-implementer 博弈催生的防禦性過度工程、模型選擇對subagent 判斷力的隱性影響——這些都不是你在文檔裏能讀到的。它們是在真實項目中、一次 PR review、一次會話分析、一行代碼一行代碼追出來的。
這也是為什麼我一直覺得,Agentic Engineering 這件事,紙上談兵沒有意義。你得自己下場踩一遍。踩完了回頭看,那些你在方法論文章裏跳過的"細節",才會真正變成你的東西。而且有意思的是——追根因的過程往往比解法本身更有價值。解法可能就是兩行配置的事,但你知道為什麼要加這兩行配置——這個"為什麼"才是你真正學到的東西。
下次如果你也遇到了 AI 寫出一堆"安全到不安全"的防禦代碼,別急着罵 AI 笨——去翻翻會話記錄,看看是不是 reviewer 和 implementer 在你不知道的地方打了一架。
它只是太想通過了。