OpenClaw 设计与实现

第18章 构建你自己的 Agent 帝国

作者 杨艺韬 · 10,193 字 · 发布于 · 更新于

第18章 构建你自己的 Agent 帝国

单 Agent 的天花板不是智能不够,而是上下文不够。200K token 听起来很多,但一次深度代码审查就可能吃掉 80K——还没开始回复,预算已去四成。多 Agent 编排的本质,是用会话隔离换上下文空间。

本章要点

  • 理解单 Agent 天花板的四个根本限制
  • 掌握树形编排模型与四种编排策略(顺序式、扇出/扇入、条件分支、事件驱动)
  • 深入多 Agent 编排的核心难题:委托准确性、上下文隔离、结果整合、孤儿 Agent
  • 规划从单 Agent 到 Agent 帝国的演进路径

18.1 从齿轮到机器

十七章,我们在源码层面逐一解剖了 OpenClaw 的每一个齿轮和螺钉——从 Gateway 的生命周期管理到 Provider 的模型降级,从 Session 的上下文压缩到安全系统的纵深防御。每个组件都已了然于胸。

但零件堆在桌上不是机器。最后一章,我们将视线从微观拉升到宏观:如何将这些精密组件组装成一台运转的机器——一个你自己的 Agent 帝国?

理解每一个音符不等于能演奏交响曲。本章讲的是指挥的艺术——何时让铜管齐鸣,何时让弦乐独唱,何时所有声部在一个和弦上交汇。

18.2 单 Agent 天花板:四个根本限制

大多数人从单 Agent 开始——配置一个 Agent,连接一个通道,分配一个模型。这在简单场景下完美工作。但随着任务复杂度增长,单 Agent 会撞上四面墙:

18.2.1 上下文耗尽

即使 200K token 的上下文窗口也可能不够完成需要同时研究、编码和沟通的复杂任务。一次深度代码审查可能消耗 50K token 的代码内容 + 20K token 的讨论历史 + 10K token 的系统提示和技能——80K token 用完了,Agent 还没开始回复。

量化分析:假设一个"全栈任务"——研究技术方案(读 5 篇文章 × 5K token = 25K)、编写代码(读 10 个文件 × 3K token = 30K)、提交 PR 并写说明(5K)。仅输入就需要 60K token。如果上下文窗口是 128K,留给推理和对话历史的只有 68K——而且这还没算系统提示和工具定义。

18.2.2 焦点稀释

一个 Agent 同时处理编码、搜索和沟通,不如三个专家。系统提示因每种场景的指令而臃肿。

反事实分析:想象一个系统提示同时塞进"代码风格指南""搜索策略""沟通礼仪""安全规则"四段指令。Agent 在编码时,后三段每一轮都在被重发、被计费、被塞进注意力,却一个字都用不上。拆成三个专业 Agent 后,每个只带与自己角色相关的那一段——省下的比例取决于四段指令的相对体积,但方向是确定的:常驻开销从"所有场景的并集"降到"当前场景的子集"。

18.2.3 无并行性

独立子任务顺序执行。可以并行五个搜索的研究任务却要逐个等待。

时间成本:5 个搜索 × 每个 10 秒 = 50 秒(顺序)vs. 10 秒(并行)。独立子任务越多,顺序执行与并行执行的墙钟时间差距越大(并行度受并发上限约束,见 18.7.3)。

18.2.4 单点故障

模型调用在任务中途失败(且降级链也已耗尽),当前这一轮就中断。已完成的步骤和失败的步骤混在同一段对话里,很难只重做失败的那一步。

多 Agent 编排能缓解这四个限制。但它引入自己的挑战——这些挑战是本章的核心主题。

关键概念:树形编排模型(Tree Orchestration) OpenClaw 的多 Agent 编排采用树形结构——主 Agent 生成子 Agent,子 Agent 可进一步生成孙 Agent,层级有可配置的深度限制(默认 DEFAULT_SUBAGENT_MAX_SPAWN_DEPTH = 1,即子 Agent 默认就是叶子,不能再生成孙 Agent,要嵌套必须显式调大 agents.defaults.subagents.maxSpawnDepth,配置校验上限为 5)。树形结构的好处在于:它保证了清晰的父子关系、单一的控制链和可预测的资源管理。图形拓扑(任意 Agent 间通信)虽然更灵活,但会带来死锁风险、审计困难和资源管理的组合爆炸。

💡 最佳实践:从单 Agent 开始,只在遇到明确的瓶颈(上下文耗尽、焦点稀释、需要并行性)时才引入多 Agent 编排。过早的多 Agent 设计会增加调试复杂度和 Token 消耗——每个子 Agent 都需要独立的系统提示和上下文窗口。

🔥 深度洞察:多 Agent 编排的本质是组织设计,不是技术实现

单 Agent 到多 Agent 的跃迁,表面上是技术问题(如何 spawn 子 Agent、如何传递上下文),本质上却是组织设计问题。Herbert Simon 在 1962 年的论文《The Architecture of Complexity》中论证:复杂系统大多呈层级结构,因为由稳定的中间组件逐层组装起来的系统更容易形成、也更经得起扰动(他的钟表匠寓言);层级内部联系紧密、层级之间联系松散("近可分解性"),每一层基本只需通过接口与相邻层打交道,而非理解整个系统。OpenClaw 的树形 Agent 编排与此同构:主 Agent 不需要理解子 Agent 的内部推理,只需要理解它返回的结果。你不是在"设计" Agent 架构——你是在为 AI 劳动力做组织设计。招聘、分工、汇报关系、绩效评估——这些概念在 Agent 编排中一一对应。

18.3 树形编排:OpenClaw 的多 Agent 模型

18.3.1 为什么是树而不是图?

OpenClaw 的多 Agent 模型是一棵树:主 Agent 生成子 Agent,子 Agent 可以进一步生成孙 Agent,深度由 agents.defaults.subagents 相关配置约束。默认值相当保守——src/config/agent-limits.ts 里写着:

export const DEFAULT_AGENT_MAX_CONCURRENT = 4;
export const DEFAULT_SUBAGENT_MAX_CONCURRENT = 8;
// Keep depth-1 subagents as leaves unless config explicitly opts into nesting.
export const DEFAULT_SUBAGENT_MAX_SPAWN_DEPTH = 1;

也就是说:默认只有两层(主 Agent + 子 Agent),子 Agent 是叶子;全局最多 8 个子 Agent 运行并发;跨会话的 Agent 运行最多 4 个并行。此外单个会话同时活跃的子 Agent 默认最多 5 个(agents.defaults.subagents.maxChildrenPerAgent,见 src/agents/subagent-spawn.ts 的 maxChildren 判断)。下面 18.4.5 节讨论的深度限制不是经验之谈——它就是默认配置。

graph TD
    subgraph "图 18-1:树形 Agent 编排"
        Main["主 Agent<br/>(编排者)"]
        Sub1["子 Agent A<br/>(编码)"]
        Sub2["子 Agent B<br/>(研究)"]
        Sub3["子 Agent C<br/>(运维)"]
        Sub1A["孙 Agent A1<br/>(前端,需放宽深度)"]
        Sub1B["孙 Agent A2<br/>(后端,需放宽深度)"]
    end
    Main --> Sub1 & Sub2 & Sub3
    Sub1 --> Sub1A & Sub1B
    style Main fill:#c0392b,color:#fff
    style Sub1 fill:#1f618d,color:#fff
    style Sub2 fill:#1f618d,color:#fff
    style Sub3 fill:#1f618d,color:#fff
    style Sub1A fill:#95a5a6,color:#333
    style Sub1B fill:#95a5a6,color:#333

替代方案是图(任意 Agent 之间的通信)。为什么不选图?

图的问题1:死锁。Agent A 等待 Agent B 的结果,Agent B 等待 Agent A 的结果。在树中,通信只能沿着边(父→子或子→父)发生,消除了循环依赖的可能。

图的问题2:责任不清。如果 Agent A 和 Agent B 同时修改了同一个文件,谁的版本生效?在树中,父 Agent 协调子 Agent,天然是冲突的仲裁者。

图的问题3:调试地狱。在图中追踪"这个决策是怎么做出的"可能需要遍历整个图。在树中,因果链是从根到叶的清晰路径。

权衡:树限制了通信灵活性——兄弟 Agent 之间不能直接通信(必须通过父 Agent 中继;子 Agent 的工具策略始终禁用 sessions_send,源码注释写明"subagents communicate through announce chain",见 src/agents/pi-tools.policy.ts 的 SUBAGENT_TOOL_DENY_ALWAYS)。但这种限制恰好强制了一个健康的架构属性:每个 Agent 都有明确的上级,避免了"谁负责"的歧义。

18.3.2 两种生成模式

OpenClaw 提供两种子 Agent 生成模式:

run 模式(一次性执行):子 Agent 执行任务,返回结果,本次运行即结束。类似函数调用——有输入,有输出。注意子会话记录默认保留(cleanup 默认 "keep",显式传 cleanup: "delete" 才会在通知后删除)。

主 Agent → sessions_spawn(mode="run", "翻译这段文字为英文") → 子 Agent 执行 → 返回翻译 → 本次运行结束

session 模式(持久会话):子 Agent 完成任务后保持活跃,可以后续发送更多消息。类似启动一个服务——它持续运行直到显式关闭。它必须绑定到一个聊天线程(thread: true),否则直接报错 mode="session" requires thread=true;而线程绑定又要求所在通道插件支持(src/agents/subagent-spawn.ts 的 resolveSpawnMode 附近)。

主 Agent → sessions_spawn(mode="session", thread=true, "你是代码审查专家") → 子 Agent 常驻在该线程 → 可以多次发送代码审查请求

选择哪种模式取决于任务的交互性:一次性结果用 run;需要多轮交互用 session。

18.3.3 推送式完成通知

这在第17章已经从模式角度分析过,这里从实践角度补充。

子 Agent 完成时,结果作为普通消息回合投递给父 Agent——无轮询循环、无浪费 API 调用。完成通告通过子 Agent 注册表管理:

机制 细节 常量 / 位置
重试退避 1s → 2s → 4s…指数退避,封顶 8s(受 3 次上限限制,实际只用到前几档) MIN_ANNOUNCE_RETRY_DELAY_MS / MAX_ANNOUNCE_RETRY_DELAY_MS(src/agents/subagent-registry-helpers.ts)
重试上限 3 次 MAX_ANNOUNCE_RETRY_COUNT = 3(同上)
过期 普通通告 5 分钟;期待完成消息的通告 30 分钟硬限制 ANNOUNCE_EXPIRY_MS / ANNOUNCE_COMPLETION_HARD_EXPIRY_MS(同上)
幂等 稳定的 announceId 去重 src/agents/announce-idempotency.ts
宽限 生命周期 error 事件先缓 15 秒再判定失败 LIFECYCLE_ERROR_RETRY_GRACE_MS = 15_000(src/agents/subagent-registry.ts)
超时 通告流程等待子运行收尾、读取输出最多 2 分钟;向父会话投递的网关调用默认 90 秒超时,可用 agents.defaults.subagents.announceTimeoutMs 调整 SUBAGENT_ANNOUNCE_TIMEOUT_MS = 120_000(src/agents/subagent-registry.ts);DEFAULT_SUBAGENT_ANNOUNCE_TIMEOUT_MS = 90_000(src/agents/subagent-announce-delivery.ts)

为什么有 30 分钟硬限制? 如果完成通告 30 分钟内仍未投递成功,说明父 Agent 很可能已经崩溃或已被清理。继续重试只是浪费资源。放弃时日志会区分原因是 retry-limit 还是 expiry——这两种放弃对应完全不同的排障方向。

还有一个容易忽略的分支:如果子 Agent 自己还有活跃的后代在跑,清理会被推迟(kind: "defer-descendants")而不是直接放弃——先把子树收干净再报完成。

18.3.4 ACP:跨进程 Agent 通信

ACP = Agent Client Protocol——这是一个外部开放标准(agentclientprotocol.com),不是 OpenClaw 自研的协议。OpenClaw 在两个方向上使用它:作为客户端通过 ACP 后端插件驱动外部编码 harness(Pi、Claude Code、Codex、Cursor、Copilot、OpenCode、Gemini CLI 等),作为服务端用 openclaw acp 把自己暴露成一个 ACP agent,让支持该协议的 IDE 直接接进来。

graph LR
    subgraph "图 18-2:ACP 跨进程编排"
        OC["OpenClaw<br/>(编排层)"]
        CC["Claude Code<br/>(编码能力)"]
        Codex["Codex<br/>(编码能力)"]
        Custom["自定义 Agent<br/>(领域能力)"]
    end
    OC --> |"ACP"| CC
    OC --> |"ACP"| Codex
    OC --> |"ACP"| Custom
    style OC fill:#c0392b,color:#fff

ACP 的传输层是 stdio + NDJSON(每行一个 JSON 对象)——这是最通用的进程间通信方式,几乎所有编程语言和操作系统都支持,不需要特殊 SDK。

要注意 OpenClaw 自己那侧的定位:docs/cli/acp.md 写得很克制——"openclaw acp 是一个 Gateway 支撑的 ACP 桥接,不是完整的 ACP 原生编辑器运行时"。它实现了 initialize / newSession / prompt / cancel / listSessions 这些核心流程,loadSession、提示内容、工具流式输出是部分支持(例如 loadSession 只重放用户/助手的文本历史,不重建工具与系统消息),而按会话的 MCP 服务器、ACP 客户端文件系统方法(fs/read_text_file 等)、客户端终端方法(terminal/*)则明确不支持。仓库里有一张完整的兼容性矩阵——"支持某协议"从来不是一个布尔值,读的时候要读到这一层。

即便如此,这一步仍然把 OpenClaw 从单体运行时推向了编排层——它不必自己实现所有 Agent 能力,而是协调最适合每项任务的 Agent 运行时。

操作面上,ACP 会话由 /acp 系列命令驱动:/acp spawn codex --bind here、/acp status、/acp model <provider/model>、/acp steer <指令>(不替换上下文地推一把)、/acp cancel、/acp close。

18.4 编排模式:四种策略

18.4.1 顺序式编排

步骤逐一执行。简单可靠,但不利用并行性。

步骤1:研究技术方案 → 步骤2:编写代码 → 步骤3:编写测试 → 步骤4:提交 PR

适用场景:步骤之间有严格依赖——后一步需要前一步的输出。

18.4.2 扇出/扇入编排

同时生成多个子 Agent,等待全部完成,处理组合结果。

         ┌→ 子Agent A(搜索技术方案)→┐
主Agent →├→ 子Agent B(搜索竞品分析)→├→ 主Agent 综合结果
         └→ 子Agent C(搜索用户反馈)→┘

适用场景:独立子任务可并行执行——如搜索、翻译、代码分析。

关键挑战:如何综合多个子 Agent 的结果?如果三个搜索子 Agent 返回了矛盾的信息怎么办?主 Agent 需要有足够的判断力来消歧。

18.4.3 条件分支编排

根据子 Agent 结果决定继续、重试或升级。

主Agent → 子Agent(编码)→ 结果
  如果成功 → 继续下一步
  如果失败(可恢复)→ 重试,提供更多上下文
  如果失败(不可恢复)→ 升级到人类

适用场景:需要根据中间结果调整策略——代码审查中发现严重问题时切换到深度分析模式。

18.4.4 事件驱动编排

最灵活的模式——不预先规划所有步骤,而是动态响应每个完成事件。

子Agent A 完成 → 根据结果决定启动子Agent D 或 E
子Agent B 完成 → 检查与 A 的结果是否冲突
子Agent D 完成 → 所有前置条件满足,生成最终报告

适用场景:探索性任务——事先不知道需要多少步骤或哪些子任务。

18.4.5 深度限制

OpenClaw 的默认配置直接把答案写死了:DEFAULT_SUBAGENT_MAX_SPAWN_DEPTH = 1——默认就只有两层(主 + 子),子 Agent 是叶子。要允许孙 Agent 必须显式放宽配置。

为什么默认这么保守?两个原因:

  1. 信息损失:每一层传递时都会丢失上下文。主 Agent 的指令到达孙 Agent 时,子 Agent 的理解可能已经过滤掉部分信息。
  2. 调试复杂度:调试两层编排需要检查两个对话历史,调试三层需要检查三个;层数越多,追溯一个决策的来龙去脉越费力。

18.5 多 Agent 编排的核心难题

18.5.1 委托准确性问题

多 Agent 编排的最大挑战不是技术实现——而是委托准确性。当主 Agent 向子 Agent 描述任务时,自然语言的模糊性可能导致理解偏差。

问题:"修复这个 bug" — 修复到什么程度?是否需要添加测试?是否需要更新文档?子 Agent 如何判断"修复完成"?

缓解策略:

  1. 结构化任务描述:不说"修复这个 bug",而说"文件 X 第 Y 行的空指针异常,原因是 Z 可能为 null,修复方案:添加 null 检查。完成标准:修改通过现有测试,不引入新的类型错误。"
  2. 明确的成功标准:告诉子 Agent "完成后运行 npm test,如果所有测试通过就算完成"。
  3. 约束边界:告诉子 Agent "只修改 src/utils/ 下的文件,不要碰 src/agents/"。

18.5.2 上下文隔离问题

子 Agent 有独立的上下文窗口——它看不到主 Agent 的对话历史。这意味着主 Agent 必须在任务描述中包含所有子 Agent 需要的上下文。

权衡:传递太少上下文,子 Agent 可能做出错误决策(因为缺少信息)。传递太多上下文,消耗子 Agent 的上下文窗口空间(留给实际工作的空间减少)。

最佳实践:传递"最小充分上下文"——子 Agent 完成任务所需的最少信息。这需要主 Agent 有能力判断"哪些信息是子 Agent 需要的"——这本身是一个需要智能的判断。

18.5.3 结果整合问题

当多个子 Agent 返回结果时,主 Agent 需要整合它们。如果结果是互补的(不同角度的研究),整合相对简单。如果结果是矛盾的(两个编码方案冲突),整合需要判断和决策能力。

18.5.4 孤儿 Agent 问题

如果主 Agent 崩溃或遭到清理,正在运行的子 Agent 变成"孤儿"——没有父 Agent 接收它们的结果。

OpenClaw 相关的机制有几个:

  • 运行超时:可以给子 Agent 设最大运行时间(sessions_spawn 的 runTimeoutSeconds,或 agents.defaults.subagents.runTimeoutSeconds);两者都没设时默认 0,即不限时(src/agents/subagent-spawn.ts)。
  • 重启恢复:网关重载打断了正在跑的子 Agent 时,重启后会扫描这些被中断的子会话,给它们发一条合成的续跑消息让工作继续,而不是清理掉(src/agents/subagent-orphan-recovery.ts)。
  • 通告过期:普通通告 5 分钟、期待完成消息的通告 30 分钟后过期,系统最终放弃投递孤儿的结果。

18.6 安全边界:多 Agent 的安全挑战

18.6.1 信任传递问题

假设主 Agent 用的是 full 工具档位。它生成的子 Agent 应该继承这些权限吗?

完全继承:子 Agent 拥有主 Agent 的所有权限。简单但危险——提示注入攻击一旦突破子 Agent,攻击者即获得完整权限。

最小权限:子 Agent 只获得完成任务所需的最少权限。更安全但更复杂——主 Agent 需要判断"完成这个任务需要哪些权限"。

OpenClaw 的方案:子 Agent 的工具集仍由同一条策略管线按目标 Agent 的配置解析(同 Agent 生成的子 Agent 沿用该 Agent 的工具档位,跨 Agent 生成则用目标 Agent 的),在此之上再叠加一级 subagent 策略:始终禁用 gateway、agents_list、whatsapp_login、session_status、cron、sessions_send,叶子子 Agent 还禁用 sessions_spawn、subagents、sessions_list、sessions_history;可以用 tools.subagents.tools 的 allow / alsoAllow / deny 调整(src/agents/pi-tools.policy.ts)。

18.6.2 凭证隔离

子 Agent 不应该看到主 Agent 的所有凭证。要分清两种子 Agent:原生子 Agent 和父 Agent 在同一个网关进程里运行,隔离的是会话而不是进程;通过 ACP 拉起的外部编码 harness 才是独立子进程,技能系统的 getActiveSkillEnvKeys()(第16章)让 OpenClaw 在拉起它时从子进程环境中剥离技能注入的密钥(src/acp/client.ts)。

18.6.3 工作区隔离

多个子 Agent 同时操作文件系统时,需要避免冲突。先看 OpenClaw 的默认行为和现有机制:

  • 默认共享工作区:同一 Agent 生成的子 Agent 自动继承父 Agent 的工作区目录(sessions_spawn 的工具描述:"Subagents inherit the parent workspace directory automatically");跨 Agent 生成时用目标 Agent 自己的工作区。想让子 Agent 各干各的,要在任务描述里划清目录边界,或把任务派给配置了不同工作区的 Agent。
  • 文件锁只管 OpenClaw 自己的状态文件:会话转录、会话存储、Auth Profile 等有写锁(如 src/agents/session-write-lock.ts),工作区里的业务文件没有——两个子 Agent 改同一个文件,谁后写谁生效。
  • 沙箱:开启 agents.defaults.sandbox(默认 mode: "off")后,子 Agent 会话可以在容器里运行;sessions_spawn 的 sandbox: "require" 要求目标运行时必须带沙箱,已沙箱化的会话也不能生成未沙箱化的子 Agent(src/agents/subagent-spawn.ts)。

18.7 企业级设计原则

将 Agent 编排从个人实验提升到生产系统,需要遵循几个原则:

18.7.1 可观测性

你无法管理你看不见的东西。

结构化日志与父子关系:网关的文件日志按 JSON Lines 写入(src/logging/logger.ts);父子关系记录在会话存储条目的 spawnedBy 字段(src/config/sessions/types.ts)和子 Agent 注册表里,据此可以重建编排树。

用量追踪:Token 消耗可以按会话、按 Agent、按模型/Provider、按通道汇总(网关的 sessions.usage 方法,src/gateway/server-methods/usage.ts)。这让运营者能回答"这个工作流花了多少钱?哪个子 Agent 最贵?"。

生命周期事件:子 Agent 的生成与结束会触发插件钩子 subagent_spawned / subagent_ended(结束结果区分完成、失败、超时等)。监控系统可以基于这些事件构建告警。

18.7.2 容错

生产系统不能假设一切正常。

模型回退(第 4 章 §4.2.3、第 17 章 §17.5):每个 Agent(以及子 Agent 默认模型 agents.defaults.subagents.model)都可以配置自己的 { primary, fallbacks } 降级链,候选模型要写全 provider/model。子 Agent A 的主模型遇到限流或认证错误时,先轮换 Auth Profile,都不行再按降级链换到下一个模型(如 openai/gpt-4o),不影响子 Agent B;上下文溢出则直接重新抛出、不换模型,交给压缩处理。降级链没有总时间预算,每个候选模型各自计时。

上下文压缩:长对话自动压缩,保留标识符。

超时保护:可以给子 Agent 设最大运行时间(runTimeoutSeconds),防止失控的子 Agent 无限期运行。默认值是 0(不限时),生产环境要显式配置。

18.7.3 成本控制

多 Agent 编排的成本可以快速失控。

逐 Agent 模型选择:编排者用 Claude Opus(需要判断力),研究者用 GPT-4o-mini(需要大量搜索但判断简单),编码者用 Claude Sonnet(平衡能力和成本)。

深度限制:DEFAULT_SUBAGENT_MAX_SPAWN_DEPTH = 1——默认就只有两层,防止递归生成把树炸开。

并行限制:DEFAULT_SUBAGENT_MAX_CONCURRENT = 8(全局子 Agent 并发上限)与 DEFAULT_AGENT_MAX_CONCURRENT = 4(跨会话的 Agent 运行并发上限),分别可用 agents.defaults.subagents.maxConcurrent 和 agents.defaults.maxConcurrent 调整。这两个数字是成本的直接闸门——并发翻倍,同一时刻的 token 燃烧速度就翻倍。想知道实际花了多少,用 openclaw gateway usage-cost --days <N> 量,别估。

18.8 实战推演:多 Agent 协同完成技术文档翻译

让我们用一个真实的工作流,展示多 Agent 编排的完整过程和常见陷阱。

18.8.1 任务

将一份 50 页的技术文档从中文翻译为英文,要求术语一致、风格统一。

18.8.2 单 Agent 方案的问题

直觉做法:让一个 Agent 从头翻到尾。问题是什么?

50 页源文本 + 系统提示 + 工具定义 + 术语表,全部塞进一个上下文窗口
→ 留给输出和对话历史的空间被挤到很小
→ 翻到中后段时上下文压缩开始生效,早期译文的风格记忆被摘要掉
→ 结果:前后风格不一致,术语翻译出现漂移

(具体数字取决于文档密度与所用模型,这里要看的是趋势:源文本占比越高,留给"记住自己刚才怎么译的"的空间越少。)

18.8.3 多 Agent 编排方案

主 Agent(编排者)
├── 术语 Agent:先扫描全文,提取术语表 + 翻译规范
├── 翻译 Agent ×5(并行):每个负责 10 页,携带术语表
│   ├── 翻译 Agent A: 第 1-10 页
│   ├── 翻译 Agent B: 第 11-20 页
│   ├── 翻译 Agent C: 第 21-30 页
│   ├── 翻译 Agent D: 第 31-40 页
│   └── 翻译 Agent E: 第 41-50 页
└── 审校 Agent:对 5 个翻译结果做一致性检查

18.8.4 编排者的任务描述(关键)

你是翻译项目的编排者。任务分四个阶段:

阶段1: 生成术语 Agent,提取全文术语表。
  输入: 原文 50 页
  输出: { "网关": "Gateway", "提供商": "Provider", "会话": "Session", ... }

阶段2: 并行生成 5 个翻译 Agent,每个接收:
  - 10 页原文
  - 术语表(必须严格遵守)
  - 风格指南: "技术文档风格,简洁准确,避免口语化"
  完成标准: 每个返回完整翻译文本

阶段3: 收集 5 份翻译结果后,生成审校 Agent:
  - 检查术语一致性(同一术语是否全文统一)
  - 检查章节衔接(第10页末尾和第11页开头是否连贯)
  - 输出修正列表

阶段4: 应用修正,合并为最终文档

18.8.5 时间和成本对比

三种方案的差异不在绝对数字,而在各项指标的变化方向:

方案 墙钟时间 Token 总量 术语一致性
单 Agent 顺序翻译 最长(50 页串行) 最低(无额外开销) 差(后段漂移)
5 Agent 并行翻译 大幅缩短 略增(术语表要重复传 5 份) 仍差(各译各的)
5 Agent + 术语 + 审校 比纯并行略长 最高(多两轮 Agent) 好(先统一、后校对)

这是多 Agent 编排的典型权衡:用 token 成本换墙钟时间和质量。想知道自己这份文档到底换了多少,翻译完跑一次 openclaw gateway usage-cost --days 1 就能看到当天的用量与成本(它按天汇总所有会话,不单列这一个工作流;要按会话拆分,看网关的 sessions.usage)——本专栏不替你估,因为估出来的数字对你的文档没有意义。

有一点是确定的:并行不会减少总 token,只会减少等待。5 个子 Agent 各译 10 页,加起来的输入 token 并不比一个 Agent 译 50 页少,还要多付术语表 ×5 的重复开销。你买到的是时间,付出的是 token。

多 Agent 编排不是"让更多 Agent 做同一件事"——而是"让不同 Agent 做不同的事,然后有人来确保它们的成果能拼在一起"。这和管理一个翻译团队完全一样:你不会让 5 个翻译各自为战,你会先统一术语表,再分工翻译,最后统一审校。Agent 编排的艺术,就是把人类团队管理的智慧翻译成配置和提示词。

18.9 要避免的反模式

18.9.1 过度委托

为每个小任务生成子 Agent 增加开销。如果任务可以在单次工具调用中完成(如 exec("git status")),直接执行比 spawn 一个子 Agent 更高效。

经验法则:如果任务需要少于 3 次工具调用,直接做。如果需要超过 10 次工具调用或需要独立上下文,spawn 子 Agent。

18.9.2 任务规格不足

"修复这个 bug" 导致子 Agent 困惑。有效委托需要:

  • 清晰的目标描述
  • 明确的成功标准
  • 操作范围约束
  • 必要的上下文信息

18.9.3 深层嵌套

三层以上的 Agent 树几乎总是可以重构为更扁平的结构。深层嵌套增加了信息损失、调试复杂度和延迟。

18.9.4 轮询结果

信任推送式通知系统。如果你发现自己写了 sessions_list 轮询循环,说明你在对抗框架而非利用它。

⚠️ 常见陷阱:子 Agent 结果轮询

OpenClaw 使用推送式完成通知,子 Agent 完成后结果自动投递给父 Agent。不要编写轮询循环检查子 Agent 状态:

❌ 错误:反复调用 sessions_list 检查子 Agent 状态——每一轮都是一次完整的模型调用
✅ 正确:调用 sessions_yield 结束本回合;子 Agent 完成后,结果会作为新的消息回合自动到达

sessions_yield 在工具目录里的描述就一句话——"End turn to receive sub-agent results"(src/agents/tool-catalog.ts)。它不是"等待",是"让出":父 Agent 主动结束当前回合去睡觉,被完成通知叫醒。如果你发现自己需要轮询,说明你在对抗框架设计。

⚠️ 常见陷阱:并行子 Agent 的资源竞争

默认配置下,单个会话同时活跃的子 Agent 最多 5 个(maxChildrenPerAgent),全局子 Agent 并发最多 8 个;即便在这个范围内,多个子 Agent 同时打同一个 Provider 也可能触发 API 速率限制。建议:

  • 为不同子 Agent 配置不同的 Auth Profile——但前提是这些 Key 的限额彼此独立;像 Anthropic 这样按组织计限额的厂商,同一组织下的多个 Key 共享配额,轮换帮不上忙
  • 或调低并发(agents.defaults.subagents.maxConcurrent / maxChildrenPerAgent)
  • 或混合使用不同 Provider(编码用 Claude,搜索用 GPT)

18.10 演进路径

graph LR
    subgraph "图 18-3:Agent 帝国演进路径"
        S1["第1步<br/>单 Agent<br/>一个Agent<br/>一个通道"]
        S2["第2步<br/>双 Agent<br/>主+辅<br/>多通道"]
        S3["第3步<br/>角色团队<br/>编码+研究+运维<br/>专业化"]
        S4["第4步<br/>自动化<br/>Cron+心跳<br/>主动运营"]
        S5["第5步<br/>生态系统<br/>ACP跨进程<br/>外部Agent"]
    end
    S1 --> S2 --> S3 --> S4 --> S5
    style S1 fill:#1f618d,color:#fff
    style S5 fill:#1e8449,color:#fff

每一步都建立在前一步的基础上。不要跳步——单 Agent 都没用好就开始多 Agent 编排,只会放大问题而非解决问题。

18.10.1 从第1步到第2步:何时需要第二个 Agent?

信号:

  • 你发现自己经常在聊天中切换话题("先不说代码了,帮我查一下...")
  • 无关历史经常填满 Agent 的上下文
  • 你希望一个 Agent 24/7 运行监控,另一个按需使用

18.10.2 从第2步到第3步:何时需要角色专业化?

信号:

  • 不同任务需要不同的系统提示和技能集
  • 你开始为不同场景切换模型
  • Agent 的通用指令开始互相矛盾("简洁回复" vs. "详细解释")

18.11 未来方向

18.11.1 标准化 Agent 间通信

行业需要开放标准——如同 HTTP 统一了 Web 通信、REST 统一了 API 设计。目前 Agent 间通信仍是多个协议并存、各框架自有一套的局面。

这里要澄清一个常见误解:ACP(Agent Client Protocol)不是 OpenClaw 发明的,它是一个独立的开放标准(agentclientprotocol.com),OpenClaw 只是同时实现了它的两端——作为客户端驱动外部 harness,作为服务端(openclaw acp,stdio + NDJSON)让 IDE 接入。这恰恰是标准化该有的样子:协议归协议,实现归实现。但真正的标准化仍需行业共识——类似 W3C 之于 Web 标准的角色。

18.11.2 自治-监督光谱

从完全手动到半自动到完全自主的平滑过渡,能力边界随信任增长。

初级自治:Agent 提出建议,人类批准。 中级自治:Agent 自主执行常规操作,异常时升级。 高级自治:Agent 自主执行大多数操作,仅在高风险决策时征求人类意见。

OpenClaw 的安全系统(第13章)和 Exec 审批流支持这种渐进式信任的建立。

18.11.3 自改进 Agent

从成功任务完成中提取程序性知识——自动生成可复用的技能定义。这形成正反馈循环:

成功完成任务 → 提取操作模式 → 生成 SKILL.md → 下次同类任务更高效

OpenClaw 的技能系统(Markdown 格式、文件系统存储)天然支持这种自改进——Agent 可以使用 write 工具创建新的 SKILL.md 文件。

18.11.4 Agent 生态系统

跨组织边界的独立 Agent 网络。你的 Agent 和我的 Agent 能够发现彼此、协商能力、安全地协作。

需要解决的核心问题:

  • 身份:如何验证远程 Agent 的身份?
  • 能力发现:如何知道远程 Agent 能做什么?
  • 信任建立:没有共同运营者的两个 Agent 如何建立信任?
  • 安全通信:如何防止中间人攻击和数据泄露?

这些问题没有简单的答案——它们与 Web 在 90 年代面临的问题本质相同,可能需要类似 DNS、HTTPS、OAuth 的一系列基础设施标准来解决。

18.11.5 AI Agent 领域的行业趋势

站在本专栏成稿的时间节点,几个行业趋势正在塑造 Agent 系统的走向(以下均为趋势判断和预测,天然带时效性,读到这里时请自行对照当下):

模型能力的快速提升。从 GPT-4 到 Claude Opus 再到下一代模型,上下文窗口从 8K 扩展到 200K 甚至更长,推理能力和工具使用精度持续提升。这意味着 OpenClaw 的上下文管理策略(压缩、分层加载、Token 预算)需要持续适配——当模型能处理百万 Token 上下文时,压缩策略的触发阈值和方式都需要重新校准。

Agent-as-a-Service 的兴起。越来越多的模型厂商和云平台开始提供托管的 Agent 运行时与工具调用基础设施。这些服务降低了入门门槛,但也引入了供应商锁定。OpenClaw 的 Provider 无关设计(第 4 章)在这个趋势中格外有价值——它让运营者可以在自托管和云服务之间自由迁移。

计算机使用(Computer Use)范式。Agent 不再只调用 API——它们开始直接操作图形界面,像人类一样使用浏览器、桌面应用和移动设备。OpenClaw 的 Node 系统(第 11 章)和浏览器控制工具已经在这个方向上迈出了一步。随着视觉-语言模型的成熟,Agent 与数字世界的交互方式将从"结构化 API"扩展到"像人类一样看和操作"。

安全与合规的硬约束。随着 Agent 系统进入金融、医疗、法律等受监管行业,安全不再是可选项而是准入条件。OpenClaw 的多级工具策略管线、Exec 审批流和审计日志(第 13 章)这类机制,有望成为行业标配。未来可能需要更细粒度的合规框架——比如 SOC 2 认证的 Agent 运行时、符合 GDPR 的上下文管理。

开放标准的竞争与融合。MCP(Model Context Protocol)、ACP(Agent Client Protocol)、A2A(Agent-to-Agent)等协议正在竞相成为 Agent 通信的"HTTP"。最终胜出的可能不是单一协议,而是分层互补的协议栈——类似网络世界中 TCP/IP + HTTP + REST 的层次关系。OpenClaw 对 ACP 的支持和对 MCP 的兼容,体现了务实的"协议无关"立场。

💡 给读者的建议:技术趋势的细节会快速过时,但底层的设计原则——抽象化、可替换性、纵深防御——不会过时。当新的模型能力或协议标准出现时,问自己:"OpenClaw 的哪个抽象层需要更新?"而不是"要推翻重来吗?"好的架构让变化成为局部修改,而非系统重写。

18.12 反思

18.12.1 Agent 是放大器,不是替代品

精心配置的 Agent 团队能显著放大个人执行能力。在不少场景下,一个人加上 Agent 能完成以前需要一个小团队分担的工作。

但 Agent 不消除复杂性——它转移复杂性。从编码转移到配置与编排,从执行转移到监督与判断,从亲手做事转移到定义"做什么"和"做到什么程度算完"。你从工匠变成了工头——手上不再沾泥,脑子里却要装下整个工地。认知负荷没有蒸发,只是换了形态。

18.12.2 可靠性悖论

Agent 系统越自主,其失败模式越难预测。

一个只执行 git status 的 Agent 几乎不会出错。一个自主决定"先研究、再编码、再测试、再部署"的 Agent 可能在任何一步做出意外决策。

这就是为什么 OpenClaw 强调安全机制和人类监督——不是出于对 AI 的不信任,而是出于对复杂系统不可预测性的尊重。多级工具策略管线、Exec 审批流、安全审计——这些不是对 Agent 能力的限制,而是让 Agent 能力变得可信赖的基础设施。

18.12.3 精密工程的启示

研究 OpenClaw 源码后最深刻的体会:优秀的 Agent 系统从来不是魔法——而是精密的工程。

每个看似简单的功能背后都有数百行处理边界情况、错误恢复和安全防护的代码:

  • 7 级默认工具策略管线,调用处再追加 sandbox 与 subagent 两级(不是一个 if)
  • 技能目录的三层格式降级:完整 → 紧凑 → 二分截断(不是直接砍掉尾巴)
  • 分层的安全模型:工具策略、exec 审批、SSRF 防护、凭证引用、安全审计(不是一道防火墙)
  • 带退避重试、双档过期、幂等去重和后代延迟清理的推送式通告队列(不是一个简单回调)

这些都不华丽。但都不可或缺。

18.13 核心技术要点回顾

回顾全部十八章,提炼五条贯穿全专栏的核心原则:

1. Token 预算就是架构。 系统提示中节省的每个 token 都是用户上下文可用的 token。工具输出的压缩不是优化——它决定了 Agent 能做多少事。按需加载不是性能技巧——它是让大量技能共存的前提。

2. 安全是一个光谱。 没有单层足够。纵深防御——捕获不同风险类别的多个独立层——是唯一健壮的方法。每一层都假设其他层可能失败。

3. 推送胜过轮询。 经济学清晰:轮询成本随子 Agent 数量和运行时间线性增长;推送成本只与通告次数有关,与子 Agent 跑多久无关。推送式编排天然适配 LLM 的回合制交互模型。

4. 配置即代码。 将 Agent 配置视为版本控制、测试、可审查的工件。追踪和审计配置变更应该和代码变更同等严格。

5. 处处优雅降级。 问题不是"一切正常时怎样?"而是"出错时怎样?"在每个层级优先降级运行而非完全失败。模型不可用时换模型。出站消息投递失败时入队重试。技能超预算时格式降级。

18.14 本章小结

本专栏始于"为什么需要 OpenClaw",终于"构建你自己的 Agent 帝国"。十八章,我们从最深的源码攀升到最高的架构制高点。

贯穿全专栏的五大设计哲学——通道无关(Channel-agnostic)、模型无关(Provider-agnostic)、运行时而非框架(Runtime over Framework)、约定优于配置(Convention over Configuration)、渐进式复杂度(Progressive Disclosure)——不仅是 OpenClaw 的设计原则,也是构建任何生产级 Agent 系统时值得借鉴的通用智慧。

本专栏想说的是:你不需要一支军队来建造有价值的东西。你需要的是理解——理解工具如何工作、为什么如此设计、以及在哪些地方它会让你失望。 十八章的源码解读不是为了让你记住 OpenClaw 的每一行代码,而是为了让你面对任何 Agent 系统时,都能问出正确的问题。

思考题

  1. 概念理解:多 Agent 协作中,"树形编排"和"扁平编排"各有什么优劣?在什么场景下扁平编排可能优于树形?
  2. 实践应用:设计一个由 5 个 Agent 组成的团队来运营一个开源项目——包含 Issue 分类、代码审查、文档更新、发布管理和社区互动。描述每个 Agent 的角色定义、它们之间的通信模式,以及你会如何处理 Agent 之间的冲突。
  3. 开放讨论:本专栏以"你不需要一支军队就能构建有价值的东西"结尾。在你看来,个人开发者 + AI Agent 团队的模式能扩展到什么规模?这种模式的天花板在哪里?

📚 推荐阅读