如何建造自己的多 Agent 開發系統
不用資料庫, 不用 WebSocket, 只用 SPEC.md + Hooks + Settings 就能協調多個 AI agent 並行開發。從一個人坐在電腦前盯 Claude Code, 到手機上看進度發指令。
我用檔案和 Shell Script 搭了一套 AI 多 Agent 開發系統
我讓 Claude Code 幫我寫程式已經好一陣子了。 一開始的體驗是: 它很會寫 code, 但完全不聽話。
你跟它說「不要改這個檔案」, 它改了。跟它說「先寫測試」, 它直接寫實作。跟它說「這個功能不要做」, 它順手就做了。規則寫在 CLAUDE.md 裡, 遵守率大概六成, 跟沒寫差不多。
這讓我開始想一個問題: 控制 AI agent 的正確方式到底是什麼? 這也是最近很紅的, Harness Engineering (雖然現在 Managed Agents 出來有人說這個東西也不用再深造了QQ)
第一個發現: 文字規則不夠, 要分層
我花了很多時間測試不同的控制方式, 最後得到一個結論 — AI 的遵守率跟你用什麼機制成正比:
| 控制層 | 遵守率 | 機制 |
|---|---|---|
CLAUDE.md 文字規則 | ~60% | AI 讀了, 但會「合理判斷」跳過 |
| Hooks (Shell Script) | ~95% | 每次操作自動觸發, AI 無法繞過 |
| Settings (權限系統) | ~100% | deny 直接擋, ask 要人類確認 |
這不是理論, 是實測的數字。寫「不要 push」在 CLAUDE.md 裡, 它偶爾還是會 push。但你把 git push* 放進 settings 的 deny 清單, 它連試都不會試。
所以我的設計原則變成: 能用 Settings 擋的不寫 Hooks, 能用 Hooks 做的不寫 CLAUDE.md。 文字規則只留給需要 AI 判斷力的事情, 比如「這個方案有結構性風險 → 暫停」。
系統架構: 四層
這個系統為什麼叫 Harness, 意思是「韁繩」— 不是限制 AI, 而是引導它往對的方向跑。零基礎設施, 不用資料庫, 不用 WebSocket, 全部靠 Claude Code 原生的檔案 + Hooks + Settings。
Layer 1: Settings (permissions) ← 100% 遵守, 硬擋
Layer 2: Hooks (shell scripts) ← 95% 遵守, 自動觸發
Layer 3: CLAUDE.md (instructions) ← 60% 遵守, 需要判斷力
Layer 4: Skills (reusable prompts) ← 按需載入, 專業知識
Layer 1: Settings — 權限邊界
~/.claude/settings.json 裡的三個清單:
deny: 絕對不能做的事。rm -rf,git reset --hard,npm publish,gh pr create。AI 不會嘗試, 連建議都不會。ask: 需要人類確認的。git push,npm install, 修改CLAUDE.md或 linter config。AI 會做, 但要你按 Enter。allow: 放行的。Bash(*),Read(*),Edit(*)等日常操作。
這一層的邏輯很單純: 把不可逆的操作攔住。AI 可以在本地隨便搞, 但不能影響遠端。
Layer 2: Hooks — 自動化守衛
這是整個系統最有價值的一層。Claude Code 支援五種 hook 時機, 我每個都用上了:
UserPromptSubmit — 你每次打字, 在 AI 看到之前先跑:
inject-context.sh: 自動注入當前任務狀態[SPEC], tech stack[TECH], Contract 摘要, agent 角色過濾。AI 不用去讀 SPEC, hook 把關鍵資訊塞進來。
PostToolUse — AI 每次改檔案之後:
validate-docs.sh: 檢查 SPEC.md 的任務狀態是否合法, Contract 變更偵測, DECISION.md 矛盾偵測, 完成時自動 review。check-diff-size.sh: 改動超過 100 行提醒, 超過 300 行警告。偵測 stub(空殼檔案)和 secret 洩漏。
PreCompact — context 快滿要壓縮之前:
pre-compact.sh: 強制把未記錄的技術決策寫進 DECISION.md, 做 pattern 回顧。這個 hook 是 blocking 的, 不寫完不讓 compact。
Stop — session 結束時:
session-retro.sh: 每 25 則訊息觸發一次回顧, 分析重複改的檔案, 建議新的 DECISION 或 skill。
每個 hook 都是普通的 bash script, 用 grep, awk, python3 解析檔案, 然後把結果 echo 給 AI 看。沒有任何外部依賴。
Layer 3: CLAUDE.md — 思維框架
文字規則留給需要判斷力的事:
- 遞迴思維: 不是列清單然後照做, 而是「從已知知識長出方案 → 驗證假設 → 發現矛盾就修正 → 重複直到收斂」。
- PAUSE 條件: 遇到歧義, 矛盾, 結構性風險 → 停下來問人類, 不要猜。
- 分層驗證: Unit → Integration → System, 每層確認邏輯對了才往上。
- 禁止行為: 不主動 push, 不修鄰近問題, 改動前先看 git log。
這些規則有 60% 的遵守率, 但這 60% 剛好是需要它的場景 — 它不一定每次都停下來, 但在真正危險的時刻, 它停下來的機率比沒寫高很多。
Layer 4: Skills — 可重用的專業知識
Skills 是 Claude Code 的 reusable prompt 機制。我寫了兩個核心 skill:
/project-init: 初始化專案的三份文件(SPEC.md, DECISION.md, CLAUDE.md)。三種模式: 新專案, 既有專案, 審計模式。包含三層遞迴質疑的規劃方法。/graphify: 把 codebase 變成知識圖譜。AI 在開發前先讀圖譜理解架構, 避免重複造輪子。
SPEC: 一個檔案搞定協調
SPEC.md 是整個系統的核心。它不只是需求文件, 它同時是:
- 任務定義: 功能群組(F001, F002...), 每個群組有 Contract, 驗收條件, 任務清單
- 協調機制: 任務有七種狀態(
[ ]todo,[>]active,[?]review,[!]blocked,[x]done,[✗]failed,[-]shelved) - 進度報告: hook 自動注入當前進度「驗收: 4/10 完成, 任務: 9/9 完成」
- 人類介面: 要加任務? 改 SPEC。要 assign? 加
assign: backend。要暫停? 標[!]
Contract 是功能群組之間的介面定義:
### Contract
- GET /api/projects → { projects: [{ name, spec_status, last_event_ts }] }
- error: 500 projects_dir not readable
- timeout: server 30s, client 10s + retry 3 次
有了 Contract, 前後端可以並行開發。Worker agent 讀到 Contract 就知道 input/output 格式, 不需要等另一個 agent 做完。
多 Agent 協作: Orchestrator + Worker
系統支援兩種角色:
Orchestrator(沒有 AGENT_ROLE):
- 讀 SPEC → 判斷複雜度
- 簡單任務自己做
- 可並行的任務 → spawn workers, 每個在獨立的 git worktree 裡
- 全部完成 → merge branches → 處理 Contract 變更 → integration 驗證
Worker(有 AGENT_ROLE):
- 讀 SPEC → 找自己 assign 的
[ ]任務 - Claim: 標
[>]+@角色+ 時間戳 - 開 branch → 按 Contract 開發
- 完成 → 標
[x]+ 寫 Log(包含踩坑記錄)
Spawn 的寫法:
Agent({
description: "F001-T01: Express server",
isolation: "worktree",
subagent_type: "Backend Architect",
run_in_background: true,
prompt: "讀 SPEC.md 的 F001-T01。按 Contract 開發。user input 假設有惡意。"
})
每個 worker 在獨立的 worktree 裡, 有自己的 branch, 不會互相干擾。subagent_type 從 200+ 種 agent 類型中選最匹配的 — Backend Architect 做 API, Frontend Developer 做 UI, Security Engineer 做安全審計。
Contract 變更的處理很關鍵: Worker 不能改 SPEC 的 Contract, 只能在 Log 裡記建議。Orchestrator merge 時讀 Log, 合理就更新 Contract, 不合理就通知改回。這避免了多個 agent 同時改 Contract 造成的衝突。
規劃: 三層遞迴質疑
這是我對 AI 規劃品質最不滿意的地方, 也是花最多時間設計的。
AI 的預設規劃模式是: 聽到需求 → 立刻拆任務 → 開始做。結果經常是功能之間的 Data Flow 不通, 或是遺漏了基礎設施依賴。
我的方法是三層遞迴, 每一層質疑通過才進下一層:
- 整體層: 所有功能加在一起能實現產品目標嗎? 有沒有漏的? 有沒有多餘的?
- 跨功能層: A 的 output type 和 B 的 input type 一致嗎? Data Flow 端到端通嗎?
- 單功能層: Contract 定義清楚嗎? 驗收條件有明確的驗證方式嗎? 任務依賴標完整了嗎?
整體不對 → 重新拆功能。跨功能不通 → 修 Contract。這個過程是遞迴的, 不是線性的。
輔助工具
Graphify — 知識圖譜
在複雜專案開始前, 我會跑 /graphify . 把 codebase 變成知識圖譜。輸出包含:
- God nodes: 被最多模組依賴的核心節點
- Communities: 自動偵測的功能群組
- Interactive HTML: 可視化的圖譜
AI 開發前先讀 GRAPH_REPORT.md 的 god nodes 和 community 結構, 改 code 時就知道影響範圍, 不會亂改到核心模組。
Git Dashboard
Terminal TUI, 一眼看所有 repo 的狀態。我加了 Pipeline bar(顯示 SPEC 的 F 群組進度)和 Agents bar(顯示 agent 狀態)。
Harness Events (harness.jsonl)
所有 hook 事件寫入 ~/.claude/harness.jsonl, 結構化 JSON。包含 session_start, task_complete, contract_changed, hook_error 等事件。這個 log 餵給 dashboard 和 iOS app 做即時監控。
實戰: 用這套系統開發一個 iOS App
為了驗證系統, 我用它開發了 harness-app — 一個讓我在手機上監控 Claude Code 開發進度的 iOS app。
SPEC 定了三個功能群組:
- F001: Express server(5 個 API endpoint, 讀 harness.jsonl + SPEC.md)
- F002: iOS Dashboard(SwiftUI, 5 秒 polling, 顯示專案進度和 agent 狀態)
- F003: iOS Log & Commands(事件 timeline + 遠端指令)
9 個任務, 多個 agent 並行, 一個 session 內全部完成。過程中發現了幾個系統問題:
- SPEC Review 沒 spawn agent: AI 自己 review 自己寫的 SPEC, 當然沒問題。修正: 強制 spawn domain agent 來 review。
- 基礎設施依賴遺漏: T02/T03 標「可並行」, 但它們需要 T01 建的
package.json。修正: 依賴欄位加 infrastructure 類型。 - Path traversal 漏洞: 所有 API route 都用未驗證的
req.params.name拼路徑。被 Code Reviewer agent 抓到。修正: 加resolveProjectDir()驗證。
每個問題都回饋到系統規則裡, 讓下次不會再犯。這就是這套系統的自我迭代循環。
缺點和限制
我不打算假裝這套系統完美。幾個明顯的問題:
- Token 消耗大: 每次 API call 都送完整 context。Context 越大, 每條訊息越貴 (實際還在測試中)。
- Hook 錯誤處理不夠: hook 報錯時只寫 log, 不會主動通知。有時候背景 session 的 hook 一直報錯, 你不看 log 就不知道。
- CLAUDE.md 遵守率: 60% 聽起來不多, 但這就是文字規則的天花板。真正重要的規則必須用 hook 或 settings 強制。
從這套系統學到的事
寫完這套系統之後, 我對「如何跟 AI 協作」的理解完全不一樣了。
最大的認知轉變是: 不要嘗試用語言控制 AI 的行為, 要用機制。 就像你不會用備忘錄管理團隊的 git 權限一樣, 你應該直接設定權限系統。
第二個是: SPEC 不只是文件, 它是協調協議。 當你有多個 agent 並行工作, 它們之間的通訊不需要任何特殊機制 — 讀同一個 SPEC, 按同一個 Contract, 寫同一份 Log。檔案就是最好的通訊協議。
第三個是: AI 的規劃能力需要結構化的約束。 你不能說「好好規劃」然後期望它做得好。你要告訴它先驗證整體, 再驗證跨功能, 最後驗證單功能, 而且每一層不通過就不能進下一層。
這套系統不完美, 但它確實讓我從「坐在電腦前盯著 AI 寫每一行 code」變成「在手機上看進度, 偶爾發個指令」。這個轉變值得那些 shell script。
這次只談了方法, 下次我們再來談談 Harness Engineering 實際要做的東西和架構方向
