Hermes Agent 分析師養成記 · 第五篇:一個人變成一支隊伍

作者:努力撞蘑菇AI
日期:2026年5月22日 上午9:06
來源:WeChat 原文

整理版優先睇

速讀 5 個重點 高亮

Hermes Agent 透過子代理系統突破單線程天花板,將單一 Agent 變成團隊實現並行分析

整理版摘要

呢篇文章係 Hermes Agent 分析師養成記系列嘅第五篇,作者分享咗子代理系統嘅設計理念同實踐方法。作者指出,傳統單一 Agent 面對需要多方向推進嘅複雜任務時,會遇到「寬」嘅問題:因為得一個注意力,所以只能串行處理,時間長、上下文被撐大,早期資訊可能被遺忘。

為咗解決呢個瓶頸,Hermes 引入咗 invoke_subagent 機制,父代理可以隨時派生多個子代理,每個子代理喺完全獨立嘅上下文入面並行執行任務。系統有三個關鍵機制:完全上下文隔離確保子代理之間唔會互相干擾;非阻塞 spawn 加顯式 await 令父代理可以喺子代理工作期間繼續做其他嘢;硬性預算邊界(30輪工具調用、10分鐘運行時間、禁止遞歸)保證系統可控。

作者強調,子代理嘅真正挑戰係點樣拆任務,要滿足三個標準:子任務之間冇數據依賴、每個子任務粒度適中、輸出格式標準化。佢仲介紹咗 keepAlive 模式,令子代理可以變成常駐專家,會話內保持上下文。最後回顧咗成個系列嘅層次,由記憶、技能、沙箱到子代理,每一層解決唔同維度嘅問題,先解釋到 Hermes 點解能處理「寬而深」嘅分析任務。

  • 子代理系統將單一 Agent 變成團隊,實現任務並行處理,突破單線程架構嘅「寬」問題。
  • 三個關鍵機制:完全上下文隔離、非阻塞 spawn + 顯式 await、硬性預算邊界(30輪/10分鐘/禁止遞歸)。
  • 相比串行方案,並行方案將總時間從 T1+T2+T3 變成 max(T1,T2,T3),同時每個子代理嘅上下文乾淨,分析質量更高。
  • 拆任務嘅三大標準:子任務之間冇數據依賴、粒度適中、輸出格式標準化,確保彙總順利。
  • keepAlive 模式令子代理變成常駐專家,會話內保持歷史上下文,適合重複同類型任務。
結構示例

內容結構

內容結構 text
父代理調用 spawn → 立刻返回 agentId → 父代理繼續其他工作                                            ↓(稍後)父代理調用 await → 等待子代理完成 → 拿到結果 → 彙總
整理重點

單線程天花板:一個 Agent 唔夠用

複雜任務唔係難,而係「寬」——需要同時喺多個方向推進,但傳統 Agent 得一個注意力,只能串行處理。呢個係 單線程架構本身嘅天花板,唔係能力問題。

整理重點

子代理系統:將一個 Agent 變成一隊人

Hermes 嘅解法係 invoke_subagent:父代理可以隨時派生一個或多個子代理,將任務分包出去。結構係父代理(Orchestrator)之下有多個子代理(Worker),各自做獨立分析。

完全上下文隔離

每個子代理喺完全獨立嘅上下文入面執行,唔知其他子代理做緊咩,唔共享變量同狀態。呢個設計令並行唔阻塞、錯誤唔傳染、結果可預測。

  1. 1 機制一:完全上下文隔離 —— 並行唔阻塞,錯誤唔互相傳染,結果乾淨確定。
  2. 2 機制二:非阻塞 spawn + 顯式 await —— spawn 即時返回 ID,父代理繼續做其他嘢,等到需要結果先 call await,慳返等待成本。
  3. 3 機制三:硬性預算邊界 —— 每子代理最多 30 輪工具調用、10 分鐘運行時間、禁止遞歸派生子代理,確保系統可控。
整理重點

拆任務嘅藝術:三大標準

有咗子代理機制,真正嘅挑戰係父代理點樣拆任務。好嘅拆解要符合 三個標準:

  • ① 子任務之間冇數據依賴:如果 A 嘅輸出係 B 嘅輸入,就唔可以並行,一定要先 await A 再 spawn B。
  • ② 每個子任務嘅粒度適中:太細會浪費通信開銷,太粗會超過 30 輪工具調用限額;合理粒度係一個有明確輸出邊界嘅獨立分析單元。
  • ③ 子任務嘅輸出格式要標準化:父代理要彙總,如果 A 出 JSON、B 出文字、C 出 Markdown,彙總邏輯會好脆弱;最好喺 task 描述入面規定統一格式。

輸出格式標準化係彙總順利嘅關鍵

整理重點

具體場景:用戶、收入、異常並行分析

假設有一份三個月嘅日誌,要從用戶、收入、異常三個維度分析。串行方案要 T1+T2+T3+寫報告,並行方案用子代理同時 spawn 三個,然後 await 全部完成,總時間約等於 max(T1,T2,T3) + 寫報告。時間壓縮係最直觀嘅收益。

並行方案嘅總時間 ≈ max(T1,T2,T3) + T_report

仲有一個唔咁直觀嘅收益:每個子代理嘅上下文淨係得自己嘅數據,分析質量往往更高。

整理重點

keepAlive:將子代理變成常駐專家

普通子代理完成任務後會自動退出,上下文銷燬。但如果設定 keepAlive=true,子代理完成後會保持空閒狀態,父代理之後可以用 send 繼續向佢發消息,佢會帶住完整歷史上下文繼續工作。

呢個機制將子代理從「一次性工人」變成「常駐專家」,例如 spawn 一個專門處理 SQL 查詢嘅子代理,之後每次查數據庫都 send 畀佢,佢記得之前嘅表結構同慣例。

呢個同第一篇講嘅記憶系統形成對稱MEMORY.md 係跨會話嘅持久記憶,keepAlive 子代理係會話內嘅持久上下文,兩個時間尺度共同構成狀態管理體系。

有啲複雜任務,單線程係做唔曬嘅。

唔係因為難,而係因為——佢同時要你喺多個方向推進,而你只得一個注意力。

傳統工作流嘅解法係:拆成步驟,一步做完先做下一步。呢個可以解決「難」嘅問題,但係解決唔到「闊」嘅問題。你仍然係串行嘅。

Hermes Agent 嘅子代理系統,處理嘅就係呢個「闊」。

記憶與遺忘


你可能冇意識到嘅問題:單代理嘅天花板

喺前四篇入面,我哋拆解咗 Hermes 嘅記憶、技能、沙箱同 Jupyter 內核。呢啲能力擺埋一齊,已經可以完成相當複雜嘅分析任務——但係有一個隱藏嘅瓶頸從來冇被提到:

佢哋都運行喺同一個上下文窗口入面。

一個 Agent 嘅工作記憶係有限嘅。當你同時要求佢:

  • 分析三個月嘅用戶行為數據
  • 對比競品嘅公開指標
  • 查閲五份歷史報告
  • 撰寫一份綜合結論

佢焗住要喺一個對話入面順序處理所有資訊。時間一長,上下文被撐大,早期嘅資訊開始被壓縮甚至遺忘。而且全程只能串行——做完 A,再做 B,再做 C。

呢個唔係 Agent 嘅能力問題,而係單線程架構本身嘅天花板。


子代理:將一個 Agent 變成一隊團隊

Hermes 嘅解法叫 invoke_subagent——父代理(Orchestrator)可以喺任何時候派生一個或多個子代理(Worker),將任務分包出去。

結構上睇起嚟好簡單:

父代理(Orchestrator)
    ├── 子代理 A:分析用戶留存
    ├── 子代理 B:分析收入趨勢
    └── 子代理 C:分析異常數據

但係設計細節先係真正有趣嘅地方。


三個關鍵機制

機制一:完全上下文隔離

每個子代理都運行喺完全獨立嘅上下文裏。

佢淨係知道父代理交畀佢嘅任務描述同初始資訊。佢唔知其他子代理做緊乜,唔共享變量,唔共享狀態。

呢個設計乍睇似係缺點——子代理之間唔可以互相參考,資訊似乎被人為割裂咗。但呢個正正係佢嘅優勢所在:

  • 並行唔阻塞:子代理 A 嘅執行唔依賴子代理 B 嘅結果,三個任務可以真正同時推進
  • 錯誤唔傳染:子代理 C 炒咗,唔影響 A 同 B 嘅結果
  • 結果可預測:每個子代理淨係做一件事,輸出係乾淨嘅

資訊隔離,換嚟嘅係執行嘅確定性。


機制二:非阻塞 spawn + 顯式 await

呢個係呢套系統入面最反直覺嘅設計之一。

invoke_subagent(action="spawn") 是非阻塞嘅——父代理發出 spawn 指令,即刻拎到子代理嘅 ID,然後繼續執行自己嘅邏輯,唔等子代理完成

子代理喺後台跑,父代理喺前台推進。

等到父代理需要結果,佢再調用 await_subagent——呢個先係真正嘅「等待」動作。

父代理調用 spawn → 立刻返回 agentId → 父代理繼續其他工作
                                            ↓(稍後)
父代理調用 await → 等待子代理完成 → 拿到結果 → 彙總

呢個設計嘅意義在於:等待本身係有成本嘅。如果 spawn 係阻塞嘅,父代理喺等子代理嘅同時乜都做唔到。非阻塞 spawn 令父代理可以喺子代理工作期間處理其他嘢——例如準備彙總框架、寫結構性結論嘅草稿、或者再派生更多子代理。


機制三:硬性預算邊界

每個子代理都有明確嘅資源上限:

資源
上限
工具調用輪次
30 輪
運行時間
10 分鐘(最長可以設 600 秒)
遞歸層級
唔允許(子代理唔可以再派生子代理)

呢三條規則夾埋一齊,構成咗一個可預測嘅執行邊界

「子代理唔可以派生子代理」呢條值得特別講。呢個唔係技術上做唔到,而係刻意禁止。允許遞歸派生會導致任務樹無限膨脹——資源消耗變得不可預測,錯誤傳播路徑變得極難追蹤。扁平化嘅兩層結構(父+子,唔再落去),犧牲咗一啲表達能力,換嚟系統嘅可控性。


任務拆解嘅藝術

有咗子代理機制,真正嘅挑戰變咗做:父代理點樣拆任務?

好嘅拆解有三個標準:

① 子任務之間冇數據依賴

如果子代理 A 嘅輸出係子代理 B 嘅輸入,佢哋就唔可以並行——父代理必須先 await A,拎到結果,再 spawn B。強行並行只會令 B 拎到空結果。

② 每個子任務嘅粒度適中

太細:一個淨係跑三行 code 嘅子代理,spawn/await 嘅通信開銷比佢慳嘅時間仲多。
太粗:一個要做完整分析報告嘅子代理,超過 30 輪工具調用直接截斷。
合理嘅粒度係:一個子代理完成一個有明確輸出邊界嘅獨立分析單元。

③ 子任務嘅輸出格式要標準化

父代理最終要彙總所有子代理嘅結果。如果子代理 A 輸出 JSON、B 輸出自然語言段落、C 輸出 Markdown 表格,父代理嘅彙總邏輯會變得非常脆。好嘅做法係喺 task 描述入面明確規定輸出格式。


一個具體嘅數據分析場景

你有一份包含三個月數據嘅日誌文件,需要從用戶、收入、異常三個維度分析,最後出一份綜合報告。

串行方案(單代理):

分析用戶 → 分析收入 → 分析異常 → 寫報告
總時間 ≈ T1 + T2 + T3 + T_report

並行方案(子代理):

spawn 子代理A(用戶分析)
spawn 子代理B(收入分析)    ← 三個同時啓動
spawn 子代理C(異常分析)

await 全部完成

父代理彙總三份結果 → 寫報告
總時間 ≈ max(T1, T2, T3) + T_report

如果三個分析任務各需要 3 分鐘,串行需要 9 分鐘,並行需要大約 3 分鐘。

時間壓縮係最直觀嘅收益。但仲有一個冇咁直觀嘅收益:三個子代理各自嘅上下文係乾淨嘅——分析用戶嗰個 Agent,上下文得用戶數據,唔會被收入數據同異常日誌嘅噪音污染。分析質量往往都會更高。


keepAlive:令子代理保持待命

有一種特殊模式值得單獨講:keepAlive=true

普通嘅子代理喺完成任務之後自動退出,上下文銷毀。但如果 set 咗 keepAlive,子代理完成任務之後會保持「空閒」狀態——父代理可以喺之後用 invoke_subagent(action="send") 繼續向佢發送消息,佢會帶住完整嘅歷史上下文繼續工作。

呢個本質上係將子代理由「一次性工人」變成「常駐專家」。例如:

父代理:spawn 一個專門處理 SQL 查詢的子代理,keepAlive=true
後續:每次需要查數據庫,直接 send 給這個子代理
      它記得之前的表結構、字段命名約定、歷史查詢結果

呢個同第一篇講嘅記憶系統形成咗一種有趣嘅對稱:MEMORY.md 係跨會話嘅持久記憶,keepAlive 子代理係會話內嘅持久上下文。兩種機制,兩個時間尺度,共同構成咗 Hermes 嘅「狀態管理」體系。


同之前幾篇嘅連接

回顧一下前五篇拆解嘅嘢,而家可以拼出一幅更完整嘅圖:

記憶系統       ──→  跨會話的「你是誰」
技能系統       ──→  跨任務的「怎麼做」
代碼沙箱       ──→  單次任務的「自動執行」
Jupyter 內核   ──→  探索性任務的「迭代推進」
子代理系統     ──→  複雜任務的「並行擴展」

每一層都在解決唔同維度嘅問題。單獨睇,每個機制都唔複雜;組合起嚟,先可以理解點解 Hermes 可以處理嗰啲「闊而深」嘅分析任務。

下一篇:定時排程——當你唔喺度嘅時候,佢做緊乜。


我係專注 AI Agent深度實踐嘅努力撞蘑菇AI,致力分享真實可用嘅 AI 使用經驗同工作流探索,歡迎你同我一齊將 AI 玩到明白,如果內容對你有幫助,歡迎關注、點讚、轉發。

有一種複雜任務,單線程是做不完的。

不是因為難,而是因為——它同時需要你在多個方向上推進,而你只有一個注意力。

傳統工作流的解法是:拆成步驟,一步做完再做下一步。這能解決「難」的問題,但解決不了「寬」的問題。你仍然是串行的。

Hermes Agent 的子代理系統,處理的正是這個「寬」。

記憶與遺忘


你可能沒意識到的問題:單代理的天花板

在前四篇裏,我們拆解了 Hermes 的記憶、技能、沙箱和 Jupyter 內核。這些能力放在一起,已經能完成相當複雜的分析任務——但有一個隱藏的瓶頸從來沒被提到:

它們都運行在同一個上下文窗口裏。

一個 Agent 的工作記憶是有限的。當你同時要求它:

  • 分析三個月的用戶行為數據
  • 對比競品的公開指標
  • 查閲五份歷史報告
  • 撰寫一份綜合結論

它不得不在一個對話裏順序處理所有信息。時間拉長,上下文被撐大,早期的信息開始被壓縮甚至遺忘。而且全程只能串行——做完 A,再做 B,再做 C。

這不是 Agent 的能力問題,這是單線程架構本身的天花板。


子代理:把一個 Agent 變成一支團隊

Hermes 的解法叫 invoke_subagent——父代理(Orchestrator)可以在任何時候派生出一個或多個子代理(Worker),把任務分包出去。

結構上看起來很簡單:

父代理(Orchestrator)
    ├── 子代理 A:分析用戶留存
    ├── 子代理 B:分析收入趨勢
    └── 子代理 C:分析異常數據

但設計細節才是真正有趣的地方。


三個關鍵機制

機制一:完全上下文隔離

每個子代理都運行在完全獨立的上下文裏。

它只知道父代理交給它的任務描述和初始信息。它不知道其他子代理在做什麼,不共享變量,不共享狀態。

這個設計乍看像是缺點——子代理之間不能互相參考,信息似乎被人為割裂了。但這正是它的優勢所在:

  • 並行不阻塞:子代理 A 的執行不依賴子代理 B 的結果,三個任務可以真正同時推進
  • 錯誤不傳染:子代理 C 崩了,不影響 A 和 B 的結果
  • 結果可預測:每個子代理只做一件事,輸出是乾淨的

信息隔離,換來的是執行的確定性。


機制二:非阻塞 spawn + 顯式 await

這是這套系統裏最反直覺的設計之一。

invoke_subagent(action="spawn") 是非阻塞的——父代理發出 spawn 指令,立刻拿到子代理的 ID,然後繼續執行自己的邏輯,不等子代理完成

子代理在後台跑,父代理在前台推進。

等到父代理需要結果了,它再調用 await_subagent——這才是真正的「等待」動作。

父代理調用 spawn → 立刻返回 agentId → 父代理繼續其他工作
                                            ↓(稍後)
父代理調用 await → 等待子代理完成 → 拿到結果 → 彙總

這個設計的意義在於:等待本身是有成本的。如果 spawn 是阻塞的,父代理在等子代理的同時什麼都做不了。非阻塞 spawn 讓父代理可以在子代理工作期間處理別的事——比如準備彙總框架、寫結構性結論的草稿、或者再派生更多子代理。


機制三:硬性預算邊界

每個子代理都有明確的資源上限:

資源
上限
工具調用輪次
30 輪
運行時間
10 分鐘(最長可設 600 秒)
遞歸層級
不允許(子代理不能再派生子代理)

這三條規則合在一起,構成了一個可預測的執行邊界

「子代理不能派生子代理」這一條值得特別說。這不是技術上做不到,而是刻意禁止。允許遞歸派生會導致任務樹無限膨脹——資源消耗變得不可預測,錯誤傳播路徑變得極難追蹤。扁平化的兩層結構(父+子,不再往下),犧牲了一些表達能力,換來了系統的可控性。


任務拆解的藝術

有了子代理機制,真正的挑戰變成了:父代理怎麼拆任務?

好的拆解有三個標準:

① 子任務之間沒有數據依賴

如果子代理 A 的輸出是子代理 B 的輸入,它們就不能並行——父代理必須先 await A,拿到結果,再 spawn B。強行並行只會讓 B 拿到空結果。

② 每個子任務的粒度適中

太細:一個只跑三行代碼的子代理,spawn/await 的通信開銷比它省的時間還多。
太粗:一個要做完整分析報告的子代理,超過 30 輪工具調用直接截斷。
合理的粒度是:一個子代理完成一個有明確輸出邊界的獨立分析單元。

③ 子任務的輸出格式要標準化

父代理最終要彙總所有子代理的結果。如果子代理 A 輸出 JSON、B 輸出自然語言段落、C 輸出 Markdown 表格,父代理的彙總邏輯會變得非常脆。好的做法是在 task 描述裏明確規定輸出格式。


一個具體的數據分析場景

你有一份包含三個月數據的日誌文件,需要從用戶、收入、異常三個維度分析,最後出一份綜合報告。

串行方案(單代理):

分析用戶 → 分析收入 → 分析異常 → 寫報告
總時間 ≈ T1 + T2 + T3 + T_report

並行方案(子代理):

spawn 子代理A(用戶分析)
spawn 子代理B(收入分析)    ← 三個同時啓動
spawn 子代理C(異常分析)

await 全部完成

父代理彙總三份結果 → 寫報告
總時間 ≈ max(T1, T2, T3) + T_report

如果三個分析任務各需要 3 分鐘,串行需要 9 分鐘,並行需要約 3 分鐘。

時間壓縮是最直觀的收益。但還有一個不那麼直觀的收益:三個子代理各自的上下文是乾淨的——分析用戶的那個 Agent,上下文裏只有用戶數據,不會被收入數據和異常日誌的噪音污染。分析質量往往也會更高。


keepAlive:讓子代理保持待命

有一種特殊模式值得單獨說:keepAlive=true

普通的子代理在完成任務後自動退出,上下文銷燬。但如果設置了 keepAlive,子代理完成任務後會保持「空閒」狀態——父代理可以在之後用 invoke_subagent(action="send") 繼續向它發送消息,它會帶着完整的歷史上下文繼續工作。

這本質上是把子代理從「一次性工人」變成了「常駐專家」。比如:

父代理:spawn 一個專門處理 SQL 查詢的子代理,keepAlive=true
後續:每次需要查數據庫,直接 send 給這個子代理
      它記得之前的表結構、字段命名約定、歷史查詢結果

這和第一篇講的記憶系統形成了一種有趣的對稱:MEMORY.md 是跨會話的持久記憶,keepAlive 子代理是會話內的持久上下文。兩種機制,兩個時間尺度,共同構成了 Hermes 的「狀態管理」體系。


和之前幾篇的連接

回顧一下前五篇拆解的東西,現在能拼出一幅更完整的圖:

記憶系統       ──→  跨會話的「你是誰」
技能系統       ──→  跨任務的「怎麼做」
代碼沙箱       ──→  單次任務的「自動執行」
Jupyter 內核   ──→  探索性任務的「迭代推進」
子代理系統     ──→  複雜任務的「並行擴展」

每一層都在解決不同維度的問題。單獨看,每個機制都不復雜;組合起來,才能理解為什麼 Hermes 能處理那些「寬而深」的分析任務。

下一篇:定時調度——當你不在的時候,它在做什麼。


我是專注 AI Agent深度實踐的努力撞蘑菇AI,致力於分享真實可用的 AI 使用經驗與工作流探索,歡迎你和我一起把 AI 玩明白,如果內容對你有幫助,歡迎關注、點贊、轉發。