OpenClaw 篇八:配置多 Agent 解决不同问题

1次阅读
没有评论

共计 10558 个字符,预计需要花费 27 分钟才能阅读完成。

在前面几篇文章中,我们介绍了 [[OpenClaw]] 的安装方法工作原理飞书接入Skills 系统长期记忆。到这里,你手上已经有了一个功能齐全、能跨平台交互、会记事、有技能的 AI 助手。但随着使用场景的增多,你会越来越明显地感受到一个问题——让同一个 Agent 同时处理写代码、做调研、跑自动化任务这些完全不同性质的工作,它的表现反而在下降。上下文互相污染、工具权限过于宽泛、不同任务之间的风格混乱,这些问题在单 Agent 架构下几乎无解。这一篇我们就来解决这个问题——在一个 Gateway 里配置多个 Agent,让不同的任务交给不同的大脑去处理。

默认 Agent

默认情况下 OpenClaw 是单 agent 模式,agentId 默认就是 main,其 session 以 agent:main:<mainKey> 为键,workspace 默认位于 ~/.openclaw/workspace,状态文件存放在 ~/.openclaw/agents/main/agent 。

为什么需要多 Agent

先说说我自己遇到的真实场景。我日常用 OpenClaw 主要做三类事情:写代码和改配置、查资料和做分析、跑一些定时的自动化任务。刚开始我把所有事情都交给同一个 Agent,效果还行。但用了一段时间之后,问题逐渐暴露出来了。

第一个问题是上下文污染。当我让 Agent 帮我写一段 Python 脚本的时候,它的上下文窗口里可能还残留着昨天帮我查的日股分析资料、前天跑的一个 Cron 任务的日志。这些无关的信息不仅浪费了宝贵的 token 额度,还会在某些情况下干扰模型的输出质量,比如 Agent 可能在代码注释里莫名其妙地引用投资术语。

第二个问题是工具权限过于宽泛。编程 Agent 需要文件读写和 Shell 命令执行的权限,这很合理。但如果这个 Agent 同时也被暴露在一个多人群聊里回答问题,那安全隐患就不小了。你总不希望群里有人随便发一条消息就触发了服务器上的命令执行。

第三个问题是模型成本失控。不是所有任务都需要最强的模型。日常闲聊用 [[Claude]] Sonnet 就绰绰有余,但复杂的代码重构可能需要 Claude Opus 级别的推理能力。如果所有任务都走同一个模型配置,要么是浪费钱,要么是关键任务效果不够好。

多 Agent 的方案本质上是一种关注点分离的策略,和软件工程里的单一职责原则一脉相承。每个 Agent 只关注自己擅长的领域,拥有恰好够用的工具和权限,维护独立的上下文和记忆。这样不仅能提升各自的响应质量,也让整个系统的安全边界更加清晰。

多 Agent 的架构基础

在 OpenClaw 的体系里,一个 Agent 不是简单的"提示词角色切换",而是一个完整的隔离单元。每个 Agent 拥有以下独立资源:

  • 独立的 Workspace 目录,包含各自的 SOUL.mdAGENTS.mdUSER.md 和记忆文件
  • 独立的 agentDir,存放认证配置和模型注册信息
  • 独立的 Sessions,会话历史完全隔离
  • 独立的工具权限和沙箱配置

这意味着你给编程 Agent 的 SOUL.md 里写的"说话直接高效、先给方案再解释原理"这种人格设定,不会影响到调研 Agent 的"分析全面、引用来源、给出多角度观点"的风格。两个 Agent 之间的记忆也是完全隔离的,编程 Agent 记住了你偏好 TypeScript 而不是 JavaScript,调研 Agent 并不会知道这件事。

整个多 Agent 系统由三层配置构成:

  • agents.list:定义每个 Agent 的身份、工作空间、模型、工具和运行时
  • bindings:定义消息路由规则,把某个渠道、账号或对话映射到指定的 Agent
  • runtime 分层:同一个 Agent 还可以把任务交给 subagent 或通过 [[Agent Client Protocol|ACP]] 调用外部代码智能体
消息渠道(Telegram / WhatsApp / Discord / 飞书)
        ↓
    Gateway 网关
        ↓ bindings 路由匹配
   ┌────┼────┬────┐
   ↓    ↓    ↓    ↓
 main  coder researcher  ops
(默认)  (编码)  (调研)    (自动化)

从零配置多 Agent

下面我们一步一步地从一个单 Agent 配置升级到多 Agent 配置。所有配置都在 ~/.openclaw/openclaw.json 中完成。

当利用 openclaw agents add <agent-name> 创建新 agent 时,OpenClaw 会在 openclaw.json 的 agents.registered 中新增注册该 agent,同时为其创建独立的 workspace、agent.md、session store 等 。main 和新 agent 是平级并存的关系。

{
  "agents": {
    "list": [
      { "id": "main", "workspace": "~/.openclaw/workspace-main" },
      { "id": "coding", "workspace": "~/.openclaw/workspace-coding" }
    ]
  }
}

定义 Agent 列表

OpenClaw 的 Agent 配置采用「默认值 + 覆盖」模式。你先在 agents.defaults 里定义所有 Agent 共享的基线配置,然后在 agents.list 中为每个 Agent 单独覆盖需要变更的部分。

{
  agents: {
    // 所有 Agent 共享的默认配置
    defaults: {
      workspace: "~/.openclaw/workspace",
      model: {
        primary: "anthropic/claude-sonnet-4-5",
        fallbacks: ["openai/gpt-4.1"]
      },
      userTimezone: "Asia/Tokyo",
      memorySearch: {
        provider: "local",
        local: {
          modelPath: "hf:ggml-org/embeddinggemma-300M-GGUF/embeddinggemma-300M-Q8_0.gguf"
        }
      }
    },
    // Agent 列表
    list: [
      {
        id: "main",
        default: true,
        identity: {
          name: "Samantha",
          emoji: "🐙"
        }
      },
      {
        id: "coder",
        workspace: "~/.openclaw/workspace-coder",
        model: {
          primary: "anthropic/claude-opus-4-6"
        },
        identity: {
          name: "Linus",
          emoji: "💻"
        }
      },
      {
        id: "researcher",
        workspace: "~/.openclaw/workspace-researcher",
        model: {
          primary: "anthropic/claude-sonnet-4-5"
        },
        identity: {
          name: "Finch",
          emoji: "🔍"
        }
      }
    ]
  }
}

这里定义了三个 Agent。main 作为默认的通用助手,处理所有没有被路由规则命中的消息。coder 专门负责编程任务,使用更强的 Claude Opus 模型。researcher 专注于资料调研和分析。每个非默认 Agent 都指定了自己独立的 workspace 目录,这是隔离的基础——没有独立 Workspace 的话,不同 Agent 的记忆和文件就会互相混在一起。

配置路由绑定

定义好 Agent 之后,需要告诉 Gateway 如何把消息分发给正确的 Agent。OpenClaw 使用一套基于优先级的绑定系统来做路由决策,设计思路和 [[Nginx]] 的 location 匹配类似——按照从具体到宽泛的顺序逐级匹配,第一个命中的规则生效。

匹配优先级从高到低依次为:

优先级 匹配维度 说明
最高 peer 精确匹配,特定的私聊或群组 ID
guild Discord 服务器级别
中高 team Slack 工作区级别
account 同一渠道的不同账号
channel 整个渠道
最低 default 默认 Agent 兜底

一个实际的路由配置示例:

{
  bindings: [
    {
      // Telegram 私聊中的投研对话交给 researcher
      agentId: "researcher",
      match: {
        channel: "telegram",
        peer: { kind: "direct", id: "90522433" }
      }
    },
    {
      // Discord 编程频道交给 coder
      agentId: "coder",
      match: {
        channel: "discord",
        accountId: "coding"
      }
    },
    {
      // WhatsApp 工作群交给 coder
      agentId: "coder",
      match: {
        channel: "whatsapp",
        peer: { kind: "group", id: "[email protected]" }
      }
    }
    // 其余所有消息走 default: true 的 main Agent
  ]
}

配置之后,当你在特定的 [[Telegram]] 私聊中发消息时,响应的就是 researcher 这个 Agent。而当你在 [[Discord]] 的编程频道里提问时,coder Agent 会接手。所有不在绑定规则里的消息,都会默认交给 main Agent 处理。

如果同一层级有多个匹配项,OpenClaw 按配置文件中的先后顺序决定。所以把更具体的规则放在前面,更宽泛的规则放在后面,这一点很关键。

peer 精确匹配(优先级最高)

"bindings": [
  {
    "agentId": "opus",
    "match": { "channel": "whatsapp", "peer": { "kind": "direct", "id": "+15551234567" } }
  },
  { "agentId": "chat", "match": { "channel": "whatsapp" } }
]

多个 Telegram Bot 对应不同的 agent

{
  "bindings": [
    { "agentId": "main",   "match": { "channel": "telegram", "accountId": "main" } },
    { "agentId": "poe",    "match": { "channel": "telegram", "accountId": "poe" } },
    { "agentId": "flurry", "match": { "channel": "telegram", "accountId": "flurry" } }
  ],
  "channels": {
    "telegram": {
      "accounts": {
        "main":   { "botToken": "111..." },
        "poe":    { "botToken": "222..." },
        "flurry": { "botToken": "333..." }
      }
    }
  }
}

为每个 Agent 塑造灵魂

每个 Agent 的 Workspace 里可以放置独立的 Markdown 文件来定义行为和人格。因为 Workspace 是隔离的,所以每个 Agent 可以有完全不同的性格和工作方式。

以编程 Agent 的 ~/.openclaw/workspace-coder/SOUL.md 为例:

## Who I Am

I'm Linus — a senior developer agent. I write clean, efficient code.

## How I Operate

- Direct and technical, skip the pleasantries
- Always explain the "why" behind code decisions
- Prefer simple solutions over clever ones
- When unsure, say so rather than guessing

## What I Won't Do

- Never commit directly, always show diffs first
- Never run destructive commands without confirmation

而调研 Agent 的 ~/.openclaw/workspace-researcher/SOUL.md 则完全不同:

## Who I Am

I'm Finch — a research analyst. I provide thorough, well-sourced analysis.

## How I Operate

- Always cite sources and provide links
- Present multiple perspectives before giving conclusions
- Flag uncertainty levels explicitly
- Summarize findings with actionable insights

## What I Won't Do

- Never present speculation as fact
- Never skip source verification

这种通过 Markdown 文件来做 prompt engineering 的方式,比起在 JSON 配置里写 system prompt 直观得多。你甚至可以用 [[Obsidian]] 来管理这些文件。

值得注意的一个技巧是 USER.md 的共享。因为不管是哪个 Agent,面对的都是同一个用户,所以可以通过软链接让所有 Agent 共享同一份 USER.md

ln -s ~/.openclaw/workspace/USER.md ~/.openclaw/workspace-coder/USER.md
ln -s ~/.openclaw/workspace/USER.md ~/.openclaw/workspace-researcher/USER.md

工具权限与安全隔离

多 Agent 的价值不仅在于分工,更在于权限隔离。OpenClaw 提供了细粒度的工具白名单和黑名单机制,可以在每个 Agent 级别单独设置。

工具预设级别

OpenClaw 内置了四个工具预设:

预设 包含的工具 适用场景
minimal memory_searchmemory_get 只读的问答 Agent
coding 文件读写、编辑、执行、记忆 编程 Agent
messaging 跨频道消息发送 通知 Agent
full 所有权限 管理员 Agent

在此基础上,你还可以用 allowdeny 做更精细的控制。记住一个核心原则——deny 在任何层级都优先于 allow。

按 Agent 类型配置权限

以下是我实际使用中的权限配置方案:

{
  agents: {
    list: [
      {
        id: "main",
        default: true,
        // 日常对话 Agent,权限适中
        tools: {
          profile: "coding",
          deny: ["exec"]  // 不需要执行命令
        }
      },
      {
        id: "coder",
        workspace: "~/.openclaw/workspace-coder",
        // 编程 Agent,需要完整的代码工具
        tools: {
          profile: "coding"
        }
      },
      {
        id: "researcher",
        workspace: "~/.openclaw/workspace-researcher",
        // 调研 Agent,只需要搜索和读写能力
        tools: {
          allow: ["web_search", "web_fetch", "read", "write",
                  "edit", "memory_search", "session_status"],
          deny: ["exec", "process"]
        }
      },
      {
        id: "ops",
        workspace: "~/.openclaw/workspace-ops",
        // 自动化 Agent,有执行权限但禁止浏览器
        tools: {
          allow: ["exec", "cron", "read", "write", "webhook"],
          deny: ["browser"]
        }
      }
    ]
  }
}

沙箱隔离

对于安全要求更高的场景,可以启用 Docker 沙箱隔离。特别是如果你有一个 Agent 会暴露在多人群组里,强烈建议为它开启沙箱:

{
  id: "public",
  sandbox: {
    mode: "all",    // 所有会话都在 Docker 沙箱中运行
    scope: "agent"
  },
  tools: {
    allow: ["read"],
    deny: ["exec", "write"]
  }
}

这样即使群里有人试图通过 prompt injection 来利用 Agent 执行恶意操作,Docker 沙箱也能提供一层物理隔离。

进阶:子 Agent 委派与 ACP 运行时

除了通过路由把不同的消息分给不同的 Agent,OpenClaw 还支持两种更高级的委派机制。

子 Agent(Subagent)

子 Agent 是 OpenClaw 原生的后台任务机制。主 Agent 可以通过 sessions_spawn 工具创建一个子 Agent 会话,把具体任务交给它执行,然后收集结果。子 Agent 适合处理调研、数据整理、批量处理这类可以在后台运行的任务。

要启用子 Agent 委派,需要在主 Agent 的配置中显式声明允许的子 Agent 列表:

{
  id: "main",
  default: true,
  subagents: {
    allowAgents: ["coder", "researcher", "ops"]
  }
}

没有这个配置的话,spawn 请求会被直接拒绝,这是一个安全默认值。子 Agent 本身不持有用户上下文,主 Agent 必须在任务提示词中明确传递所有必要信息,这种设计确保了即使子 Agent 被攻破,也无法访问完整的对话历史。

ACP 运行时

[[Agent Client Protocol|ACP]](Agent Client Protocol)是 OpenClaw 连接外部代码智能体的机制。你可以把编程 Agent 的 runtime 设为 ACP,让它调用 [[Codex]]、[[Claude Code]] 或 [[Gemini CLI]] 这样的专业编码工具来处理代码任务。

{
  id: "coder",
  workspace: "~/.openclaw/workspace-coder",
  runtime: {
    type: "acp",
    acp: {
      agent: "codex",
      backend: "acpx",
      mode: "persistent",
      cwd: "/workspace/project"
    }
  }
}

ACP 和 Subagent 的选择经验是:纯 OpenClaw 内部的任务优先用 Subagent,需要 Codex 或 Claude Code 这类专业工具的编码任务用 ACP。

启用 ACP 还需要在全局配置中打开:

{
  acp: {
    enabled: true,
    backend: "acpx",
    defaultAgent: "codex",
    allowedAgents: ["codex", "claude", "gemini"]
  }
}

完整配置示例

把前面所有内容整合在一起,下面是一个包含四个 Agent 的完整配置:

{
  agents: {
    defaults: {
      workspace: "~/.openclaw/workspace",
      model: {
        primary: "anthropic/claude-sonnet-4-5",
        fallbacks: ["openai/gpt-4.1"]
      },
      userTimezone: "Asia/Tokyo",
      memorySearch: {
        provider: "local"
      }
    },
    list: [
      {
        id: "main",
        default: true,
        identity: { name: "Samantha", emoji: "🐙" },
        subagents: {
          allowAgents: ["coder", "researcher", "ops"]
        },
        tools: {
          profile: "coding",
          deny: ["exec"]
        }
      },
      {
        id: "coder",
        workspace: "~/.openclaw/workspace-coder",
        model: { primary: "anthropic/claude-opus-4-6" },
        identity: { name: "Linus", emoji: "💻" },
        runtime: {
          type: "acp",
          acp: { agent: "codex", backend: "acpx" }
        },
        tools: { profile: "coding" }
      },
      {
        id: "researcher",
        workspace: "~/.openclaw/workspace-researcher",
        model: { primary: "anthropic/claude-sonnet-4-5" },
        identity: { name: "Finch", emoji: "🔍" },
        tools: {
          allow: ["web_search", "web_fetch", "read", "write",
                  "edit", "memory_search"],
          deny: ["exec", "process"]
        }
      },
      {
        id: "ops",
        workspace: "~/.openclaw/workspace-ops",
        model: { primary: "anthropic/claude-sonnet-4-5" },
        identity: { name: "Otto", emoji: "⚙️" },
        tools: {
          allow: ["exec", "cron", "read", "write", "webhook"],
          deny: ["browser"]
        }
      }
    ]
  },
  bindings: [
    {
      agentId: "coder",
      match: {
        channel: "discord",
        accountId: "coding"
      }
    },
    {
      agentId: "researcher",
      match: {
        channel: "telegram",
        peer: { kind: "group", id: "-100xxx" }
      }
    },
    {
      agentId: "coder",
      match: {
        channel: "whatsapp",
        peer: { kind: "group", id: "[email protected]" }
      }
    }
  ],
  acp: {
    enabled: true,
    backend: "acpx",
    defaultAgent: "codex",
    allowedAgents: ["codex", "claude", "gemini"]
  }
}

落地步骤与验证

配置写好之后,按以下步骤落地:

先备份现有配置,这一步不要跳过。多 Agent 配置涉及目录结构的变更,万一出了问题需要回滚。

cp ~/.openclaw/openclaw.json ~/.openclaw/openclaw.json.bak

然后编辑 openclaw.json,加入 agents.listbindings 配置。接着为每个新 Agent 创建独立的 Workspace 目录,并在其中放入 SOUL.mdUSER.md 等文件。

mkdir -p ~/.openclaw/workspace-coder
mkdir -p ~/.openclaw/workspace-researcher
mkdir -p ~/.openclaw/workspace-ops

重启 Gateway 使配置生效:

openclaw gateway restart

openclaw agents list --bindings 验证路由是否正确:

openclaw agents list --bindings

最后在各个渠道里做三类测试,确认消息正确路由到了对应的 Agent:

  • 在绑定了 coder 的渠道里发送一条编程请求,确认响应的 Agent 身份是 Linus
  • 在绑定了 researcher 的渠道里发送一条调研请求,确认响应的 Agent 身份是 Finch
  • 在没有绑定规则的渠道里发送消息,确认走的是默认的 main Agent

你也可以在任何渠道里通过 /agent coder 这样的斜杠命令手动切换当前会话使用的 Agent,方便临时调用。

常见的坑

在实际配置过程中,有几个容易踩到的问题值得提前了解。

复用同一个 agentDir 给多个 Agent 是最常见的错误。每个 Agent 的 agentDir 必须是独立的,否则认证信息和会话记录会互相覆盖,导致各种诡异的问题。如果你在 agents.list 中没有显式指定 agentDir,OpenClaw 会自动生成位于 ~/.openclaw/agents/<agentId>/agent 的目录,一般不需要手动设置。

bindings 顺序放错也是高频问题。如果你把一条宽泛的 channel 级别匹配放在了 peer 级别匹配的前面,宽泛规则会先命中,导致后面更具体的规则永远不会生效。始终把更具体的规则放在前面。

开了 ACP runtime 但忘了启用 acp.enabled 也很常见。ACP 需要全局配置中的 acp.enabled: true 才能工作,仅在 Agent 级别设置 runtime.type: "acp" 是不够的。

每次修改完配置之后,建议运行一次 openclaw doctor 进行自动诊断。它会检查 API Key 是否有效、渠道配置是否正确、文件权限是否合适,并尝试自动修复常见问题。

最后

在一个 Gateway 里配置多个 Agent,是 OpenClaw 使用过程中从"能用"到"好用"的关键一步。通过把不同性质的任务分配给不同的 Agent,每个 Agent 都可以拥有最合适的模型、最精确的工具权限和最干净的上下文环境。编程 Agent 用最强的推理模型、拥有代码执行权限;调研 Agent 配备联网搜索工具但禁止命令执行;自动化 Agent 可以跑 Cron 和 Webhook 但没有浏览器访问——这种精细化的分工让每个 Agent 都在自己最擅长的领域发挥最大价值。

我自己的经验是,不需要一开始就追求完美的多 Agent 架构。先从两个 Agent 开始——一个默认的日常助手,一个专门负责你最常用的场景(比如编程或调研),感受一下消息路由和工作空间隔离带来的清爽体验。等你确认这套模式确实好用之后,再根据需要逐步增加新的 Agent。先跑通再增强,可维护性永远比功能完备性更重要。

相关链接

正文完
 0
评论(没有评论)