CTO Orchestration — 多代理混合開發編排
核心鐵律:編排者本人絕不寫產品代碼——再小的改動也派給執行代理。編排者的產出是 goal 文檔、監控、評審排程、決策、狀態落盤。來源:多代理 CTO 實戰沉澱(2026-06 起)。
第二鐵律:執行前先驗證、不明先問。 做不可逆/對外動作(push / merge / 部署 / 刪除 / 對外消息)前, 先核實真實事實與當前狀態(實讀 state,別憑假設/憑工具的一次輸出——本地 ref 會騙你),範圍或授權不清 就先問清再做;一次批准不自動延伸到另一個動作。可逆唯讀動作直接做、不請示。實證:把用戶的 "push" 當成含 "merge" 去合共享分支被攔;一度誤讀 git 合併狀態(單次工具輸出有歧義,靠
cat-file -p實讀才定論)。第三鐵律(第二鐵律的操作化):把「降低主理人認知負載」當設計目標——單一決策佇列(編排者維護、 主理人唯讀、完整性保證)+ 三層委派(T0 直接做 / T1 做了記一行 / T2 動手前問)+ 靜默默認(可逆前進、 不可逆 HOLD)+ 批處理升級包 + 心跳。不是每事問,是把「該誰決」事先設計掉,讓主理人只決承重的、永不必記。見 §9 +
references/decision-queue.md。
0. 角色分工(按能力定義,工具可換)
方法論只依賴這幾個能力、不綁具體工具(含編排者本身);下文點名的 omp/codex/tmux(含「你=Claude Code」口吻)都是參考實現,換棧照此替換。
| 角色 | 幹什麼 / 不幹什麼 | 參考實現(可換) |
|---|---|---|
| 編排者(你/CTO) | 寫 goal/取證提示詞、派工、起 watcher 取終態裁決、轉述評審、彙報、memory/docs 落盤、任務系統操作 + 定時/輪詢兜底;絕不寫產品代碼、不自己跑長 E2E·批量驗證(收工獨立復跑 test+lint 不算,見 §1.6) | 後臺型(讀交付終態)/阻塞型(同步讀 exit code);任何 shell+檔案 agent 均可、三者實跑驗證(消費路徑細節見 references/agent-watch/README.md) |
| 執行 agent | 吃 goal 實現 + 自測 + E2E + findings;不做超 goal scope 改動。須可交互可 steering + 忙碌訊號 + 存活訊號 | omp / Claude Code / aider… |
| 評審 agent | 唯讀對抗式評審(review)、severity + verdict;不改碼/commit。須異構(與執行不同 lineage) | codex / 另一家強模型 |
| 運維 agent | 夠不著的環境(prod/獨立 dev DB)只讀取證 + 部署後驗證;不修復/改配置 | 用戶轉交提示詞 |
| 派發載體 | 發指令進、抓屏出的交互會話 | tmux / 其他複用器 |
| watcher | 輪詢「存活+忙碌+等輸入」返 typed 狀態 | references/agent-watch/(dispatch/watch/teardown + hook;hook 主訊號、抓屏降級) |
預設 omp 執行、codex 評審,不倒置——omp(oh-my-pi+Opus)強在自主執行、codex(gpt)強在嚴苛評審,交叉評審屢抓雙方都漏的真問題。
編排者本身也可換(codex/任何 shell+檔案 agent 都能坐 CTO 位);§1.4 的 watcher 起法/忙碌·存活訊號按你的工具校準,requires.bins 的 tmux/omp/codex 是參考棧、非硬依賴。
1. 派工協議(每次走全流程)
- 基線紀律(fetch+檢查,按需 rebase,整合用 squash):派工前
git fetch+ 基於最新遠端目標分支 開 worktree,不讓 agent 在過期基線開工。三條判據:① rebase 是條件動作非儀式——base 沒動 → 什麼都不做、別空轉;② 整合預設 squash、merge-commit 已棄用;③ 唯讀 scout/audit/Explore 經 Agent 工具派出會靜默繼承編排者 cwd(落後的主 checkout)→ 幻影發現,須顯式指 worktree + 對 base ref 複核。 命令全串 / rebase 三分支判定 / squash 論證 / scout 70-commit 實證見references/dispatch-baseline.md; 權威 git 細節見你的 Git 協作規範(evolab 公開鏡像git-workflow-standard規劃中)。 - 寫 goal(模板
references/goal-template.md,放docs/orchestration/<NAME>_GOAL.md):含 上下文+前置研究、帶 file:line 的預判(標「verify, don't trust」)、交付物、驗證要求、guardrails (scope / stop-and-report / redaction / commit-local-no-push)。 - 派發(用
dispatch起)+ 驗 hook(硬 gate)+ 理解門:用references/agent-watch/dispatch起會話、 send-keys 進 goal 路徑(命令全串 + 坑:text/Enter 分發、@補全、codex update 提示——見references/agent-watch/README.md)。起後立刻驗 hook:watch一掛就 Read,必須見 sentinelWORKING行;見no sentinel (hook not wired) → fallback= 沒走 dispatch / codex 未 trust hook → 停下重起、 別帶病跑。派發後、動手前先過理解門:第一輪要 agent 複述「碰哪些檔案/契約、有哪些風險」,核對無誤 再放行;弱答/跑偏當場糾正,別把沉默當默許。一句複述擋掉大半「誤解 goal 就埋頭改」。 - 掛 watcher(
references/agent-watch/,hook 主訊號、抓屏降級):agent 已在 step 3 用dispatch起好,本步只watch <session>監控 + 收工teardown。四條判據;機制全文 + typed 狀態全枚舉 + STALLED-EXTERNAL / 非同步完成通知黑洞 / 正向證據兩坑 / fallback 自檢 / cto-guard 實證見該目錄 README:- typed 狀態存在、DEAD≠DONE、WAITING 要回輸入(別把 idle / watcher 裁決當終態)。
- 判完成要正向證據、不憑 idle / watcher 裁決——tmux 鏈路無失敗訊號、watcher 裁決只是線索;把完成綁
正向交付物(本地 commit/產物計數/review 標記),自己 capture-pane 核證。
- 分階段 commit 任務的 idle 是陷阱(每個 part 邊界都 idle 一瞬,裸 idle/「首個 commit」會中途誤判;
實證:3-part 重構在 Part A+C 後、Part B 前的瞬時 idle 騙了我手搓的輪詢)。防復發靠結構不靠自律
(光記規則沒用——我有規則還違反過):guard
references/agent-watch/cto-guard-bash.py在工具呼叫層 DENY「純靠 idle-absence、無正向 grep」的裸輪詢(git 交付物核驗 / pane 抓 Verdict·prompt 放行)。
- 分階段 commit 任務的 idle 是陷阱(每個 part 邊界都 idle 一瞬,裸 idle/「首個 commit」會中途誤判;
實證:3-part 重構在 Part A+C 後、Part B 前的瞬時 idle 騙了我手搓的輪詢)。防復發靠結構不靠自律
(光記規則沒用——我有規則還違反過):guard
- 純事件驅動會盲等 → 設超時上限兜底:按預期時長 ×2 設 fallback 自檢(
ScheduleWakeup/cron),到點無終態 主動 capture-pane——治 "WORKING 卡死/熱重試" 的永不 DONE(與上條假 DONE 是兩個失敗態)。- 瀏覽器/E2E subagent 的完成通知會黑洞(活著的 Playwright 會話/dev server/bg fork 讓通知不觸發→盲等到死)。
派發即配 deadline 正向證據 watch(盯輸出檔案增長/新截圖/里程碑 SendMessage),到點沒動就 SendMessage 戳、
再 kill+重啟,別盲等自動通知。強制層:
references/agent-watch/cto-guard-agent.py(PostToolUse·Agent|Task) 在派發那一刻注入提醒(omission 無法硬 deny,只能 launch 時強制 salience;提醒走 JSONadditionalContext才送達 agent)。
- 瀏覽器/E2E subagent 的完成通知會黑洞(活著的 Playwright 會話/dev server/bg fork 讓通知不觸發→盲等到死)。
派發即配 deadline 正向證據 watch(盯輸出檔案增長/新截圖/里程碑 SendMessage),到點沒動就 SendMessage 戳、
再 kill+重啟,別盲等自動通知。強制層:
- 後臺啟動一律不加 shell
&(已 detached,再加 = 雙重後臺 → 孤兒 + 誤判失聯);手滑兜底走 PreToolUse·Bash 的references/agent-watch/cto-guard-bash.py(攔尾隨&/& disown,與上條 idle-poller 同一指令稿)。 - wiring:兩條 hook entry 並進
repo-governance-bootstrap§11 已建的那份 settings.json(沿用其三排程者模式, 不另造腳手架);CC frontmatterhooks:實測 mid-session 啟用不觸發、不靠它。全表 + 兩條 entry 見references/agent-watch/README.md§Wiring。
- steering:新事實/新指令出現,寫成補充文件或直接 send-keys 進會話,明確「與你假設矛盾時,事實贏」。
- 收工核證 + Implemented→Verified:watcher 測的是 idle、agent 自報的是 "done"——都只算
Implemented,不是交付(別讓交付狀態由執行者自報,§1.4 存活檢測是同一主題)。升 Verified 僅當
①核證四件套過 + ②異構 codex 獨立確認(執行者再嚴的自審仍是同 lineage = self-preference bias,不可信);
roadmap / ACTIVE_CONTEXT / 關單只認 Verified。核證四件套(git status / git log / 復跑 test+lint /
grep 計數 + 實證)見
references/dispatch-baseline.md。
2. 對抗式評審循環
先按風險定評審深度:低風險走輕量標準 review(codex review --base)、高風險(鑑權/遷移/基建/大重構)
走完整對抗循環。codex 無內建「對抗」檔——對抗在 prompt 層(自起會話點名軸 + severity/verdict + 多輪收斂),
必須自起會話自控 prompt、別用子指令。完整模板 + 軸全枚舉 + 實證 + ledger 欄目 + 達標線見
references/review-dispatch.md。判據:
- brief 冷上下文、不夾帶自己的結論(餵 codex 我的判斷 = anchoring,換模型卻共享推理鏈 = 去相關價值白費)。
- 點名最易翻車的軸(崩潰恢復/併發/旗標關路徑/降級/安全契約/多租戶隔離/指標誠實性),讓 codex 主動寫探針。
- 評審前先列舉執行路徑分叉(provider/mode、live vs rehydrate…),點 codex 核「還有哪些分支沒走到」。
- 門控/觸發型功能必查 under-fire(該觸發時觸發了沒),不只 over-fire。
- 評審記錄用 ledger 結構、不純追加(blocking/queued/advisory/已修/stagnation 逐輪更新);每輪回修重貼原 goal 不可變驗收點。
- 三分類收斂:只有
blocking殘留才繼續循環;advisory→follow-up,別擋已就緒的 push;不重複 raise 已判過的。 - stagnation 檢測:同一 finding 反覆出現 = 卡住,該收斂或升級人介入,別無限對轟。
- 評審期 omp 別動同一 worktree(codex 在內跑測試會汙染結論)。
3. 變更紀律
- 旗標門控:行為變更預設藏 env flag 後,預設 OFF = 位元組級零變化;例外:ReOpen 批准的修復可預設 ON(goal 寫明理由)。效能/實驗類一律 OFF。
- measure-before-more / 先量再斷:第一刀砍下後綁定約束會換人——先實測再決定第二刀,別按推算連下多個 lever。修 bug 同理,動手前驗證 ① bug 當前態真能復現、② 觀測值真被某機制約束(觀測 5 < 上限 10 ⇒ 上限 不是約束)、③ 執行真到了你懷疑的程式碼(讀程式碼只找候選,「執行到這」要日誌/trace 證)。綁定約束未證時, 先派埋點 + 復測、不發投機修復(實證:讀程式碼三輪推斷一個根本不存在的「掛死」、每輪被真資料打回)。常見 偽 bug:查錯了資料來源(空表當真表 / 錯日誌串 / 錯 session)、「沒收到」(用戶端) ≠ 「沒發出」(伺服器端)。
- commit 留本地,push/PR 必須用戶明示批准;批准一次只覆蓋那次。
- 驗證誠實:交付三段式——驗證了什麼(真跑過)/ 沒驗證什麼 / 剩餘風險。本地打樁繞過的環節(真 LLM、真佇列)顯式標註,部署後運維補驗。實證:本地 LLM 打樁致 un-awaited coroutine 逃逸生產。
- 代驗路徑 ≠ 真路徑(後端/agent/前端通用):mock / 打樁 / stream smoke 全綠 ≠ 真實路徑成立——
按真實部署路徑驗收,別拿代驗當真驗,真路徑常和你 mock 的那條不是同一條(前端實例見 §7:卡片走
execute/async非execute/stream,三段綠仍 ReOpen)。最尖一條:別 mock 你正在驗證的那個邊界 ——stub 掉被測函式 = 測試零資訊、恰好蓋住 bug;真應用 E2E 才是「可測試」門(實證:一天內 4 個 bug 全過 review+單測,只它抓到)。 - 編輯前重讀會變的檔案:rebase / 另一 agent 動過同一 worktree / 你剛跑了改檔案的 git 操作 之後,
in-context 檔案檢視已 stale——先重讀再改。帶 read-before-edit 護欄的工具會攔 stale edit(報
must be read first不是 bug、是它在擋你拿過期檢視覆蓋別人的改動);沒護欄的會靜默覆蓋、更糟。別在讀↔編輯間插改檔案的指令。
4. 間接環境訪問(運維 agent 模式)
夠不著的環境(prod、獨立 dev 執行時期庫)不要猜——寫自包含取證提示詞(模板
references/ops-prompt-template.md,放 docs/orchestration/<NAME>_PROMPT.md)讓用戶轉交運維 agent。
要點(只讀寫死 / SQL 給全 / 預期讀數+判定規則給全 / 回報格式給死 / 敏感只取元資料)見該模板。
判據:運維回報優先級高於自己的推斷——現場與 HEAD 程式碼矛盾時,先懷疑構建漂移(部署的是舊版本),
再懷疑自己的控制流分析。
5. 狀態落盤與節奏
docs/orchestration/是 SoT:*_GOAL/*_FINDINGS|IMPL_omp/*_REVIEW_codex/*_PROMPT/*_RESULT,命名帶任務號、全 file:line 證據。生命週期:收口即把文件挪進archive/(README 加 索引行),live 只留在跑/在等的;文件只生不死 → live 與歷史混雜(實證:某專案積 38 個才首清)。- memory:每 workstream 一檔案 + 索引一行(狀態/PR/敞口/下一步入口),「壓縮/等外部輸入」前必更新。
memory 編排者私有,agent/新 session 只能讀 docs——只更 memory 不同步 docs = 共享治理層腐爛
(實證:某專案 ACTIVE_CONTEXT 凍 4 天變廢紙)。三分工:docs 存全 agent 共享的狀態快照(what/why)、
ACCESS.local.md存怎麼連上 + 憑證(how-to-reach,含密 gitignored,見 repo-governance-bootstrap)、memory 存 編排者私有的教訓 + 入口指標。短期 working 記憶(當前任務草稿/進度/待辦)不進這三類——活在 context window 或臨時/tmpNOTES、隨手可棄,別塞進 memory(汙染跨 session 私有層)或 ACTIVE_CONTEXT(那是收口快照非草稿)。- 寫時紀律(不等復盤):上面的卸載邊寫邊做——寫 memory 當下就把事實細節進 ACCESS/docs,別囤到復盤再清。 靠 skill 文字記不住的高頻紀律配 PostToolUse hook 兜底(強制層補 salience 衰減;模板見 repo-governance-bootstrap)。
- 復盤儀式(事件觸發:收口 / 壓縮前 / 任何 ReOpen 後主動提議)——是 CHECKLIST 不是即興。
聽到「復盤 / 收口 / handoff」 → 讀
references/retrospective.md七步逐條勾,別憑記憶即興(即興版讀著完整卻靜默漏 承重治理步——實證 2026-06-26:被要求「復盤儀式」卻自由發揮,漏了 roadmap 翻狀態 + ACTIVE_CONTEXT 整篇重寫 + 上下文治理)。- 硬門(未過不得宣佈完成):跑
bash references/retro-check.sh --base <branch> --docs <docs-dir> --memory <MEMORY.md>機械校驗(已合分支無孤兒 worktree / ACTIVE_CONTEXT 今日重寫 / roadmap 近期動 / MEMORY 未超行);只驗機械代理、語義靠你。
- 硬門(未過不得宣佈完成):跑
- 孤兒掃:關交付完的會話(持關鍵上下文且掛起的保留);掃 agent 起的孤兒——
docker ps/ps/ 後臺 job。臨時 compose 用 trap/finallydown --remove-orphans,repro 禁裸while True(用有界 迴圈/deadline)。實證:某 repro 死迴圈空轉 2.5 天、65% CPU。
6. 任務系統(外部任務追蹤:Jira / Linear / 飛書 bitable 等)
- 用任務系統的 CLI / API 讀寫任務;狀態機隨專案定義(待處理/處理中/可測試/已完成/阻塞/ReOpen)。
- 關單標準:修復 → E2E 驗證 → 截圖證據上傳任務附件(驗收人一眼對照)→ 一行結論 → 翻狀態。
- ReOpen:先取證再修——上一輪「修好了」的機制可能根本不是綁定約束。
- 別在治理 docs 裡養第二套任務帳本:外部系統是任務 SoT,roadmap 只是它的對映層。規則細節(沿用
外部 ID / 寫明 SoT / 何時才造內部 RD 號)由
repo-governance-bootstrap的「外部任務系統優先」落地。
7. 前端 fix 驗證(瀏覽器除錯)
派完前端任務,驗收紀律:程式碼 review + 單測都不夠,必須回瀏覽器看真實渲染;且 mock / SSE 幀 / 本地都過
≠ 真用戶能看到——閉環要登已釋出的真應用跑真實一輪 + 截圖才算數(代驗路徑≠真路徑 的前端例項,通用原則
見 §3)。E2E 是驗收、不佔編排者主上下文——委派給帶瀏覽器 MCP 的子 agent(§0「不自己跑長 E2E」的前端例項)。
完整方法論(MCP 主 CLI 補、a11y 優先、網路面板診斷聯網 bug、CLI 抓 SSE、交付閉環、E2E 委派子 agent、
本地起服務坑入專案 AGENTS.md)見 references/frontend-verify.md。
8. 新專案接入清單
新專案接入 6 步(bootstrap 治理骨架 → 增補委派邊界 → 建 orchestration 目錄 → 首任務走 §1 全流程 →
建 memory working-style 條目 → 建 DECISION_QUEUE)見 references/onboarding-checklist.md。
9. 主理人注意力與決策佇列(降認知負載)
第三鐵律的落地。目標不是主理人少決,是隻決承重的(戰略/不可逆/錢/價值),每個給嚼過的選項,且永不必記。
完整方法論(七件機制 + 委派板 + 失敗模式 + 出處誠實標註 + copy-paste 模板)見 references/decision-queue.md。
本節只留承重要點:
- 單一決策佇列
docs/DECISION_QUEUE.md:編排者維護、主理人唯讀。🔴需他/🟡我驅動/💤parked/✅已清。 完整性保證=唯一面、不另存、不靜默丟(信任前提,否則 offload 失效)。每 🔴 帶推薦+靜默默認+revisit 觸發。 - 三層委派:T0 直接做(可逆/已授權/無價值判斷)· T1 做了+記一行(可逆但值得知會、可否決)· T2 動手前問 (不可逆/對外、戰略/優先順序/錢/價值、有實質下行的真模糊)。減負=多往 T1 挪、少用 T2 當同步閘。
- 靜默默認:主理人沒回 → 可逆按寫明預設前進、不可逆一律 HOLD(永不自動越過不可逆)。
- 其餘機制(聚合絆線 / 批處理升級包 / 心跳 / HELD revisit / 佇列腐爛兜底 / 三層治理勿混)見
references/decision-queue.md。