子代理優先 · 主代理不下場 是做什麼的?
主代理的注意力屬於使用者,不屬於任務。 凡是預計要跑很多輪的活,一律派給子代理後台去做;主代理只負責拆解、派活、驗收、收口,始終保留隨時響應使用者的能力。
很多 agent 用得彆扭,根因不是模型不夠強,而是主代理被重活占住了:使用者發一句話,主代理埋頭跑二十輪工具呼叫,中間既不能應答、也不能改向,使用者只能乾等。等它終於抬頭,需求可能已經變了。
本技能提供的是一套作業紀律——把「什麼時候該派、怎麼派、怎麼驗收」變成可判定的規則,而不是靠手感。紀律是平台無關的:任何支援子代理 / 後台任務的 AI Agent(Claude Code、Codex、Cursor、WorkBuddy、Hermes 以及其他同類工具)都適用,差別只在工具名——映射見本文檔的「工具名對照表」一節。
落到具體平台時的實況差異:Hermes 的欄位名、併發上限、後台語義與成本口徑整理在
references/hermes-runtime-reality.md(示例實作,其他平台可忽略)。正文只講紀律,不依賴那一頁。
觸發條件
出現以下任一情況,就應當按本技能做事(而不是順手自己幹):
- 任務預計超過 2–3 輪工具呼叫:例如「讀 8 個檔案再彙總」「跑一輪檢索再整理」。
- 一次要處理多個相互獨立的單元:多檔案、多目錄、多 URL、多份資料、多個候選方案。
- 長研究 / 長搜尋:需要反覆檢索、抓取、比對,耗時以分鐘計。
- 批次處理:對一批輸入做同樣的一套操作(清洗、轉換、逐條核對、逐條生成)。
- 使用者明確要求並行或要求「同時做幾件事」。
- 主代理正處在與使用者的對話中間:使用者可能隨時追問、改需求、插新任務。
- 子任務彼此無依賴、可以同時開工:典型如「三份文件分別校對,最後合併結論」。
- 重活在後台跑的同時,使用者還想繼續聊別的(這是本技能最主要的收益場景)。
反過來的觸發條件:如果一件事一輪工具呼叫就能做完,使用者發完這句話就不再跟你說話——那自己做。硬派子代理只會更慢。判據見下一節的決策樹。
核心原則
- 主代理不下場做重活。 主代理只做四件事:拆解 → 派活 → 收口彙總 → 跟使用者對話。它必須保持「隨時可應答」的狀態。
- 重活必派子代理(強制)。 滿足上面的觸發條件就派,不許「我覺得我快我順手做了」。判斷標準是任務屬性,不是主代理的自信程度。
- 自報不等於事實。 子代理說「已完成」只是它的說法;沒有經過驗證的產出,一律視為未完成(詳見「驗收清單」)。
- 上下文必須自包含。 子代理看不到你與使用者的對話歷史。你腦子裡的背景,它一個字都收不到。派活工單寫不全,它一定跑偏——這不是它笨,是你沒給。
- 並行有邊界。 無依賴的活才並行;有先後依賴的活必須串行,或者把上游產出餵給下游。
- 需要使用者拍板的不外派。 需要使用者確認、需要承擔不可逆後果、需要即時把關的,留在主代理手裡。
- 跨會話長任務換機制。 需要活過本次會話的(持續監控、定時觸發、常駐進程),用你平台的定時 / 常駐機制(定時任務、計畫任務、常駐後台進程),不用子代理——子代理的生命週期跟一次委派綁定。
- 失敗要降級,不要編造。 子代理失敗、超時、產出不合格:降級自己動手,或換路徑重派。絕不允許把「沒拿到的結果」寫成「拿到了」。
這套原則對應的是工程上公開的 fork-join / fan-out-fan-in 典範:把任務分叉給多個執行單元,再匯合結果(Java 的
ForkJoinPool、以及 Dean 與 Ghemawat 在 OSDI 2004 提出的 MapReduce 都是這一思想的具體實作)。本技能不發明新概念,只把它落成 agent 場景下可執行的作業紀律。
決策樹:什麼算重活,什麼自己做
按順序回答下列問題,第一個答「是」的分支就是結論。
第 1 問:這件事一輪工具呼叫能做完嗎?
| 判斷項 | 判據 |
|---|---|
| 工具呼叫次數 | 你自己數得出來,且 ≤ 1 輪 |
| 是否要讀多個檔案 | 否(0–1 個) |
| 是否有迴圈 | 否(沒有「對每一個…」) |
| 預計耗時 | 秒級 |
四項全部滿足 → 自己做。 任何一項不滿足 → 進入第 2 問。
第 2 問:這件事需要使用者拍板嗎?
- 需要使用者在幾個方案裡選一個 → 自己做(或先只做資訊收集,把選項擺給使用者)。
- 涉及不可逆操作(刪資料、對外發布、付款、發訊息給第三方)且需要即時把關 → 自己做。
- 只是「需要使用者知道」,不需要使用者過程中做決定 → 可以外派,但彙總時要交代清楚。
第 3 問:這件事需要活過本次會話嗎?
- 是(定時觸發、持續監控、常駐服務)→ 用平台的定時 / 常駐機制(定時任務、計畫任務、後台進程),不用子代理。
- 否,本次會話內跑完就行 → 進入第 4 問。
第 4 問:能拆成互不依賴的幾塊嗎?
- 能 → 並行派多個子代理,各自歸各自的檔案 / 目錄 / URL / 資料集,最後主代理合併。
- 不能,但有明確先後 → 串行派,或者單派一個子代理把整條鏈跑完(它也比你下場省事)。
- 拆不動、又不長 → 回到第 1 問再確認一次,多半是自己做。
量化速查表
| 活的性質 | 典型耗時 | 處置 |
|---|---|---|
| 查一下某個值、讀一個檔案的某段 | 秒 | 自己做 |
| 改一處文案、跑一條命令 | 秒 | 自己做 |
| 讀 3 個檔案並彙總 | 1–2 分鐘 | 可做可派;使用者正在等你時派 |
| 讀 8 個檔案、逐份摘要 | 數分鐘 | 派 |
| 多源檢索 + 交叉比對 | 數分鐘到十幾分鐘 | 派(可分塊並行) |
| 批次處理 N 個輸入(N ≥ 5) | 隨 N 增長 | 派(切片並行) |
| 需要使用者從方案裡選 | 不定 | 自己做(收集 + 擺選項) |
| 每天定時跑一次 | 跨會話 | 定時任務(不是子代理) |
五步流程
第 1 步:拆解
先把活切成邊界清晰的單元。每個單元必須能獨立回答三個問題:
- 輸入是什麼:具體到檔案路徑、目錄、URL 列表、資料集名、參數。
- 產出是什麼:具體到檔案名稱、格式、路徑。
- 怎麼算做完:可判定的判據,不是「弄好就行」。
切分時守住兩條:
- 寫檔案不能撞車:兩個子代理絕不能寫同一個檔案。要嘛各自寫各自的檔案,最後主代理合併;要嘛串行。
- 依賴要顯式:A 產出餵給 B 的,不能並行派——必須串行,或者讓一個子代理把 A+B 都做掉。
完成判據(逐項打勾)
- 每個單元都寫清了輸入(含具體路徑 / 列表)
- 每個單元都寫清了產出(檔案名稱 + 格式 + 存放位置)
- 每個單元都有可判定的完成判據
- 沒有兩個單元寫同一個檔案
- 所有依賴關係已標註(哪些必須串行)
第 2 步:派活
用你平台的子代理 / 後台任務工具把每個單元派出去(Hermes 下是 delegate_task,其他平台按「工具名對照表」映射),工單按「四要素」寫(見下一節)。要點:
- 一個子代理只領一件邊界清楚的活,別把三件不相關的事塞進一個工單。
- 工單裡把背景寫全——子代理看不到你與使用者的對話。
- 明確告訴它產出落到哪個路徑,以及要回報什麼(檔案路徑?行數?命令輸出?)。
- 明確要求它只回報經得起驗證的東西:跑了什麼命令、拿到了什麼輸出;沒做到就直說。
- 如果平台支援結構化回報 / 輸出校驗(例如按 JSON Schema 校驗子代理的最終答覆)——能給結構化就別給自由文字。
完成判據
- 每個工單四要素齊全(目標 / 背景 / 產出結構 / 驗收方式)
- 每個工單都指定了產出路徑
- 每個工單都要求回報可驗證的證據(命令 + 真實輸出)
- 工單裡沒有「你懂的」「照之前那樣」這類殘缺指代
第 3 步:並行調度
- 能並行的並行派:彼此無依賴的單元一次性派出去,別排隊等。
- 有依賴的串行:等上游驗收通過,再把它的產出作為下游工單的 context。
- 並行度要有上限:同時開太多會互相搶資源、也增加你彙總時的負擔。一次三到五個是常見的舒服區間;再多考慮分批(超上限的後果各平台不同,見「工具名對照表」與平台實況頁)。
- 派完立刻回到使用者身邊:不要站在原地等子代理。這正是本紀律的目的——使用者在等你的時候,你應該是可應答的。
- 不要輪詢、不要乾等:委派呼叫應當立即返回,結果由平台送回;主代理在等待期間要能接住使用者的新訊息。如果你的平台預設阻塞,就把委派呼叫放進後台 / 非同步模式再派。
- 給使用者留一個現場控制口:平台若支援檢視在跑的子代理、給某個子代理補糾正、提前終止並保留部分成果,用它;不支援就退化為「下一批工單裡帶上糾正」。
完成判據
- 無依賴的單元已同時派出(不是一個個排隊派)
- 有依賴的單元已按順序串行,且下游拿到了上游產出
- 並行度在可控範圍(沒有一次性鋪開十幾個)
- 派完後主代理沒有阻塞等待,仍可響應使用者
第 4 步:驗收
這是最容易被跳過、也最不能跳過的一步。 子代理的「已完成」是待驗證聲明,不是結論。
按順序驗證(詳見「驗收清單」):
- 產出存在嗎:檔案真的在嗎?路徑對不對?讀一眼真實內容。
- 產出合規格嗎:格式、欄位、行數、範圍符合工單要求嗎?
- 結論有證據嗎:它聲稱的關鍵數字/結論,有沒有對應的命令輸出或來源?
- 原文抽查:隨機抽 1–2 處,回到一手來源核對。
任何一條不過 → 按第 5 步的失敗處置走。
完成判據
- 每個子代理的產出都用平台的讀檔案 / 執行工具真實回讀過(Hermes 下是
read_file/terminal)- 格式與欄位符合工單要求
- 關鍵結論有可追溯的證據
- 至少抽查過一處原文,與子代理的說法一致
- 失敗/不合格的產出已明確標記,沒有混進最終結果
第 5 步:收口
彙總給使用者時,必須做到三件事:
- 標明來源:哪部分是子代理做的、哪部分是你自己做的。使用者有權知道。
- 標明狀態:哪些已驗證、哪些未驗證、哪些失敗。不要用「大概」「應該是」糊過去。
- 給下一步:需要使用者拍板的地方明確擺出來。
失敗處置(按優先順序):
- 降級自己做——活其實不大,那就自己動手。
- 換路徑重派——把失敗原因寫進新工單,換個方法再來一次。
- 拆分重派——工單太大導致跑偏,切小了再派。
- 如實上報——跑不通就跑不通,把卡點和已排除的路徑講清楚。不允許編造結果。
完成判據
- 彙總裡標明了每部分的來源(子代理 / 主代理)
- 彙總裡標明了每部分的驗證狀態
- 失敗的活已處置(自己做 / 重派 / 如實上報),沒有隱身
- 需要使用者決定的事項已單獨列出
- 沒有一句未經證實卻被寫成事實的話
派活四要素
每個工單都必須包含這四樣。缺任何一樣,事故機率顯著上升。
1. 目標(goal)—— 要做什麼
一句話說清目標,用動詞開頭、結果導向。
- 好:
把 3 份 CSV 合併成一份去重後的 combined.csv,保留原始列順序 - 差:
處理一下這幾個檔案
2. 背景(context)—— 為什麼做、憑什麼做(必須自包含)
這是四要素裡最容易寫崩的一個。 原因很簡單:
子代理看不到你與使用者的對話歷史。它只知道你在工單裡寫了什麼。你腦子裡的背景——使用者的偏好、之前踩過的坑、為什麼不能用某個方案、資料的口徑——它一個字都收不到。
所以 context 裡必須顯式寫:
- 任務背景:這件事服務於什麼目標,使用者在乎什麼。
- 硬性約束:必須遵守的口徑、格式、命名規則、禁止事項。
- 輸入清單:具體的檔案路徑 / 目錄 / URL / 資料集,不寫「那幾個檔案」。
- 已知的坑:之前試過什麼不行、哪裡有陷阱、容易誤解的地方。
- 環境資訊:工作目錄、可用的工具、依賴是否已安裝。
自查方法:把工單單獨發給一個完全不了解前情的同事,他能照做嗎? 能,就算自包含。
3. 產出結構(output schema)—— 產出長什麼樣
把產出結構寫死,避免回來還要你再加工一遍。
- 檔案類:路徑 + 檔案名稱 + 格式(
markdown/json/csv)+ 必需的欄位或章節。 - 報告類:要求回報的結構(結論 / 證據 / 來源 / 未解決項),而不是一段散文。
- 機器可讀優先:能給
json就別給自由文字——省掉你二次解析的功夫。 - 平台若支援輸出校驗(按 schema 校驗子代理答覆),打開它;平台不支援就在工單正文裡把結構複述一遍,並要求「照此結構回報」。
4. 驗收方式 —— 怎麼證明做成了
提前告訴它你要怎麼驗,它就會照著做;事後才發現沒證據,只能返工。
- 要求回報真實執行過的命令與輸出(而不是「我檢查過了」)。
- 要求產出路徑可直接回讀。
- 要求明確列出未完成/存疑的部分——主動交代比被你抓出來好。
四要素速查表
| 要素 | 一句話 | 常見缺陷 |
|---|---|---|
| 目標 | 要做什麼,結果導向 | 太籠統:「整理一下資料」 |
| 背景 | 背景 + 約束 + 輸入清單 + 已知坑 | 只寫目標不寫背景,子代理自由發揮 |
| 產出結構 | 產出路徑、格式、欄位 | 沒指定路徑,產出散落找不到 |
| 驗收方式 | 用什麼命令/標準判定 | 無判據,靠「感覺還行」放行 |
驗收清單
對每一個子代理產出,逐項過一遍。任何一項「否」,就不算完成。
A. 存在性
- 產出檔案真實存在於工單指定的路徑(用平台的讀檔案 / 執行工具實測,不是只看檔案名稱)
- 檔案非空,內容不是佔位符 / 模板殘留 / 明顯截斷
- 如果是程式碼或腳本:能真的跑起來(不是「看起來對」)
B. 合規性
- 格式、欄位、命名符合工單要求
- 數量對得上(要 10 條就是 10 條,不是「大概 8 條」)
- 沒有越界:沒改不該改的檔案、沒寫工單之外的位置
- 並行任務之間沒有互相覆蓋(檢查檔案修改時間 / 內容完整性)
C. 真實性
- 子代理聲稱跑過的命令,有對應的真實輸出
- 關鍵結論能追溯到具體來源(檔案、URL、命令結果)
- 隨機抽 1–2 處,回到一手來源核對,結論一致
- 沒有「看起來很合理但找不到出處」的數字或論斷
D. 完整性
- 工單要求的每一項都交了
- 未完成 / 存疑的部分被主動列出,而不是被藏起來
- 失敗項有明確說明(錯在哪、試過什麼)
E. 彙總前的最後一道
- 我在給使用者的答覆裡標明了來源與驗證狀態
- 我沒有把子代理的「自報成功」當成「已完成」寫進結論