Get started

Swarms — 程式碼模式中的代理分流與協調

Swarms — 程式碼模式中的代理分流與協調

狀態:已發布 — 已由 docs/tools/swarm.md 取代。本文件保留作為 實作設計紀錄。

1. 內容與原因

Swarm 是由程式碼模式指令碼以確定性方式協調的多個子代理: 分流 N 個讀取代理、以對抗方式驗證發現、透過具狀態的優先排序器進行整合, 並依決策閘門循環。控制流程(Promise.allwhileif)_本身就是_協調機制 — 此設計刻意不採用圖形 DSL、 不新增模式,也不新增頂層工具介面

OpenClaw 程式碼模式(QuickJS-WASI、快照/續接、橋接請求)是其 基礎。暫停中的橋接呼叫可歷經 VM 快照與閘道重新啟動,並 從停止之處精確續接 — 這比日誌重播設計更強,而且 不會對指令碼施加確定性限制。

命名:產品/文件名稱為 Swarm。程式碼識別碼維持原文: agents.* 客體 API、tools.swarm 設定、swarm 群組欄位。

2. 決策(維護者,2026-07-17)

  • 成本:強制執行設定上限;每個 Swarm 的權杖預算為選用。不強制要求預算。
  • 核准:子代理以失敗時關閉/非互動式方式執行。需要核准的 動作會遭拒絕;拒絕結果會回報於子代理結果中;由指令碼 決定後續處理。分流不會向操作員大量傳送提示。
  • v1 僅支援由模型撰寫的臨時指令碼。儲存/命名工作流程、命令列介面/排程 進入點:稍後支援(無介面程式碼模式已可供排程使用)。
  • 子代理身分:預設透過 tools.swarm.defaultAgentId 設定使用專用工作代理(依現有子代理目標允許清單驗證);每次生成可使用 agentId 覆寫。核心不附帶任何內建代理 ID;文件建議使用精簡的 worker 代理設定。
  • 不變更 Codex 原始碼。Codex 測試框架使用生成/等待慣用法(§8)。

3. 架構概觀

Code
程式碼模式指令碼(QuickJS VM、閘道)          Codex V8 指令碼(codex 程序)  agents.run(...) ── 暫停中的橋接呼叫           tools.sessions_spawn / tools.agents_wait        │                                                │ 項目/工具/呼叫 RPC(每次 ≤600s)        ▼                                                ▼             核心(不限定測試框架,本存放庫)  sessions_spawn {collect:true, outputSchema, fastMode, groupId}  agents_wait {ids, timeoutSeconds}  子代理登錄檔(SQLite):收集器完成紀錄、Swarm 群組 ID  子代理 = 一般子代理工作階段(受通道上限限制、核准採失敗時關閉)  sessions.changed SSE ──► Control UI 圓點/側邊欄/頻道狀態訊息

生成/完成/結算語意只有一個標準擁有者(核心工具 + 登錄檔)。 兩種等待傳輸:QuickJS 會無限期暫停橋接呼叫(快照); Codex 則在有界 RPC 中輪詢 agents_wait

4. 設定閘門(v1)

新增 tools.swarm(全域 + 個別代理覆寫,合併模式與 tools.codeMode 相同):

jsonc
"tools": {  "swarm": {    "enabled": false,            // 主閘門,預設關閉    "maxConcurrent": 8,          // 同時執行的子代理數量(Swarm 通道上限)    "maxChildrenPerGroup": 50,   // 每個 Swarm 群組的作用中子代理數量    "maxTotalPerGroup": 200,     // 每個群組生命週期內的生成總數(失控防護)    "waitTimeoutSecondsMax": 600,    "defaultAgentId": ""         // 選用;生成省略 agentId 時使用的子代理 ID  }}
  • Zod:聯集 boolean | strict object,類似 CodeModeSchemasrc/config/zod-schema.agent-runtime.ts);swarm: true{enabled: true}
  • 型別位於 src/config/types.tools.ts(個別代理與頂層 tools 皆有), 標籤位於 schema.labels.ts,說明位於 schema.help.runtime.ts
  • 解析輔助函式 resolveSwarmConfig(cfg, agentId) 仿照 resolveCodeModeConfigsrc/agents/code-mode.ts:215),並限制所有數值範圍。
  • 停用時的閘門效果:工具目錄中不會出現 agents_waitsessions_spawn 上的 collect/outputSchema/fastMode/groupId 參數 會遭拒絕,並顯示明確指出設定鍵的錯誤。其他行為不變。
  • defaultAgentId 透過 resolveSubagentAllowedTargetIdssrc/agents/subagent-target-policy.ts)進行驗證;未知 ID → 生成錯誤,不會回退。

5. 核心:收集器模式生成 + agents_wait(v1)

5.1 sessions_spawn 新增項目(全部受 Swarm 啟用狀態控制)

  • collect: boolean — 為 true 時,子代理執行會登錄至 expectsCompletionMessage: false 並建立收集器完成紀錄, 而不是進行公告/引導傳遞。工具會立即傳回 { runId, sessionKey }。 不繫結頻道/討論串。
  • outputSchema: object — JSON Schema。子代理的工具介面會附加一個合成的 structured_output 工具;系統提示詞附加內容會指示它使用最終結果 呼叫該工具恰好一次。驗證失敗時,子代理會收到一次提醒以重試;若仍失敗, 完成紀錄會包含 structured: undefined、原始文字以及 schemaError
  • fastMode: true | "auto" | false — 透過 resolveSubagentModelAndThinkingPlansrc/agents/subagent-spawn-plan.ts),使用現有的 FastMode 維度 (src/shared/fast-mode.ts),與模型/思考設定一起傳入子代理工作階段修補。 省略 = 繼承。
  • groupId: string — Swarm 群組戳記。預設為 swarm:<requesterSessionKey>:<runId-of-requesting-run>。它會持久保存於 登錄紀錄與子代理工作階段資料列中,用於上限、列出、批次 封存及圓點。
  • label: string 已存在 — 會顯示於圓點和 subagents list 中。
  • 子代理 ID:params.agentId → 否則 tools.swarm.defaultAgentId → 否則 使用請求者代理(現有行為)。

5.2 核准採失敗時關閉

收集器子代理使用非互動式核准脈絡執行:任何需要操作員核准的 工具呼叫,都會解析為子代理可見的結構化拒絕結果 (approval_required),並預期子代理在結果中回報 受阻情況。實作方式:重用現有的執行/工具核准 原則管線,並對收集器模式的子代理執行強制使用 deny 解析器。 收集器子代理不會向操作員介面發出核准事件。

5.3 agents_wait 工具(新增,受閘門控制)

Code
agents_wait({ ids: string[], timeoutSeconds?: number })→ {    completed: [{ runId, status: "done"|"failed"|"killed"|"timeout",                  result: string, structured?: unknown, schemaError?: string,                  sessionKey, label?, usage?: {inputTokens, outputTokens} }],    pending: string[]  }
  • 只要至少一個 ID 完成便立即傳回(最先完成/競速 語意,可支援流水線),或逾時並傳回 completed: []
  • timeoutSeconds 預設為 30,並限制至 waitTimeoutSecondsMax
  • 具冪等性:已完成的 ID 會再次傳回其紀錄(紀錄會 保留至群組封存)。未知 ID → 個別 ID 錯誤項目,不會擲出錯誤。
  • 擁有權:只有生成執行的工作階段(或其父系鏈)可等待 該執行 — 與程式碼模式中的 wait 採用相同擁有權規則 (code-mode.ts:1684)。
  • 登錄檔:完成紀錄存放於現有的子代理登錄檔 SQLite 儲存區(subagent-registry.store.sqlite.ts)— 新增欄位,不新增 儲存區,也不提升結構描述版本(僅新增欄位;請參閱 §9 限制)。

5.4 上限強制執行

  • maxConcurrent:收集器子代理在現有子代理通道上執行,但 依 Swarm 群組分別計數;超過上限的生成會依先進先出順序排隊(由主機端在 生成路徑處理 — 立即傳回 runId,釋出名額後開始執行)。
  • maxChildrenPerGroup / maxTotalPerGroup:超過上限後,生成會以具型別的錯誤 拒絕;錯誤文字會指出設定鍵。
  • 深度:收集器子代理維持 DEFAULT_SUBAGENT_MAX_SPAWN_DEPTH 語意 (除非明確設定巢狀,否則子代理均為葉節點)。

6. 測試契約(v1,通道 A)

  • 單元測試:設定解析/範圍限制;停用時的閘門拒絕;groupId 預設值;上限強制執行(排隊 + 拒絕);等待競速語意;等待 冪等性;擁有權拒絕;結構化輸出驗證 + 提醒重試 + schemaError 路徑;fastMode 傳入工作階段修補;defaultAgentId 驗證。
  • 整合測試(vitest、模擬模型執行階段):生成 3 個收集器子代理、在迴圈中 等待、斷言最先完成順序與最終清空;閘道重新啟動 模擬:重新載入登錄檔 → 等待從持久保存的完成紀錄解析。
  • 所有測試均與 *.test.ts 放置於同一處;不進行即時模型呼叫。

7. QuickJS 客體介面(通道 B,核心完成後)

  • 客體全域項目安裝於 CONTROLLER_SOURCEsrc/agents/code-mode.worker.ts:190-374),保留名稱新增至 code-mode-namespaces.ts
    • agents.run(prompt, opts) → Promise<result|structured> — 語法糖: 收集器生成 + 在專用橋接方法(agentWait)上暫停等待, 由主機在完成時結算(不輪詢;支援快照)。
    • agents.session(system, opts) → Promise<handle>handle.send(input, opts) → Promise<...>handle.close()。(v1.1 — 在 run() 之後發布;使用 mode:"session" + 每回合收集器紀錄。)
    • phase(title)log(message) — 即發即棄的橋接通知 → Swarm 進度事件。
  • 橋接方法新增至 CodeModeBridgeMethodcode-mode.ts:91): agentSpawnagentWaitswarmNoteagentSpawn/agentWait 依構造即具重播安全性:冪等性鍵 (codeModeRunId, bridgeId) 儲存於登錄紀錄中;重新啟動會從持久保存的完成紀錄重新結算, 且絕不重複生成。
  • 待處理的 agentWait 橋接呼叫會延長執行的快照 TTL(待處理 代理集合就是訊號;不使用旗標)。
  • API.read("agents.d.ts") 虛擬檔案記載具型別的介面,以及 分流/閘門/循環慣用法(createCodeModeApiVirtualFilescode-mode-namespaces.ts:876)。

8. Codex 測試框架投影(後續通道)

  • sessions_spawn(含新參數)與 agents_wait 會流經 現有的動態工具橋接;在 Codex 程式碼模式指令碼中,它們會自動顯示為 tools.*(已驗證:codex-rs/code-mode/src/runtime/globals.rs:14-65codex-rs/core/src/tools/spec_plan.rs:448-507)。
  • agents_wait 會取得較長的動態工具逾時類別(上限 600s; extensions/codex/src/app-server/dynamic-tool-execution.ts:37-39),並標記為 逾時/重播安全。
  • Codex 父代理的群組鍵:swarm:<parentSessionKey>:<turnId>
  • Codex 原生 spawn_agent 子代理可共存;其任務鏡像資料列會提供給 相同的進度介面。

9. 持久性與保留

  • 不新增儲存區。登錄紀錄會擴充現有的子代理登錄檔 SQLite 資料表;子代理是一般的 sessions 資料列。僅新增欄位 — 任何需要提升 SQLite 結構描述版本的變更,都必須先取得 維護者明確核准(存放庫原則)。
  • Swarm 群組 ID 位於登錄紀錄 + 子代理工作階段中繼資料。
  • 保留:已完成的收集器紀錄會保留至群組封存: 當父執行完成(或 TTL 到期)時,群組的子代理會 批次封存(擴充現有的 DEFAULT_SUBAGENT_ARCHIVE_AFTER_MINUTES 清理作業,使其依群組運作)。

10. 進度介面(「圓點」)— 後續通道

  • 隱含式,由測試框架驅動。衍生自現有的 sessions.changed SSE + 登錄檔;phase/log 備註新增語意。不由代理驅動呈現。
  • Control UI:工作區小工具系列 (ui/src/lib/workspace/widgets/)中的 swarm 轉譯器 — 依階段分組的圓點網格、旁白 行、各圓點的狀態/標籤/模型;側邊欄子代理樹維持不變。
  • 頻道:每個群組僅有一則經節流並編輯更新的狀態訊息(遵循 docs/concepts/streaming.md;絕不為每個子代理傳送訊息)。

11. 實驗室頁面(控制介面,獨立工作線)

Settings → Labs:實驗性功能切換開關,首批項目為 Code ModeSwarm。每列包含:名稱、單行說明、文件連結、透過 現有的 config.patch RPC 連接的切換開關(RFC 7396 合併修補程式——設定 tools.codeMode.enabled / tools.swarm.enabled),以及適用時顯示的「需要重新啟動」 提示。此頁面可被找到,但文案會明確說明其實驗性狀態。 i18n:所有字串都透過一般的 en.ts + 同步流水線處理。

12. 執行位置(稍後)

  • placement 產生時選擇:"local"(預設)| "cloud:<profile>",透過 現有的工作程式環境分派(sessions.dispatch);若共用執行環境中的 SSH 沙箱子項目 證明不足,稍後再加入集區式執行位置。
  • 協調器 VM 一律保留在閘道上;收斂/點狀態/預算 不受執行位置影響。

13. 非目標

  • 不使用圖形 DSL——控制流程本身就是圖形(刻意如此,且已記錄於文件)。
  • 不變更 Codex 原始碼;不重複使用 Codex Code Mode 內部機制。
  • v1 不提供已儲存/具名的工作流程;不提供命令列介面進入點。
  • 不逐一向上傳遞每個子項目的操作員核准要求。
  • 不在扇出規模下進行 1:1 雲端佈建。
  • 不提供穩態執行階段相容性墊片;Swarm 是新的介面,受閘門控管。

14. 建置階段 / PR 切分

  1. 工作線 A(核心):§4 設定 + §5 產生/等待/上限/核准 + §6 測試。
  2. 工作線 C(實驗室頁面):§11——獨立,可先合併。
  3. 工作線 B(QuickJS 介面):§7——在 A 的合約合併後進行。
  4. 點狀態轉譯器(§10)、Codex 投影(§8)、agents.session(§7 v1.1)、 執行位置(§12)、使用者文件改寫——依此順序在後續 PR 中進行。

每個 PR:CI 通過、$autoreview 無問題、預設由閘門關閉、主分支可發布。

Was this useful?
On this page

On this page