重點摘要
- 規劃 staffing 跟執行 staffing 必須分離——HOME123 的 AGENTS.md 寫死 8 職稱 + 沒 update 機制,跑 33 cycles 紋風不動,變成「歷史文物」。
- 寫入單線程,讀取並行——多 agent 平行寫程式碼會產生隱性風格 + 決策衝突,但平行派 5 個 persona newbie 讀程式碼抓 bug 完全沒問題。
- Generator-Verifier ROI 最高——只加一個 verifier agent 就顯著提升品質,且 verifier 不共享 generator 的 context 反而效果更好。
- Persona-driven newbie 抓 PM 漏的 finding——HOME123 C29 派 5 個不同 persona 平行 audit,抓出 23 個 PM + Tom 都漏的 finding,其中 4 個是 cycle blocker。
- 「INV 全綠」≠「對」——C11 user 隨便點 chairman dashboard 就抓出 11 個 verification cycle 都漏的 LEFT JOIN ARRAY_AGG NULL bug。Cycle SOP 只能抓「SOP 想得到的」,user 抓「SOP 想不到的」。
讀完愛好 AI 工程的 Multi-Agent 架構再探: 三省六部反模式和業界收斂共識(2026-05-19),裡面整理的 Anthropic、Cognition、LangChain、Stanford 各家對 multi-agent 系統的共識,跟我家 HOME123_NEW 從 R35 21 輪迴圈踩坑、演化到 R36 cycle SOP 的軌跡高度重疊。
但「重疊」不等於「教會我新東西」。我反而在對照中發現,有五個自家踩出來的細節,業界文章沒講或講得不夠重——這篇就把這五個補丁寫下來,給跟我一樣已經在生產環境跑 multi-agent workflow 的人參考。
本文不從 0 開始講 multi-agent 概念,假設你讀過原文或熟悉 orchestrator-subagent / generator-verifier 這類詞彙。
補丁 1:AGENTS.md 為什麼變死文件——「規劃 staffing」跟「執行 staffing」必須分離
我家 HOME123_NEW 的 AGENTS.md 是 2026-05-12 寫的,列了 8 個職稱角色:架構師 / PM / UI-UX 設計師 / 後端工程師 / Flutter 工程師 / Postgres DBA / 資料探索員 / QA。看起來像一張漂亮的組織圖。
實際跑起來呢?專案 33 個 cycle 結束、Phase 1 ship 之後,這份 AGENTS.md 一次都沒動過。
對照同一個 repo 的 docs/workflow.md:從 R36 step 3 v1.0 寫下來,持續演化到 v2.1 per-layer QA、v2.2 加 TDD red-green + SCN P0-1,六個 commit,每一輪 cycle 收穫都回寫。workflow.md 活著,AGENTS.md 死了。
死文件的兩個必要條件
盤點下來,一份文件變死,要同時滿足兩個條件:
- 寫了「會變的具體細節」——例如「8 個職稱 + 主要工作 + 預估記憶體佔用 600MB」。這些隨專案演化必然會變。
- 沒有強制 update 機制——沒掛在任何「每 cycle 必看」「每 PR 必檢」的閘口上。
任一條件缺失,文件還能活:
- 只寫不會變的部分(資源預算上限、role 類別 taxonomy),沒 update 機制也 OK——因為真的不需要 update。
- 寫具體細節,但每 cycle 強制 re-check(像 HOME123 的
docs/cycles/Cn-*.md活在 git,Stage 8 merge gate 強制檢查),也 OK——因為會被更新。 - 兩個都犯 = 上線當天就在 rot。
解法:規劃 staffing vs 執行 staffing 分離
| 文件類型 | 性質 | 該怎麼活 |
|---|---|---|
| 規劃文件(AGENTS.md / ROADMAP.md) | 計畫期的「我以為會這樣」 | 寫 timestamp、標 initial assumption,職責限縮到「不會變的部分」(資源預算、role taxonomy、必讀 brain 索引) |
| 執行契約(workflow.md / invariants.md / cycle file) | 違反就退回的活文件 | 每 cycle / 每 PR 強制 re-check,違反當 review fail,cycle 收完歸檔留檔 |
原文「三省六部幻覺」段批的「把 agent 命名成 PM / 架構師 / QA」,本質上就是把規劃文件當執行契約用——以為列了 8 個職稱就能跑,但職稱不會自我更新,專案演化會立刻甩開它。我這次踩到的就是這個。
補丁 2:不是「Single vs Multi」,是「寫入單線程 + 讀取並行」
原文整理 Anthropic 2026/1 給 multi-agent 的三個合理場景:context 隔離、並行覆蓋、工具專業化。也引用 Cognition 2026/4 的反直覺發現:「寫入動作維持單線程,其他 agent 只負責提供判斷,不負責動手」。
我家的實踐長這樣(從 R36 開始穩定):
| 元件 | 配置 | 對應原文模式 |
|---|---|---|
| Writer | 永遠 1 個 Engineer agent,寫 code + 寫 unit test | Cognition「寫入單線程」 |
| Verifier wave | 並行 2-5 個 QA newbie,每個 scope 鎖死 1-3 個 INV | Generator-Verifier + Parallel exploration |
| Orchestrator | 我自己(PM 兩道閘:規格定錨 + finding triage) | 人類在 loop |
| 外部狀態 | docs/cycles/Cn-*.md 活在 git |
原文「orchestrator-worker + 外部狀態文件」 |
整套是Orchestrator-Subagent + Generator-Verifier 混合,五種協調模式裡 ROI 最高的兩個疊起來。
對應 Stanford 那篇論文的實戰觀察
原文引用 Stanford 2026/4 的 Single-Agent LLMs Outperform Multi-Agent Systems on Multi-Hop Reasoning Under Equal Thinking Token Budgets(arxiv 2604.02460),用資訊理論的「數據處理不等式」證明:固定 token 預算下,單一 agent 在 multi-hop reasoning 上贏過 multi-agent。
把這個結論套到 code generation 場景就是:Engineer 那 1 個 agent 才是真正在做連續推理的——它要把 spec → schema → resolver → test 一路推下去,context 連續性是品質關鍵。讓五個 agent 平行寫不同模組,結果就是 Stanford 那篇講的:每個 agent 自己的 context 縮短了,推理深度不夠。
但 verification 不是 multi-hop reasoning,它是多點獨立檢查。每個 newbie scope 鎖死 1-3 個 INV,根本不需要 multi-hop reasoning;反而從乾淨 context 出發比較好——這也是 Cognition 觀察「verifier 不共享 generator context 反而更好」的原因。
所以選 single 還是 multi 不是哲學問題,是「這個子任務需不需要連續推理」的問題。需要 → single;獨立檢查 → multi。
補丁 3:Generator-Verifier 的六個 HOME123 細節
原文講 Generator-Verifier 是五個協調模式裡 ROI 最高的,但講的是「為什麼有效」。HOME123 R35→R36 演化過程中,六個操作細節決定了它真的有效還是只剩形式:
- QA scope 鎖死 1-3 INV,不准抓「任何 bug」。R35 21 輪迴圈的反面教材就是讓 QA「找任何問題」,結果 finding 無限發散。Scope 鎖死後,每個 newbie 只查它自己的契約。
- QA 不准標 P0 / P1。只能標 ✅ / ❌ / OPEN。P0/P1 是 PM 的 authority,QA 上交給 PM triage。這條防止 QA agent「自己升級嚴重度」拖累節奏。
- PM 兩道閘:第一道是寫 spec / 加 INV(規格定錨),第二道是 finding triage(bug / feature / usage / not_issue 30 秒分判)。少了任一道,QA wave 都會無限發散。
- PR header 強制宣告 INV 影響。每個 PR description 必填三段:滿足哪些 INV、可能影響哪些 INV、提議新增哪些 INV。沒填完整 = PR 不算開,reviewer 直接退。
- Verifier 不共享 Writer 的 context。QA agent prompt 模板只給它「PR commit SHA / 一條 INV / test users / 環境」,不給它 Writer 的對話歷史。乾淨 context 反而推理更深(Cognition 觀察)。
- Mutation testing 對抗 groupthink。每月一次,故意往 verified INV 對應的 code path 塞一個 plausible bug,看 QA agent 抓不抓得到。抓不到 = invariant test 不夠 sharp,補 attack scenario。
第 6 條是原文沒講的盲區。QA agent 跟 Engineer agent 來自同一個 LLM 譜系,shared assumption 會讓兩邊「想得一樣」——0 ❌ 不一定是程式對,可能是兩個 LLM 從同一個訓練資料裡學到同樣的 blind spot。Mutation testing 是目前我知道唯一能對抗這個的方法。
補丁 4:Over-design 怎麼補救——2026-05-22 砍 1000 LOC 實錄
原文講 multi-agent 的成本非線性爆炸、錯誤放大,但沒講「multi-agent 容易生出 over-design 的 schema / API」這個副作用。HOME123 跑到 2026-05-22 做了一次 over-design audit,結果是砍掉 1000+ 行。我把那份 audit 攤開,看 multi-agent workflow 為什麼會生出垃圾,以及怎麼補救。
5 個 dead schema 一次掃掉
| 砍掉的東西 | 為什麼是死的 |
|---|---|
Query.myCapabilities |
0 frontend caller(me.capabilities 已涵蓋) |
Parcel.notifications + type Notification |
0 frontend query,Phase 2 push 走別條 path |
type Guard |
整個 type 標 @deprecated,0 caller |
Mutation.batchDeliver + BatchDeliverInput |
0 frontend call(所有 UI 都打 deliverParcelBatch),約 260 LOC resolver |
Mutation.createParcelIntakeBatch + UI dialog |
跟 C31 session-based batch intake 共存,UI 兩個批次按鈕讓警衛 cognitive load 爆炸,砍掉 ~343 LOC frontend + ~360 LOC backend |
反 anti-pattern:「往後查」
這五個 dead schema 全部都是同一個 anti-pattern:「為將來預留」。設計時 agent 想「萬一將來要顯示通知 timeline 呢?」「萬一未來 batch deliver 改 session model 呢?」「萬一要 polling caps 呢?」——於是 schema 多了 field、resolver 多了支、tests 多了行。
但 multi-agent workflow 的特性是沒人記得當初為什麼加:今天的 Engineer 不是當初寫 schema 的 Engineer,QA 不會質疑 schema design 是不是必要,PM 看 finding 不會回頭 audit schema 健康度。「往後查」的 anti-pattern 在 multi-agent 環境會比 single-developer 累積更快。
三個補救機制
- 定期 over-design audit(每 ~2 個月一次或大 milestone 後)。PM scan 角度:「99% 無痛、edge case 不擋 99%、不為將來 may-be 需求預留、不為『好體驗』造成系統壓力」。
- 砍之前先 grep 全 codebase 確認 0 caller。「我以為沒人用」跟「
grep -r證實 0 caller」是兩件事。HOME123 砍batchDeliver前 grepapp/lib/,只在註解出現,於是放心砍。 - 砍完寫進 INV 防回流。砍 dead schema 之後加
INV-SCHEMA-001:「standalone batch* mutations 不再加,batch 行為一律走 session-based pattern」。沒寫 INV 半年後同樣的 over-design 會回來。
Design 不足:persona-driven newbie 才挖得出來
Over-design 反過來是 design 不足。HOME123 C29 跑了一個實驗:派 5 個 persona-driven adversarial newbie 平行 audit,每個 persona 有明確的「你是誰、你假設世界是什麼樣、你要找的不是『功能對不對』而是『產品對不對』」mandate:
- Newbie 1:高吞吐警衛阿伯(每天 300 件包裹)
- Newbie 2:無棟透天社區主委(12 戶,只有「幾號幾樓」概念)
- Newbie 3:多棟社區主委(5 棟,要選棟才能下一步)
- Newbie 4:老年住戶用 iPhone 11(375px 螢幕、視力差)
- Newbie 5:跨租戶 RLS 測試者
5 個 newbie 平行 audit 抓出 23 個 finding,其中 4 個是 cycle blocker——這些都是我跟 PM 看了無數遍漏掉的。
最戲劇性的是 N2 跟 N3 加起來證實了我的 directive 錯了:我 2026-05-20 拍板「不用管棟」,N2 跑去把 buildings 設成空陣列發現 backend 硬擋(buildings cannot be empty),N3 跑去測多棟社區發現 dropdown collision。兩個 persona 的觀察合起來,證明「不用管棟 globally」over-fit 到單一棟的場景,我自己只看單一棟所以沒撞到。後來我把 directive partial revoke,改成 buildings.length > 1 才顯示棟 picker。
Persona-driven newbie 是補 design 不足最便宜的工具。成本就是每個 newbie 一份明確 persona prompt + 一輪 read-only audit,沒有寫衝突、沒有 merge 成本。
補丁 5:「我很有信心,但你隨便測就炸」——C11 完整故事
這條是 multi-agent 系統最容易掉進去的坑——而原文完全沒談。先講事件:
2026-05-10 晚上,HOME123 R36 跑完 11 個 verification cycle、56 條 INV 全綠、所有 QA wave 都報 ✅。我用 chairman 帳號(admin01)登進 dashboard,點開「主委交接」tab——爆炸:
讀取失敗:can't scan into dest[4] (col: roles):
failed to scan array element 0: cannot scan NULL into *string
同一個 session 我隨便點了 chairman dashboard,找到 4 個 bug:這個 NULL scan、communities.public_contact_phone 殘留的 <script>alert('XSS')</script> 測試資料、parcel serial 多顯示一個 #(spec 沒寫)、carrier barcode 沒有 lookup query 入口。
名言誕生:
R36 11 個 cycle + 56 條 INV ✅,user 隨便點 1 次 → 4 個 bug。
User browser smoke remains the most valuable QA signal.
深挖那個 LEFT JOIN ARRAY_AGG NULL bug
有問題的 SQL 是 CommunityUsers resolver,長這樣:
SELECT u.*, COALESCE(
ARRAY_AGG(ur.role_code) FILTER (WHERE ur.revoked_at IS NULL),
'{}'::text[]
) AS roles
FROM users u
LEFT JOIN user_roles ur ON ur.user_id = u.id
WHERE u.community_id = $1
GROUP BY u.id;
Bug 在哪?LEFT JOIN 對沒匹配的 user 會 pad 一行 ur.* 全部 NULL 的 row。SQL 三值邏輯下,NULL IS NULL 是 TRUE——所以 FILTER (WHERE ur.revoked_at IS NULL) 把這個 pad row放進了 aggregate。結果 ARRAY_AGG 回傳的不是空陣列、是{NULL}(包一個 NULL 元素的陣列)。COALESCE 看到的是非 NULL 陣列,直接 pass through,Go scan 進 []string 時就爆 cannot scan NULL into *string。
修法很簡單:FILTER 加一個 AND ur.role_code IS NOT NULL,把 pad row 排除掉。但為什麼 11 個 verification cycle 都沒抓到?
因為這個 bug 只在「有 user 沒有任何 user_roles row」時觸發。C6 cycle 的 seed-demo.sh 改成 idempotent 之前,所有 demo user 都有至少一個 role;C6 之後,seed 改成「先 DELETE 殘餘 user 的 roles 再 disable user」,結果 DEMO001 多出 11 個 disabled-residue user 帶 zero user_roles row。fixture 狀態改變才暴露 bug,前 11 個 cycle 跑的時候 fixture 還沒進入這個狀態。
這條 cycle file 寫下了 multi-agent 系統最殘酷的真相:
Cycle SOP catches what cycle SOP can imagine; user catches the rest.
為什麼 TDD 也擋不住
我這套 workflow 有強制 TDD red-green 三步(Stage 5a 寫 failing test、Stage 5b 寫 fix、Stage 5c refactor),為什麼還是漏?
- Vacuous green test。Test 永遠 pass 不是因為實作對,是因為 assert 太寬或 fixture 沒覆蓋觸發條件。C11 那個 NULL bug 在前 11 個 cycle 的 test fixture 裡,根本沒有「user 帶 zero roles」這個狀態,所以 test 一直 green。
- Groupthink。QA agent 跟 Engineer agent 同 LLM 譜系,想得一樣。Engineer 寫 test 時想到的 attack scenario,跟 QA 寫 test 時想到的 attack scenario,高度重疊。盲點是 shared 的。
- L1-L3 全綠 ≠ L4-L5 也對。HOME123 把「對」分 6 層:L0 spec → L1 INV → L2 schema → L3 resolver → L4 frontend → L5 E2E。前 11 個 cycle 主要驗 L1-L3,L4 user click 沒人驗。INV 全綠是 L1 全綠,跟 user 在 chairman dashboard 看到什麼是兩件事。
5 個建議方向
- User smoke = primary detection。不是 secondary、不是「最後再點一次」。每個 milestone 結束第一件事是 user 隨便點,不是看 CI report。
- Mutation testing 對抗 groupthink。每月或大 INV amendment 後跑一次,故意塞 plausible bug,看 QA agent 抓不抓得到。抓不到 = QA prompt 跟 Engineer 想得太像,得補 attack scenario。
- Adversarial persona 平行覆蓋。C29 模式:每個 persona 有明確「你跟 Engineer 想法不同的地方在哪」mandate,5 個 newbie 平行 audit,讀取型 multi-agent 完全沒衝突風險。
- 6-layer thinking 防止誤推。看到「INV 全綠」先問「這是 L 幾全綠?L4 / L5 有人驗過嗎?」L1-L3 全綠不等於對,只是「未驗中比較強的子集」。
- TDD red-green 三步分 commit。Stage 5a 寫 failing test 單獨 commit、Stage 5b 寫 fix 單獨 commit,commit message 必填
Failing test verified at: <5a-sha>。bisect 看得出 red→green 軌跡,防 vacuous test。「test 跟 fix 同 commit」= test 從沒 fail 過 = 沒驗 test 有效。
結語:業界共識是地圖,cycle file 是地形
原文整理的業界共識像一張地圖:告訴你 Anthropic 走哪條、Cognition 撞了什麼牆、LangChain 怎麼分 patterns。地圖很有用——你不會走錯方向。
但地圖不是地形。HOME123 33 個 cycle 累積的 docs/cycles/*.md 才是地形:哪個彎要慢、哪段路會塞、哪裡橋斷了走小路。地圖告訴你「先試 single-agent」,地形告訴你「single-agent 的 Engineer 寫完之後,第二件事是叫 5 個 persona newbie 去點點看」。
這篇五個補丁,本質上是把地形寫下來。給已經在跑 multi-agent workflow、開始撞牆、覺得業界文章沒講透的人。
下一步:把這次討論抽出的「規劃 staffing vs 執行 staffing 分離」原則,寫進 ~/.claude/projects/-home-tom/memory/brain/adaptive-agent-team-staffing.md brain;把 HOME123 R36 的 PM/Engineer/QA workflow.md 抽象成 ~/.claude/templates/workflow.md 通用模板。這樣下個專案就不用從 R35 21 輪迴圈重新踩一次。
延伸閱讀
- Multi-Agent 架構再探: 三省六部反模式和業界收斂共識(愛好 AI 工程,2026-05-19)——本文呼應對象
- Anthropic: Building Multi-Agent Systems(2026-01)
- Anthropic: Multi-Agent Coordination Patterns(2026-04)
- Cognition: Multi-Agents: What’s Actually Working(2026-04)
- Stanford: Single-Agent LLMs Outperform Multi-Agent Systems on Multi-Hop Reasoning Under Equal Thinking Token Budgets(arxiv 2604.02460,2026-04)
發佈留言