跳转至

子智能体并发、恢复和停止

并发

每个派生会话都有自己的进程内队列,用于普通子代理。设置 agents.defaults.subagents.maxConcurrent 限制该会话的并发子运行 (默认 8)。独立会话拥有独立预算,因此一个 繁忙会话不会消耗另一个会话的子代理槽位。嵌套 编排器的子项使用该编排器的预算,而不是其父级的预算。

预算属于子项的直接派生/控制会话。 更改子项完成的投递位置不会将其执行 移动到另一个会话的预算中。超过执行上限的已接受运行会排队,直到 有空闲槽位。

Swarm 收集器子项(collect: true)改用专用 subagent:swarm:<schedulerGroupKey> 通道。其上限是该组解析后的 tools.swarm.maxConcurrent(默认 32),独立于父级的普通 subagent:<immediate session> 通道。来自同一父级的普通派生 可以在其 Swarm 通道已满时开始。由收集器派生的普通子项使用 该收集器自己的会话通道。每个运行中的收集器消耗一个模型流 和一个 Code Mode 工作器隔离;根据 Gateway 的资源调整 Swarm 上限。

maxChildrenPerAgent 是每会话活动子项的单独准入限制 (默认 5);提高执行并发不会提高该 限制。收集器准入改用 Swarm 的 maxChildrenPerGroup(默认 50)和 maxTotalPerGroup(默认 200);提高执行并发不会 提高任一组限制。Codex 原生子代理 使用 Codex 自己的调度器 和限制,独立于这些 OpenClaw 队列。

挂起的完成投递不会阻塞新工作。原生子代理、ACP 会话和可见会话保留其正常活动运行限制和 授权检查,独立于投递积压。

当投递积压达到 25 时,OpenClaw 会发出警告。在 Gateway 进程中, 未变化的积压计数不会每次扫描都重复警告。计数变化 达到或超过 25,或恢复后回到该阈值,会产生新 警告。积压大小不会丢弃结果或更改其保留。

存活与恢复

OpenClaw 不会将 endedAt 缺失视为子代理 仍然存活的永久证明。当读取进程可以验证当前 执行所有者或精确的排队收集器预留时,未结束的运行无论年龄多久都继续 计数。仅持久化元数据不会在另一个进程中确立该 所有权。其他未结束的运行在过期运行窗口后停止计为活动/待定 (2 小时,或配置的运行超时加上短暂宽限期, 以较长者为准)。这些保留计数控制 /subagents list、 状态摘要、后代完成门控和每会话并发 检查;它们不是执行器存活的证明。

在优雅重启期间,已准入的替换运行可以在关闭前完成 刷新延迟子结果。刷新保持被跟踪, 直到捕获和持久化完成;它不会准入新运行。

Gateway 重启后,父级拥有用户任务的续接。 中断的子代理通过其正常完成路径终结,而不是 自动重新启动。其结果告诉父级执行被 中断,并且部分完成的操作需要检查。等待 其子项批次的父级会收到已结算结果,包括在重启前完成的 子项,并决定剩余工作。

对于已让渡的嵌套请求方,已准入的完成轮次不同于 孤儿子项启动。其冻结的子结果批次在重启中保留精确的 保存续接。注册表恢复等待该所有者,而不是 在相同续接被重放时报告中断。这 不授权自动重新启动无关的中断子项工作。

恢复处理标记为 abortedLastRun: true 的会话以及阻止关闭标记写入的强制终止。对于强制终止,子项 会话仍必须识别来自已退役 Gateway 的精确运行,且没有更新的 运行或已准入工作拥有该会话。活动执行和排队收集器 保留其现有所有者。孤儿运行在清理前结算其原生执行状态, 因此保留的子项会话不会留下幻影运行活动。 如果结算失败,完成仍可用于重试。

恢复记住活动会话所有权,而不保留保存的 Prompt 快照。 未变化的拥有行跳过会话读取;所有权释放或已发布的会话 变更请求在一秒内进行另一次扫描。不可用的恢复读取按行重试, 指数退避从一秒到一分钟。注册表生命周期 变更和会话发布会清除该退避。没有活动 所有者的持久化行在恢复可以更改其状态前仍需要新鲜读取。

启动会话维护在一个信息性 摘要中报告保留的运行/任务所有者。这些行保留在注册表恢复中;仅会话的孤儿修复 不会竞争其所有权。修复期间的所有权变更和失败 所有权检查仍会产生警告。

父级可以检查保留的子项转录,并使用 sessions_send 继续该会话,或在确认旧执行 已停止后派生替换。重用子项会恢复其对话上下文;它不会重放 中断的命令。现有清理和保留设置仍适用。

当分离的清理尝试记录 subagent cleanup finalize failed 时,其 重试在当前 Gateway 进程中使用有界退避。如果这些重试 耗尽,运行仍记录为清理不完整;检查警告 以识别失败操作。无关的 子代理完成不会重启失败清理或重置其重试预算。 后代完成仍会唤醒等待该工作的当前请求方祖先。 这些清理重试独立于完成投递。

Note

如果子代理生成失败,并出现 Gateway PAIRING_REQUIRED / scope-upgrade,请在编辑配对状态之前检查 RPC 调用方。 当调用方已经运行在 Gateway 请求上下文中时,内部 sessions_spawn 协调会在进程内分发, 因此它不会打开 loopback WebSocket,也不依赖 CLI 的已配对设备 scope 基线。 Gateway 进程外的调用方仍使用 WebSocket 回退, 以 client.id: "gateway-client" 和 client.mode: "backend" 通过直接 loopback 共享令牌/密码认证。远程调用方、显式 deviceIdentity、显式 device-token 路径以及浏览器/Node 客户端 对于 scope 升级仍需要正常设备审批。

停止

针对父 run 的显式 Stop 会取消与该 run 关联的子项及其后代,包括普通子代理和 Swarm 收集器。成功取消会阻止选中的排队收集器启动,同时正在运行的子项停止。精确 run 取消不会取消 无关的 turn,也不会清除无关的会话级队列。

Stop 还会使所选工作的待处理完成续接失效,即使某个子项已经完成。取消一个完成 turn 会使匹配的子项批次失效,因此自动投递重试无法在新的 run ID 下再次启动它。已捕获的子项结果及其执行结果保持完整;之后你可以检查它们或发送新指令。

对于 Gateway 调用方,带 runId 的 chat.abort 使用此精确父级范围。 带 runId 的 sessions.abort 也针对该 run。当它解析一个没有 chat controller 的已恢复 native run 时,只有当捕获的活动父级接受 Stop 时才会取消子项;被拒绝或无活动 run 的结果(包括已经正在最终化的父级)会保持这些子项不变。

在请求方聊天中发送 /stop 具有更宽的范围:它会中止请求方会话工作,清除其队列,并取消其活动子树。会话级 sessions.abort 也会请求取消后代;清除排队的后续操作需要 clearQueued: true。不带 runId 的普通 chat.abort 不会级联到子项。这些操作保留其正常授权检查。

通过 chat.send 发送的类型化 /stop 会遵循 expectedLeafEntryId,并且当存在该分支检查时,还会遵循 sessionId。如果在后代取消期间检查失败,Gateway 会拒绝进一步取消并报告 active-leaf-changed。已被子项接受的取消仍会完成。

不完整的取消会报告为错误,而不是干净的成功。/stop 会报告实际停止和失败的子项数量。使用 subagents 检查剩余的 native 子代理 run,并重试它们的取消; 请求确认并不意味着所有运行时清理都是即时完成的。

已接受的子项在普通父级完成、yield 或超时后仍保持独立。这些事件不会自动取消它们。

限制

  • 直接 announce 尝试是尽力而为的,但已准入的会话排队完成交接及其 native 子代理记录会在共享 SQLite 状态数据库中跨 Gateway 重启保留。
  • 子代理仍共享相同的 Gateway 进程资源;并发上限按生成会话或 Swarm 组应用,而不是按 Gateway 总并发应用。
  • 当启动被接受时,sessions_spawn 返回 { status: "accepted", runId, childSessionKey },而不会等待子任务完成。Cloud-worker 生成可以在返回此回执之前等待配置完成。
  • 子代理上下文仅注入 AGENTS.md(没有 SOUL.md、IDENTITY.md、USER.md、MEMORY.md 或 BOOTSTRAP.md)。其 ## Tools 部分包含环境特定说明。Codex-native 子代理通过 native AGENTS.md 发现遵循相同边界,而仅限父级的人格、身份和用户文件会作为 turn 范围的协作指令注入,以免子项克隆它们。
  • 默认启用递归生成,深度为 5。将 maxSpawnDepth 设置为 1 到 5 可降低边界。
  • maxChildrenPerAgent 限制每个会话的活动子项数量(默认 5,范围 1-20)。

本页原文 Markdown:在 AtomGit 查看·内容源自开源项目 cl/openclaw