標籤: Subagent

  • 「為什麼修不完?」— 從 21 輪迴圈到 5 type taxonomy 的多 agent 角色設計

    場景

    你接手一個 multi-tenant 專案,系統有 5 個角色(sysadmin / 主委 / 警衛 / 戶長 / 住戶),不同角色有不同 RBAC 權限。你建了 AGENTS.md 派 1 RD + 1 QA,以為這就是 multi-agent team。

    然後出事了。

    本系列【入門篇】· 給「想知道為什麼」的人

    這篇談為什麼 multi-agent 工程需要 cycle file workflow + 5 種 agent type
    怎麼用8 幕劇 · 第一人稱故事 · 真實踩坑反推
    下一步讀完想看 怎麼做(8-stage SOP / 4 個檔範本 / bootstrap)→ 進階篇

    本篇路線圖

    幕 1AGENTS 兩角色跑起來 → 局部檢測 + 不會按角色測(第一次嚴重問題)
    幕 2要求按角色登入測試 → 一天 flip-flop(換角色每次都不對)
    幕 3小白角色誕生 — 不問對錯 / 按 SPEC 走 / 問 PM
    幕 4PM 回到多元職能 → 原本「開發+QA」結構無意義
    幕 5後來踩 R12 — 11 輪 self-audit 還是漏 P1
    幕 6C29 派 5 個 persona — Newbie 多元化
    幕 7從踩坑反推 5 個 type 的形狀
    幕 8每個 cycle 派幾個 — dynamic staffing

    幕 1

    AGENTS 兩角色跑起來:局部檢測 + 不會按角色測

    當時我以為「2 個 agent ping pong」就是 multi-agent。AGENTS.md 配:

    RD agent(寫 code) + QA agent(跑 audit)

    跑起來幾輪後問題顯現,QA 的 audit 有兩個結構性缺陷:

    QA 在做什麼 缺陷 為什麼致命
    ① 局部檢測 只看單一 resolver / 單一 endpoint · 看不到跨檔/跨系統的互動 系統整體性沒被驗
    ② 不會按角色切換進入測試 QA 都用「一個視角」測,從來沒登入過不同 RBAC 角色看是不是被擋對 / 看到對的東西 RBAC 路徑(最重要的安全特性)完全沒檢查

    為什麼「不會按角色測」是嚴重問題

    RBAC 角色 看到什麼 / 能做什麼 沒測會怎樣
    sysadmin跨社區管理cross-tenant leak 沒驗
    主委本社區管理能看到別社區?能改別人家?
    警衛處理包裹/訪客能看到住戶資料嗎?
    戶長管自己家能看到別家的包裹?
    住戶看自己包裹能查到別人寄件?

    第一次嚴重問題:QA 表面綠燈,但 RBAC 跟多租戶隔離這兩條最重要的安全路徑完全沒被驗過——因為 QA agent 從來沒登入過不同角色。系統最該被守住的地方,變成最暴露的地方。


    幕 2

    要求按角色登入測試:一天 flip-flop

    我介入,告訴 Claude:「不要只在後端查 code,實際用各個角色帳號登入測。」

    它真的開始用 sysadmin / 主委 / 警衛 / 戶長 / 住戶 五個帳號登入測。但很快變成:

    輪次 用哪個角色測 QA 說 RD 動作
    輪 1sysadmin抓到 5 個淺問題RD 修
    輪 2主委「剛剛修的東西在主委角度看是不對的」RD 改
    輪 3警衛「警衛角度又不對」RD 又改
    輪 4戶長「戶長角度又不對」RD 又改
    輪 5住戶「住戶角度又不對」RD 又改
    輪 6回到 sysadmin「現在 sysadmin 角度又不對了」(因為剛改的把 sysadmin 弄壞)RD 又改
    5 個角色輪流每換一個角色就抓到「上輪修壞了」永遠在改

    這樣無限循環了一天

    每輪都是「淺淺檢測 5 個問題 → RD 修 → 換角色又不對」

    最後我叫停。

    失敗 insight:QA 每次按角色測都對(以那個角色的視角看),但加起來都不對(角色之間有衝突)。沒有公共的「對」基準——每個角色都是 QA 自己定義的「對」,沒有 SPEC 在中間定錨。


    幕 3

    小白角色誕生:不問對錯 / 按 SPEC 走 / 問 PM

    叫停之後我重新設計。問題不在「QA 不努力」,在「QA 一邊測一邊自己定義對錯」——這個 mode 永遠 flip-flop。

    新角色:小白。他長這樣:

    小白特性 具體動作 解掉什麼
    ① 不問對錯 只報「我看到什麼」,不下「這對 / 這不對」的判決 QA 自己定義「對」→ flip-flop
    ② 按 SPEC 走 拿 spec 文件去測,測 spec 寫了什麼。Spec 沒寫的就算了 QA 一邊測一邊提新需求 → 規格膨脹
    ③ 有問題問 PM 看到不對勁但不確定 → 報 OPEN finding,送 PM 判 QA 直接 ping RD 修 → 沒人擋
    小白 audit → 報 finding(不下對錯) → PM 對 SPEC 比對 → 是 bug 才給 RD 修

    小白的本質不是「換一種 audit 風格」,是把「判對錯」這件事從 audit 角色拿走,送回 PM 那裡。Audit 只負責觀察,PM 才負責對 SPEC double-check。


    幕 4

    PM 回到多元職能 → 原本的 AGENT 結構無意義

    小白把「判對錯」送回給 PM 之後,PM 不能只當「triage 一個動作」。PM 的職能本來就多元,只是 R35 兩角色設定下我把這層拿掉了。現在它回來了:

    PM 職能 具體動作 為什麼需要
    ① 對 SPEC double-check 每個 finding 拿 SPEC 比對:是不是 bug?還是小白看錯? 提供公共「對」基準
    ② Finding 4 選 1 分判 bug(該修) · feature(進 backlog) · usage(改 docs) · not_issue(close) 不讓所有 finding 都進 fix loop
    ③ 規格定錨 小白報「這應該也要 work」→ PM 判斷該不該加進 SPEC,加的話寫 INV-XXX-NNN 擋 spec 漂移
    ④ 跨角色視角整合 這個 finding 在 sysadmin 角度跟主委角度有衝突 → PM 拿 SPEC 判哪個角色該贏 解掉幕 2 的「換角色 flip-flop」

    原本的 AGENTS.md 結構變無意義

    最早 AGENTS.md(失敗) 小白 + PM 出現後
    RD agent RD 還在,但只接 PM triage 過的 bug
    QA agent(直接 ping RD) 變小白(不問對錯 / 按 SPEC / 報 PM)
    (沒有 PM) PM 多元職能進場
    結構:RD + QA ping pong 結構:小白 → PM → RD 三角入口

    學到的事 → Multi-agent 不是「派幾個 agent」的問題,是「agent 之間誰擋誰、誰判對錯」的問題。沒有公共 SPEC + PM 守門,任何 audit 方式都會撞 flip-flop。


    幕 5

    後來踩 R12:11 輪 self-audit 還是漏 P1

    小白 + PM 結構穩定後 cycle 順暢很多。我以為角色設計問題解了。然後 R12 cycle 出事。

    R12 cycle 條件 數字 / 結果
    我自己跑 audit11 輪
    場景文件覆蓋132 個
    所有人簽 ✅RD ✅ · PM ✅ · 我 ✅ → merge
    事後發現P1 漏掉:戶長能看到整個社區的資料

    為什麼 11 輪 + 132 場景還漏?

    11 輪 self-audit 11 個獨立檢查
    同一個視角(我自己)跑 11 次11 個不同視角各跑一次
    寫的時候的盲點,驗的時候也是盲點不同視角會覆蓋不同盲點
    132 場景由同一視角設計不同視角會想到不同場景
    等號不成立

    解法:把小白進化成「fresh newbie」(零 context)

    Newbie 條件全新 sonnet,沒給過去 11 輪的 audit context · 不知道之前抓過什麼
    紀律沿用小白規矩(不問對錯 / 按 SPEC / 問 PM),只是「context 比小白更乾淨」
    結果第一輪就抓到那個 P1

    學到的事 → 小白本身不夠,要再進化成「零 context」的 fresh newbie——避免「跑著跑著也累積成跟原 audit 同視角」的退化。


    幕 6

    C29:派 5 個 persona 平行 audit

    一個 fresh newbie 補一個盲點。不同 newbie 帶不同假設 → 平行補多個盲點。所有 finding 仍走 PM triage,不直接給 RD。

    # Persona 他的世界假設 抓到的盲點
    高吞吐警衛阿伯 每天 300 件包裹,每秒都要省 FAB 排太多 · 批次掃描藏在三點選單
    無棟透天主委 12 戶共一棟,沒有「A 棟 B 棟」 後端硬擋空「棟」欄位
    多棟社區主委 5 棟,選戶必須先選棟 picker dropdown collision
    老年用 iPhone 11 375px 螢幕、視力差 FAB 不在拇指區、按鈕找不到
    跨租戶 RLS 測試者 拿 A 社區帳號戳 B 社區資料 RLS policy 守不守得住

    5 個 persona 抓出 23 個 finding

    4 個 cycle blocker · 全部都是 PM + 我自己漏掉的

    小白 → newbie → persona newbie 的進化線

    設計 解掉什麼
    第一代
    小白
    不問對錯 / 按 SPEC / 問 PM QA 自己定義對 → 換角色 flip-flop
    第二代
    Fresh Newbie
    零 context · 不知道過去 audit 結果 小白跑久了累積成跟原 audit 同視角 → shared assumption
    第三代
    Persona Newbie
    多 persona 平行 · 各自帶不同世界假設 單一視角必有盲點 → 多視角覆蓋

    幕 7

    從踩坑反推:5 個 type 的形狀

    走過這幾個踩坑,5 個 agent type 不是想像出來的,是反向工程的結果:

    Type 動作 並行? 從什麼反推
    Writer 寫 code / spec / migration NO(單線程) 原本 RD 角色 · 兩 writer 平行會打架
    Verifier scope 鎖死 1-3 INV 的 audit · 按 SPEC 走 YES 第一代小白 · 解「QA 自己定義對」
    Triage 對 SPEC double-check · 4 選 1 分判 · 規格定錨 · 跨角色整合 NO(人類) PM 多元職能 · 解「換角色 flip-flop」
    Comparison 零 context 的獨立 verifier · 不知道原 audit findings YES 第二代 fresh newbie · R12 11 輪漏 P1 · shared assumption
    Newbie Adversarial persona-driven audit YES 第三代 persona newbie · C29 23 finding · 單一視角盲點
    傳統 8 職稱 這 5 個 type
    架構師 / PM / UI-UX / 後端 / Flutter / DBA / QA Writer / Verifier / Triage / Comparison / Newbie
    組織圖長相 · 看起來工整 動作類型(寫不寫 / 並行不並行 / 判不判對錯)
    寫進 AGENTS.md 之後 cycle 跑起來,只有 PM/QA 對應到事故學到的 每個 type 對應一條真實踩坑

    幕 8

    每個 cycle 派幾個?

    5 個 type 有了。但每個 cycle 派多少?不同 cycle 規模需要不同編制:

    Cycle 規模 派誰 總 RAM 為什麼
    改 1 行 typo RD-Sonnet + Verifier-Haiku ~1.0 GB 簡單變動 · 簡單覆蓋
    中等 PR RD-Sonnet + 2 Verifier-Haiku + Comparison-Haiku ~2.2 GB 中等變動 · 需 cross-check shared assumption
    大改 schema(含 RBAC) RD-Opus + 3 Verifier-Sonnet + Comparison-Haiku + 5 Persona-Newbie ~5.5 GB 大變動 + 跨角色 · 需多視角補 RBAC 盲點
    固定編制(每 cycle 都派同樣 N 個) Per-cycle dynamic staffing
    小 cycle 浪費資源小 cycle 派 2 個 agent
    大 cycle 漏 perspective大 cycle 派 9 個 agent
    9 Opus 撐爆 16 GB 機器每 cycle 算一次 budget

    規劃 vs 執行 staffing 分離

    AGENTS.md不變部分(taxonomy + RAM 上限 + Iron Rules) · 半年不變
    docs/cycles/Cn-*.md Header具體 staffing(派誰 / 什麼 model / 多少 RAM) · 每 cycle 重算
    前者性質規劃文件
    後者性質執行契約

    結語:cycle file 是這故事的結晶

    維度 補丁 從什麼反推
    角色 5 個 type taxonomy + PM 多元職能 + 小白進化線 局部檢測 / 不會按角色測 / 換角色 flip-flop / shared assumption / 單一視角盲點
    流程 8-stage SOP + 小白 → PM → RD 三角入口 沒收斂條件 / 沒規格定錨 / 沒 SPEC 守門員
    資源 per-cycle dynamic staffing 固定 9 Opus 撐爆機器

    cycle file workflow 的價值不是「設計得多漂亮」,是「每個設計選擇都對應到一個踩過的坑」。Multi-tenant + RBAC 系統的盲點不是「LLM 不夠強」,是「沒有公共 SPEC 守門員 + 多元視角覆蓋」就會撞牆。

    你接手新專案那天

    需要什麼4 個檔案 + 一段 bootstrap prompt
    完整版在哪進階篇

    系列文章

    第一篇「56 條 INV 全綠,user 點一次抓出 4 個 bug」— Multi-Agent 業界共識的五個自家補丁
    進階篇Cycle File:Multi-Agent 工程的狀態接力棒 — 完整 SOP / 8-stage / 4 個檔範本
    呼應業界Multi-Agent 架構再探: 三省六部反模式和業界收斂共識(愛好 AI 工程)
  • Cycle File:Multi-Agent 工程的狀態接力棒 — file-as-state-machine 方法論

    重點摘要

    • 動手的 agent 只能一個(寫入單線程)。但同一個 agent 不可能從頭做到尾,工作數小時後注意力品質下降(context rot)。
    • 解法不是換 agent,也不是加 agent,是讓「下一個 agent」能無痛接手。接力棒設計才是 multi-agent 工程的真正關鍵。
    • Cycle file = file-as-state-machine:把每個 cycle 的完整狀態寫進一份 markdown,活在 git,跨 session 可讀,撐過對話 compaction。
    • 8-stage 結構每個 stage 對應一個 multi-agent 容易踩到的坑:baseline 污染、ripple effect、vacuous test、groupthink。
    • 5 種 cycle type,各有 stage profile。不是每個 cycle 都跑 8-stage,硬塞會浪費或漏。
    • file-as-state-machine 不只 multi-agent 用得到。ADR、RFC、postmortem 都是這個 pattern,multi-agent workflow 把它的價值放大 100×。
    • 新環境 bootstrap:4 個檔案 + 一段 prompt,就能在新電腦 / 新 Claude Code / Antigravity / Codex / Cursor / Aider 上啟動這套流程,不分工具。

    本系列【進階篇】。提供完整 SOP 跟 4 個檔範本,假設你已經知道為什麼 multi-agent 工程需要 cycle file workflow。還沒看過為什麼?先讀 入門篇:「為什麼修不完?」— 從 21 輪迴圈到 5 type taxonomy 的多 agent 角色設計——用第一人稱故事告訴你 5 個 agent type 是怎麼從踩坑反推出來的,讀完再回來看這篇就會懂為什麼這 4 個檔長這樣。

    Multi-agent 工作流有個業界共識的硬約束:同時間只能有一個 agent 動手寫(寫 code / 寫 spec / 寫 migration)。多個 agent 平行寫產生隱性風格 + 決策衝突,Cognition / Anthropic / Stanford 都從不同角度驗證過這條。

    但這條約束衍生一個立刻撞上的問題:

    寫入單線程沒錯,但一個 agent 怎麼跑一個多月的長期專案不撞 context rot?同一個 agent 從第一週寫到第六週,中間累積的對話歷史不會把它壓垮嗎?

    答:不是「一個 agent 跑到底」,是「每個 cycle 換新 agent,cycle file 接力」

    這篇講 cycle file 設計方法論——為什麼必須是檔案不是對話、為什麼必須在 git 不能在 Notion、8-stage 結構每個 stage 對應哪個 multi-agent 踩坑,以及這個 pattern 怎麼推廣到 ADR / RFC / postmortem 這類非 multi-agent 場景。

    對照組:傳統工業界 RD 開發流程

    在進入 multi-agent cycle file 方法論之前,先把工業界標準的 RD 開發流程攤開——對照基準清楚了,後面的對應關係才好讀。本文不是發明新流程,是把這套經典 SDLC 對應到能跑在多個 AI agent 上的 cycle file 結構。

    經典流程九步

    1. PM 整理需求 — business requirement,decide what to build
    2. SA 分析需求(可由 PM 兼任)— 系統分析,what the system must do
    3. SD 設計需求(可由 PM 兼任)— 系統設計,how the system should do it
    4. RD 撰寫程式 — implementation
    5. RD 自測後交付 — pre-PR self-test
    6. QA 進行測試,建立錯誤表 — finding list,QA 只報事實不下 P0/P1
    7. PM 確認錯誤表,跟 SPEC 比對 — triage:是 bug 還是 feature 還是 usage 還是 not_issue
    8. 交給 RD 修正 → 修正後再給 QA → PM,持續 loop — 直到 PM 點頭。這個 loop 是品質的核心,不是 bug,是設計
    9. 上到 GA 區,以正式資料進行測試 — production smoke,真實數據才能發現假性綠燈

    測試分三段——這三段不能混

    類型 內容 在 cycle file 對應
    測試程式 unit test / integration test / E2E test scripts Stage 5a failing test + Stage 5c regression suite
    測試環境 staging server / sandbox / test docker compose / backend services Stage 0.5 Pre-cycle hygiene 確認所有服務 up
    測試資料 fixture / seed data / disposable test users / canonical baseline Stage 0.5 fixture reset + disposable qa_* fixtures

    經典流程 ↔ Cycle file 對應

    傳統 RD 流程 Cycle file 對應 stage
    PM 整理需求 Cycle file Header 的 spec section + related INV
    SA / SD 分析設計 Spec.md + invariants.md 條目(契約寫死)
    RD 撰寫 + 自測 Stage 1 RD 自測(單線程,一個 agent 動手)
    QA 測試 + 錯誤表 Stage 2 QA wave 並行 + Stage 3 OPEN findings
    PM 確認比對 SPEC Stage 4 PM triage(bug / feature / usage / not_issue)
    RD 修正 → QA → PM loop Stage 5 fix → Stage 6 regression → Stage 7 comparison QA → 回 Stage 3
    PM 點頭 Stage 8 merge gate(全綠才合)
    上 GA 區正式資料測試 Production smoke + user smoke(primary detection,觸發 T-user-smoke-followup cycle)

    關鍵差別:傳統流程角色是「人」(PM / SA / SD / RD / QA),cycle file workflow 把這些角色變成「agent 在不同 stage 的職責」——同一個 LLM agent 在 Stage 1 是 RD,在 Stage 2 wave 之中扮演 QA(但 scope 鎖死),Stage 7 是 comparison QA。PM 永遠是人,因為「跟 SPEC 比對 + 做價值判斷」這層 LLM 不該越界。

    §1 為什麼「對話 context」是錯誤的狀態載體

    多數人用 Claude / GPT / Cursor / Aider 寫 code 的時候,默認狀態活在對話裡——上一句問題、AI 上一個回應、再上一個截圖,都在 chat history 裡。看起來理所當然,直到撞到三個事實:

    1. 對話會壓縮(compaction)。主流工具在 context 接近上限時都會自動壓縮歷史。「我剛剛跟你說過 X」這句話,壓縮一輪後就變成「我們討論過某些事」。具體細節進了 summary,但 summary 本身會再被壓縮。資訊密度持續下降。
    2. 對話只活在單一 session。開新 session = 全新對話,讀不到上次的 context。即使有 memory file(persistent profile / preferences),那是「人格 / 偏好」層,不是「這個專案這個 PR 跑到哪了」的狀態。
    3. 對話沒 git history。半年後翻回去看「為什麼這個 PR merge」,翻 chat log 是不可能任務——對話沒 commit message、沒 tag、沒 diff,review 工具完全用不上。

    傳統 workaround 是「我把上下文 paste 進新 session」。這是 fragile 的——你會漏、你會省略、你會把 600 字濃縮成 30 字然後新 session 推不出原本的決策邏輯。

    結論:對話狀態必然會掉,任何長期 multi-agent workflow 都要把 state 寫到對話以外的地方。Cycle file 是其中一種具體實踐。

    §2 Cycle File 的核心思想:file-as-state-machine

    一個 cycle file = 一個 PR cycle 的完整狀態機。離散的 stage 有明確 entry / exit 條件,跨 session 接手 = 讀檔不是讀對話。

    為什麼必須是 markdown 不是 JSON / DB

    • Human-AI 雙方都能讀。人要看,AI 要讀,PR reviewer 也要看。Markdown 是最低共通格式。
    • Diff 友善。Stage 3 加一個 finding,git diff 看得清清楚楚。JSON 一改整個檔重排,DB 改一個 row 沒 diff。
    • 離 code 近docs/cycles/Cn-*.md 跟 source code 在同一個 repo,branch 切換時 cycle file 也跟著切換。

    為什麼必須在 git 不能在 Notion / Confluence

    • Audit trail。每次 cycle file update 都是一個 commit,who / when / why 一目了然。Cloud doc 改了就改了,沒人記得是誰改的。
    • 跟 code 同生死。Branch 跟 cycle file 綁在一起,rebase / cherry-pick / revert 都會帶走 cycle file。Notion 不知道 code 在哪個 branch。
    • 跨工具不依賴。Cloud doc 服務掛了 cycle file 就讀不到。Git 不會掛——而且即使原 repo 沒了,每個 clone 都有完整歷史。

    §3 8-stage 結構——每個 stage 對應一個 multi-agent 踩坑

    本節拆 cycle file 8-stage 的標準結構,標出每個 stage 對應哪個 multi-agent 容易撞的坑。

    Header — cycle 身分證

    # Cycle Cn — <short PR title>
    
    Owner: <engineer agent / human>
    Started: YYYY-MM-DD HH:MM
    Status: open / in_qa / in_triage / in_fix / regression / closed
    Cycle Type: T-PR-cycle / T-regression-fix / T-feature-cycle /
                T-spec-audit / T-user-smoke-followup / T-mutation-test
    Related:
      - PR / branch: <commit_sha>
      - Spec section: <§X.Y>
      - Primary INV(s) targeted: INV-XXX-NNN

    下個 agent 接手第一件事是讀 Header。Cycle Type 決定哪些 stage 必經、哪些 N/A——不分 type 把所有 cycle 都當 PR-cycle 跑,結果 regression-fix 跑 8-stage 浪費,user-smoke-followup 跑 8-stage 又錯位(user 已經是 primary detection 了,還跑 QA wave 是反過來)。

    Stage 0.5 — Pre-cycle hygiene

    • git status --short clean(除了本 cycle 將動的 file)
    • HEAD = <commit-sha>,不是 mid-rebase / mid-merge state
    • seed / fixture reset script 跑過,fixture 為 canonical
    • 列出本 cycle 將建立的 disposable test fixtures,不複用共享 fixture
    • 所有相關服務 healthy(backend / proxy / DB / storage 皆 up)

    對應的坑:跨 cycle 副作用會讓新 cycle 在污染狀態跑出 false positive ✅。上輪 cycle 殘留的 test payload、未清的 disabled user、過期的 rate-limit lockout——新 agent 進場已經在污染狀態,QA wave 跑出來的綠燈是 false confidence。Pre-cycle baseline check 是唯一的事前防線。

    Stage 1: RD 自測

    • 單元測試全綠(附 commit SHA)
    • Live smoke:對 endpoint X / user Y 跑 happy path(寫一兩行紀錄)
    • PR header 完整(INV 宣告 / QA scope / Verification 三段)

    RD 在開 PR 之前就先過自己的關。沒過自測的 PR 連 Stage 2 都進不去——直接退回。

    Stage 2: QA wave(並行讀取)

    2-4 個 QA agent 並行,每個 scope 鎖死 1-3 個 invariant。這是 multi-agent「平行覆蓋」的核心場景——讀取不衝突。

    QA agent A — INV-XXX-NNN red-team
    QA agent B — INV-YYY-MMM regression
    QA agent C (optional) — same scope as A, no knowledge of A's findings
                           (consistency check; 結果一致則 spec 寫得清楚,
                            不一致則 spec 有歧義先收斂)

    QA agent 只能標 ✅ / ❌ / OPEN,絕對不准標 P0/P1——那是 PM 的 authority。OPEN 一律往 PM triage 走。

    Stage 3: OPEN findings(等 PM triage)

    所有 QA agent 的 OPEN finding 收進一張 finding table。Finding 格式:

    ### Finding F-Cn-001
    - QA agent: A
    - Resolver/Feature: <name>
    - Observed: <事實>
    - Repro: <exact commands>
    - PM triage:
      - Class: bug / feature / usage / not_issue / spec_clarification
      - Confidence: high / low
      - Reasoning: <≤2 sentences citing spec/INV>
      - User review needed: yes / no

    Findings ≥3 時派 PM-agent 跑 first-pass triage,user 只 review confidence=lowclass=spec_clarification 兩類。Findings ≤2 user 直接判,省 round-trip。

    Stage 4: User review(只看 low-conf)

    User 對每個 confidence=lowspec_clarification 項目走 PM triage 分判,30 秒一個 finding。超過 2 分鐘 = finding 太大,要拆。

    Downstream sweep(Stage 5 之前必填)

    本 cycle 改動的 state(DB tables / schema / role-cap definition / fixture state),列出有哪些其他 resolver / query 會讀到。grep 全 repo 找 reader,寧可 false positive 多列幾條,少列就漏 ripple。

    對應的坑:改動會 ripple 到 cycle scope 外的 readers,沒 explicit list 必漏。經典場景:Cycle A 改了 fixture seed script,衍生 1 小時後 user 點 dashboard 某個 tab 崩。原因是 Cycle A 改了某張表的 state,影響到 cycle scope 外的另一個 resolver——那個 resolver 不在 Cycle A 的測試範圍裡,沒人提醒去看,bug 就溜進去。Downstream sweep 強制 RD 在 Stage 5 開修前 explicitly list ripple 範圍,Stage 6 regression 必須 cover。

    Stage 5: RD fix(TDD red-green 拆 5a / 5b / 5c)

    Stage 5a — write failing test
      - 寫 test 對應 invariant / 對應 finding attack scenario
      - 跑 test → 預期 ❌ red(沒紅 = test 寫錯)
      - commit "test: failing test for F-Cn-NNN / INV-XXX-NNN (red)"
    
    Stage 5b — implement fix
      - 寫 fix
      - 重跑 5a 的 test → 預期 ✅ green
      - commit "fix: ... (green via test in <5a-sha>)"
      - commit message 必填 "Failing test verified at: <5a-sha>"
    
    Stage 5c — refactor + regression
      - refactor 必要時
      - 跑全套既有 test 確認無 regression

    對應的坑:「test + fix 同 commit」沒驗 test 真的會抓對應 bug,可能是 vacuous test(永遠 pass 但不 cover 要 cover 的 case)。沒有「test 先 ❌、fix 後 ✅」這個 TDD 基本動作,你不知道 test 是真的在驗還是空跑。拆三個 commit 的好處是 bisect 看得出 red→green 軌跡。

    Stage 6: Regression

    Stage 5 fix 跑完,QA agent 重跑 Stage 2 的 wave(同樣的 prompt,只是 commit SHA 換成 fix sha)。Downstream sweep 列出的 ripple 範圍必須驗。

    Stage 7: Comparison QA(對抗 groupthink)

    派一個全新的 QA agent(不告訴它原 QA 抓到什麼),跑同一份 PR。如果它抓出新 finding = 原 QA 還有盲點。如果它跟原 QA 結論一致 = 確認可信。

    對應的坑:QA agent + Engineer agent 同 LLM 譜系,想得到的 attack scenario 高度重疊,共有盲點。Comparison QA 是減輕 groupthink 的最低成本做法——成本是多派一個 agent,收穫是另一個視角的覆蓋。

    Stage 8: Merge gate

    要合 PR,全部都要打勾:

    • PR header 完整(INV 宣告 / QA scope / Verification)
    • 宣告的「滿足」invariant:兩個 QA agent 都報 ✅
    • 宣告的「可能影響」invariant:回歸都 ✅
    • 兩個 QA agent 報告結論一致
    • OPEN list 清空(全部 triage 完)
    • 單元測試綠
    • 如 PR 影響 UI → 手動 smoke 一次 happy path

    Stage 8 全綠才 merge,cycle file commit 留檔,close cycle。

    §4 Cycle Type — 5 種 stage profile,不是每個 cycle 都跑 8-stage

    「Cycle Type」field 解決一個很實在的問題:不同性質的 cycle 用不同 stage profile,硬塞 8-stage 會浪費 stage 或漏 stage。

    Cycle Type 觸發 Stage profile
    T-PR-cycle 開 PR 等 merge 完整 8-stage(QA wave + regression + comparison newbie)
    T-regression-fix Engineer / agent 自抓 regression 5-stage:skip Stage 2 QA wave + Stage 4 user review;root cause 在 cycle file 開頭講清
    T-feature-cycle Forward-going 新 feature Stage 5 在 Stage 2 之前(先實作再 QA wave 對 INV 驗證)
    T-spec-audit 隨機抽樣 / category 全驗 Stage 2 only + report;無 fix。Findings raise 為 OPEN 給 PM
    T-user-smoke-followup User 直接報 bug Stage 3 直接收 finding(user 是 primary detection)+ skip Stage 2;後續 5/6/7/8 全跑

    Cycle file 開頭強制填 Cycle Type: T-XXX,Stage 8 merge gate 只 enforce 該 type 必經的 stage。

    §5 三個工程效益——為什麼這個設計值得

    效益 1:撐過對話 compaction

    對話被壓縮的時候,壓的是 chat history,不是 git artifact。下個 session 我打開 docs/cycles/Cn-*.md,完整的 persona、attack scenario、findings、PM triage 結果都還在。

    對照組:如果這些資訊只活在對話裡,compaction 一輪 → 只剩「我們做了一些 QA」這種無資訊摘要 → 下個 agent 接手等於從零開始。

    效益 2:跨 session / 跨 agent 可讀

    新 agent invocation(無論是新 session、不同 agent、甚至不同人接手),讀檔就能上工。長期專案累積的 cycle 是獨立 Engineer invocation,每個 cycle 開頭讀 workflow SOP + invariants 契約 + 當前 cycle file 進度,3 分鐘進入狀況。

    對照組:沒 cycle file 的話,新 agent 進場第一件事是「請告訴我前面跑到哪了」——你自己要把 600 行對話濃縮 paste 給它,中間漏東漏西。

    效益 3:6 個月後的自己有 audit trail

    半年後 grep 某條 invariant ID,找到這條 invariant 是哪個 cycle 加的、為什麼加、當時 PM 怎麼判的——全部在 git 裡,commit message 帶 finding ID。

    對照組:Cloud doc 寫的 ADR、Confluence 寫的 design doc——半年後權限過期、url 換掉、search 找不到。

    §6 推廣:file-as-state-machine 不只 multi-agent 用得到

    Cycle file 的核心是 file-as-state-machine:把工程過程的 state 從「對話 / 會議 / 腦袋」搬到「檔案 / git」。這個 pattern 在傳統軟工不是新東西,只是名字不一樣。

    名稱 用途 跟 cycle file 共同性質
    ADR(Architecture Decision Record) 記錄架構決策的 context / 選項 / 決定 / 後果 活在 git,撐過人員流動,6 個月後可 audit
    RFC(Request for Comments) 大型 feature 的設計提案 + comment trail 同上;增加 review 階段的離散 stage
    Postmortem incident 事後分析 + 行動項 同上;Stage 包含 timeline / root cause / action items
    Cycle file single PR 的完整 lifecycle 同上;比 ADR/RFC 更短週期、更高頻次

    共同性質:把工程過程的 state 從可揮發載體(對話、會議、腦袋)搬到不可揮發載體(git、版控檔案)。對 single-developer 也有用——你不會記得三個月前為什麼選 PostgreSQL 而不是 MySQL,但 ADR 會記得。

    對 multi-agent 工作流,這個 pattern 的價值放大 100×。因為 multi-agent 有兩個額外的揮發源:

    • 對話 compaction(每幾小時就一次)
    • 跨 session / 跨 agent 切換(每個 cycle 一次)

    Single-developer 的對話 context 一個專案可能撐幾天,multi-agent workflow 可能撐幾小時。Cycle file 的「狀態接力棒」價值在 multi-agent 場景才完整展現。

    §7 在新環境啟動這套流程——4 個檔案 + 一段 bootstrap prompt

    如果今天換新電腦、開新專案、或換工具(Claude Code → Antigravity / Codex / Cursor / Aider),怎麼快速把這套 cycle workflow 啟動到「下一個 agent 進來就能照跑」的狀態?答案是最小可行 kit:4 個檔案 + 一段給 agent 的開場白

    最小可行 kit:4 個檔案

    檔案 內容 變動頻次
    docs/workflow.md 8-stage SOP 完整版(本文 §3 內容) 每 retro 一次 amend
    docs/cycle-template.md Cycle file 結構 template(複製即可填) 穩定,少改
    docs/invariants.md 所有 INV-XXX-NNN 契約列表(初始空白,隨 cycle 累積) 每 cycle 可能 amend
    AGENTS.md Role taxonomy(perspective-driven,不是 8 職稱)+ 資源預算上限 穩定,專案改 tech stack 時才動

    這 4 個檔不是「規劃文件」,是「執行契約」——每 PR 強制讀,違反退回。具體 staffing / per-cycle 進度寫在 docs/cycles/Cn-*.md

    4 個檔案的最小內容範本

    下面 4 段是直接可複製貼到專案的 minimal 內容。Day-1 把這 4 個檔放進 docs/ 跟 root 之後,就有完整的 cycle workflow kit,新 agent 進來照走。

    檔案 1/4 — docs/workflow.md

    8-stage SOP 的 skeleton。詳細每個 stage 規則見本文 §3,這份 skeleton 是「每個 agent 開工前必讀」的最小契約版本。

    # Workflow SOP — Cycle-based PR Pipeline
    
    > 所有 PR 走 cycle file 流程。違反 stage 順序的 PR 直接退回。
    
    ## 8 Stages
    
    | Stage | 動作 | 誰做 | 必經? |
    |---|---|---|---|
    | 0.5 | Pre-cycle hygiene (baseline 乾淨確認) | Writer | yes |
    | 1 | RD 自測 (unit test + live smoke + PR header) | Writer | yes |
    | 2 | QA wave (2-4 verifier 並行,每個 scope 鎖 1-3 INV) | Verifier(s) | yes (PR-cycle) |
    | 3 | OPEN findings table (QA agent 收 finding) | Verifier | yes |
    | 4 | PM triage (bug / feature / usage / not_issue 分判) | PM / Triage | yes |
    | Downstream sweep | grep 列出 ripple 範圍 (本 cycle scope 外的 readers) | Writer | yes |
    | 5 | RD fix — 5a 寫 failing test → 5b 寫 fix → 5c refactor | Writer | yes (有 bug 才跑) |
    | 6 | Regression (重跑 Stage 2 wave,scope 含 ripple) | Verifier | yes |
    | 7 | Comparison QA (新 agent 不知道原 QA 結果,re-audit) | Verifier | recommended |
    | 8 | Merge gate (全綠才合) | Writer + PM | yes |
    
    ## 5 Cycle Types (決定哪些 stage 必經)
    
    | Type | 觸發 | Stage profile |
    |---|---|---|
    | `T-PR-cycle` | 開 PR 等 merge | 完整 8-stage |
    | `T-regression-fix` | engineer 自抓 regression | 5-stage:skip Stage 2 + Stage 4 |
    | `T-feature-cycle` | forward-going 新 feature | Stage 5 在 Stage 2 之前 |
    | `T-spec-audit` | 隨機抽樣 / category 全驗 | Stage 2 only + report (無 fix) |
    | `T-user-smoke-followup` | user 報 bug | Stage 3 直接收 finding,skip Stage 2 |
    
    ## Iron Rules (執行契約,違反退回)
    
    1. **寫入單線程**:同時間只能 1 個 Writer agent 動手。其他 agent 都不准動 code / spec / schema / migration。
    2. **Verifier 不准標 P0/P1**:只能 ✅ / ❌ / OPEN。嚴重度是 Triage 的 authority。
    3. **Verifier scope 鎖死 1-3 INV**:不准「找任何 bug」(R35 21 輪迴圈的反面教材)。
    4. **TDD red-green 拆三 commit**:Stage 5a failing test red commit → 5b fix green commit (帶 `Failing test verified at: <5a-sha>`) → 5c refactor。`test+fix 同 commit` = 沒驗 test 有效。
    5. **修了 bug 必須加 INV 到 `docs/invariants.md`**:沒加不算修完。半年後同類 bug 一定回來。
    6. **cycle file 留檔不刪**:cycle 收完 commit 進 git,當作 audit trail。
    7. **每月 retro amend workflow.md**:漏掉的 bug / 浪費的 stage / 卡住的 finding → 回頭改 SOP。
    

    檔案 2/4 — docs/cycle-template.md

    每個 cycle 開頭從這份複製出 docs/cycles/Cn-<topic>.md(n 是流水號,grep 看下一個)。照著填,不要自己改 stage 結構。

    # Cycle Cn — <short PR title>
    
    **Owner**: <agent ID / human>
    **Started**: YYYY-MM-DD HH:MM
    **Status**: open / in_qa / in_triage / in_fix / regression / closed
    **Cycle Type**: T-PR-cycle / T-regression-fix / T-feature-cycle / T-spec-audit / T-user-smoke-followup
    **Related**:
    - PR / branch: <commit_sha or branch>
    - Spec section: <§X.Y or "N/A">
    - Primary INV(s) targeted: INV-XXX-NNN, INV-YYY-MMM
    
    ---
    
    ## Stage 0.5 — Pre-cycle hygiene
    
    - [ ] `git status --short` clean (除了本 cycle 將動的 file)
    - [ ] HEAD = <commit-sha>
    - [ ] fixture reset 跑過, baseline canonical
    - [ ] 列出本 cycle 用的 disposable fixtures (qa_<cycle>_<role>_<timestamp> prefix)
    - [ ] 所有相關服務 healthy
    
    ## Stage 1: RD 自測
    
    - [ ] unit test 全綠 (commit: <sha>)
    - [ ] live smoke 紀錄:<endpoint X / user Y / happy path 結果>
    - [ ] PR header 完整 (滿足 INV / 可能影響 INV / 提議新增 INV 三段)
    
    ## Stage 2: QA wave
    
    ### QA agent A — INV-XXX-NNN red-team
    - Launched: HH:MM
    - Result: ✅ / ❌ / OPEN
    - Findings: <count>
    
    ### QA agent B — INV-YYY-MMM regression
    - Launched: HH:MM
    - Result: ✅ / ❌ / OPEN
    
    ## Stage 3: OPEN findings
    
    ### F-Cn-001
    - QA agent: A
    - Resolver/Feature: <name>
    - Observed: <事實,不下判斷>
    - Repro:
      ```
      <exact commands / GraphQL / curl>
      ```
    - PM triage:
      - Class: bug / feature / usage / not_issue / spec_clarification
      - Confidence: high / low
      - Reasoning: <≤2 sentences citing spec/INV>
      - User review needed: yes / no
    
    (repeat for each finding)
    
    ## Stage 4: User review (only low-conf items)
    
    - [ ] F-Cn-XXX user-confirmed class: <class>
    
    ## Downstream sweep (Stage 5 之前必填)
    
    ### 本 cycle 改動的 state
    - DB tables: <list>
    - Schema: <changes>
    - Fixture state: <changes>
    
    ### 讀取上述 state 的其他 resolver / query
    
    | State | Reader | Stage 6 必驗 |
    |---|---|---|
    | <table_X> | <Resolver A / Query B> | ✅ |
    
    ## Stage 5: RD fix
    
    ### Stage 5a — failing test (red)
    - Test 檔: <path>
    - 跑出 red: commit <5a-sha>
    
    ### Stage 5b — implement fix (green)
    - Fix commit: <5b-sha> (帶 `Failing test verified at: <5a-sha>`)
    
    ### Stage 5c — refactor + regression
    - 全套既有 test pass: ✅
    
    ## Stage 6: Regression
    
    - QA wave 重跑 (scope 含 downstream sweep ripple)
    - 結果: ✅ / ❌
    
    ## Stage 7: Comparison QA
    
    - 新 verifier 不告知原 QA 結果, re-audit
    - 結論: 跟原 QA 一致 / 不一致
    
    ## Stage 8: Merge gate
    
    - [ ] PR header 完整
    - [ ] 宣告的「滿足」INV: ✅
    - [ ] 宣告的「可能影響」INV regression: ✅
    - [ ] 兩個 QA agent 結論一致
    - [ ] OPEN list 清空
    - [ ] unit test 綠
    - [ ] 如影響 UI: manual smoke happy path
    
    ---
    
    ## Cycle close
    
    - **Closed**: YYYY-MM-DD HH:MM
    - **Outcome**: merged-on-dev / abandoned / split into Cn+1
    - **Total commits**: <count>
    - **New INVs added**: <list>
    - **Bugs fixed**: <count>
    - **Lessons** (going to brain): <bullet points>
    

    檔案 3/4 — docs/invariants.md

    專案的 invariant 契約 catalogue。初始空白,隨 cycle 累積。每修一個 bug 必須在這加對應條目——沒加不算修完。半年後 grep 某個 INV ID 應該找得到「誰加的、為什麼加、對應哪個 test」。

    # Invariants — Project Contract Catalogue
    
    > Every invariant here is a contract. Code must hold. Tests must verify.
    > Format: `INV-<CATEGORY>-<NNN>: <statement>` + origin + severity + test ref.
    
    ## Categories (調整為你專案實際需要的)
    
    - `INV-AUTH-*` — authentication / session / token rotation
    - `INV-RBAC-*` — role-based access control / capability checks
    - `INV-RLS-*` — row-level security (multi-tenant isolation)
    - `INV-DATA-*` — data integrity / nullability / FK / atomicity
    - `INV-IDEM-*` — idempotency (probe-then-INSERT, advisory locks)
    - `INV-INPUT-*` — input validation / sanitization
    - `INV-UI-*` — frontend behavior contracts
    - `INV-RESOLVER-*` — resolver-level contracts (scope, error shape)
    - `INV-SCHEMA-*` — schema design constraints (反 over-design 用)
    - `INV-BATCH-*` — batch operation invariants
    
    ## Verification Layer Reference
    
    每條 INV 標 verification layer:
    
    - L0 spec / L1 INV / L2 schema / L3 resolver / L4 frontend / L5 E2E
    
    (同一條 INV 可能 multi-layer。看本文 §5 對 6-layer doneness 的說明。)
    
    ---
    
    ## Invariants
    
    ### INV-AUTH-001 (example template — 換成你的)
    - **Statement**: <one-line contract,可被測試直接驗證>
    - **Origin**: Cycle C<n> (YYYY-MM-DD) — <short context, why this surfaced>
    - **Severity**: P0 / P1 / P2
    - **Test**: <path/to/test.go::TestFuncName> or <❌ TODO in backlog>
    - **Enforcement layer**: L1 + L3
    - **Related findings**: F-C<n>-NNN
    
    ---
    
    ## Backlog (test ❌ TODO)
    
    當你寫了 INV 但 test 還沒寫完時, 標 ❌ 放這裡。半年後拿這個 backlog 跑「補測試 sprint」:
    
    - ❌ INV-XXX-NNN (待補 integration test)
    - ❌ INV-YYY-MMM (待補 E2E test)
    
    ---
    
    (initial state: empty — populate as cycles surface bugs.
    每 fix commit 必須在這加對應 INV, 沒加不算修完。)
    

    檔案 4/4 — AGENTS.md

    Role taxonomy + 資源預算。不寫具體職稱(架構師 / PM / UI-UX / 後端 / Flutter / DBA / QA)——那是死文件做法。寫的是「執行類型」(Writer / Verifier / Triage / Comparison / Newbie) + 機器資源上限,具體 staffing 在每個 cycle file 的 Header 裡。

    # Agents — Role Taxonomy + Resource Budget
    
    > Roles are **perspectives**, not headcount. Agent count is an OUTPUT
    > of staffing per cycle, declared in each cycle file Header.
    > This file holds only the **invariant** parts: budget ceiling + type taxonomy.
    
    ## Resource Budget (本機, 改成你的數字)
    
    | Item | RAM | Notes |
    |------|-----|-------|
    | Total RAM | 32 GB | This machine |
    | OS + Docker + browser reserve | ~7 GB | Baseline |
    | **Available for agents** | **~22 GB** | Max budget |
    
    ## Model Memory Reference (Claude Code)
    
    | Model | RAM | When to use |
    |-------|-----|-------------|
    | Opus | ~1.0 GB | architecture / cross-file reasoning / security / senior thinking |
    | Sonnet | ~0.6 GB | implementation / API / tests / documentation |
    | Haiku | ~0.4 GB | file scanning / config compare / simple SQL / read-only audit |
    
    口訣:需要「想」→ Opus | 需要「做」→ Sonnet | 需要「找」→ Haiku
    
    ## Role Taxonomy (perspectives, not job titles)
    
    | Type | Action | Parallelizable? | Typical model | Notes |
    |------|--------|----------------|---------------|-------|
    | **Writer** | mutate files (code / SQL / migration / spec) | NO (single-thread) | Sonnet / Opus | 同時只 1 個 |
    | **Verifier** | read-only inspection / red-team / regression | YES | Haiku / Sonnet | scope 鎖死 1-3 INV |
    | **Triage** | classify findings (bug / feature / usage / not_issue) | NO (sequential) | Sonnet (或人類) | PM authority |
    | **Comparison** | independent re-verify (Stage 7) | YES (with #1 verifier) | Haiku | 不知道原 QA 結果 |
    | **Newbie** | adversarial persona audit (broader coverage) | YES | Sonnet | each persona explicit prompt |
    
    ## Per-Cycle Staffing (declared in cycle file Header)
    
    每個 cycle 在自己的 `docs/cycles/Cn-*.md` Header 宣告本輪派多少 agent。範例:
    
    | Agent ID | Type | Model | RAM | Scope |
    |----------|------|-------|-----|-------|
    | RD-1 | Writer | Sonnet | 0.6 GB | 整個 cycle 寫入 |
    | QA-A | Verifier | Haiku | 0.4 GB | INV-XXX-NNN red-team |
    | QA-B | Verifier | Haiku | 0.4 GB | INV-YYY-MMM regression |
    | QA-C | Comparison | Haiku | 0.4 GB | Stage 7 (盲 re-audit) |
    | PM-Tri | Triage | Sonnet | 0.6 GB | Findings ≥3 才派 |
    
    **Memory budget check**: 加總 ≤ available。Over budget → merge 兩個最低 scope Verifier。
    
    ## Iron Rules (執行契約, 違反退回)
    
    1. **一個 cycle 同時只能 1 個 Writer agent 動手**。其他 agent 都不准動 code / spec / schema / migration。
    2. **Verifier 永遠不准標 P0/P1**——只能 ✅ / ❌ / OPEN。
    3. **Verifier scope 必須鎖死 1-3 個 INV**。不准「找任何 bug」。
    4. **TDD red-green 必拆 5a / 5b / 5c 三 commit**。
    5. **cycle file 必須留檔**, 跨 cycle 不刪。
    6. **每月 retro 一次, amend workflow.md 或 AGENTS.md**——這份檔死掉就跟 staffing 死掉一樣慘。
    

    4 個檔放好之後,接下來那段 bootstrap prompt 就有東西可指了——每個動作都對應到上面具體的檔案內容。

    5 個 type 的事故來源 — 入門篇深挖

    看到 AGENTS.md 列 Writer / Verifier / Triage / Comparison / Newbie 5 個 type,你可能會想:「為什麼不直接用傳統 8 職稱(架構師 / PM / UI-UX / 後端 / Flutter / DBA / QA)?」答案是這 5 個 type 不是想像出來的,是踩過真實角色事故反推出來的補丁——21 輪 ping pong、11 輪 self-audit 漏 P1、5 persona 抓 23 finding。每個 type 對應一條具體事故。

    故事完整版在入門篇用第一人稱寫:「為什麼修不完?」— 從 21 輪迴圈到 5 type taxonomy 的多 agent 角色設計。沒看過入門篇的讀者建議先回頭讀,再看本篇 5 個 type 怎麼用會更有 context。

    另一個跟 type 並列的設計選擇是 per-cycle dynamic staffing:不是「每 cycle 派固定 N 個 agent」,而是每個 cycle 在 docs/cycles/Cn-*.md Header 自己宣告派哪些 type、什麼 model、佔多少 RAM,加總要 ≤ machine available。改 1 行 typo 跟改 schema 不會用同樣編制。同樣在入門篇的故事裡詳細展開。

    Bootstrap prompt(複製貼到新 session 的開場白)

    你接手這個專案。第一輪 onboarding 強制讀以下檔案,讀完再開工:
    
    1. docs/workflow.md   — 8-stage cycle SOP,所有 PR 必經
    2. docs/cycle-template.md — cycle file 結構,每個 PR 複製一份
    3. docs/invariants.md — 所有 invariant 契約,改動前先看會影響哪幾條
    4. AGENTS.md          — 本機資源預算 + role taxonomy
    
    從現在開始,所有改動走 cycle file 流程:
    
    1. 開 PR 前 git checkout -b feat/<topic>
    2. 從 cycle-template.md 複製成 docs/cycles/Cn-<topic>.md
       (n = 流水號,grep 既有 docs/cycles/ 看下一個 n 是什麼)
    3. 填 Header(owner / start time / cycle type / related INV)
    4. 跑 Stage 0.5 pre-cycle hygiene 確認 baseline 乾淨
    5. 進 Stage 1 RD 自測 → Stage 2 QA wave → ... → Stage 8 merge gate
    6. 收尾時 cycle file commit 留檔,絕對不刪
    
    紀律:
    - QA agent 永遠不准標 P0 / P1(那是 PM 的 authority)
    - 任何 fix 必須 5a 寫 failing test 紅燈 → 5b 寫 fix 綠燈 → 5c refactor
    - 任何改動先 grep 找 downstream reader,沒列必漏
    - cycle file 寫具體 evidence,不寫抽象 status
    - 修了 bug 必須加 INV 到 docs/invariants.md,沒加不算修完
    
    不確定的 stage 先問我,不要自己腦補。

    這段直接 paste 進新 Claude Code session、Antigravity initial message、Codex 的第一輪 prompt、或 Cursor 的 chat input 都能用。共通點是這些工具都讀 markdown,所以方法論本身跨工具。

    跨工具相容性——自動觸發機制

    差別不在「方法論能不能跑」,在「自動觸發機制」。每個工具有自己的「啟動時必讀」slot:

    工具 自動觸發 slot 怎麼放 bootstrap
    Claude Code CLAUDE.md(專案根目錄)+ ~/.claude/skills/ CLAUDE.md 第一段宣告「## Domain Skill: cycle-workflow」+ skill 寫 cycle SOP 引導
    Codex / OpenAI Agent AGENTS.md(OpenAI 協議) AGENTS.md 開頭加「啟動時讀 docs/workflow.md 必經 8-stage」段落
    Antigravity 專案 root system prompt 同上,在 system prompt 內 reference docs/workflow.md
    Cursor .cursorrules .cursorrules 寫「每次回應前讀 docs/workflow.md」+ reference cycle template
    Aider .aider.conf.yml / CONVENTIONS.md CONVENTIONS.md 寫 cycle SOP 要點,啟動時 –read 進去
    純 ChatGPT / Claude Chat 無自動 slot 手動 paste 上面 bootstrap prompt 進每個新對話

    關鍵 insight:方法論存 markdown,觸發機制存工具專屬 slot。換工具時方法論不用重寫,只要更新觸發機制怎麼指向同樣那 4 個檔案。

    持續 update 機制——別讓 kit 變死文件

    啟動只是第一步。長期維護有三條強制 update trigger,少了任何一條,kit 半年後就會 rot:

    1. fix: commit 強制 update invariants.md:修了 bug 必須加對應 invariant,沒加不算修完。沒這條,同類 bug 半年後一定回來。
    2. 每 cycle 收尾 commit docs/cycles/Cn-*.md:cycle file 留檔不刪,當作 audit trail + 給未來 cycle 參考。沒這條,cycle 跑完就忘,跨 cycle lesson 全部蒸發。
    3. 每月 retro amend workflow.md:跑了一個月會發現某個 stage 太重 / 漏 / 順序不對。retro 看數據(漏掉的 bug、浪費的 stage、卡住的 finding),回去 amend SOP。沒這條,workflow.md 變死文件。

    這三條 trigger 應該寫進 workflow.md 自身,讓「每個 agent 開工前必讀 workflow」這個動作自動帶上「該 update 什麼」的提醒。

    第一個專案的 day-1 動作

    1. git init + 建 docs/cycles/ 目錄
    2. 把上面 4 個檔案複製進來(workflow.md / cycle-template.md / invariants.md 空白 / AGENTS.md)
    3. CLAUDE.md(or 對應工具的 root prompt 檔)宣告必讀那 4 個
    4. 第一個 PR 就照 cycle file 流程走——不要說「先簡單做,以後再上 SOP」,以後不會來
    5. 跑完第一個 cycle,commit cycle file + 第一條 invariant + 第一輪 workflow.md amend(會發現自己漏寫了什麼)

    這套不需要先「累積經驗」才能啟動。第一個 cycle 跑完就有第一份 cycle file 範例給未來自己 / 未來 agent 看,雪球從第一天就開始滾。

    §8 反模式——cycle file 怎麼寫會死掉

    • 寫太抽象:只列 status(QA: ✅),沒列 evidence(哪個 invariant、哪個 attack scenario、reproduce 步驟)。半年後讀不懂自己寫了什麼。
    • 寫太瑣碎:每個 keystroke 記 timestamp,cycle file 變成 chat log。讀的人撈不到結論。
    • 不留 cycle file:對話結束就忘,跨 session 必撞失憶。最常見也最致命。
    • 不分 stage:一個 cycle 寫成一坨流水帳。新 agent 不知道現在跑到哪。
    • 寫在 cloud doc / Notion 不是 git:沒 audit trail,branch 切換 cycle file 不會跟著切,跨工具不依賴的好處全部失去。
    • 不分 Cycle Type 硬跑 8-stage:user-smoke-followup 跑 Stage 2 QA wave 等於把 user 抓的 bug 丟回給 QA agent 確認——錯位、浪費。

    結語:接力棒不是裝飾,是 multi-agent 工程的真正關鍵

    Multi-agent 工程兩條互補規則:

    1. 動手的 agent 只能一個(寫入單線程,從 Cognition / Stanford 等業界共識)
    2. 下一個 agent 必須能無痛接手(cycle file 接力棒,業界文章很少談)

    多數人聽到「multi-agent」想到的是「多個 AI 一起工作」。實際上正確的設計是:同時間只有一個 AI 在動手,其他都是不動手的判斷者;動手的累了下一個來,接力棒(cycle file)不能丟

    業界文章很少談接力棒——他們談 orchestrator-subagent、談 generator-verifier、談 context isolation,但很少談「下一個 agent 從哪裡讀狀態」。可能因為 demo 場景太短,撞不到 compaction 也撞不到跨 session 失憶。長期專案跑下來,這個盲區會反覆把人燒一遍。

    Cycle file 是踩坑長出來的工程紀律。file-as-state-machine pattern 可以推廣到所有需要「process state 跨人 / 跨時間延續」的場景——不分是不是 multi-agent。

    延伸閱讀

  • 「56 條 INV 全綠,user 點一次抓出 4 個 bug」— Multi-Agent 業界共識的五個自家補丁

    重點摘要

    • 規劃 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 死了

    死文件的兩個必要條件

    盤點下來,一份文件變死,要同時滿足兩個條件:

    1. 寫了「會變的具體細節」——例如「8 個職稱 + 主要工作 + 預估記憶體佔用 600MB」。這些隨專案演化必然會變。
    2. 沒有強制 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 演化過程中,六個操作細節決定了它真的有效還是只剩形式:

    1. QA scope 鎖死 1-3 INV,不准抓「任何 bug」。R35 21 輪迴圈的反面教材就是讓 QA「找任何問題」,結果 finding 無限發散。Scope 鎖死後,每個 newbie 只查它自己的契約。
    2. QA 不准標 P0 / P1。只能標 ✅ / ❌ / OPEN。P0/P1 是 PM 的 authority,QA 上交給 PM triage。這條防止 QA agent「自己升級嚴重度」拖累節奏。
    3. PM 兩道閘:第一道是寫 spec / 加 INV(規格定錨),第二道是 finding triage(bug / feature / usage / not_issue 30 秒分判)。少了任一道,QA wave 都會無限發散。
    4. PR header 強制宣告 INV 影響。每個 PR description 必填三段:滿足哪些 INV、可能影響哪些 INV、提議新增哪些 INV。沒填完整 = PR 不算開,reviewer 直接退。
    5. Verifier 不共享 Writer 的 context。QA agent prompt 模板只給它「PR commit SHA / 一條 INV / test users / 環境」,不給它 Writer 的對話歷史。乾淨 context 反而推理更深(Cognition 觀察)。
    6. 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 累積更快。

    三個補救機制

    1. 定期 over-design audit(每 ~2 個月一次或大 milestone 後)。PM scan 角度:「99% 無痛、edge case 不擋 99%、不為將來 may-be 需求預留、不為『好體驗』造成系統壓力」。
    2. 砍之前先 grep 全 codebase 確認 0 caller。「我以為沒人用」跟「grep -r 證實 0 caller」是兩件事。HOME123 砍 batchDeliver 前 grep app/lib/,只在註解出現,於是放心砍。
    3. 砍完寫進 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),為什麼還是漏?

    1. Vacuous green test。Test 永遠 pass 不是因為實作對,是因為 assert 太寬或 fixture 沒覆蓋觸發條件。C11 那個 NULL bug 在前 11 個 cycle 的 test fixture 裡,根本沒有「user 帶 zero roles」這個狀態,所以 test 一直 green。
    2. Groupthink。QA agent 跟 Engineer agent 同 LLM 譜系,想得一樣。Engineer 寫 test 時想到的 attack scenario,跟 QA 寫 test 時想到的 attack scenario,高度重疊。盲點是 shared 的。
    3. 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 個建議方向

    1. User smoke = primary detection。不是 secondary、不是「最後再點一次」。每個 milestone 結束第一件事是 user 隨便點,不是看 CI report。
    2. Mutation testing 對抗 groupthink。每月或大 INV amendment 後跑一次,故意塞 plausible bug,看 QA agent 抓不抓得到。抓不到 = QA prompt 跟 Engineer 想得太像,得補 attack scenario。
    3. Adversarial persona 平行覆蓋。C29 模式:每個 persona 有明確「你跟 Engineer 想法不同的地方在哪」mandate,5 個 newbie 平行 audit,讀取型 multi-agent 完全沒衝突風險。
    4. 6-layer thinking 防止誤推。看到「INV 全綠」先問「這是 L 幾全綠?L4 / L5 有人驗過嗎?」L1-L3 全綠不等於對,只是「未驗中比較強的子集」。
    5. 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 輪迴圈重新踩一次。

    延伸閱讀

  • Claude Design 實戰拆解:brainstorming/spec/plan 三層流程的必要性與代價

    重點摘要

    • Claude Design 不是一個工具,是 Claude Code 裡由 brainstormingwriting-planssubagent-driven-development 三個技能組成的結構化開發流程,把「想 → 寫規格 → 拆任務 → 做 → 審查」變成可追蹤的步驟。
    • 最大價值是「砍掉不該做的事」——在我的失智症陪伴專案裡,這個流程幫我在寫 code 前砍掉了背景音樂、獨立話題卡、每日心情打卡三個功能,省下至少 3-4 小時重工。
    • 設計原則會在對話中浮出來——使用者一句「照顧者腦子清晰的,可以有期待的方式知道」變成整個系統的「可預期」原則,驅動 45 條提示語都用同一個模板。
    • 但它不適合所有情境——單檔 HTML 原型用 subagent-driven-development 會被 39 次 subagent dispatch 拖到超慢,實測比 inline 慢 3-5 倍。
    • 判斷標準:想事情時用 brainstorming、寫一致內容時用 spec、多檔複雜時用 subagent;單檔改一個函式就直接 inline。
    • 最深的反省:Claude Design 其實就是把 SDD「菜譜化」。人人可以照做,但如果不懂菜譜背後的「為什麼」,遇到菜譜涵蓋不了的變化就卡住。AI 時代最危險的是「永遠繞著菜譜轉、卻以為自己會了」——你的能力上限會被 AI 給的菜譜深度封頂。
    • 用中華一番「大魔術熊貓豆腐」案例說明:對手下黑手、大豆意外變納豆、把汙染當靈感——這三個 AI 結構上做不到的元素。文末附 7 個對抗菜譜化的具體做法,最關鍵是「保留一塊 AI 絕不介入的創作領域」。

    「Claude Design」這個名字其實沒有官方定義,它是 Claude Code 裡一組設計驅動的工作流程技能(superpowers:brainstorming / writing-plans / subagent-driven-development)的總和。我最近用它做了一個失智症陪伴 APP 的重大功能迭代,這篇文章把它在實戰中「什麼時候救了我」跟「什麼時候反而拖慢我」完整拆給你看。

    Claude Design 是什麼?三層流程一次看懂

    Claude Design 是一套讓 AI 助手在動手寫 code 前先「想清楚 → 寫規格 → 拆任務」的結構化流程。它不是任何新工具,而是 Claude Code 內建的三個技能組合使用:

    階段 技能名稱 產出 目的
    1. 發想 brainstorming 設計 spec(Markdown) 用多輪一問一答釐清需求、砍掉不該做的、浮出設計原則
    2. 規劃 writing-plans 實作計畫(含驗證步驟) 把 spec 拆成 10-20 個可個別 commit 的小任務
    3. 執行 subagent-driven-development 每個 task 一個 commit 派 subagent 做、派 subagent 審 spec、派 subagent 審 code quality

    重點不是「三個步驟」這個形式本身,而是每一步強迫你跟 AI 在不同粒度上達成共識:brainstorming 達成「做什麼」、spec 達成「做成什麼樣」、plan 達成「怎麼拆」、subagent 執行時還能雙重審查。

    沒用 Claude Design vs 用 Claude Design 的實際差異

    同樣是「加一個照顧者支援功能」的需求,兩種做法的差別在哪?這是我實測後的對照:

    面向 直接叫 AI 寫 走 Claude Design 流程
    需求釐清 憑 AI 猜,常常做錯方向 多輪問答,需求明確後才動手
    功能範圍 容易做太多(AI 傾向加功能) 在 brainstorming 階段就砍掉不必要項目
    一致性 做到一半風格會漂移 spec 用表格固定內容模板
    可追蹤 一個大 commit 或多個散亂 commit 每 task 一個 commit,可個別 revert
    重工成本 常常寫完才發現方向錯 方向錯在 spec 階段就發現
    速度 單點快、整體容易重工 前期慢、後期穩;不適合微任務

    實戰案例一:砍功能,省下 3-4 小時重工

    Claude Design 最值錢的貢獻不是寫 code,是阻止你寫不該寫的 code。在我的失智症陪伴 APP 迭代過程中,brainstorming 流程實際上幫我砍掉了三個功能:

    砍掉案例 1:背景音樂

    我一開始提議加背景音樂(失智症音樂療法有根據),brainstorming 過程中討論到「單檔 HTML 沒辦法帶 MP3、base64 嵌入會讓檔案爆到 30MB、用 File API 每次要重選」三個技術方案的取捨後,使用者自己說「先不要」。如果沒經過討論直接開寫,我大概會先做 File API + ducking 邏輯寫個兩小時,結果做完發現整個方向不對。

    砍掉案例 2:獨立話題卡

    原本規劃「話題卡」+「遊戲中陪伴提示」是兩個獨立功能。討論到一半,使用者界定:「這個 APP 是玩樂的時候用,真的要純聊天另外開 APP」。這句話直接把「獨立話題卡」功能從 spec 刪除,只保留遊戲情境下的提示。沒有這個界定,我會把話題卡塞進首頁,未來做下一個 APP 會有功能衝突。

    砍掉案例 3:每日心情打卡

    我在 brainstorming 時列過 5 個功能候選,其中「每日狀態簡記」(3 秒打卡心情/精神/食慾)看起來很有價值。使用者沒選這個,理由是「會把 v2 從『打開就用』變成『每天要記得打卡』,失智照顧者已經很累了」——這是使用者比我更懂他的使用情境的典型例子。AI 單獨設計是想不到這層的。

    這三個砍掉的功能合計估計省了 3-4 小時的 coding + 之後的 code review + git 回改。這才是 Claude Design 最值錢的部分——它讓「沒寫到 code 就砍掉」變成可能。

    實戰案例二:「可預期」這個原則如何救了 45 條提示語

    brainstorming 過程中,使用者往往會不經意說出一句話,變成整個系統的設計支柱。這次是這一句:

    「我希望對於照顧者而言,他是腦子清晰的,他可以有期待的方式知道,我可以看到該說什麼。」

    這句話裡面的「可預期」被提煉成整個功能的設計原則,寫進了 spec。然後這個原則驅動了三個具體決策:

    1. 提示固定模板:15 個遊戲 × 3 個時機(開場/答對/完成)= 45 條提示,全部用「情境 → 可以直接說的話」這個同一個格式,照顧者看一次就學會。
    2. 摘要強制預覽:不是一按就複製,而是開 modal 預覽、確認內容,才複製。照顧者對輸出「可預期」。
    3. 按鈕只在完成活動後才出現:有資料才有按鈕,避免使用者按下去才發現「沒東西可傳」。

    沒有 brainstorming 把這個原則浮出來、沒有 spec 把它寫下來,我會寫 45 條有個性的不同句型(AI 本能會追求多樣性)。結果照顧者每次要重新解讀 UI,反而更累。「可預期」這個字沒有出現在原始需求,是對話中自然生成的,但它比任何功能清單更重要。

    實戰案例三:Spec 表格讓語氣不漂移

    Spec 文件裡有一張表格,把 15 個遊戲 × 3 個時機 × 實際內容全部列出來:

    遊戲 開場 答對時 完成時
    顏色辨識 哇,好多顏色,你以前最愛穿什麼顏色? 對!你好厲害 今天陪你看顏色,我也覺得很漂亮
    認字遊戲 這個字你以前就認得吧 對啦,這個字你小時候就會了 今天還認這麼多字,真棒
    呼吸練習 我們一起慢慢呼吸 (改成中段顯示)吸氣…吐氣…不急 輕輕摸摸他的手,這樣就好

    如果不是在 spec 階段一次寫完這張表,而是「做到顏色遊戲時寫顏色的 3 條 → 做到形狀遊戲時寫形狀的 3 條」這樣推進,語氣一定會漂移。寫到第 10 個遊戲的時候我會忘記前面的語氣,變成有些句子很溫暖、有些很乾。表格逼我一次寫完,才有辦法保持「你年輕時、你很厲害」這類一致的溫度。

    這是表格化內容的威力——它讓「一致性」不是靠意志力維持,而是靠資料結構強制。

    反例:Claude Design 不適合的時候

    這次實戰也讓我踩到一個很明顯的坑:subagent-driven-development 對單檔 HTML 原型是殺雞用牛刀

    我一開始對 13 個 task 全部套用標準流程:每個 task 派 1 個 implementer subagent + 1 個 spec reviewer + 1 個 code reviewer,總共 39 次 subagent dispatch,每次 20-130 秒。前幾個 task 都只是「加一個 const、改一個函式」這種改動,triple review 完全是過殺。

    使用者實測後直接問我:「你寫程式變慢很多你用什麼模型」——這是一個誠實的信號。我當下檢討並切換到 inline 執行模式(我自己在 session 裡直接做),後半段 8 個 task 的速度回到正常的 3-5 倍。

    這個教訓很值:流程的 overhead 必須跟 task 粒度匹配。如果你的 task 只是改 20 行 code、不會影響其他模組,triple review 沒有價值,還會讓每個 task 多花 3-5 分鐘在 subagent 啟動/總結上。

    更重要的反省:Claude Design 是「菜譜」,不是基本功

    讀到這裡,你可能會問:「Claude Design 其實不就是 Spec-Driven Development(SDD)嗎?」 沒錯。brainstorming + spec + plan + implement 這四步是 SDD 老方法,不是 Claude Code 發明的。Claude Design 做的事其實是把 SDD 從「一千個人有一千種做法」方法化成「人人可以順暢工具化」的標準流程

    這是好事,也是很危險的事。

    菜譜出現前、出現後

    想像一下麻婆豆腐這道菜:

    • 菜譜出現前:只有師傅會做。每個師傅的麻婆豆腐都不一樣,因為他們從「為什麼要用豆瓣醬、為什麼花椒要後下」這種基本功思考過。客人要求「少辣多麻、加竹筍」這種變化,師傅能即時調整。
    • 菜譜出現後:人人可以照做,麻婆豆腐變得普及。但只會照菜譜的人,遇到「客人對豆瓣醬過敏,要用別的替代」這種問題就卡住了——因為他從來沒問過「為什麼要用豆瓣醬」。

    Claude Design 就是出現了菜譜。它把 SDD 的步驟變成 Skill、把「設計審批」變成 <HARD-GATE>、把 subagent 審查變成標準流程。你不需要知道為什麼要分離「設計」和「實作」,照著 skill 走就有規範的輸出。

    為什麼 AI 時代這件事特別危險

    菜譜時代的廚師,至少還能從菜譜回推原理——多做幾次就知道花椒晚下是為了香氣不揮發。但 AI 時代:

    1. 你問 AI「怎麼做需求分析」→ AI 給你 Claude Design 流程
    2. 你照流程做,產出看起來很漂亮的 spec 和 plan
    3. 你以為你會做需求分析了
    4. 遇到「這個需求太模糊、brainstorming 走 10 輪還是卡住」這種菜譜沒涵蓋的情況
    5. 你再問 AI → AI 給你另一個菜譜
    6. 你永遠繞著菜譜轉,沒有真的建立「為什麼需求會模糊、要怎麼引出使用者的隱藏前提」這種基本功

    最可怕的結果:你的能力上限永遠等於 AI 提供的菜譜深度。菜譜涵蓋不了的變化,你就做不到。而且因為你沒痛過傳統 SDD 的坑,你連「現在這個情境是菜譜解不了的」都判斷不出來——你不知道自己不知道

    SDD 真正的基本功是什麼

    Claude Design 的 skill 不會教你這些,但這些才是真正讓你能判斷、變通、甚至挑戰流程的基本功:

    菜譜只教你「做什麼」 基本功讓你懂「為什麼」
    brainstorming 要一次問一個問題 人的認知頻寬有限,多問題並排會讓使用者選擇癱瘓而隨便回答
    spec 要寫 45 條提示的表格 分批生成會有語氣漂移,但為什麼會漂移?因為 LLM 每次 context 都重新「感覺」一次
    實作前要設計審批 因為修改 code 的成本遠高於修改文字,越晚發現方向錯越貴
    subagent 要 triple review 多視角審查降低單一 agent 的盲點,但前提是 task 複雜到值得這個 overhead
    每 task 一個 commit Git bisect 的粒度等於 debug 速度,太粗的 commit 追 bug 要多花 10 倍時間

    懂了「為什麼」,你才能在菜譜斷裂的地方自己接住。例如:brainstorming 走不下去,你會知道這是因為使用者自己也沒想清楚,你要換一個方式(給他看 mockup 而不是繼續問字)而不是換另一個菜譜。

    給讀者的反省題

    每次用 Claude Design 之前,自問一句:「如果沒有這個菜譜,我會怎麼做這件事?」

    • 如果你答得出來 → 你用 Claude Design 是省時間
    • 如果你答不出來 → 你該先花時間讀 SDD 的原理,而不是依賴 skill 的自動化

    這不是反對 Claude Design。菜譜是好事,讓一道菜普及化。我想提醒的是:Claude Design 方便到你可能永遠不會問「為什麼」。而一個工程師的上限,取決於他問過多少個「為什麼」

    什麼時候用、什麼時候跳過?判斷決策表

    情境 建議流程 理由
    有多個可能方向、還在猶豫 brainstorming 避免選錯方向重工
    要改 15+ 個相似位置、要寫一致的內容 brainstorming + spec 用表格強制一致性
    多檔複雜後端、有 test framework、多人協作 完整三層 + subagent triple review 能防止衝突跟回歸 bug
    單檔 HTML、改一個函式、加一個按鈕 直接 inline,跳過流程 overhead 大於價值
    修 bug 已經知道怎麼修 直接改,不派流程 問題明確時流程是拖累
    重構一個模組的架構 brainstorming + spec(可能跳過 subagent) 要想清楚新架構但執行可以快

    3 個給讀者的實作建議

    1. 開工前先問自己一句話:「這個 task 的粒度適不適合走流程?」如果是「修一個 bug」「改一個顏色」,直接做;如果是「加一個新功能」「重構一個模組」,走 brainstorming。
    2. brainstorming 時刻意引導 AI 砍東西,不是加東西。AI 本能傾向加功能,你要主動問「這個是不是另一個 APP 的事?」「這個能不能先不要做?」。砍掉的功能是最值錢的產出。
    3. Spec 一定要用表格呈現重複性內容。如果你有 10+ 個相似的東西(15 個遊戲的 3 條提示、20 個 API 端點的 error message、12 個表單欄位的 placeholder),強制用表格一次寫完,不要分批生成。

    中華一番案例:AI 結構上做不到的創新

    講到這裡都還是抽象論述。讓我用一個具體案例把「AI 為什麼結構上做不到某些創新」講清楚——1997 年日本動畫《中華一番》第 43 集「大魔術熊貓豆腐」。

    劇情背景:小當家與黑暗料理界的邵安,在樓麟艦上進行豆腐對決。評委要求不能用現成豆腐,必須從黃豆開始做。比賽中:

    1. 對手下黑手:黑暗料理界的向恩把稻草偷偷放進小當家的大豆裡
    2. 意外發生:稻草上的納豆菌讓大豆發酵,大豆變成了納豆(日本傳統發酵食品)
    3. 認知翻轉:小當家看到黏糊牽絲的納豆,不是當成「比賽被破壞」丟掉,而是把這個意外當成靈感起點
    4. 創新誕生:從納豆的特性衍生出做法與工具,最終做出「大魔術熊貓麻婆豆腐」擊敗邵安

    (資料來源:萌娘百科納豆條目,ACGN 中的納豆相關劇情段落)

    這故事裡有三個 AI 結構上做不到的元素

    劇情元素 AI 為什麼做不到
    對手下黑手破壞材料 AI 的 brainstorming 永遠假設「正常情境」,不會模擬「比賽中有人陷害你」這種社會性干擾
    辨識大豆已變納豆 需要跨文化背景知識在當下湧現。一個四川廚師要有人把日本發酵食品的視角帶進來,AI 知道但不會主動從「邊緣」冒出來
    把失敗當靈感起點 AI 被訓練避免失敗、給成功解。被汙染的食材應該丟掉重做——這是 AI 的強勢模式。把 contamination 翻轉成創新起點是訓練資料裡的反模式

    我把這個對比叫做「紹安路 vs 小當家路」

    • 紹安路:精修技術、重組既有元素、走正統菜譜 → AI 擅長
    • 小當家路:個人記憶 + 意外事件 + 跨文化知識 + 重新定義失敗 → AI 做不到

    紹安在豆腐三重奏對決中輸得更深:他自以為原創的料理,其實 7 年前師父陳邦鈴就做過一樣的。他切斷了有意識的傳承,但無意識的傳承切不斷——他走遍中國、投奔黑暗料理界研發的「自創」菜,結構上還是師承的重組。

    用 Claude Design 久了的人可能遇到比紹安更慘的處境:紹安至少還是在複刻真實的師父,你在複刻 AI 訓練資料——但你不會知道,因為沒人會告訴你「這個東西 AI 在 2023 年就生成過一模一樣的了」。

    7 個對抗紹安化的具體做法(可以從下個 task 開始)

    如果你接受「菜譜化是現實、不會回頭」這個前提,那問題就不是「要不要用 Claude Design」,而是「怎麼用但不被它吃掉」。以下是我經過這次專案後整理的 7 個具體做法:

    1. 先離線想 10 分鐘,再開 AI

    用紙筆或純文字檔,在沒有 AI 的狀態下先寫下你對這題的想法——即使亂七八糟、半句話、只有關鍵字。寫完才來找 AI。這 10 分鐘的差別,是你有沒有在對話開始前建立自己的立場。

    2. 刻意加入 AI 絕對不會建議的約束

    AI 傾向推薦「平均來說最好的解」。你主動加怪條件逼自己走不一樣的路。例:做失智症陪伴工具時,不要說「做陪伴 APP」,說「做一個只能給老花眼、色盲、聽障照護者用的工具」——限制是創新的助產士。

    3. 每週跟一個「四郎」講一次話

    不是讓他們給你解決方案,是把他們的「意外知識」放進你生活。失智照護協會的阿姨、你媽或阿嬤(上一代的照護記憶)、會日文的朋友、幼稚園老師(他們跟認知差異的小孩互動方式跟失智照顧很像)⋯⋯讓他們隨口說的話在你腦裡發酵,像稻草丟進黃豆

    4. 把「bug / 意外 / 失敗」當創作材料,不是要避免的事

    開一個 inspirations-from-failures.md,每次遇到意外事件,先不要問怎麼解,先寫三句話:這個意外讓我看到什麼我原本沒看到的?這個限制如果我接受它,會變成什麼新東西?如果我把這個「bug」當成功能,會是什麼?AI 的訓練資料裡「bug 要修」是強勢模式,你要刻意反抗這個傾向。

    5. 對 AI 使用「反向問法」

    每次 AI 給你答案,下一句問:「這答案的相反是什麼?」「80 歲阿嬤會怎麼想這件事?」「如果這是錯的,錯在哪?」「這答案看起來合理,可是我錯過了什麼?」——這會強迫 AI 跳出訓練資料的中心,去邊緣抓東西。AI 不會主動做這件事,你得逼它。

    6. 保留一塊「AI 絕不介入」的創作領域

    不是「少用 AI」,是完全禁止。具體例子:照顧長輩的手寫日記(絕不給任何 AI 看)、一個嗜好(煮菜、種花、學樂器)、每週一天完全不開 Claude / ChatGPT。這塊領地是你保持「能產生小當家型靈感」的保護區。失去這塊,你永遠只能是紹安。

    7. 跟 AI 約定「小當家模式」信號詞

    當你要創新、不要優化時,直接跟 AI 說:「這次我要小當家模式,不要 Claude Design」。你的 AI 應該立刻做三件事:關閉所有 brainstorming/spec/plan 流程建議、不給業界做法、反過來問你的個人史跟身邊的人。這是你跟 AI 之間的信號詞。沒有它,AI 會把菜譜當成預設。

    優先順序:如果只能選一個開始

    選第 6(AI 禁區)。沒有這個,其他六個遲早會被 Claude 侵蝕回去。禁區是你維持「小當家能力」的物理基礎。

    結論:不是流程多就好,是流程跟 task 匹配才好

    Claude Design 不是一個「你該永遠用」的聖杯,也不是一個「多此一舉」的噱頭。它是一套當你面對真正需要思考的問題時,把你跟 AI 之間的對話規則化的工具。

    我這次失智症陪伴 APP 專案裡,Claude Design 救了我的前半段(brainstorming 砍功能 + spec 寫一致的 45 條提示),拖慢了我的後半段(subagent-driven-development 對單檔 HTML 過殺)。能分清這條線,是下次用它用得更好的關鍵。

    如果你的下一個 task 真的很簡單、你已經知道怎麼做——直接做。但如果你正在「想不清楚這功能該不該做」或「要做 15 個相似的東西怕語氣不一致」,那就值得花 20 分鐘先走 brainstorming。這 20 分鐘會幫你省下 3-4 小時。

    延伸閱讀