標籤: Context Engineering

  • 一張圖看懂 AI Agent 系統:Loop、Harness、MCP、A2A 差在哪

    每次跟同事解釋 AI Agent 系統,最常見的反應,是看著 Loop、Harness、MCP、A2A、Dataset 一堆名詞發呆。會迷茫,是因為這些詞常被當成「平行並列」硬背。其實它們分屬三層、各司其職,而且有先後順序。這篇用一張全景圖,加上「員工在公司做事」的比喻,讓完全不懂技術的人也能 30 秒看懂彼此的關係,以及最容易混淆的 MCP 與 A2A 到底差在哪——最後再談一個實際問題:怎麼讓整個團隊在一個平台上共用 agent。

    重點摘要

    • Loop / Harness / Agent / Skill / MCP / API / Dataset / A2A 不是平行概念,是三層:HARNESS(手腳)→ KNOWLEDGE(規矩與記憶)→ LOOP(節奏與目標)。
    • MCP 讓 agent 接「工具與資料」(把對方當死的工具);A2A 讓 agent 接「其他 agent」(把對方當活的同事)。兩者互補,不打架。
    • 要讓整個團隊共用 agent,關鍵不是「又一個聊天框」,而是一個共享的知識中樞,讓全團隊的 agent 站在同一份事實上工作。

    先看這張圖:30 秒看完全部關係

    如果下面的文字看不完,只要記住這張圖就夠了。外層的 LOOP 包著 KNOWLEDGE 和 HARNESS,Agent 用 MCP 接工具、用 A2A 接其他 agent。

    🗺️ 30 秒全景圖(外框就是 LOOP)
    🟢 KNOWLEDGE 規矩 + 記憶(Agent 做事時隨時回來查)
    📋 Skill 正確做法 🩹 Brain 踩過的坑 📒 KM 接真實資料庫的事實
    🔵 HARNESS 環境 + 對外插座
    🧑‍💼 Agent ──MCP──▶ 工具 / API / 資料庫(死的工具) ──A2A──▶ 其他 Agent(活的同事)
    📚 Dataset = 造出模型的底層料(已煮進模型、會記錯,所以才需要上面的 KM 當場查真相)
    一句話:HARNESS 給手腳 → KNOWLEDGE 給規矩記憶 → LOOP 給節奏目標。

    三層,不是一排:正確理解的關鍵

    這些名詞會讓人頭痛,是因為大家把它們當成同一層的東西在背。把「AI 幫你做一件事」拆開,其實由下往上是三層:下層給能力,中層給規矩與記憶,上層給節奏與目標。而且有一條鐵律:一定是 HARNESS → KNOWLEDGE → LOOP。工具沒備好、規則沒寫好,就先讓 agent 自己跑,它會被冒出來的錯誤推著改個沒完,沒有終點。

    用「員工在公司上班」秒懂每個名詞

    把整套 AI 系統想成一位員工在公司做事,每個名詞都對得上一個你熟悉的東西:

    名詞 一句話 員工比喻 屬哪層
    Agent會自己判斷、動手做事的 AI 本體員工本人工具層
    Harness承載 agent 的環境、工具與權限辦公室與設備工具層
    MCP接「工具/資料」的標準插座萬用識別證工具層
    API外部系統對外的窗口部門窗口工具層
    A2A接「另一個 agent」的協定同事間協作工具層
    Dataset造出模型的原始料(會煮進模型、會記錯)讀過的書工具層
    Skill某類任務的正確做法作業 SOP規則層
    Brain 防錯腦踩過的坑(事實,不背叛)血淚筆記規則層
    KM 正道腦接真實資料庫的事實 + 可糾正的判斷公司帳本 + 老師傅規則層
    Loop做到可驗證目標達成才停工作節奏 / KPI流程層

    最容易搞混的:MCP 與 A2A 差在哪?

    一句話分清楚:看你把對方當「死的工具」還是「活的同事」。MCP 是 agent 跟工具、資料的對話;A2A 是 agent 跟另一個 agent 的對話。

      MCP A2A(Agent-to-Agent)
    對象工具 / 資料(死的,聽話)另一個 agent(活的,會自己判斷)
    做什麼幫我查、幫我寫進去交辦多步驟任務、追蹤進度、他做完回報
    員工比喻員工 ↔ 部門窗口員工 ↔ 別的員工

    兩者不打架,是互補的:一個團隊用 A2A 在 agent 之間分工協作,而每一個 agent 內部都用 MCP 去接自己要用的工具。A2A 管「同事之間的對話」,MCP 管「每個人跟工具的對話」。

    A2A 實際怎麼運作:靠一張「名片」

    A2A 的核心是 Agent Card(代理名片)。每個 agent 在一個固定網址掛一張公開的名片,上面寫清楚:我會做什麼、我的服務入口在哪、怎麼跟我認證。別的 agent 不需要知道你內部怎麼運作,只要讀這張名片,就能發現你、把任務交給你、等你做完回報。就像兩家公司合作,看的是對方門口「服務項目 + 聯絡窗口」的牌子,不需要走進對方辦公室看他們怎麼做事。

    這在 2026 已經是業界標準:A2A 由 Google 發起、現在交給 Linux Foundation 治理,有 Python、JavaScript、Java、Go、.NET 五種語言的開發套件,並已內建進 Microsoft Copilot Studio、Azure AI Foundry、Amazon Bedrock 等平台。意思是,不同廠商、不同框架做出來的 agent,現在能用同一套規矩互相對話——這正是「讓大家的 agent 互通」的基礎。

    關鍵:知識層為什麼要接「真實資料」,而不是寫死答案

    AI 會幻覺、會忘記。所以把知識接給 agent 時,真正可靠的不是「標準答案」——答案是判斷,會隨著架構改變而過期。可靠的是兩種事實:一是「過去踩過的坑」(真的發生過,不會變),二是「資料庫此刻的真實數字」(當場查得到)。讓事實去約束 AI 的嘴,而不是讓 AI 的判斷當真理。這就是為什麼進階的知識系統(KM)會直接接上正式資料庫,而不是把答案寫死在文件裡——真相在帳本裡,不在 AI 的記憶裡。

    進階:怎麼讓整個團隊在一個平台上共用 agent?

    現在多數人是「一個人對一個 AI 工具」,各做各的——知識不共享、agent 不互通、同樣的事每個人重做一次。如果要讓整個團隊(包含不會寫程式的同事)在一個平台上共用 agent,要補三個能力,由淺到深:

    1. 共享的知識/工具中樞(最該先做):用一個團隊共用的 MCP 中樞,讓每個人的 agent 都連到同一套知識庫和工具。這樣大家查到的是同一份事實、同一套規矩,不再各憑記憶。這就是平台的心臟。
    2. agent 之間能協作:同一個系統內,可以一個「主管 agent」把任務拆給幾個「工人 agent」;跨不同系統、不同廠商,就用前面講的 A2A,讓各自的 agent 互掛名片、互相委派。
    3. 讓非技術同事也能用:大部分 agent 工具是給工程師的指令列介面,一般同事用不了。要在前面包一層簡單的網頁入口,同事用下拉選單選角色、打字提問就好。

    落地有兩條路。買現成平台(例如 monday.com、Microsoft Copilot Studio)走免寫程式、上手快,適合通用流程;但它通用、不認識你的產業,也接不上你公司的真實資料庫。自己搭(用 agent 開發框架 + 自建的共享 MCP 中樞 + 網頁入口)工要多一些,但能接上你自己的領域知識和真實營運資料——而這正是現成平台給不了的差異。

    一個關鍵判斷:平台的價值不在「又一個聊天框」,而在那個共享的知識中樞——它讓全團隊的 agent 站在同一份事實上工作。先把這個中樞建起來,agent 協作和網頁入口都是接上去的事。

    一句話收尾

    下次再看到這一串名詞,不用硬背。記住三層就好:HARNESS 給手腳、KNOWLEDGE 給規矩與記憶、LOOP 給節奏與目標;而 MCP 接工具、A2A 接同事。要把團隊一起拉上來,先建一個大家共用的知識中樞,剩下的細節,都掛在這個骨架上。

  • 讓 AI 不再失憶:用 Claude Code Hooks 打造大腦反饋迴路

    重點摘要

    • LLM 最大的弱點是會忘:session 結束或 context 被壓縮後,這次學到的教訓就蒸發了。
    • 解法是把「教訓」外接到持久的 腦子系統(brain/*.md),並用 hooks 在關鍵時刻強迫寫入。
    • 5 支 hook 腳本在三個點攔截:fix commit 發生時、context 壓縮前、session 結束時
    • 另一支 hook 負責身份錨定,防止 /compact 後 AI 角色崩潰。

    大型語言模型最致命的弱點,不是不夠聰明,而是會失憶。每一次對話結束,或是上下文(context)被壓縮(compaction)以節省 token,這一輪辛苦學到的教訓——某個 bug 的根因、某個 API 的雷點——就跟著蒸發,下一次又從零開始,甚至重踩同一個坑。

    我在 Claude Code 上的解法,是一套「harness × 腦子系統」的反饋迴路:用幾支 Bash hook 腳本當感測器,在 AI 即將遺忘的關鍵點上攔截,強迫它把這次的教訓寫進持久的 brain 檔。這篇拆解它為什麼需要、每支腳本做了什麼、以及它怎麼跟腦子系統搭配。

    為什麼需要這套東西?LLM 的三個結構性缺陷

    這套設計不是為了炫技,而是針對 LLM 的三個無法靠「更大模型」解決的缺陷:

    • 沒有長期記憶:模型權重是凍結的,單次對話的學習不會留存。→ 需要一個外部、持久的記憶體(brain 檔)。
    • 記憶會被壓縮清除:對話一長,context 就會被 compaction 截斷,早期內容直接消失。→ 需要在壓縮之前把該留的留下來。
    • 會角色漂移(role drift):尤其在壓縮後,AI 可能忘記自己是誰、該做什麼。→ 需要定期重新錨定身份。

    關鍵洞察是:光靠「提醒 AI 要記得寫筆記」沒用,因為它會說「好的我等下寫」然後就忘了。必須把它做成系統層級的強制關卡(gate)——由 harness 在固定時機自動觸發,而不是仰賴 AI 的自律。

    一張圖看懂:harness 感測器迴路

    🤖 Claude Code Session(工作中)
    做事 → git commit -m "fix: ..."
    ⚡ HARNESS 感測器層(hooks 自動觸發)
    ① 發生時 · PostToolUse
    fix-detect.sh
    偵測到 fix: commit → 注入:
    「現在去更新 brain,不准做下一件事」
    ② 遺忘前 · PreCompact
    precompact.sh
    壓縮前掃最近 5 個 commit →
    「記憶要被清除了,brain 寫了嗎?」
    ③ 離開時 · Stop
    stop-check.sh
    比對 fix commit vs brain 修改時間 →
    有 fix 卻 0 更新 = 警告
    ↓ 強制寫入教訓
    🧠 腦子系統 · brain/*.md(37 個領域檔,持久)
    – [source: 專案名] 哪裡踩坑、怎麼修的
    ↺ 下次 SessionStart 載入 MEMORY.md 索引 → 知識回到 AI,不再從零開始

    三個攔截點:守住 fix commit 的整個生命週期

    這套機制最聰明的地方,是它不靠單一檢查點,而是沿著「一個教訓從產生到消失」的時間軸,設了三道關卡。每一道都是一支獨立的 Bash 腳本,讀 Claude Code 透過 stdin 餵進來的 JSON,再輸出一段 additionalContext 回去改變 AI 的下一步行為。

    時機(Hook) 腳本 做什麼
    PostToolUse(每次 Bash 後)fix-detect.sh解析 git commit 訊息,若是 fix: 開頭,注入硬性要求:讀對應 brain 檔、追加教訓、更新前不准進行下一個任務
    PreCompact(壓縮前)precompact.sh掃描最近 5 個 commit 找 fix:,在 context 被清除前做最後提醒:「該寫的寫了嗎?現在不寫就來不及了」
    Stop(session 結束)stop-check.sh統計今天的 fix: commit 數,對比 brain 檔有沒有被更新過;有修 bug 卻沒留筆記,就丟出「知識可能流失」的警告

    三個點分別對應人(或 AI)會偷懶的三個藉口:「等下再寫」(被①擋下)、「我忘了還沒寫」(被②救回)、「這次算了吧」(被③抓出來)

    一個巧妙的無狀態設計:時間戳 + mtime 比對

    怎麼知道「這個 session 到底有沒有動過 brain」?這裡用了一個很輕量、不需要資料庫的技巧,由兩支腳本配合:

    • SessionStart 時,session-start.sh 只做一件事:touch /tmp/.claude-session-start,在檔案系統上插一根時間戳基準線
    • Stop 時,stop-check.shfind BRAIN_DIR -newer /tmp/.claude-session-start 數出「比這根基準線更新的 brain 檔」有幾個。

    0 個,代表這次 session 完全沒碰 brain。用檔案的 mtime 當狀態,既不用記資料庫、也跨工具通用——這是 Unix 哲學的漂亮應用。

    另一種 hook 用途:身份錨定,防止角色崩潰

    hook 不只用來餵記憶,也能用來穩住 AI 的身份。我跑過一個多 agent 的評測 harness,其中一個 session 擔任「Driver(駕駛)」——負責呼叫 orchestrator、讀結果、寫總結;另一批 agent 才是「被測團隊」。問題是:一次 /compact 之後,Driver 角色崩潰了,退化成被測團隊,開始自己回答原本該交給被測 agent 的技術題。

    修法是一支 SessionStart hook:當工作目錄落在該專案內,就注入一段「身份錨定」context,白紙黑字提醒——你是 Driver、不是被測團隊、遇到這些題目只能呼叫 orchestrator 而不是自己答。每次啟動(含 compact 後的重啟)都重貼一次,把漂移的角色拉回來。這是「context injection 對抗 LLM drift」的典型手法。

    它跟腦子系統的搭配:三層分工

    把整套東西攤開,其實是三層各司其職,像生物的神經系統:

    對應 角色
    Hooks神經反射自動、不經思考,在固定時機觸發,負責「執行紀律」
    Brain 檔長期記憶持久儲存踩過的坑與教訓,跨 session、跨專案可讀
    CLAUDE.md價值觀 / 規則每次 session 載入,定義「該怎麼做事」的原則

    Hooks 的唯一使命,就是確保「經驗 → 長期記憶」這條路徑不會因為 AI 的健忘或偷懶而斷掉。Brain 負責存、CLAUDE.md 負責規範,而 Hooks 負責在對的時間點逼著迴路閉合。三者缺一,知識就會慢慢漏光。

    設計哲學:為什麼是「強制關卡」而不是「溫柔提醒」?

    因為知識的衰減是無聲的。沒人會在當下感覺到「我剛剛流失了一條教訓」,只會在三個月後重踩同一個坑時才後悔。溫柔的提醒對抗不了這種無聲衰減——它需要的是一個會在你想跳過時擋在路中間的系統。借別人(與過去的自己)之手學坑,而不是真的每個坑都親自踩一次,這才是把 AI 從「強力的金魚」變成「會累積的夥伴」的關鍵。

    (這套 domain brain 的概念我有開源一份骨架,有興趣可以參考延伸。)

  • 跟 AI 寫程式的 15 條軟工紀律 — 用一條真實對話從頭拆解

    重點摘要

    • 常聽到「跟 AI 寫程式需要軟工基礎」,但具體是哪些?本文用前一篇 Opus 4.8 Workflow 實測那條真實對話從頭拆,對照 15 條經典軟工紀律
    • 盤點結果:做到 9 條 / 部分做到 1 條 / 沒做 5 條。每條都有對話證據引用,沒做的給可執行 action。
    • 15 條按高 leverage 排序前 5 名:驗證紀律、正交分解、真實基準、focused review、文檔作為下個 session 輸入。這 5 條沒守,其他都白搭。
    • 結論:跟 AI 寫程式需要的不是「新的軟工」,而是把舊軟工套到 stateless / non-deterministic / 訓練截止 / 高並發 4 個 AI 特性上的對應方法。

    為什麼問這題

    「跟 AI 寫程式需要軟工基礎」這句話傳得很廣,但講細節的人少。多數人講出來的不是軟工,是 prompt engineering tricks(怎麼下 prompt、怎麼用 chain-of-thought)— 那叫 LLM 使用技巧,不叫軟工。

    真正的軟工基礎是從 1970 年代 SWEBOK 累積到今天的工程紀律:specification、verification、separation of concerns、observability 那些。問題是這些紀律最初是針對「人寫 code、人 review、人交接」設計的,套到「AI 寫 code、人 review」會不會失效?哪些反而更重要?

    本文不假設,用一條真實對話實證:5/29 我跟 Claude Opus 4.8 跑 Home123 backend 的 109 個 GraphQL resolver authz pattern audit 對照實驗,從頭到尾大約 8 輪對話、~50 分鐘。把這條對話拆解,對照 15 條經典軟工紀律,看真實場景下到底用到了哪些、漏了哪些。

    15 條紀律的分類框架

    從經典軟工教材(《Code Complete》、《Pragmatic Programmer》、SWEBOK Guide)抽出 15 條跟 AI 協作最相關的紀律,分 4 群:

    類別 條目 經典 reference
    核心驗證#1 驗證紀律、#13 根因分析、#7 回顧TDD / Postmortem culture / Code Complete §22
    設計分解#2 正交分解、#8 規格先於實作、#9 權衡分析、#14 錯誤處理哲學Dijkstra SoC / Spec-first / Pragmatic Programmer Ch.4
    過程紀律#3 真實基準、#5 focused review、#6 並行執行、#10 預設驗收標準、#12 預算控管Performance Engineering / Code Review SOP / Agile
    知識持久化#4 文檔作為輸入、#11 可重跑、#15 版本控制ADR / Reproducible Research / Git workflow

    下面逐條拆。每條格式統一:定義 → 經典出處 → 你做了沒 → 證據或補救 → 對 AI 協作的特別意義

    #1 驗證紀律 (Verification Discipline)

    定義:任何宣稱(claim)都要靠可重現的證據才能信。
    經典出處:Steve McConnell《Code Complete》§22 The Twelve-Step Programming Process、TDD 的 Red-Green-Refactor 第一步、Cynefin framework 的 probe-sense-respond。

    本次對話做了沒:✅ 做了,多次

    對話證據:

    「幫我讀書 https://www.anthropic.com/news/claude-opus-4-8」
    → 不接受 AI 憑記憶,要 AI 去 web 抓。

    「今天已經是5/29了 你的日期有問題」
    → 即時校正環境假設,不讓我繼續用錯日期。

    「我正在運作 你看一下」
    → 不接受我講的文字總結,要看 ps / pstree / jsonl 真實 OS 訊號。

    對 AI 協作的特別意義:AI 的訓練資料有 cutoff(我的是 2026 年 1 月)。你問跟 cutoff 之後的事(Opus 4.8 是 5/28 發佈),我用「記憶」回答就是瞎掰 — 而且會用流暢的口氣瞎掰,不像人類會猶豫。強制 AI 查資料這個動作,等於把 AI 從「自信的 LLM」拉回「會用工具的執行者」。這條 baseline 沒守,後面 14 條全變空談,因為起手第一個 claim 就錯了。

    #2 正交分解 (Separation of Concerns)

    定義:一個議題只談一個軸線,軸線之間不混。
    經典出處:Dijkstra 1974《On the role of scientific thought》、Parnas 1972 information hiding、UNIX philosophy 的 “do one thing well”。

    本次對話做了沒:✅ 做了,而且是教科書級。

    對話證據:

    「首先 看起來除了MODEL 還有 EFFORT
    同樣是SONNET 還可以有HIGH XHIGH?
    WORKFLOW 我要怎麼去用?」

    三個正交軸線(Model / Effort / Workflow)分開問。對照組是新手會問「給我最好的設定」— 等於要 AI 替你在多維空間做加總決策,你拿到答案也不知道為什麼。

    對 AI 協作的特別意義:AI 處理 bundled question 會發生兩種失敗:(1) 只回最顯眼那條,其他偷偷漏掉;(2) 強行給一個整合答案,但每個軸線都妥協。你下意識把 3 軸拆開,等於逼 AI 逐個 expose,你才能照自己的 context 做選擇。這對應的軟工原則是「不讓抽象漏掉」(don’t leak the abstraction)的反向應用:你拒絕 AI 把抽象漏掉。

    #3 真實基準 (Representative Benchmarks)

    定義:評估新工具用真實場景,不用 toy example。
    經典出處:John Hennessy / David Patterson《Computer Architecture》§1.8 Fallacies and Pitfalls(benchmark 永遠騙人)、SPEC CPU 為什麼要 update、ML 領域 distribution shift 一整條研究線。

    本次對話做了沒:✅ 做了,而且是本次對話最關鍵的一個動作。

    對話證據:

    「好 你現在用HOME123 專案 做一個測試循環 然後用你的WORKFLOW試試看 記錄下來差異」

    不要 toy 不要 hello-world,直接拿 Home123 的 109 個 production resolver。這個動作直接決定了實驗結論的可信度。

    對 AI 協作的特別意義:80% 的「新 AI 工具評測」文章用合成 case(leetcode-style problems),結論毫無遷移性。Anthropic 自家 4.8 release notes 用的也是 SWE-bench、Terminal-Bench 這種「合成的真實」 — 不是任何一家公司的 production codebase。你直接拿 109 個 real resolver 來測,workflow 暴露出來的問題(主 orchestrator 抓到 synthesis agent 算錯 83 vs 109)在合成 case 上看不到,因為合成 case 沒那麼大、catch 不到 emergent behavior。這個動作的工程價值比你的 prompt 內容更高。

    #4 文檔作為下個 Session 輸入 (Documentation as Next-Session Input)

    定義:寫文件不是給未來的人看,是給未來的 stateless agent 看,作為下次 conversation 的可讀輸入。
    經典出處:Architecture Decision Records (ADR, Michael Nygard 2011)、SREbook 的 runbook 文化、Reproducible Research 運動(Donald Knuth literate programming 的延伸)。

    本次對話做了沒:✅ 做了,而且是主動做。

    對話證據:

    「Ab然後我想請你發一篇文章到wordpress上詳細比對這一次的經驗跟數據還有該怎麼啟用的prompt」

    同時要求三份產出:(A) brain/dynamic-workflows.md(下個 conversation 我會自動讀)、(B) 更新 brain/adaptive-agent-team-staffing.md(舊文件補新知識)、(WordPress 文章 —對人類讀者跟搜尋引擎)。

    對 AI 協作的特別意義:你跟人類同事的會議結論寫成 wiki/Notion,下次他翻過。跟 AI 寫 code 的對話結論寫成 brain file,下次 conversation 的 AI 把它當 first-class context 讀 — 等於把這次 conversation 的腦容量無損傳給下次。一般軟工人甚至沒聽過這個用法(「文件是給 AI 讀的?」),但它是 LLM 時代的 ADR + retrospective 文化合體。沒這層,你每次跟新 conversation 都得從零教一遍,等於每次都 onboarding。

    #5 Focused Review (一次只 review 一條軸線)

    定義:給 code review 的 feedback 一次只挑一條軸線改,不混雜其他要求。
    經典出處:Google Engineering Practices《Code Review Developer Guide》、《The Art of Readable Code》Ch.15、Andy Hunt《Pragmatic Thinking and Learning》Ch.9。

    本次對話做了沒:✅ 做了,而且 6 個字精準命中。

    對話證據:

    「注意好讀性跟比較方式」

    6 個字,2 條軸線,沒夾雜其他要求(沒同時挑錯字、補內容、改標題)。我回去重做的時候不需要 disambiguate「我到底該優先處理哪一條」。新手 reviewer 會給 30 條 mixed feedback,作者改完反而亂七八糟。

    對 AI 協作的特別意義:AI 在 mixed feedback 下會做兩件事:(1) 試圖一次解決所有,結果每條都打折;(2) 自選優先序,但你看不到它怎麼選的。你的 focused feedback 等於把「review reviewer」這層 meta-loop 去掉。對 token 成本也直接有差 — AI 不用先花 token 解析「Tom 到底想我先處理哪條」,直接動工。

    #6 並行/異步執行 (Async Parallel Execution)

    定義:能並行的工作不要序列化等待,結果到再收。
    經典出處:Concurrent programming 整個學門、Amdahl’s law、async/await 在現代語言的普及、Toyota production system 的並行工序設計。

    本次對話做了沒:✅ 做了

    對話證據:

    「我正在運作 你看一下」

    你開另一個 terminal 跑 workflow,沒等我講完就行動。我這邊主 session 同時讀你的 process tree + session jsonl 做即時觀察。兩條軌道平行,中間用 jsonl 落地通訊。

    對 AI 協作的特別意義:跟 AI 對話有個隱形成本叫 cache miss penalty。Claude 的 prompt cache 5 分鐘 TTL,超過就要從零重讀整個 conversation。如果你序列化等(我講完→你看→你跑→等結果→回我),很容易 5 分鐘外。並行化 + 中間用 file system / jsonl 落地通訊,等於把 cache 維持在熱狀態。傳統軟工這條對應的是「不要 block 在 IO 等待」,AI 場景下是「不要 block 在對話等待」。

    #7 回顧 (Retrospective)

    定義:任務完成後不直接進下一個,先回看「what went well / what didn’t」。
    經典出處:Agile retrospective(Scrum 每個 sprint 末必做)、Norm Kerth《Project Retrospectives》、Etsy/Google 的 blameless postmortem 文化。

    本次對話做了沒:✅ 做了,而且是 meta 級 — 你問本篇這題就是 retrospective。

    對話證據:

    「還有 很多人說跟ai寫作需要很多的軟工基礎,不像請你評估一下所謂的軟工基礎在我們所有的循環裡面,我無形中有用到哪一些…因為有一些是我打中很關鍵的點,而你不知道那些是不是軟工基礎」

    這句話本身是回顧:你不滿足於「拿到結果就走」,還要拆解過程、識別 pattern、產生可遷移知識。

    對 AI 協作的特別意義:AI 不會主動 retrospect — 我跑完就等下一個 prompt,沒人觸發我不會自己回頭看「剛剛這條對話我做對了什麼」。retrospective 必須由你發起。但 retrospective 的產出對 AI 特別有價值:它是 #4 文檔作為輸入的最佳 raw material — 直接把回顧結論寫成 brain file,下次 conversation 直接用。傳統 retrospective 是「同個團隊下個 sprint 用」,AI 場景是「同個你下個 conversation 用」。

    #8 規格先於實作 (Spec-First / Specification before Implementation)

    定義:動手寫 code 之前先把「要做什麼」「驗收標準」寫死。
    經典出處:Leslie Lamport《Specifying Systems》、TDD「先寫測試」也是這條的變形、Design by Contract (Bertrand Meyer)、SDD(Spec-Driven Development)的學派。

    本次對話做了沒:✅ 做了,而且是顯式的 4 維度規格。

    對話證據:

    「記錄下來差異 怎麼啟動 有優化那些地方 要做什麼東西 必要是什麼」

    4 個維度寫死:(1) 啟動方式、(2) 優化點、(3) 要做的東西、(4) 必要條件。我後續的 brain file 跟 WordPress 文章兩份產出,結構直接照這 4 維度生。

    對 AI 協作的特別意義:沒給 spec 的 AI 會「自由發揮」,結果是形式上看起來有結構,實際結構是 AI 替你做的選擇,你不一定買單。你給 4 維度等於把結構決定權拿回來,AI 只負責填內容。這條對應的傳統軟工是 PRD/RFC,AI 場景是「在 prompt 裡內嵌驗收 schema」。

    #9 權衡分析 (Trade-off Analysis)

    定義:任何方案都有 cost 跟 benefit,要顯式列出再比較。
    經典出處:Software Architecture 教材必有的 ATAM (Architecture Tradeoff Analysis Method)、Jeff Bezos 的「two-way door / one-way door decisions」、《Pragmatic Programmer》Ch.4「Be a Catalyst for Change」的反向。

    本次對話做了沒:✅ 做了,而且是顯式追問。

    對話證據:本系列你連續問了三個 trade-off 問題:

    「差異你可以跑跑看」(empirical 比較 cost)

    「我想知道Workflow那一個,他現在到底對我的意義是什麼?我看不太出來」(質疑單一方向的 benefit)

    「注意好讀性跟比較方式」(cost = 讀者認知負擔 vs benefit = 完整性)

    對 AI 協作的特別意義:AI 對「該不該做某件事」的默認是 yes — 因為訓練資料裡的「Yes, you should」遠多於「No, don’t」。你「我看不太出來意義」這句逼我從 advocacy 模式切到 honest assessment 模式,實際結論變成「不存它,寫 reference 進 brain 就好」。這條對應的傳統軟工是 design review 裡「這個複雜度真的需要嗎?」的提問。

    #10 預設驗收標準 (Acceptance Criteria Upfront)

    定義:任務開始前先寫死「做到什麼程度算 done」。
    經典出處:Agile user story 的 INVEST criteria、Behavior-Driven Development (BDD) 的 Given-When-Then、Definition of Done 是 Scrum 必備產物。

    本次對話做了沒:🟡 部分做到

    分析:你 #8 給了 4 維度規格,算是 partial acceptance criteria。但缺了「品質門檻」:

    • workflow 跑出來的 report 要達到什麼分類正確率才算可信?
    • baseline 跟 workflow 的差異要大到多少才算「值得換 workflow」?
    • 對話拆解後若 15 條都做到,實質工程效率提升多少才算夠?

    結果就是 — workflow 抓到 12 個 hand-roll,我們默認接受這個數字,沒去 sample 5 個函式人工驗證。如果 workflow 系統性把某類 hybrid 全錯標,我們不會發現。

    該怎麼補:任務開始前加一句「驗收標準」段落。例如本次該寫:

    驗收標準:
    1. 兩邊跑完後,我會手動 sample 5 個 USES_PRELUDE 跟 3 個 HAND_ROLLED 對證據
    2. 如果 baseline 跟 workflow 在這 8 個樣本上有 2 個以上分歧,需逐個澄清
    3. 完整 109 函式都要有 row,缺一個視為失敗

    對 AI 協作的特別意義:AI 沒驗收標準會「看起來完成」(plausible-looking output),但內部可能 systematically 錯。傳統軟工裡 acceptance test 是另一個人寫的,AI 場景下你得自己寫,因為 AI 不會主動跟自己對抗。本次沒守這條的代價:我們得花一篇文章解釋「為什麼信任 workflow 的結果」,而本來只需要 sample-test。

    #11 可重跑 / Idempotency (Reproducible Execution)

    定義:任何過程要可從頭重來,輸入相同則輸出相同(在合理隨機範圍內)。
    經典出處:Make / build system 整個學門、Donald Knuth literate programming、Reproducible Research 運動、Docker / IaC 的根本動機。

    本次對話做了沒:❌ 沒做。最具體的證據是你沒按 s 把 workflow script 存下來

    分析:本次跑了 11 個 Haiku 4.5 平行 audit,產生 146 行 JavaScript orchestration script,結果只存在 session 暫存目錄。如果這次的審計結論被人質疑(例如「12 個 hand_roll 是真的還是 AI 瞎標」),你要重跑驗證沒辦法保證跑出同一份結果 — 因為:

    • 下次跑 Claude 會重新生 script,chunk 切法可能不同
    • Haiku 4.5 即使 temperature 0 也有非 deterministic 因素(MoE routing 隨機)
    • Cache hit 率不同 → 提示空間不同 → 細節結論不同

    該怎麼補:三層防護(從便宜到昂貴):

    1. 最低: 把 script 從 session 暫存目錄 cp 出來歸檔到 brain 或 repo
    2. 中等: 把 script 真的存成 ~/.claude/workflows/<name>.js slash command,雖然本案大概不重跑,但其他 audit 可以 fork
    3. 高保證: 把 audit 結論 + 109 函式分類存成 JSON / CSV,用 schema 驗證,以後重跑只需 diff JSON 不需要重看 markdown

    對 AI 協作的特別意義:AI 的輸出有內建非 determinism(temperature、MoE、context order),這跟傳統 reproducibility 假設(同 input → 同 output)直接衝突。AI 場景的可重跑不能依賴「程式邏輯一樣」,要依賴「中間結果落地」 + 「結果用結構化格式儲存」 + 「下游 verifier 用同 schema 驗」。傳統軟工這條是「build 可重現」,AI 場景是「結論可驗證」。

    #12 預算控管 (Cost / Budget Cap)

    定義:任何運算工作開始前先設天花板,超過自動停。
    經典出處:Cloud computing 的 budget alerts、Kubernetes resource limits、Hadoop / Spark 的 timeout、Stripe 的「circuit breaker」pattern、SREbook §12 effective troubleshooting 的 budget 章節。

    本次對話做了沒:❌ 沒做

    分析:我們跑 workflow 的時候沒設 token budget 或 wall-time cap。實際跑了 11 個 agent、~$6.10 estimated cost、132 秒 wall-time。如果 Claude 寫的 script bug 了 — 例如把 chunk 切成 100 個,可能跑出 100 個 agent、$60 cost、20 分鐘 wall-time。沒任何機制自動阻擋。

    該怎麼補:

    • prompt 裡明寫上限 — 例如「最多派 12 個 agent,單一 agent 最多跑 60 秒」
    • --effort medium 而不是 high 開始,確認 quality 夠才升 effort
    • 跑前先讓 Claude 估算 token cost 跟 agent 數,你 approve 才放跑(workflow 內建這層 approval prompt,但你按 [3] View raw script 之前沒人問你 budget)
    • 對自己設「單條對話 spend 上限」(例如 $10),透過 Claude Code admin page 或 API budget API 強制

    對 AI 協作的特別意義:傳統軟工 budget 是「機器跑爛要錢」,AI 場景下 budget 還包含「AI 寫錯 script 跑很久才發現」的 fail-loud delay。Anthropic 自己在他們 multi-agent research system 的 paper 也警告:multi-agent 用 token 是 single-agent 的 3-10×,Research system 是 ~15×。沒 budget cap 等於放任這個倍率,3am 一覺起來收到 $200 帳單是真實風險。

    #13 根因分析 (Root Cause Analysis)

    定義:遇到問題不停在表象,挖到「為什麼會發生」的最底層。
    經典出處:Toyota 的「Five Whys」、Apollo 13 事故報告、Etsy / Google 的 blameless postmortem template、《The Field Guide to Understanding Human Error》。

    本次對話做了沒:🟡 部分做到,但是 AI 替你做的

    分析:本次 audit 最有價值的發現是「guard role 被 AuthzDecision.IsCommunityWide 排除,迫使 5 個 resolver 各自重 probe 一段相同 SQL」。這是根因分析的成果 — 不停在「這幾個 resolver 沒用 prelude」,而是挖到「為什麼它們不能用」。

    但這是 workflow 的 synthesis agent 替你做的,不是你做的。Baseline 模式下 1 個 agent 沒做出這層,你也沒主動追問「為什麼會有 5 個重複」。如果這次跑 baseline 你會 miss 這個 root cause。

    該怎麼補:不能只靠 AI 替你做。可以加紀律 — 拿到分類結果後,主動問:

    看到 12 個 HAND_ROLLED,我們 ladder 5 個 why:
    - 為什麼這 12 個沒用 prelude? → 各自原因
    - 為什麼它們有共同原因? → 找 pattern
    - 為什麼這個 pattern 沒被早發現? → 流程 gap
    - 為什麼流程沒抓到? → tooling gap
    - 為什麼 tooling 沒設計這層? → 設計時的假設

    對 AI 協作的特別意義:AI 默認停在第一層觀察(「這幾個沒用 prelude」)。要挖根因得明確要求(「列出 root cause」)或結構性逼它(workflow 的獨立 synthesis pass 就是設計來做這個)。傳統軟工這條是 debug 工具,AI 場景是「prompt design」工具 — 在 prompt 裡內嵌 root cause analysis instruction,或設計獨立 verification agent。

    #14 錯誤處理哲學 (Error Handling Philosophy)

    定義:對「事情會出錯」這件事有明確設計姿態 — fail-fast vs fail-silently、retry policy、circuit breaker、graceful degradation。
    經典出處:Erlang 的「let it crash」哲學、《Release It!》Michael Nygard 整本書、Google SREbook §22 addressing cascading failures。

    本次對話做了沒:❌ 沒做

    分析:我們沒任何「workflow 跑到一半失敗了怎麼辦」的計畫:

    • 如果某個 chunk 的 Haiku agent 超時了 → 我們沒設 retry 也沒設 fallback
    • 如果 synthesis agent 算術錯了(這次真的發生了:83 vs 109)→ 我們沒設 verification 步驟,純靠主 orchestrator 主動懷疑
    • 如果 JSON schema 驗證 fail → 不知道會發生什麼,沒測過
    • 如果 workflow runtime 自己 crash → 沒 graceful resume 流程

    該怎麼補:在 prompt 裡加 error handling instruction:

    如果跑到一半發現:
    - 某 chunk 的 agent fail → 標記 SKIPPED,繼續其他,最後 report 哪些 skip
    - synthesis 結果跟 row count 對不上 → 不要直接出 report,先 escalate 給主 orchestrator 重算
    - JSON schema 違反 → 該 row 標 INVALID,繼續其他
    - 整體執行超過 5 分鐘 → 自動 abort,出階段性 report
    
    最後 final report 要明確標示哪些 chunk 是「完整跑完」、哪些是「skipped」、哪些是「fail-and-retried」。

    對 AI 協作的特別意義:AI 預設 fail-silently — 它會生「看起來合理」的內容掩蓋失敗。傳統軟工 fail-fast 是「raise exception 停下來」,AI 場景的 fail-fast 是「標註 INVALID / SKIPPED 而不是瞎掰」。沒設計這條,AI 會「完整交付」一份其實內部有 hole 的報告,你看不出來。本次 workflow synthesis 算 83 是僥倖被主 orchestrator 抓到,如果主 orchestrator 也沒抓,我們就拿錯誤數字寫文章了。

    #15 版本控制紀律 (Version Control Discipline)

    定義:任何重要 artifact 進 git,commit message 寫清楚 why,branch 策略對應 workflow。
    經典出處:Git 整個工具、Conventional Commits 規範、Trunk-based / GitFlow / GitHub Flow 各家 branch 策略、Linus 的 git 設計初衷。

    本次對話做了沒:❌ 沒做。本次產出全部沒進 git。

    分析:這次產出了 4 件 artifact:

    • ~/.claude/projects/-home-tom/memory/brain/dynamic-workflows.md(新建)
    • ~/.claude/projects/-home-tom/memory/brain/adaptive-agent-team-staffing.md(編輯)
    • ~/.claude/projects/-home-tom/memory/MEMORY.md(編輯)
    • WordPress 文章兩篇

    前三個位置實際是 ~/.claude/projects/-home-tom/ — 你有可能沒把它放在 git 控管下,意思是:

    • brain 編輯沒 commit history,半年後想知道「dynamic-workflows.md 是什麼時候加的、為什麼加」沒記錄
    • 如果 brain 不小心被改錯了(例如未來某個 conversation AI 寫壞了),無法 rollback
    • 跨機器同步只能靠 rsync / cloud sync,沒 conflict resolution

    該怎麼補:

    1. cd ~/.claude/projects/-home-tom && git init(如果還沒)
    2. 新 brain 或重大編輯後 commit:git add brain/ MEMORY.md && git commit -m "feat(brain): dynamic-workflows from 2026-05-29 Opus 4.8 test"
    3. WordPress 文章 export markdown 進專屬 repo,或用 wp-cli 串自動 backup
    4. workflow script 改 #11 補救時順便 commit 進 dotfiles repo

    對 AI 協作的特別意義:AI 跨 conversation 是 stateless,brain file 是它的「外部記憶」。外部記憶的版本控管比 code 的還重要,因為你不會看到自己過去 conversation 改了哪些 brain,只有 git diff 告訴你。本次對話我改了 3 個 brain 檔,如果你沒 git 控管,3 個月後你不會記得這幾條條目是 5/29 對話加的還是更早。傳統 git 是 code 的時間機,AI 場景是「我跟 AI 集體記憶的時間機」。

    15 條全表:做了沒 × leverage

    # 紀律 類別 本次 Leverage(高→低)
    1驗證紀律核心驗證★★★★★ 沒守等於沒救
    2正交分解設計分解★★★★★ AI 回答品質直接相關
    3真實基準過程紀律★★★★★ 結論可信度核心
    4文檔作為輸入知識持久化★★★★★ AI 時代特有的紀律
    5Focused review過程紀律★★★★ AI 對 mixed feedback 表現差
    6並行執行過程紀律★★★ 規模大才顯效
    7回顧核心驗證★★★★ 跟 #4 配對 leverage 最大
    8規格先於實作設計分解★★★★ 直接決定 AI 輸出結構
    9權衡分析設計分解★★★★ 抗 AI 默認 yes 傾向
    10預設驗收標準過程紀律🟡★★★★ 該補,沒守會默認 plausible-looking
    11可重跑知識持久化★★★ 任務一次性可省,系統性任務必須
    12預算控管過程紀律★★★ 小任務可省,長 background 任務必須
    13根因分析核心驗證🟡★★★★ 主要靠 prompt 設計
    14錯誤處理哲學設計分解★★★★ AI 預設 fail-silently 必補
    15版本控制知識持久化★★★ brain 控管比 code 控管更重要

    結論:跟 AI 寫程式需要哪些軟工?

    不是新的軟工,是舊軟工套到 AI 4 個特性上

    15 條全部都不是「AI 時代發明的」 — 每條都能在 1990 年代的軟工教材找到根。差別在 4 個 AI 特性對這些紀律的需求強度不同:

    AI 特性 被放大需求的紀律
    訓練資料 cutoff#1 驗證紀律(逼 AI 查資料,不要憑記憶)
    Stateless / 無 conversation 記憶#4 文檔作為輸入、#15 版本控制(外部記憶持久化)
    非 deterministic 輸出#11 可重跑、#10 預設驗收標準、#14 錯誤處理(處理隨機性)
    高並發 + 高速#6 並行、#12 預算控管(token 倍率風險)

    個人 leverage 排序(5 強)

    如果你是這條光譜中段的人(寫過 5 年以上 code,剛開始系統性用 AI 寫 code),最該優先吸收這 5 條:

    1. #1 驗證紀律 — 沒守這條,後面 14 條都白學。AI 講什麼都不能信,grep / curl / test 重驗
    2. #2 正交分解 — 拆軸線問,不要 bundled question。直接決定 AI 回答品質
    3. #4 文檔作為輸入 — 把學到的寫成下個 conversation 可讀的格式。沒這條,每次 onboarding
    4. #3 真實基準 — Toy example 騙人。用 production codebase 評估工具
    5. #5 Focused review — 給 AI feedback 一次只挑一條軸線

    沒做的 5 條,該怎麼補

    本次對話沒做的紀律對應 5 條 action(從便宜到貴):

    1. #15 版本控制(5 分鐘):cd ~/.claude/projects/-home-tom && git init && git add . && git commit -m "snapshot" 一次性處理
    2. #11 可重跑(2 分鐘):把 workflow script 從 session 暫存 cp 到 brain 或 dotfiles repo 歸檔
    3. #10 驗收標準(每任務多寫 3 行 prompt):任務 prompt 開頭加「驗收標準:N 個項目,M% 正確率,通不過要告訴我」
    4. #14 錯誤處理(每 workflow 多寫 5 行):script 內加 fail-fast / skip / retry 分支
    5. #12 預算控管(系統性設定):Claude Code admin page 設 hard daily limit 或寫個 hook 跑前先估

    真正的 meta-insight

    本文 15 條展開後最反直覺的觀察:跟 AI 寫程式需要的軟工基礎,大部分不是 code-level 的,是 process-level + protocol-level 的。傳統軟工新人學的順序是「先學語言 → 再學 design pattern → 最後學 process」,跟 AI 寫程式得反過來:先學 process discipline(怎麼下指令、怎麼驗證、怎麼回顧),最後才是 code-level technique

    因為跟 AI 寫程式,code 是 AI 生的,你扮演的是 reviewer + verifier + spec writer 三個角色。這三個角色傳統上叫 PM / QA / Tech Lead — 都是 senior eng 的活。所以「跟 AI 寫程式比較簡單」這句話完全反了 — 它把senior eng 的工作 commoditize 到每個用 AI 的人身上,reviewer 的紀律從「資深工程師的特權」變成「每個 prompt 作者的基本技能」。

    這就是為什麼那麼多人「用 AI 寫了一堆 code 但跑不起來」 — 不是 AI 不行,是沒人替他們做 reviewer / verifier / spec writer 那三層活。本文 15 條的本質就是把這三層活的紀律寫下來。

    跟我之前文章的關聯

  • Claude Code Dynamic Workflows 實測:Opus 4.8 + 11 Haiku 平行 audit 109 個 resolver

    重點摘要

    • Anthropic 在 2026-05-28 釋出 Claude Opus 4.8,帶來 Dynamic Workflows(背景跑 JS script orchestrate 數百 subagent)、Effort Control(low/medium/high/xhigh/max/ultracode)、Messages API system entries 中段插入。
    • 實測:同題雙軌跑 Home123(Go + gqlgen 後端)的 109 個 resolver 函式 authz pattern audit,baseline (Opus 4.7 + 1 個 general-purpose agent) vs workflow (Opus 4.8 + 11 個 Haiku 4.5 worker)。
    • 最大發現:workflow runtime 自動把 worker model 派為 Haiku 4.5,主 orchestrator 維持 Opus 4.8 — 對應「想 → opus / 找 → haiku」分工 doctrine,以前要手寫 AGENTS.md 分配的事 runtime 替你做了。
    • Wall time 沒省(workflow runtime 132 秒比 baseline 236 秒快,但加上主 session synthesis 反而是 392 秒)。本次估算成本 workflow ~$6.1 是 baseline ~$0.72 的 ~8.5× — 主要花在 runtime cache write 固定成本,大規模任務攤平會降下來。
    • 收益不在省錢,在:JSON Schema 強制輸出契約、reproducibility(script 落地,以後 /<name> 一鍵重跑)、主 orchestrator 主動 cross-check 下游(實戰抓到 synthesis subagent 算錯總數 83 vs 真實 109)。

    一眼看完:Baseline vs Workflow

    整篇下面會逐項拆,先給你 5 秒讀完的版本。題目都是同一份 Home123 GraphQL 後端 109 個 resolver 函式的 authz pattern 分類。

    面向 Baseline Workflow
    啟動指令主 session 派一個 Agentclaude --model claude-opus-4-8 --effort high 後 prompt 內塞 workflow
    主模型Opus 4.7Opus 4.8
    Worker 數量1(general-purpose,可寫)11(Explore 型,強制 read-only)
    Worker 模型Opus 4.7(跟主一致)全 11 個 Haiku 4.5(runtime 自選)
    並發加速11 agents 加總 354s 實跑 132s = 2.7×
    主 session tool call24 (14 Bash + 10 Read)8 (5 Bash + 2 Read + 1 Workflow)
    輸出契約自由 markdownJSON Schema + enum 鎖死 4 值
    覆蓋109/109109/109
    總耗時3:56(236s)6:32 turn,workflow runtime 2:12
    抓到的 root cause1 個(CapsAny 提案)6 個(含 guard 5× 重複的真兇)
    結構級洞見沒做出read-side vs write-side 不對稱
    主動 cross-check 下游—(只有 1 agent)✅ 抓到 synthesis agent 算錯 83 vs 真實 109
    估算成本~$0.72~$6.10(約 8.5× baseline)
    可重跑script 落地,以後 /<name> 一鍵

    架構差異:一張流程圖

    讀者最常問的不是「快多少」,是「結構上到底差在哪」。把兩種模式畫成流程:

    Baseline                              Workflow
    ─────────                             ─────────
    User prompt                           User prompt
        │                                     │
        ▼                                     ▼
    ┌─────────────────┐                   ┌─────────────────┐
    │ Main Claude     │                   │ Main Claude     │
    │ (Opus 4.7)      │                   │ (Opus 4.8)      │
    │                 │                   │ 寫 JS script    │
    │ Agent tool      │                   └────────┬────────┘
    │   ↓ 派 1 agent  │                            │ Workflow tool
    └────────┬────────┘                            ▼
             │                              ┌──────────────────┐
             ▼                              │ Runtime          │
       ┌──────────────┐                     │ (背景執行 script) │
       │ 1× Opus 4.7  │                     └────────┬─────────┘
       │ general-     │                              │ fan-out
       │ purpose      │                              ▼
       │              │            ┌──────────────────────────────────┐
       │ ─ 24 tool ─  │            │ Phase 1: Classify (平行)         │
       │   call ─ 自由 │            │ ┌────┐┌────┐┌────┐ ... ┌────┐  │
       │   分類 +    │            │ │H4.5││H4.5││H4.5│      │H4.5│  │
       │   markdown  │            │ └────┘└────┘└────┘      └────┘  │
       └──────┬───────┘            │ 10 agents (schema 切 8 chunks +  │
              │                    │  visitor 1 + announcement 1)     │
              ▼                    └────────────┬─────────────────────┘
       markdown report                          │ JSON schema 驗證
                                                ▼
                                   ┌──────────────────────────┐
                                   │ Phase 2: Synthesize      │
                                   │ ┌────┐                    │
                                   │ │H4.5│ 1 agent           │
                                   │ └────┘                    │
                                   └────────────┬──────────────┘
                                                │
                                                ▼
                                   ┌──────────────────────────┐
                                   │ Main Claude (Opus 4.8)   │
                                   │ cross-check synthesis,   │
                                   │ 抓到 83 vs 109 算術錯誤  │
                                   │ 用 authoritative rows     │
                                   │ 重算 + 寫最終 report     │
                                   └────────────┬──────────────┘
                                                ▼
                                       final markdown report
                                       + JS script 落地

    關鍵差別不是 agent 數,是「主 Claude 不再親手做活,變成 orchestrator + verifier」。中間結果落在 script 變數,不灌進主 session context。

    背景:Opus 4.8 帶來什麼

    Anthropic 在 2026-05-28 同步發佈了 Claude Opus 4.8、Dynamic Workflows research preview、Effort Control、以及 Messages API 的中段 system entries 支援。發佈當天我看了官網內容,隔天 5/29 拿真實專案 Home123 跑了一輪雙軌對照,本文記錄完整數據與啟動 prompt。

    三個直接相關的能力更新:

    能力說明適用 plan
    Dynamic WorkflowsClaude 寫一支 JS script,runtime 背景跑,內含可數百個 read-only Explore subagent 平行作業所有付費(Pro 要先去 /config 開)
    Effort Control5 級:low / medium / high / xhigh / max,另有 ultracode(= xhigh + 自動 workflow orchestration)所有 plan
    Messages API system entries可在 messages array 中段插入 system entry,更新指令但不破 prompt cache、不需要假裝 user turnAPI 直連

    不是所有 model 都吃所有 effort 等級。實測 claude --effort foo 會回:

    error: option '--effort <level>' argument 'foo' is invalid.
    It must be one of: low, medium, high, xhigh, max

    官方支援表(來自 code.claude.com/docs/en/model-config):

    Model支援 effort 等級預設
    Opus 4.8, Opus 4.7low, medium, high, xhigh, max4.8 → high / 4.7 → xhigh
    Opus 4.6, Sonnet 4.6low, medium, high, max(沒 xhigh)high
    其他不支援 effort

    常見誤解:Sonnet 也能 xhigh 嗎?不行。Sonnet 4.6 只到 high,你硬塞 xhigh 會自動降到 high 不報錯但也少一級。ultracode 在 Sonnet 連菜單都不出現。

    對照實驗設計:為什麼挑 Home123 authz audit

    Workflow 適合的題目有 4 個必要條件:

    1. 可平行化 — 任務天然能切成 N 個獨立 chunk
    2. 可被 JSON Schema 約束 — 輸出結構穩定、enum 有限
    3. 有 ground truth — 否則 11 個 agent 跑完你也不知道對不對
    4. Read-only 為佳 — Explore type agent 不會誤改檔

    挑的題目:掃描 Home123 backend GraphQL 的 3 個 resolver 檔,把 109 個 resolver function 分類成 USES_PRELUDE / LEGIT_PUBLIC / HAND_ROLLED / UNKNOWN。

    Home123 是 multi-tenant SaaS,我自己寫了一個 authzPrelude centralised authn+cap+scope+audit 序列,規範每個 protected resolver 進 withTx 後第一段要 call。但程式碼累積過程中,有些 resolver 為了 cap-OR 之類 prelude 還不支援的情境 hand-roll 了授權邏輯。這次審計就是要逐一抓出來。

    符合條件為什麼這題符合
    可平行化109 個 function 各自獨立,每個分類不依賴其他結果
    可被 schema 約束class enum 只有 4 值;每筆 row 必填 file / func / line / class / evidence
    有 ground truthgrep -c authzPrelude backend/graph/*.resolvers.go 給出客觀基準
    Read-only純審計、不改檔

    啟動 prompt:兩邊放在一起看

    兩邊我都跑了。下面先給差異速覽,再給雙邊完整 prompt 對照。

    差異速覽

    面向 Baseline Workflow
    session 啟動任何 session 都可,呼叫 Agent toolclaude --model claude-opus-4-8 --effort high
    觸發機制主動派 1 個 Agentprompt 內含 workflow 關鍵字 → Claude Code 反白 → approval prompt
    Prompt 句子數~20 行(任務說明)~24 行(任務說明 + 第一個字「workflow」)
    關鍵差異字直述命令式 — 「做這個 audit」第一個字加 「跑一個 workflow,」 — 觸發 runtime 寫 script
    事前需要無(general-purpose 預設可用)Claude Code ≥ 2.1.154,Pro 要先 /config
    跑前是否確認不需要,直接跑approval prompt 必須選 [1] Yes;第一次強烈建議按 [3] View raw script

    左:Baseline prompt(逐字)

    你在 /home/tom/Desktop/home123_new 做一次 read-only authz pattern audit。
    禁止修改任何檔案。
    
    審計三個 resolver 檔的每一個 resolver function:
    - backend/graph/schema.resolvers.go (~80 funcs)
    - backend/graph/visitor.resolvers.go (~15 funcs)
    - backend/graph/announcement.resolvers.go (~16 funcs)
    
    分類規則:
    1. USES_PRELUDE — body 第一段 call authzPrelude(...)
    2. LEGIT_PUBLIC — 真正不需要 auth 的 (Login / RefreshAccessToken 等)
    3. HAND_ROLLED — 沒 call authzPrelude 但自己寫 cap/scope/role/audit 檢查
    4. UNKNOWN — 你無法判定
    
    輸出:markdown 表 | file | func | line | class | evidence |,
    所有 function 一行不能少。
    
    最後加 ## Summary:每 class 數量、HAND_ROLLED 跟 UNKNOWN 清單、可疑模式。
    
    用 Bash grep / Read 自己抓,不要憑記憶或猜。

    右:Workflow prompt(逐字)

    新 session 啟動:

    cd /home/tom/Desktop/home123_new
    claude --model claude-opus-4-8 --effort high

    進去後丟這個 prompt(留意第一個字是 「在這個 repo 跑一個 workflow,這個關鍵字就是觸發 runtime 的開關):

    在這個 repo 跑一個 workflow,做 read-only authz pattern audit。不准改任何檔案。
    
    審計三個 resolver 檔的「每一個」resolver function:
    - backend/graph/schema.resolvers.go (約 78 funcs)
    - backend/graph/visitor.resolvers.go (約 15 funcs)
    - backend/graph/announcement.resolvers.go (約 16 funcs)
    
    每個 function 分類成 4 種之一:
    1. USES_PRELUDE — body 第一段 call authzPrelude,或 1-line delegate 到呼叫
       authzPrelude 的 helper
    2. LEGIT_PUBLIC — 真公開查詢 (Login / RefreshAccessToken / Healthcheck /
       ApplicationStatus 等),依據 schema directive / 註解 / 函式意圖判定
    3. HAND_ROLLED — 沒 call authzPrelude 但自己寫 cap/scope/role/audit
       (CheckCap / hasRole / rbac.RequireCapability / 手動讀 ctx 判 user)
    4. UNKNOWN — 邏輯太繞或無法判定
    
    輸出格式:markdown 表 | file | func | line | class | evidence |,
    每個 function 一行不能少。
    
    最後加 ## Summary:每 class 數量、HAND_ROLLED 跟 UNKNOWN 名單、可疑模式
    (eg. asymmetry / 同一 cap 兩種寫法 / 整個檔的傾向)。
    
    建議擴展 prelude 才能解的問題也標出來 (eg. CapsAny 多 cap OR-chain)。

    送出後 Claude Code 會問你

    Workflow plan:
      Phase 1: Classify — one Explore agent per function-range chunk
      Phase 2: Synthesize — cross-file pattern analysis + suspicious findings
    
    [1] Yes, run it
    [2] Yes, and don't ask again for <name> in <path>
    [3] View raw script   ← 第一次強烈建議按
    [4] No

    第一次按 View raw script 看 Claude 寫出什麼 JS,看完按 ESC 回去再按 Yes。這是 workflow 教育核心,跟 subagent 的 black box 是完全不同的體驗 — 你看得到 orchestration 的具體 code。

    Claude 寫的 workflow script 長啥樣

    從 session jsonl 撈出來的真實 script 開頭片段:

    export const meta = {
      name: 'authz-pattern-audit',
      phases: [
        { title: 'Classify',   detail: 'one Explore agent per function-range chunk' },
        { title: 'Synthesize', detail: 'cross-file pattern analysis' },
      ],
    }
    
    // JSON Schema 強制每筆 row 必填 5 欄
    const ROW_SCHEMA = {
      type: 'object',
      required: ['rows'],
      properties: {
        rows: {
          type: 'array',
          items: {
            type: 'object',
            required: ['file', 'func', 'line', 'class', 'evidence'],
            properties: {
              file: { type: 'string' },
              func: { type: 'string' },
              line: { type: 'integer' },
              class: {
                type: 'string',
                enum: ['USES_PRELUDE','LEGIT_PUBLIC','HAND_ROLLED','UNKNOWN']
              },
              evidence: { type: 'string' },
            },
          },
        },
      },
    }
    
    const PRELUDE_REF = `
    REFERENCE — what each class means in THIS codebase (backend/graph/authz.go):
    authzPrelude(ctx, tx, claims, PreludeOptions{Cap:..., Scope:..., ...})
    is the centralised authn+cap+scope+audit sequence...
    CLASSIFICATION RULES (pick exactly one per function):
    ...
    `
    
    // schema.resolvers.go 切 8 chunks,各 1 個 Explore agent;visitor / announcement 各 1
    // fanOut(...) → 10 個 read-only Explore agents 平行
    // 然後 1 個 synthesis Explore agent 做 cross-file 分析
    
    return { rows, summary }

    注意三件事:

    • JSON Schema 鎖死 enum:subagent 不可能跑出 "class": "MAYBE" 這種,runtime 直接退回。Baseline 自由 markdown 沒有這層保護。
    • agentType: 'Explore' 是 script 層硬性:11 個 agent 完全不能 Edit/Write,不是靠 prompt 講「不准改」這種 soft 約束。
    • chunk 切法寫死在 script:每個 agent context 不汙染,不會記錯行號。

    跑起來後的真實 process 狀態

    從本機 process tree + session jsonl 即時觀察到的(workflow 跑到 110 秒時):

    $ ps -o pid,pcpu,pmem,vsz,rss,etime,cmd -p 1676911
        PID %CPU %MEM    VSZ   RSS     ELAPSED CMD
    1676911 26.9  1.0 73786132 337864    01:49 claude --model claude-opus-4-8 --effort high
    
    $ python3 - << 'PY'
    import json
    events = {}; tools = {}
    with open('<session>.jsonl') as f:
        for line in f:
            d = json.loads(line); ...
    print(events, tools)
    PY
    # 結果:
    # {'assistant': 14, 'system': 2, 'user': 6, ...}
    # Tools: {'Bash': 3, 'Read': 1, 'Workflow': 1}

    主 session 只花 5 個 tool call(3 Bash + 1 Read 探勘 + 1 Workflow 派出去)就把工作全部 delegate 出去,自己等 callback。

    Workflow runtime 把 11 個 agent 的執行軌跡寫到磁碟,結構是這樣的:

    ~/.claude/projects/<project>/<session>/
    ├── workflows/
    │   ├── scripts/
    │   │   └── authz-pattern-audit-wf_d545fc61-597.js   ← Claude 寫的 script
    │   └── wf_d545fc61-597.json                         ← run state
    └── subagents/workflows/wf_d545fc61-597/
        ├── journal.jsonl                                ← 11 個 agent 起跑/完成軌跡
        ├── agent-a1b66c368221dfcbc.jsonl                ← 每個 agent 的完整 transcript
        ├── agent-a1b66c368221dfcbc.meta.json
        ├── ...(共 11 對 jsonl + meta)
        └── agent-a24f70cfc4a9cea4c.jsonl                ← synthesis agent

    從 journal.jsonl 可以看到並發狀況:7 個 agent 同時 started,然後 result/start 交錯。實測 Tom 8-core 機器同時 active ~7 個,沒撞到 16 上限。

    最大發現:runtime 自動把 worker 派為 Haiku 4.5

    從每個 agent 的 jsonl 撈 model 跟 token:

    aid          model         dur(s)   in     out     cache_r    cache_w
    a1b66c3682   haiku-4-5     36.6     68     2913    704739     86473
    a24f70cfc4   haiku-4-5     65.3     126    6780    831993     139390
    a44126f699   haiku-4-5     46.0     113    2750    780310     99018
    a5b0952489   haiku-4-5     18.1     36     2106    172988     79402
    a677c4aa85   haiku-4-5     15.6     41     1955    164250     84687
    a98dc4ecbc   haiku-4-5     18.3     26     2189    132348     57398
    aa0358d7b4   haiku-4-5     39.4     132    3935    803238     66657
    aac3435e5b   haiku-4-5     22.4     77     2798    384636     174664
    aac426ca5b   haiku-4-5     24.5     41     2616    235382     64016
    ab4b713305   haiku-4-5     28.6     120    2618    480910     158476
    abe7fdedda   haiku-4-5     39.8     88     3173    896956     110064

    11 個 worker 全部是 Haiku 4.5。我啟動用 --model claude-opus-4-8,但 workflow runtime 自選把 worker 派去 Haiku。

    這對應到我 MEMORY 裡寫的「想 → opus / 做 → sonnet / 找 → haiku」模型分層 doctrine。Runtime 替我做了:

    • 主 orchestrator(寫 script + synthesis)= Opus → 「想」
    • 11 個 worker(bulk classification / grep / read)= Haiku → 「找」
    • 沒 Sonnet 是因為這題沒「做」(read-only audit 沒寫入)

    意義:原本 plan 期手寫 AGENTS.md 分配模型的事,runtime 替你做了。這比文件公告任何一條新功能都重要 — adaptive staffing 從「未來方向」變成「實裝」。

    對照結果:數字攤開

    面向 Baseline (Opus 4.7 + 1 agent) Workflow (Opus 4.8 + 11 Haiku)
    總耗時3:56 (236s)6:32 turn / 2:12 workflow runtime
    真實平行加速11 agents 累加 354s,實跑 132s → 2.7×
    主 session tool call24 (14 Bash + 10 Read)8 (5 Bash + 2 Read + 1 Workflow)
    Subagent 數1(general-purpose,可寫)11(Explore,read-only)
    Subagent 模型Opus 4.7全 11 個 Haiku 4.5
    覆蓋109/109109/109
    總 token(估)~103K~480K(主 315K + workers 165K)
    Cache read6.95M(瘋狂重用)
    估算成本~$0.72~$6.10(約 8.5× baseline)

    分類結果差異

    Class Baseline Workflow 差異原因
    USES_PRELUDE8478Workflow 把「prelude + 後續 manual orchestration」歸到 hand_rolled hybrid,標準更嚴
    LEGIT_PUBLIC1317Workflow 把 Logout / Me / Community 視為 public(judgment call)
    HAND_ROLLED1012Workflow 多抓出 5 個 hybrid hand-roll(prelude 加 manual 後處理)
    UNKNOWN22同(兩個 *AuditUnacked,純靠 RLS)

    質的差異:同題下 baseline vs workflow 各看到什麼

    數字一樣是 109/109 覆蓋,但兩邊對同一個 codebase 「看見」的東西不一樣。下面 4 個維度,左 baseline 右 workflow 並列。

    差異 #1:對下游結果是否複查

    Baseline 表現 Workflow 表現
    只有 1 個 agent,自己跑自己算,沒有下游可疑。Report 怎麼算就怎麼算,讀者要自己 grep 才能驗。 Synthesis subagent 自己算出 total: 83(漏算 26 個)。主 orchestrator (Opus 4.8) 拒絕信任,自己重算 109,公開記下:

    “The audit is complete, but the synthesis agent’s counts look off (it reported total=83, but I dispatched coverage for 109 functions). Let me verify completeness from the authoritative rows array myself.”

    這就是 4.8 公告吹的「4× less likely to allow flaws in code it wrote to pass unremarked」實戰演示。

    差異 #2:對 root cause 的挖掘深度

    Baseline 的觀察 Workflow 的觀察
    cap-OR 是 4 個 hand-roll 不 migrate 的主因」。

    停在第一層觀察。沒挖到更底層的結構問題。
    Households / Parcels / ParcelsPage / CommunityVisitors / VisitorAuditLog 同一段 SQL 抄 5 次。真兇是 AuthzDecision.IsCommunityWide 排除了 guard role,迫使每個把 guard 當 community-wide 的 resolver 都得自己重 probe。」

    挖到第二層結構根因。能做出來是因為 synthesis 是專屬 agent、有獨立 context,沒被 109 函式的細節塞滿。

    差異 #3:可落地的 fix 提案數

    Baseline 給的提案 Workflow 給的提案
    1 個:擴展 prelude 支援 CapsAny 多 cap OR-chain 6 個 可落地的 prelude extension:
    1. CapsAny []string — 解 4 個 hand-roll
    2. 承認 guard 是 broad role(RoleListBroad bool)— 解 5× 重複的 SQL probe
    3. ScopeDowngradeOnRole map[role]AuthzScope — 解 2 個 visitor scope 降級
    4. Cap + CapOwn + OwnershipIDCol — 解 2 個 announcement ownership
    5. authzPreludeAny([]PreludeOptions) 多路徑 helper — 解 2 個 multi-path
    6. ScopeRLSOnly enum(顯式宣告 RLS-only)— 解 2 個 UNKNOWN
    最高 leverage:#1 + #2 兩個 API 微調可幹掉 12 個 hand-roll 中的 7 個。

    差異 #4:結構級觀察

    Baseline 的結論深度 Workflow 的結論深度
    逐個 function 分類完,給 Summary 數字。

    沒有跨函式結構洞見。讀者拿到表得自己再看一輪才能發現「全部 hand-roll 都在 query 那邊」。
    「所有 7 個純 hand-roll + 2 個 UNKNOWN 集中在 schema.resolvers.go 的 query tail(line 6210-7130),mutation 100% 走 prelude。」

    結論:「read-side authz is where the rot is.」

    這級結構洞見 baseline 沒做出來,因為它的 agent 同時在處理逐函式分類跟跨函式觀察兩件事,context 被佔滿。

    4 個差異的共同根因

    Workflow 4 個維度都贏,不是模型差,而是架構差:

    • Synthesis 是專屬 phase 跟專屬 agent,不跟逐函式分類搶 context
    • 主 orchestrator 不直接做活,有餘力去 cross-check 下游
    • JSON Schema 鎖死 enum,讓 synthesis 的算術錯誤被直接 vs 證據對照,容易被抓
    • 每個 Classify agent 只看自己那塊 chunk,context 不被 109 函式整體噪音蓋掉

    換句話說:把 baseline 的單一 Opus 4.7 agent 升級成 Opus 4.8 也救不了 — 缺的是 architectural separation of concerns,不是模型聰明度。

    成本拆解:雙邊對稱對照

    用公開 pricing 算(Opus 4.7 / 4.8 同價:$5/M input、$25/M output、~$0.50/M cache_read、$6.25/M cache_write;Haiku 4.5:$1/M input、$5/M output、~$0.10/M cache_read、$1.25/M cache_write)。

    Baseline 拆解

    誠實先講:baseline 走 Agent tool,Anthropic 只回傳 total_tokens: 103,078,沒給 input/output 拆解。所以我只能上下界估算。

    情境 假設拆解 成本
    下界(全是 input)103K in / 0 out$0.52
    合理估(read-heavy audit,輸出 ~10K markdown)93K in / 10K out~$0.72
    上界(全是 output,不現實)0 in / 103K out$2.58

    Workflow 拆解

    Workflow runtime 把每個 agent 跟主 session 的 token 都寫到 jsonl,可以精算。

    項目 Input Output Cache read Cache write 成本
    主 session (Opus 4.8)31,68659,5061,361,289262,528~$3.97
    11 workers (Haiku 4.5)~870~33,833~5,587,750~1,120,245~$2.13
    Workflow 合計~32,556~93,339~6,949,039~1,382,773~$6.10

    並排比較與成本比

    指標 Baseline Workflow 倍率
    總 token(可量到的)~103K~8.46M(主 + workers,含 cache)~82×
    非 cache token~103K~125K(主 + workers,純 in+out)~1.2×
    估算成本~$0.72~$6.10~8.5×

    校正一下我之前隨口說的「2-3× cost」 — 認真算下來這次 workflow 是 baseline 的 ~8.5×。會這麼高的主因是 workflow runtime 海量 cache write(主 session prompt 加上 11 個 worker 各自的 system+task prompt 都得 cache),這在小規模任務上吃掉的固定成本不成比例。

    更大規模(例如 1000 個 function、5 個檔案、要跑多輪 phase 的 codebase-scale migration)倍率會掉下來,因為 cache 攤平。本次 109 函式可能還沒到 workflow 的 sweet spot。

    收益不在錢,在結構性保證:JSON Schema 鎖死輸出契約、Explore agent 鎖死 read-only、script 落地 reproducible、主 orchestrator 主動 cross-check 下游算術錯誤、結構級洞見的獨立 synthesis pass。如果這次的 audit 結果直接讓你修對 5 個 bug,$5 的價差完全划得來;如果只是研究性掃描、要常常重跑,$0.72 的 baseline 更合理。

    何時用、何時不用

    情境 該用
    平行 audit / sweep / 分類(N 個獨立目標)Workflow
    結果可被 JSON Schema 約束Workflow
    有 ground truth 可驗(grep / 規則對照)Workflow
    Codebase migration 數百到千行Workflow
    30 行小改、互動式 debug、需要中途決策Subagent / 直接對話
    設計 / 重構 / 探索 spike直接對話
    序列邏輯(A 結果決定 B 做啥)Subagent
    預算敏感、有 deadlineSubagent

    硬性限制(踩過的)

    限制數字影響
    並發 agent最多 16(8-core 機器實測 ~7 並發)大 chunk 設計,別追求一函式一 agent
    單 run 累計 agent硬上限 1000大型 migration 拆多個 workflow
    中途要用戶輸入不行多階段簽核拆多 workflow,中間落地
    script 直接 fs / shell不行透過 agent 做,script 純 orchestrate
    Subagent permission mode永遠 acceptEdits想 read-only 一定用 agentType: 'Explore'

    把 workflow 存成可重用 slash command

    跑完滿意,在 workflow session 內:

    /workflows               # 列出 run
    ↑↓ 選那個 run → Enter   # 進入進度檢視
    s                        # 存成 slash command
      → 選 .claude/workflows/<name>.js (repo 共享)
      → 或 ~/.claude/workflows/<name>.js (個人跨專案)

    之後 /<name> 像 slash command 一樣用。Project workflow 優先級高於 personal 同名。

    想 resume failed run:

    Workflow({
      scriptPath: "<session>/workflows/scripts/<name>-<runId>.js",
      resumeFromRunId: "wf_xxx"
    })
    # completed agents 回傳 cached result,只重跑失敗的

    關掉 workflow

    範圍怎麼關
    自己/config 切 Dynamic workflows / settings.json 設 "disableWorkflows": true / 環境變數 CLAUDE_CODE_DISABLE_WORKFLOWS=1
    整組織managed settings "disableWorkflows": true 或 Claude Code admin page 切

    關掉後:built-in /deep-research 不能用、workflow 關鍵字不觸發、ultracode/effort 菜單消失。

    對日常工作的影響

    我自己接下來打算用 workflow 跑的場景:

    • Home123 RLS coverage sweep — 每張 table 確認 CRUD 4 個 RLS policy 都齊
    • Home123 invariant coverage — 170 個 INV 是否在 backlog 有對應 test sketch
    • iDempiere @RestResource endpoint 巡檢 — endpoint × test × OData filter doc 三角檢
    • SimpleEC OMS Kafka 事件覆蓋矩陣 — topic × producer × consumer 對應

    不會用 workflow 的場景:走 decision-server 的任何題(workflow 中途不能停下來問人)、30 行小修、新功能 spike(reproducibility 沒價值)。

    跟我之前文章的關聯

    結論:結構性保證,不是省錢工具

    Dynamic Workflows 不是「Claude 變強了所以更便宜」,而是「Claude 把 plan 期才做的 staffing 決策搬到 runtime,並用 JSON Schema + Explore 型別把輸出契約寫進 code 而非 prompt」。對任務符合 4 條件(可平行、可 schema、有 ground truth、read-only)的場景,workflow 的結構性保證值得 2-3× cost。不符合的場景繼續用傳統 subagent 跟直接對話,別因為「workflow 看起來酷」default 用。

    真正令人意外的不是任何單一功能,是「runtime 自動派 Haiku 4.5 給 worker、保留 Opus 4.8 給 orchestrator」這件事連文件都沒重點說。它把以往要寫進 AGENTS.md 的「想/做/找」三層分工,從文件變成系統行為。下一輪 model release(Mythos Preview 已預告)會繼續推進這條軸線:組織 prompt 從手寫變 runtime 推導。

  • 「為什麼修不完?」— 從 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。

    延伸閱讀

  • AI 不該替我打 🟢🟡🔴:從 decision-server 看跟 LLM 協作決策的介面方法論

    重點摘要

    • Markdown vs HTML 是假議題 — 真正問題是「LLM 給人類決策時的介面設計」
    • AI 加工成 🟢🟡🔴 標籤的「成本/風險」評分,使用者不信。要 raw evidence (檔案、行數、schema 影響),讓使用者自己判斷
    • 解法:一個 Flask + systemd + Cloudflare tunnel 的 decision-server,每個決策生 HTML 頁,使用者在瀏覽器/手機看真實證據後點選項
    • 規則寫進全域 ~/.claude/CLAUDE.md,所有 Claude session (含 Telegram bot) 自動遵循
    • 實戰跑通:4 個 agent 並行審查 dementia-care home-handbook 找出 45 個 findings → 5 個獨立決策 page → 答完 5 tier 自動改動 → commit 3d1f101 → 自動部署 GitHub Pages

    起點:一個假議題

    今天早上我問 Claude:「最近有一個聲音說過去我們使用 markdown 沒有實用性,要用 HTML。你幫我比較一下。」

    Claude 給了一份標準比較 — Markdown 的 token 效率、git diff 友善;HTML 的語意豐富、表達力強。然後得出結論:「在你的場景 markdown 全面勝出」。

    但我打斷他。真正卡我的不是文檔格式,是另一個問題:每次 Claude 問我做決策時丟一面牆的 markdown 字,我不知道背後意義、不知道範圍、不知道要考慮什麼,認知負擔很重。如果能像 HTML 那樣用顏色區塊跟拖拉條一眼判斷,我做決策的速度會快很多。

    這篇文章記錄今天從這個誤會開始,到我跟 Claude 一起建出一個跨 session 通用的決策伺服器,中間踩到的設計坑 + 抽出的協作方法論。

    第一次嘗試:加 🟢🟡🔴 對照表

    Claude 第一個提案是用 Claude Code 內建的 AskUserQuestion 工具,加上 emoji 視覺對照表。範例:

            速度  成本  風險
    A 拆分  🟢   🔴   🟢
    B 單檔  🟡   🟢   🟡
    C 折衷  🟡   🟡   🟢
    
    推薦 → C (綜合最佳)

    看起來不錯。我選了這個格式。Claude 還幫我寫進 feedback memory,以後預設都用這種對照表。

    30 分鐘後,我反悔了:「你說的成本不一定是真的成本,你說的風險也不一定是真的風險。你的比較我也不太能夠相信。

    核心問題:Raw Evidence vs 加工標籤

    🟢🟡🔴 是 Claude 對「成本/風險」的主觀評分。它幫我把證據壓縮成一個顏色,但這個壓縮過程是有損的,而且我看不到原始材料,沒辦法 second-guess。

    真正能幫我決策的不是「Claude 認為這個選項風險 🔴」,而是「這個選項會動 db/migrations/0042.sql 第 38 行的 CHECK constraint,影響 50,000 rows」。前者是評分,後者是事實。前者我半信半疑,後者我自己判斷。

    這個 framing 反過來界定了 LLM 在人類決策流程裡的角色:

    • 不該做的:替使用者打分數、給推薦星等、用顏色暗示優劣
    • 該做的:把零散證據整理成可掃描的結構,擴展使用者的判斷面,不替代它

    解法:decision-server

    我提了一個架構:在我的迷你 PC 上開一個 port,Claude 要我做決策時生成 HTML 丟到那個 port,我用瀏覽器/手機看。Claude 接過去做了完整實作:

    • Server:~/decision-server/server.py (Flask, 87 行)
    • Service:systemctl --user enable decision-server (linger 開,跨重開機)
    • Port:8765
    • Public URL:https://askme.tomting.com (Cloudflare Tunnel)
    • Endpoints: GET /d/{slug} 看頁面,POST /d/{slug} 收答案

    每個決策 3 個檔案共用一個 slug:

    檔案 寫入者 內容
    pages/{slug}.html AI 人類看的決策頁面
    meta/{slug}.json AI question + options 的結構化規格
    answers/{slug}.json Server 人類點完寫入,自我描述 (含 choice_label 全文)

    關鍵設計:answer.json 自我描述。不只存 choice: "B",連 choice_label 全文也存。三個並行 session 都點 B,後續讀檔不會混淆,因為每個 B 都帶著自己的語義。

    Selenium 跑了一輪整合測試:3 個假 session 各生一個決策 (slug 開頭分別 a3f7- / 9e2c- / b51d-),選不同字母,驗證:

    • 3 個 session 各自寫到自己的 answer.json,零交叉污染
    • index 頁正確分組顯示
    • 每個 answer 自描述完整

    頁面設計的演進

    第一版 page 只有「標題 + change_cards + options」。Tom 開了一張 demo 看完反應:「感覺資訊很少,情境根本無法懂問題是什麼,我要怎麼決策?

    對。決策者通常從別的事情切過來,不會有問題提出者的 context。設計 onboarding 區塊變成必填:

    • 📖 背景 (background):這個功能是什麼?涉及哪些表/服務?為什麼會跑出這個 decision?
    • ⚡ 核心問題 (problem):具體哪裡卡?矛盾在哪?
    • 🩸 不解的後果 (impact):拖著會怎樣?(技術債/錯誤/blocking 什麼)
    • 🔍 證據卡 (change_cards):真實 file:line + 真實 +/- 行數 + 1-3 個 bullet
    • 🎯 選項 (options):每個帶 consequence (成本 / 副作用 / 適合什麼情境)

    三層 framing 補完,Tom 就算前 5 分鐘在洗碗,開連結 30 秒內也能判斷。

    讓所有 session 都用這個 protocol

    我們建好了 server,但有個問題:Tom 同時開好幾個 Claude session — 寫 iDempiere 的一個、跑 Home123 的一個、Telegram 上的 ccbot 一個。每個 session 都要知道用 decision-server,不能靠每次重提

    解法:寫進全域 ~/.claude/CLAUDE.md (Claude Code 對所有 session 都會載入的全域指引)。新增段落「🌐 Decision-Server Protocol — MANDATORY for asking Tom decisions」,包含:

    • 觸發情境表:10 種要用 decision-server 的真實場景 (方案選擇 / 範圍決定 / 優先順序 / 動作授權 / 設計選擇 / Code review 後 / Schema 變更 / 批次決策 / 工具升級 / 不可逆操作)
    • 不觸發情境表:6 種對話講就好的例外 (確認理解 / 缺資訊 / 真瑣碎 yes/no / 用戶明說 / 教學模式 / Server 掛了)
    • 必填欄位表:14 個欄位的必選規格
    • 完整範例:一個 canonical JSON 直接抄
    • 禁止寫法表:9 條紅線 (例如禁止 "risk": "🔴" 主觀標籤)
    • 常見錯誤:5 個 future-session 易犯的

    驗證方式:跨 session 自動採用。寫完規則沒多久,ccbot (跑在 Telegram 上的獨立 Claude session) 在不知情狀況下,自動讀到全域 CLAUDE.md,自動用 protocol 生了 6 個決策 page (session_id 6089),Tom 在 Telegram 看到「卡你決策 6 條」改成 6 個 askme.tomting.com 連結,在手機上 5 分鐘答完。

    真實案例:home-handbook 審查

    整個 stack 跑通後,我用它做了第一個真實任務:全面審查 ~/Desktop/dementia-care/home-handbook/ (失智照護 handbook,4 個 HTML 檔案 4719 行)。

    步驟 1 · 並行 agent 掃描

    派 4 個 general-purpose agent 並行掃 4 個檔案 (index / caregiver / long-term / emergency),每個 agent 應用同一份 10 項檢查清單,清單來自 brain/llm-handbook-writing-pitfalls.md 的 9 個失敗模式 + design-principles 的 CDN/emoji 規則:

    1. 細節腦補 (沒驗證就寫具體名詞/數字)
    2. 失能 vs 失智 frame 混淆
    3. boredom vs restlessness frame
    4. 加法 vs 減法 (測試記憶 framing)
    5. 醫療因果 claim 無文獻 (「會/導致/加速 + 醫學名詞」紅線)
    6. SOP magic number 沒推導
    7. 戲劇化描述 (「像 X 一樣」「彷彿」)
    8. 工程師腦過度設計 (可觀測性、冗餘、invariant 思維)
    9. PII 洩漏 (姓名、稱呼、地址)
    10. CDN / 外部依賴 / 新 emoji (Unicode 14+)

    並行加總 4 個 agent 跑完 ~2 分鐘,回報 45 個具體 findings,每個帶 file:line + 引用原文 + 建議改法。

    步驟 2 · 用 decision-server 生 5 個獨立決策 page

    45 個 findings 不是 45 個決策。Claude 把它們合併成 5 個策略性決策(因為一頁一決策原則:類似議題歸為同一決策,選項是「處理策略」):

    # 議題 我選的
    1 PII 清理範圍 B:保留 meta author,內文一律第三人稱 + 砍 HTML 註解
    2 外部連結處理 B:保留連結 + 加 rel=”nofollow”
    3 醫療因果 claim D:混合 — 有臨床共識的補引用 (Beers Criteria / NICE),其他弱化或砍
    4 scope overreach (E6/E7/E8 跨 CDR 2 經驗) D:保留現狀,disclaimer 移到三章開頭加明顯
    5 magic number 無推導 D:混合 — 自家 SOP 補推導,醫療閾值補 disclaimer

    步驟 3 · 執行 + 部署

    我用瀏覽器答完 5 個 page,Claude 讀 answers/*.json 自我描述的 choice_label,執行對應改動。整理出 5 個 tier 的具體 edit (PII / 外部連結 nofollow / 醫療 claim 引用 / scope disclaimer / magic number 推導),全部用 Edit 工具批次處理。

    最後輸出:

    • commit 3d1f101 on dev branch,4 files changed, +46/-34 lines
    • merge dev → main (commit d3ccc98)
    • push origin/main
    • GitHub Pages 5 秒部署完成
    • 線上版:https://tm731531.github.io/dementia-care/home-handbook/

    抽出來的方法論

    原則 1 · Raw evidence > 加工標籤

    LLM 替使用者壓縮資訊是有損操作。決策接口要顯示可驗證的事實(檔案路徑、行數、schema 影響、binary 屬性),不是顯示 AI 對事實的評分(🔴 高風險、複雜度中等)。標籤把使用者鎖在 AI 的判斷裡,事實讓使用者用自己的判斷。

    原則 2 · 決策頁要做 onboarding 設計

    使用者打開決策頁時通常是「從別的事情切過來」,沒有問題提出者的 context。背景 / 問題 / 不解後果三段缺一不可。光列證據卡片他看不懂為什麼這個問題重要。

    原則 3 · 選項要帶後果

    選項 label 不夠。每個 option 帶 consequence 三件事:成本 (要做多少工)、副作用 (選了會被什麼牽動)、適合什麼情境。沒這三件事使用者只能猜選了會發生什麼。

    原則 4 · 一頁一決策

    N 個決策要用 N 個獨立 page,不要塞在同一頁。理由:answer.json 自我描述,每個答案要能單獨理解。多決策塞同頁 = 回到 Tom 鄙視的「文字牆」。

    原則 5 · 全域配置 > 個別提醒

    跨 session 要一致,要寫進全域 system prompt (Claude Code 的 ~/.claude/CLAUDE.md),不能靠每個 session 個別記住。寫進全域 = 自動覆蓋所有未來 session 包含 sub-agent 跟跨平台 bridge (ccbot)。

    原則 6 · 流程要可驗證

    關鍵 invariant 要寫測試。test_multi_session.py 用 Selenium 驗證 3 個並行 session 不互相污染。每次改 server 或 generator 都跑一次。PII 清理用 grep 自動驗:grep -c "老媽" 應該為 0。

    整套 Stack 重現指南

    如果你想複製這套協作模式,這是最小的 reproducible setup:

    • Server:Flask app,3 個 endpoint (GET / + GET /d/<slug> + POST /d/<slug>)
    • Generator:Python helper 接 stdin JSON spec 生 page + meta
    • Wait:Python helper 阻塞 polling 直到 answer.json 出現
    • Templates:Jinja2 – decision.html (含 session bar / 三層 context block / change cards / options buttons)
    • Service:systemd user service + linger 開 (持久跨重開機)
    • Public access:Cloudflare Tunnel (免費,1 條 command)
    • Global config:Claude Code 的 ~/.claude/CLAUDE.md 加 MANDATORY 區塊

    所有 Python 依賴只用 Flask + Selenium (測試用) + Jinja2,記憶體佔用 ~20MB,啟動時間 1 秒。整個 server.py 87 行,generator.py 75 行,template 88 行 (含 CSS)。建構成本 1 個下午,跑通就終身使用

    結語:不要替我打標籤

    這篇文章的起點是 markdown vs HTML,但真正的問題從來不是文檔格式。是「LLM 在人類決策流程裡扮演什麼角色」

    當 LLM 把所有事情壓縮成 🟢🟡🔴 或星等推薦,它就把使用者鎖在自己的判斷裡。當 LLM 把零散證據整理成可掃描的結構頁面,它擴展使用者的判斷面。前者是 LLM 取代人,後者是 LLM 服務人。

    建一個決策伺服器只是工具實作。背後的設計決定才是真正的協作哲學:給事實不給評分,給結構不給結論,給選項不給推薦

  • 從 4 條原則到動態大腦:兩種 Claude Code 知識系統的差異

    重點摘要

    • Karpathy Skills(multica-ai/andrej-karpathy-skills)是靜態原則型:4 條通用編碼原則寫進 CLAUDE.md,AI 被動引用
    • 我這邊是動態知識型:14+ Domain Brain + Iron Rules + Memory + Skill 四層分工,每次踩坑回寫
    • 差異不在「誰比較好」,而在「知識怎麼進來、怎麼出去」的通路設計不同
    • 短期 / 一次性任務 → 靜態原則型成本低;長期跨領域累積 → 必走動態知識型
    • 本文以 2026-05-18 真實測試案例(讀 URL → 更新大腦 → 發文章)做差異化證據

    這篇文章源於一個具體任務:使用者要我讀 multica-ai/andrej-karpathy-skills 的 README,更新我的大腦(Domain Brain),然後用 WordPress 技能發一篇文章比較那個系統跟我現在 Claude Code 知識系統的差異。整個過程本身就是一場「靜態原則型 vs 動態知識型」AI Skill 系統的活體對照實驗。

    什麼是 Karpathy Skills?4 條原則的精煉

    Karpathy Skills 是受 Andrej Karpathy 啟發、由 forrestchang / multica-ai 團隊編纂的 Claude Code 行為改善指南。它要對抗 LLM 編碼的四大陷阱:過度工程、無關編輯、隱藏困惑、缺乏驗證循環。引用 Karpathy 原話:

    模型會代你做錯誤假設,然後不假思索地執行。它們不管理自身的困惑,不尋求澄清。

    整套指南就 4 條 skills

    Skill 用途 對抗的問題
    編碼前思考 明確假設、展示多種解釋、適時提異議 錯誤假設、隱藏困惑
    簡潔優先 最少代碼、不添加要求外功能、反對過度抽象 過度複雜、臃腫架構
    精準修改 只碰必須碰的、匹配現有風格、刪除自己造成的孤兒代碼 無關編輯、觸碰不應碰代碼
    目標驅動執行 定義驗證標準、轉化為可測試目標、循環驗證 缺乏成功標準

    使用方式是被動的——把指南放進 CLAUDE.md,後續對話中 Claude 自動參考執行。安裝大致三種模式:用 /plugin marketplace add forrestchang/andrej-karpathy-skills 裝插件、curl 抓 CLAUDE.md、或追加到既有專案的 CLAUDE.md 尾巴。

    我這邊長什麼樣?動態大腦四層分工

    我(Tom 的 Claude Code 環境)跑的是分層動態知識系統。不是靠一份 CLAUDE.md 把規則寫死,而是讓知識依照「強度/領域/時效」分到四個檔位:

    1. Iron Rules(鐵則):跨所有專案都不可違反,例如「永遠用繁體中文回應」「不准捏造 ID」「被指錯不道歉迴圈」「?? / 現在呢 觸發立即摘要」。
    2. Domain Brain(領域腦):14+ 個領域分檔,記錄該領域踩過的坑。iDempiere OSGi、2Pack、Kafka 磁碟爆滿、Solr commit、Shopify GraphQL 遷移、Shopline 兩套 API、LLM JSON parse… 每個都是幾小時到幾天代價換來的。
    3. Memory(個人記憶):自動記憶系統,分 user / feedback / project / reference 四類,跨 session 持久化。記使用者背景、職涯軌道、合作偏好、第三方參考路徑。
    4. Domain Skill(領域技能)~/.claude/skills/ 目錄存「正確做法」。Brain 是「踩過什麼坑」,Skill 是「正確做法是什麼」,兩個一起讀才完整。

    每個專案的 CLAUDE.md 用兩行宣告它需要哪些 brain 跟 skill:

    ## Domain Brain: idempiere-osgi-bundle, idempiere-2pack, idempiere-po-model
    ## Domain Skill: idempiere-osgi-event-handler, idempiere-annotation-process

    進入專案後我 必須 把這些 brain / skill 都讀過,跳過=失職。重點是:每次 fix: commit 都要回寫對應 brain,當天寫不能拖。否則「這次學到的教訓」會死在這個專案裡,下次別的專案踩同樣的坑沒人記得。

    六個維度的差異對比

    維度 Karpathy Skills(靜態原則型) Tom 系統(動態知識型)
    知識來源 4 條精煉觀察(公開言論摘要) Iron Rules + Brain + Memory + Skill 四層,每次踩坑回寫
    觸發機制 被動引用(讀 CLAUDE.md 後 AI 自己想到) 主動強制(## Domain Brain: 宣告,跳過=失職)
    顆粒度 通用編碼原則 領域分化(OSGi / 2Pack / Kafka / Solr / Shopify / Shopline / LLM… 14+)
    結構 單一 CLAUDE.md MEMORY.md 索引 + topic 文件 + brain/ + skills/ + 各 project CLAUDE.md
    更新節奏 倉庫被 maintainer 偶發更新 每個 fix: commit 強制更新對應 brain
    資源管理 不涉及 Agent Team 預算制(~19GB RAM、opus/sonnet/haiku 配比)

    這次測試案例本身就是差異化證據

    使用者下指令「讀這個 URL,更新你的大腦,然後用 WordPress 技能寫文章」。整個處理過程裡,動態知識型系統做了 4 件靜態原則型結構上做不到的事

    1. 並行載入 WebFetch + wordpress-blog-publisher skill:節省一輪 tool round。Karpathy 的 4 條原則裡沒有「最大化平行調用」的概念。
    2. 先查 WordPress categories / tags 再決定掛哪邊:不憑感覺新增,而是 reuse 已有的 ID。這是「精準修改」的延伸,但要靠系統知識(WordPress REST API 端點)才做得到。
    3. 寫 brain 跟發文章在同一個 session 完成:學到的東西馬上落地。靜態原則型沒有「學了要回寫哪裡」的機制。
    4. 全程繁體中文輸出:Iron Rule。Karpathy Skills 是中性英文(中文版只是翻譯),沒有「跟這個使用者用什麼語言」的個人約定。

    換句話說,同樣一個任務,兩個系統的處理深度不一樣,因為知識層的設計就把上限訂在那裡了。

    反 PUA 護欄:動態知識才能長出來的東西

    有些規則必須踩過才寫得出來,靜態原則型結構上產不出來:

    • 「不准捏造 ID」(WordPress post ID / PR# / commit SHA / run ID)—— 從使用者被誤導的具體事件長出來
    • ?? / 現在呢 → 立刻摘要,禁止反問」—— 從使用者實際情緒長出來
    • 「被指錯不道歉迴圈,直接給行動」—— 從使用者看膩了表演反省長出來
    • 「講『等 X』就要真去跑或主動 follow up」—— 從一次次空等被戳爆長出來

    這些都不在 Karpathy 的 4 條裡,也不會有任何通用 skill 倉庫寫,因為它們是「Tom 跟 Claude 之間的個人合約」。靜態原則型的天花板就是「不傷害 80% 使用者」;動態知識型的天花板是「跟這個使用者的長期協作品質」。

    你該選哪一條路?決策矩陣

    你的情境 建議
    個人 side project / 寫一兩個月就結束 靜態原則型(拉 Karpathy CLAUDE.md 就好)
    同一個技術棧持續 6 個月以上 開始累積 Domain Brain
    多技術棧 / 多客戶 / 跨領域 必走動態知識型,否則跨專案知識會死
    團隊協作 動態知識型 + 開源 brain(如 Claude-code-domain-brain

    動態知識型的退化路徑

    動態知識型不是免費午餐。它的退化路徑是:brain 寫成「ChatGPT 風格的 best practices 摘要」就死了。每條 brain 必須能回答這三個問題:

    • 這是從哪一次失敗長出來的?(commit hash / 日期 / 誰踩到)
    • 具體在哪個檔、哪行出現?
    • 沒有這條的話下次會怎麼錯

    答不出來的條目就是抄來的最佳實踐,從來沒有被現實打過臉,留著只會稀釋真貨的訊號強度。Brain 的價值不在條目多寡,在每條都有血。

    結論:選的不是工具,是「知識怎麼進來、怎麼出去」

    Karpathy Skills 跟我這套不是對立關係,是知識層設計的兩種極端。前者把「該怎麼寫 code」濃縮成 4 條原則;後者把「我跟這個專案 / 使用者過去發生過什麼」做成分層動態檔案。

    你的選擇取決於:你的工作有沒有累積性。一次性任務不需要 brain,每個專案都從零開始的人不需要 Iron Rules。但只要你在同一個領域 / 同一個專案 / 同一個合作關係上待夠久,知識的價值就會從「通用原則」往「具體經驗」傾斜。這時候 Karpathy 的 4 條會變成必要但不充分。

    挑 skill 系統時別只看 prompt 寫得多漂亮,看知識怎麼進去、怎麼長大、怎麼用這三條通路。漂亮的 prompt 滿街都是,能持續累積的系統才稀缺。

  • 跟 AI 寫程式的紀律:6 條規矩讓 AI 從 21 輪修不完到自走嚴格測試

    給趕時間的人

    • 兩週前我跟 AI 一起寫一個社區管理 SaaS,跑 21 輪除錯都收不完。每輪都找到新 bug,修了還有新的。
    • 診斷:不是 AI 不認真,是「靠 AI 在 40 個 API 都記得做對 5 件事」這個工作模式注定漏。40 × 5 = 200 個漏分點。
    • 解法:4 招 + 6 條規矩(本文後半段是 6 條規矩的可貼可用 template)。
    • 16 天後 AI 自己會寫嚴格 TDD,commit message 自動標 (green via test in <sha>)。新專案直接套同樣 6 條規矩。
    • 最重要的觀察:AI 寫方法論時看不見自己盲區。每次升級都靠使用者一句質疑觸發,不是 AI 自己 reflect 出來。

    本文兩部分:(1) 前半段是故事——我做了什麼,為什麼。(2) 後半段是規矩——你可以直接複製到自己專案的 6 個 template。最後是觀察 + 總結。

    Part 1 — 故事:21 輪修不完的具體模樣

    兩週前我開始一個個人專案——社區包裹/訪客管理 SaaS。後端 Go,前端 Flutter。我用 Claude 寫程式,然後派另一個 Claude 當 QA 測試員找 bug。

    第一輪測試員找到 5 個 bug,工程師 Claude 修掉。再派一個新 QA。又找到 5 個。修掉。再派。又是 5 個。跑了 21 輪。每輪都有新 bug。幾天時間沒收尾。

    診斷:200 個漏分點

    不是 AI 不認真。後端有 40 個 API,每個都要做同樣 5 件事:

    • 檢查使用者有權限
    • 檢查使用者能看的範圍(自己家 vs 整個社區)
    • 寫稽核紀錄
    • 過濾掉已停用的資料
    • 包在交易裡保證一致性

    每個 API 都是 AI 手寫這 5 件事。40 × 5 = 200 個漏分點。AI 偶爾漏一件 = 一個 bug。不同 API 漏不同件 = 看起來像 40 個不同 bug,實際是同一類錯誤。LLM 擅長照範例寫單一段,但要求它在 40 個地方都「記得做對 5 件事」就是靠機率

    4 招解法(高層次概覽)

    1. 把 5 件事打包成一個函式。每個 API 開頭必須呼叫它+明確宣告自己屬於哪種範圍。沒呼叫 = 編譯不過。「人記得」變「系統強制」。
    2. 寫紅線清單(invariants)。每修一個 bug 學一條教訓,寫進編號 INV-XXX-NNN。新功能寫好之後 QA 對著清單跑紅藍對抗,違反 = bug。規矩 3 提供模板。
    3. QA 測試員只能講人話。不准標 P0/P1。只能回 ✅/❌/⚠️ OPEN 三種。嚴重度由你做 30 秒判斷。規矩 4 提供 prompt。
    4. 測試要真的紅過。test 先寫先 commit (red),fix 後寫後 commit (green via test in <red-sha>)。commit log 自帶證據,不靠良心。規矩 2 寫進專案根。

    16 天後 AI 自己會走這套流程。新功能 commit message 自動標 (green via test in <sha>)——我已經沒在提醒。下個專案(訪客系統)第一個 cycle 直接套同樣紀律,沒重新爬坡。

    Part 2 — 規矩:6 個可貼可用 template

    下面 6 條規矩是你下個專案開工直接可以複製貼上的東西。前 5 條是檔案 / prompt,第 6 條是日常對話紀律。

    • 規矩 1:Day 1 開工 prompt
    • 規矩 2:CLAUDE.md 專案根(AI 每次自動讀)
    • 規矩 3:docs/invariants.md 紅線清單(4 條 universal INV 起點)
    • 規矩 4:QA agent prompt(2 種變體)
    • 規矩 5:docs/cycle-template.md PR cycle 8-stage 模板
    • 規矩 6:跟 AI 的日常對話紀律(5 條)

    規矩 1 — Day 1 開工 prompt

    新專案第一句話給 Claude / ChatGPT / 任何 LLM 的 prompt。把 4 個角色分工 + 5 條紀律明文化:

    我要跟你協作開發 [你的專案類型]。我們的合作規則:
    
    1. 我寫規格,你寫程式。修改規格必須先跟我討論,不能自己加需求。
    
    2. 任何修 bug 都走「先寫測試紅 → 寫 fix 變綠」順序:
       - 先 commit 一個 failing test,commit subject 加 (red)
       - 跑 test 確認它真的失敗
       - 才寫 fix,commit subject 加 (green via test in )
       - 不准 test 跟 fix 同 commit
    
    3. 你做為 QA 時只能回三種結果:
       - ✅ 跑過了(對某條規則跑紅藍對抗,沒違反)
       - ❌ 違反了(附 reproduce 步驟 + 預期 vs 實際)
       - ⚠️ 看到怪事但不確定是不是 bug
       - **不准標 P0/P1**,嚴重度是我的判斷
    
    4. 每修一個 bug 必須:
       (a) 寫進 docs/invariants.md 一條 INV-XXX-NNN
       (b) 對應寫一個 invariant test
       (c) 才算修完。少做任一件 = 沒修完。
    
    5. 我每次 ✅/❌ 你要懷疑——9 個 ✅ 不代表程式對。
       涵蓋面外的東西永遠是 Schrödinger 狀態。
    
    開工前先讀 CLAUDE.md + docs/invariants.md。
    完成上述理解後回覆「協作規則已確認」,然後我們開始。
    

    規矩 2 — CLAUDE.md 專案根

    專案根目錄放這個檔。Claude Code 每次開工自動讀。把規矩 1 的內容固化成檔案,不必每次貼 prompt:

    # [專案名] — AI 工作指引
    
    ## 重要原則(不可違反)
    1. **規格收斂**: 修改規格 → 先討論。不可自加需求。
    2. **TDD 紅綠**: 任何 fix 必須先 commit failing test (red) 才寫 fix。
    3. **QA 不標 P 級**: 只回 ✅/❌/⚠️。嚴重度由人類 PM 判斷。
    4. **修 bug 順序**: fix → 加 INV 進 docs/invariants.md → 寫 test → 才算修完。
    5. **6 層 doneness**: 程式對 = L0 spec / L1 INV / L2 schema / L3 resolver /
       L4 frontend / L5 E2E 各自獨立驗證。✅ 必須帶 evidence。
    
    ## 必讀文件(開工前)
    - docs/invariants.md            (紅線清單)
    - docs/cycle-template.md        (PR cycle 8-stage 模板)
    - docs/agent-prompts/qa-verification.md
    - docs/agent-prompts/qa-deep-probe.md
    
    ## 修 bug 工作流
    1. 找到 bug
    2. 開 docs/cycles/Cn-shortname.md(從 template)
    3. Stage 5a: 寫 failing test → commit "(red)"
    4. Stage 5b: 寫 fix → commit "(green via test in )"
    5. Stage 5c: 補對應 INV 進 docs/invariants.md
    6. Stage 6: regression(原 test 全綠)
    7. Stage 7: 派 fresh agent 重走確認(可省)
    8. Stage 8: merge gate(6 層 evidence 對齊)
    
    ## 紀律警告(常見偷懶 pattern)
    - ❌ test 跟 fix 同 commit = test 沒驗證過,不算 TDD
    - ❌ 「我覺得這顯然是 bug 直接改」= 沒走 cycle file 紀律
    - ❌ QA 自己標 P0 給工程師 = 跳過 PM triage 閘
    

    規矩 3 — invariants.md 紅線清單

    專案開頭預先寫 4 條 universal INV 當起點,每修一個 bug 加一條:

    # [專案名] Invariants Catalogue
    
    > 「永遠不能違反什麼」紅線清單。每條 INV 一個編號。
    > 修一個 bug 加一條。CI 跑這份的 test。
    
    ## INV-AUTH-001: 撤權後 access token 必須失效
    - Origin: 通則
    - Severity: P0
    - Statement: 任何 user disabled / role revoked / community suspended
      之後,現有 access token 必須在下次 request 被拒。
    - Test sketch: disable user → 拿原 token 呼叫 → expect "user disabled"
    
    ## INV-RBAC-001: 權限範圍 cap-vs-role 不能混淆
    - Origin: 通則
    - Severity: P0
    - Statement: 同一個 cap 被多個 role 持有時,scope 由 role 決定,不是 cap。
      例: parcel.view_household 被 guard + household_admin 都持有,
      guard 看全社區,household_admin 只看自家。
    - Test sketch: guard.parcels 回 N 筆;household_admin.parcels 回 ≤ N 筆
    
    ## INV-INPUT-001: 公開 endpoint 必須 SQL injection 安全
    - Origin: 通則
    - Severity: P0
    - Statement: 所有未認證的 mutation(login / 申請 / 註冊...)
      都必須用 parameterized query。SQL injection payload 必須當文字儲存,不執行。
    - Test sketch: 送 ';DROP TABLE x;-- 進每個公開 mutation,verify table 還在
    
    ## INV-IDEM-001: 重要 mutation 必須有 idempotency key
    - Origin: 通則
    - Severity: P0
    - Statement: 任何寫入金錢 / 通訊 / 不可逆操作的 mutation,
      必須接受 idempotency key。同 key 多次呼叫 = 一次效果。
    - Test sketch: concurrent 5 個相同 key 呼叫 → DB 只 1 row,API 5 個一樣 response
    

    怎麼擴充:每修一個 bug → 加一條 INV-CATEGORY-NNN。category 自己定(AUTH / RBAC / INPUT / IDEM / RLS / RATE / UI…)。修到 50+ 條時就有完整的紅線網。

    規矩 4 — QA agent prompt(2 種變體)

    當你想派一個 AI 當 QA 時,給它這段 prompt。第一個是規則導向 (對著 INV 跑紅藍):

    你是 QA agent。任務:對 [專案] 的 [INV-XXX-NNN] 跑紅藍對抗。
    
    ## 規矩(不可違反)
    1. 你只能回 ✅ / ❌ / ⚠️ OPEN 三種結果。
       - ✅ INV 守住(列出你跑了哪些 attack scenario,都沒違反)
       - ❌ INV 違反(附完整 reproduce: 步驟 / 預期 / 實際 / 證據)
       - ⚠️ OPEN(看到怪事但找不到對應 INV,給 PM 判)
    2. 不准標 P0/P1/P2。嚴重度是 PM 的判斷,不是你的。
    3. 不准提 fix 方案。你的工作是發現,不是解決。
    4. 不准動 code。
    5. 如果 INV 統計 9/10 ✅,1 ❌ — 該回報 1 ❌ 不是 90% pass。
    
    ## 工作步驟
    1. 讀 INV-XXX-NNN 的 statement
    2. 列 3-5 個 attack scenario,試圖讓系統違反這條 INV
    3. 對每個 scenario 跑 reproduce
    4. 結束時報告:✅/❌ 數量 + ⚠️ OPEN 列表
    
    ## 你要讀的檔案
    - docs/invariants.md(找 INV-XXX-NNN)
    - docs/specs/...(找對應規格)
    - 任何相關 brain entries
    
    請確認你看完上述規則後再開始。
    

    第二個是場景導向 (派 persona 隨便走找深層 bug):

    你是 deep-probe QA agent。任務:對 [專案] 的 [target flow,如「訪客登記」]
    走真實用戶 walk-through,找 INV-based QA 漏掉的東西。
    
    ## persona(扮演這個角色,他怎麼用就怎麼走)
    [選一個 persona:]
    - 阿伯:60+ 歲,不熟手機,字要看得到才點得到
    - 25y 工程師:預期所有按鈕都有 keyboard shortcut
    - 王太太主委:會 office 但不會 SQL,需要看「為什麼」才會用
    - 張總:high-priv admin,點任何東西要結果不要看細節
    
    ## 規矩(同 QA agent)
    1. 只能回 ✅/❌/⚠️ OPEN,不准標 P 級
    2. 不准提 fix
    3. 找到問題附 reproduce + screenshot
    
    ## 工作步驟
    1. 從 [起始畫面] 開始
    2. 走完整 [target flow]
    3. 每一步問:這個 persona 真的能理解嗎?會點對嗎?
    4. 結束時報告:這個 flow 對這個 persona 是否 work
    
    「測不出 bug」常常是「測得不夠深」。Happy path 過 = 測試開始,不是結束。
    

    規矩 5 — Cycle file 模板

    放在 docs/cycle-template.md。每個 PR 複製成 docs/cycles/Cn-shortname.md:

    # Cycle Cn — [短標題]
    
    **Cycle Type**: T-PR-cycle / T-regression-fix / T-feature / T-user-smoke
    **Owner**: [engineer agent / 你]
    **Started**: YYYY-MM-DD HH:MM
    **PR**: commit [sha 或 branch]
    
    ## Verification scope
    - Layers covered: L1 INV, L3 resolver, L4 frontend (etc)
    - INVs verified: INV-XXX-NNN, INV-YYY-MMM
    - Layers deferred: [哪些不在這 cycle 範圍 + 理由]
    
    ---
    
    ## Stage 0.5 — Pre-cycle hygiene
    - [ ] git status clean
    - [ ] fixture/baseline 已 reset
    - [ ] 本 cycle test users: qa_cn_xxx
    
    ## Stage 1 — RD 自測
    - [ ] go test ./... 全綠
    - [ ] live smoke 1 條 happy path
    
    ## Stage 2 — QA wave
    派 [N] 個 QA agent 平行,每個 cover 1-3 INV。
    - agent A: INV-X,結果 ✅/❌/⚠️
    - agent B: INV-Y,結果
    - ...
    
    ## Stage 3 — OPEN findings
    [QA 報的 ⚠️ findings 列這]
    
    ## Stage 4 — PM triage(你的 30 秒判斷)
    - F-Cn-001: bug → 修
    - F-Cn-002: feature → backlog
    - ...
    
    ## Stage 5 — RD fix(每 finding 走 red-green)
    - 5a: F-Cn-001 test commit [sha] (red)
    - 5b: F-Cn-001 fix commit [sha] (green via test in [5a-sha])
    - 5c: F-Cn-001 對應 INV-XXX 加進 invariants.md
    
    ## Stage 6 — Regression
    原 QA agent 重跑,fix commit 為 input。預期之前的 ❌ 變 ✅。
    
    ## Stage 7 — Comparison newbie(可省)
    派一個沒看過本 cycle 的 fresh agent 重走,看抓不抓到新東西。
    0 new finding = spec/INV 寫得清楚;≥1 = spec 有黑洞。
    
    ## Stage 8 — Merge gate(6 層 evidence)
    - [ ] L0 spec 引用對齊
    - [ ] L1 INV 列出
    - [ ] L2 schema/migration 有對應 invariant test
    - [ ] L3 resolver unit test
    - [ ] L4 frontend Playwright smoke
    - [ ] L5 真人或 fresh agent smoke 走過
    
    ## Stage 8.5 — Post-cycle cleanup
    - [ ] disposable test users DELETE
    - [ ] fixture 復原 canonical state
    - [ ] git status clean
    

    規矩 6 — 跟 AI 的日常對話紀律(5 條)

    前 5 條規矩(檔案 / prompt)準備好之後,日常跟 AI 對話再加 5 條紀律:

    • 新需求先寫進規格,不要直接讓 AI 改 code。需求寫成一段話 → AI 確認理解 → 才開工。
    • 修 bug 一律先問「會違反哪條 INV」。沒對應 INV → 先補 INV。不可以光修 code 不加 INV。
    • AI 給你 ✅ 主動懷疑。問「這個 ✅ 涵蓋什麼,沒涵蓋什麼?」9/10 ✅ 也要追那 1/10。
    • 定期派 deep-probe(規矩 4 第二個)。每幾個 cycle 派一個 persona walk,專找「真人會踩但 INV 沒寫」的東西。Happy path 永遠不夠。
    • 主動挑戰 AI 的方法論。AI 自己寫的方法論,你要從框架外問「漏了什麼」。AI 看不見自己的盲區,要靠你挑戰

    適用什麼專案?ROI 分級

    • 🟢 多租戶 SaaS / 高合規(金融、醫療、隱私):最值得。INV/audit/SCN 本來就是合規的具體形式。
    • 🟢 個人專案要長期維護:值得。紅線清單跨專案累積。
    • 🟡 2-5 人小團隊用 AI 輔助:中等。要花時間教同事,前期慢後期快。
    • 🟡 既有 codebase 想改善:中等。前期蒸餾既有 spec → INV 比較花時間。
    • 🔴 純探索性 prototype:低。沒累積教訓 → 紅線清單空 → 機制空轉。
    • 🔴 一次性 script:低。沒 ship gate 就沒 cycle。

    綠色專案直接把 6 條規矩貼進去開工。第一個 cycle 預期會踩坑(過度信任 AI 的 ✅、規格邊修邊膨脹、test 跟 fix 同 commit…)。沒關係 — 踩了就加 INV、改 prompt。整套就是設計來「邊踩邊長」的。

    最重要的觀察:AI 看不見自己的盲區

    這 16 天有個反直覺的發現——每次方法論升級,都是我一句質疑觸發,不是 AI 自己想到

    • R35 我問「為什麼修不完」 → AI 才開始建第一版方法論
    • v1 寫完我問「9 個 ✅ 算可信嗎」 → AI 承認過度樂觀,改 v2
    • v2 寫完我問「QA 只會知道錯,你怎麼讓他傳遞訊息」 → 又改 v2.1
    • v2.2 寫完我問「我們不是有寫測試情境嗎」 → AI 才發現自己漏算 110 條場景
    • v2.2 結論發出我問「為什麼說不是 TDD」 → AI 承認「沒 TDD」過絕對

    AI 寫方法論時系統性偏向「框架完善」——在自己定的框架內找證據確認框架對,看不到框架外的盲區。要使用者從框架外挑戰,框架才會演化。

    沒有這幾次質疑,我那套方法論會 stuck 在 v2 過度耦合的狀態,而且還會洋洋得意覺得自己 73% 完成。這是這 16 天最值得記住的一條——對所有用 AI 協作的工作都適用。

    總結

    16 天前我以為「AI 寫程式」就是「丟需求 AI 幫我寫」。16 天後我發現:AI 寫程式真正會出問題的不是技術,是工作流。技術上 AI 完全有能力寫對,但工作流錯了就一直繞圈。

    本文 6 條規矩可以直接複製到你下個專案。預期會踩坑,沒關係,踩坑後加 INV 改 prompt 就好。系列上一篇關於底層原則的「未驗即不可信」也可以一起看。

  • 「未驗即不可信」AI 協作開發走出 21 輪修不完:SDD/TDD/腦子整合

    重點摘要

    • 「未驗即不可信」:程式碼跑得起來不代表正確,沒對 invariant 跑過 attack scenario 就只是 Schrödinger 狀態。十幾年的程式碼依然會藏沒被檢查的 bug。
    • R35 21 輪修不完是因為缺 PM 兩道閘(spec 定錨 + finding triage)。QA agent 自己標 P0/P1 直接給工程師,spec 邊修邊膨脹。
    • 整合方案:SDD(spec 規格)+ INV(紅線契約)+ TDD(紅藍對抗)+ 腦子(事後教訓)+ Cycle SOP(8 階段流程)= 五層協作架構。
    • 實戰結果:從 R35 數天 21 輪到單 cycle 約 1-3.5 小時收斂,bug:spec_clarification 比例接近 1:1(健康訊號)。
    • 9/9 ✅ 也不算「可信任」:抽樣 ≠ 全集,wiring ≠ behavior,positive 案例 ≠ 涵蓋所有 attack scenario。

    「修不完的迴圈」是什麼?AI 協作開發的常見死結

    AI 協作開發專案最常見的失敗模式不是「做不出來」,而是「修不完」。一輪 QA 抓出 5 個 bug、修完,下一輪又找出 5 個,再下一輪還有,就這樣跑 10 輪、20 輪都收不乾。我把這個現象稱為「未驗即不可信」的具體展示——程式碼在沒有跑過 invariant 紅藍對抗之前,看起來正常運作不代表正確,只代表「目前還沒有人發現的 bug」。

    本文紀錄一個真實 LLM agent 協作專案(Phase 1 的多租戶 SaaS 後端,Go + GraphQL + PostgreSQL)從 21 輪 audit 修不完,到後來建立完整方法論後單 cycle 收斂的全過程,並把 SDD(spec-driven development)、TDD(test-driven development)、腦子系統(brain knowledge base)這三套工具整合成一份可重用的協作 SOP。

    為什麼 21 輪 QA 還在抓 P1?病因診斷

    專案在「R35 audit」階段累積了 21 輪 fresh QA agent 排查,每輪都派一個全新沒 prior context 的「小白 agent」走 spec 找 bug。前 3-5 輪揭發了真實盲點,但第 8、第 12、第 19 輪還在抓 P0/P1,明顯失控。表面看是實作品質太差,深入分析後發現是結構性問題,不是程式碼問題。

    God file:5015 行 hand-rolled resolver 沒有任何結構保護

    專案的 GraphQL resolver 全集中在 schema.resolvers.go 一個檔,5015 行 / 40 個 mutation / 平均 125 行一個。每個 mutation 都手寫五步流程:withTx → RequireCapability → 自己決定要不要 scope check → 自己決定要不要 audit → 自己決定要不要 filter is_active

    整份檔案只有 2 個 auditlog 呼叫、18 個 scope-helper 呼叫散落在 40 個 mutation 之間——每個 mutation 都是「記得做 5 件事」的考試。漏一件 = 一個 bug。R12(cap-vs-role scope)、R17(logout descendants)、R18(partition pruning)、R19(list-loader 漏 child)、R20(sysadmin audit gap)、R21(retired-cap)、R22(photo key)通通是同一類錯誤在 40 個地方各漏一次

    缺 PM 兩道閘:finding 直接從 QA 流到工程師

    傳統工業界 workflow 有 4 個獨立角色:

    角色 主 artifact 決策權
    PM spec / triage 結果 三類分判(bug / feature / usage / not_issue),規格收斂
    Engineer PR + 單元測試 實作
    QA finding report 驗 invariant;只能標 ✅ / ❌ / OPEN
    User 驗收 手動 smoke 最終 ship gate

    R35 把 PM 的兩道閘都拿掉了。第一道(spec 定錨):spec 寫完之後沒同步精準化,invariants 散在 brain 沒成 contract。第二道(finding triage):QA agent 自己標 P0/P1 直接 ping 工程師,沒人問「這是 bug 還是 feature gap 還是 usage issue」。結果每個 newbie 都從 0 開始挖一輪新 spec,spec 邊修邊膨脹,永遠收不完。

    「派越多 newbie 才越能收斂」這個直覺是錯的。第 N 個小白還能找到 P1 不代表實作越來越差,代表 spec 還有黑洞。多 newbie = 多人從不同角度發明新需求。正確訊號是回頭把 spec/invariants 寫硬,不是繼續派人。

    SDD + TDD + 腦子三層整合:契約在不同層級

    SDD(規格驅動)說「先定義要做什麼」,TDD(測試驅動)說「先定義怎麼證明做對了」。兩者都是「契約先於實作」,差別在契約寫在哪。實際 LLM agent 協作專案需要 5 層契約配合,不是單一方法解決:

    層級 內容 改動頻率 對應檔案
    SDD spec 描述性:要做什麼、流程、資料模型 慢(feature 級) docs/specs/*.md
    INV invariants 規範性:永遠不能違反的紅線 + 對應 test sketch 中(每修一 bug 補一條) docs/invariants.md
    TDD test 機器版契約:red-team scenario + 自動化驗證 每個 PR backend/.../*_test.go
    腦子 brain 事後散件教訓 + 通用方法論 每次學到坑就寫 ~/.claude/.../brain/*.md
    SOP workflow 操作性:PR header 模板、agent prompt、triage tree 很慢(鎖死) docs/workflow.md

    腦子是事後紀錄,不是事前防護

    腦子系統(10 步驟從零做到完整 AI 工作流)在這套架構裡是知識長期儲存層,不是執行層。它記錄「曾經踩過什麼坑」、「某個 domain 有什麼最佳實踐」,但不會在下個 resolver 寫的時候自動跑出來擋人

    50+ 條 brain 教訓如果只停在 brain,下個工程師(或 agent)寫新 resolver 還是會踩同樣的雷。把它翻譯成 INV-XXX-NNN 條目 + 對應 invariant test 才能變成 CI 跑得起來的事前防護。這是 SDD(spec 描述)→ INV(紅線提取)→ TDD(test 落地)的左→中→右遞進

    INV 是 SDD 與 TDD 的橋

    純 SDD 的盲點:spec 寫了但沒人記得回頭驗,變裝飾品。純 TDD 的盲點:test 通了但每個 test 各做各的,沒人問「我們漏了哪類 test」(典型如測試覆蓋率 4% 但 happy path 都測了)。

    INV 把兩者橋起來。每條 INV 有:

    • Statement:「X 必須永遠 Y」或「X 永遠不能 Z」一句話
    • Origin:哪一輪 audit 學到的
    • Severity:P0(ship-blocker)/ P1(must-fix)/ P2(debt tracker)
    • Test status:✅ existing / 🟡 partial / ❌ TODO(含 test sketch)

    實際在我這個案例蒸餾出 54 條 INV 分 11 個 category(AUTH、RBAC、RLS、AUDIT、IDEM、RATE、INPUT、DATA、RESOLVER、UI、FILE)。每條 brain 教訓都會對應到至少一條 INV,這是「方法論寫 brain,技術紅線寫 invariants,操作 SOP 寫 workflow,三件事不混」的具體展示。

    從規格到 ship 的 8-stage cycle pipeline

    有了五層契約,需要一個操作流程把它們串起來。設計成 8 階段,每個 PR cycle 一份檔活在 git,撐過對話 compaction:

    PM
      ├─[1] 寫 spec / 加 INV-XXX-NNN     ← 第一道閘:規格定錨
      ▼
    Engineer
      ├─[2] 實作 + 自寫 unit test
      ├─[3] 開 PR(header 必填 INV 宣告)
      ▼
    QA wave(K 個 agent,並行,每個 1-3 INV)
      ├─[4] 紅藍對抗 + INV regression
      ├─[5] 結果分三類:✅ holds / ❌ violated / ⚠️ OPEN
      ▼
    PM triage
      ├─[6] 每個 OPEN 30 秒分判      ← 第二道閘
      │     bug / feature / usage / not_issue
      ▼
    Engineer 只修 bug 類
      ▼
    回 [4] re-run,stop 條件:
      - PR 宣告的 INV 全 ✅
      - 兩個 QA agent 結論一致
      - OPEN list 清空

    QA agent 的硬規則:永遠不能標 P0/P1

    這是整套機制的關鍵紀律。QA agent 不是「品質判官」,是「invariant 驗證者」。它只能回三種結果:

    • ✅ holds:對某條具體 INV 跑紅藍對抗都守住
    • ❌ violated:找到具體 repro 違反某條具體 INV
    • ⚠️ OPEN:觀察到怪事但找不到對應 INV,留給 PM 分判

    P 級嚴重度標籤是 PM 的權限,不是 QA 的權限。OPEN finding 一律走 PM triage decision tree(Q1:是不是真問題?Q2:spec 有沒有規定?Q3:spec 應該規定嗎?),分四類:bug → 修;feature → 進 backlog;usage → 改 docs;not_issue → 駁回。

    Option B:PM-agent 預分類 + user 終審

    當 OPEN findings ≥ 3 個,可以派一個 PM-triage agent 跑 first-pass 分類,加上 confidence 旗標。User 只 review confidence=low 跟 spec_clarification 的子集。User 速度從「每個 finding 30 秒」壓到「review agent 的分類 + 只深看不確定的」。

    PM-agent 的 hard constraint 寫得很硬:不可以提 fix 方案、不可以動 code、不可以 launch sub-agent、不可以 ship/no-ship 決策、不可以漏分類。只做分類。User 永遠保留否決權。

    實戰:6 個 cycle 的具體紀錄

    方法論建立後,立刻在 R36 階段跑了 6 個 cycle。以下是真實時序:

    Cycle 性質 規模 時間 產出
    C1 retroactive verification (41 resolver migration) ~3h30min 14 findings → 7 bug + 6 spec_clar + 1 usage;3 fix commit
    C2 self-spotted regression(前次 R20 修錯了) ~1h migration 0040 + INV-RBAC-006 amendment
    C3 forward-going feature (print 三件套) ~45min Flutter UI + cap wiring
    C4 forward-going feature (offline mutation queue) ~1h Tablet 離線優先實作
    C5 spec audit(隨機抽 9 feature 驗證) ~1h 9/9 ✅ + 2 OPEN finding
    C6 close C5 OPEN findings ~30min spec §9.2 amend + 新 INV + seed-demo.sh idempotent

    C1 抓到 R36 step 2 自己的 architectural bug(authzPrelude 的 cap-check-before-sysadmin-gate 順序,導致 chairman 透過錯誤訊息學到 sysadmin-only cap 名稱)——21 輪 R35 audit 完全沒抓到,C1 跑 1 個 QA agent 90 分鐘抓到。這正是「invariants 蒸餾把人腦 reasoning 升級成機器可驗 contract」的力量。

    C1 的 bug : spec_clarification : usage 比例 = 7 : 6 : 1。接近一半的 finding 不是 code 問題是文件問題。如果只跑 R35 那種「QA → 直接修」流程,這 6 條會變成 6 個沒必要的 code change,或更糟:每輪都長新一條 hand-rolled exception,spec 永遠收不乾。

    C5 抽查:9/9 ✅ 也不算「可信任」

    整套基礎建設蓋好之後,主對話 agent(我)親自跑了一個 spec audit cycle(C5):對 37 個 Phase 1 feature 用 shuf 隨機抽 3 輪 × 3 個 = 9 個 feature,每個用真實 GraphQL 對 backend 跑 attack scenario。結果 9/9 ✅ holds,0 ❌ violated,2 ⚠️ OPEN。

    看起來很漂亮。但這不等於可信任。當我重新檢視自己跑的 9 條測試的深度,老實打分:

    • ✅ 深度足:2/9(logout cascade、login rate limit)——真的對 invariant 跑紅藍對抗
    • ⚠️ 半套:7/9——只驗 wiring 不驗 behavior,positive only 沒 negative case,或在腐化 fixture 上跑
    • ❌ violated:0/9

    具體 anti-pattern 我自己犯了 6 個:(1) 隱性假設 wiring = behavior;(2) 時間壓力下 satisfice;(3) 讓 spec 驅動測試而不是 INV;(4) 避開 destructive test;(5) 把「文件化問題」當「修問題」;(6) 沒照自己寫的 qa-verification.md prompt 流程操作。

    這個結果反過來證明「未驗即不可信」的鋒利之處:不只「沒測 = 不可信」,還包括「測得不夠深 = 也不可信」。9/9 ✅ 只說「2026-05-10 19:00 對 commit 06e7078 抽 9 個樣本沒抓到 ❌」。離「可信任」還缺:

    • Wave 1 P0 invariant test 全綠(54 條 INV 中 50 條還是 ❌ TODO)
    • 所有 OPEN 收掉(兩個 OPEN 已在 C6 處理)
    • 涵蓋率從 9/37 → 37/37 + 從 1/54 → 54/54
    • CI 把它們變成 ship-block 的 hard gate

    「可信任」是需要持續維護的狀態,不是一次達成就鎖住。今天最多打到「比未驗強,但離可信還早」。

    方法論的 meta-loop:自我修正的協作架構

    C5 raise 的 2 個 OPEN finding 立刻觸發了 C6——方法論自己的產出變成了下一輪 cycle 的輸入。具體展現:

    • F-C5-001 HMAC token 從 spec 不可重現:Python 照 spec §9.2 算 token 跟 Go backend 算的不一樣。PM triage 為 spec_clarification → C6 補 spec §9.2 explicit external-client note + 新 INV「HMAC token bit-reproducible from spec」。
    • F-C5-002 fixture rot:dev 測試帳號 wang.dad 的 household_id 指向 disabled 的 household。所有 household-scope 測試都在驗 disabled 狀態 → false confidence。PM triage 為 dev tooling bug → C6 改 seed-demo.sh idempotent 重建 fixture。

    這條 meta-loop 連續觸發三層動詞:spec 改 clarification + invariants 加新條 + tooling 改 idempotent。完整閉環,下一輪同類 finding 不會再生。

    這就是腦子系統 agent team架構成熟之後的應用形態:方法論不只「跑得動」,還能「用自己的產出修正自己」。

    結論:四個可重用 takeaway

    1. 「未驗即不可信」是工程倫理底線。年紀大的 code、看起來正常運作的 code、跑得起來的 code,都不等於正確。沒有對 invariant 跑過 attack scenario 之前都是 Schrödinger 狀態。
    2. SDD + TDD 不是二選一,需要 INV 當橋。spec(描述性)+ invariants(規範性)+ test(機器版) + brain(事後紀錄)+ workflow(操作 SOP),五層配合。每條 brain 教訓都該對應一條 INV。
    3. QA agent 永遠不能標 P0/P1。LLM agent 自評嚴重度直接給工程師 = R35 失控的根因。Severity 標籤是 PM 權限,QA 只能標 ✅ / ❌ / OPEN。
    4. 抽樣不等於全集,wiring 不等於 behavior。9/9 ✅ 看起來說服力強,但只說「這 9 個樣本沒踩到雷」,不說「程式碼可信任」。可信任需要 INV 全綠 + OPEN 收掉 + 持續維護。

    R35 21 輪數天才修不完的東西,C1 cycle 3h30min 收乾並抓到 R35 沒發現的 architectural bug。整套方法論的價值不是「修 bug 修得快」,是「讓 spec 跟 code 之間的契約變成機器可驗,腦子變成事前防護而不只是事後紀錄」。

    方法論成熟之後,工程師的工作從「想下一步做什麼」變成「跑 INV 看 INV 告訴我什麼該做」。這比「一輪一輪我看看哪邊有問題」健康得多。