Multi-Agent Routing

Mục tiêu: chạy nhiều agent độc lập (workspace + agentDir + session riêng biệt), cộng với nhiều tài khoản channel (ví dụ hai WhatsApp) trong một Gateway đang chạy. Tin nhắn đến sẽ được route tới agent thông qua bindings.

”Một agent” là gì?

Một agent là một bộ não hoàn chỉnh với các thành phần riêng:

  • Workspace (files, AGENTS.md/SOUL.md/USER.md, ghi chú local, quy tắc persona).
  • Thư mục state (agentDir) cho auth profiles, model registry, và config riêng của agent.
  • Session store (lịch sử chat + routing state) trong ~/.openclaw/agents/<agentId>/sessions.

Auth profiles là per-agent. Mỗi agent đọc từ file riêng của nó:

~/.openclaw/agents/<agentId>/agent/auth-profiles.json

Credentials của agent chính không được chia sẻ tự động. Không bao giờ dùng chung agentDir giữa các agent (sẽ gây xung đột auth/session). Nếu muốn share credentials, copy auth-profiles.json vào agentDir của agent khác.

Skills là per-agent thông qua thư mục skills/ của mỗi workspace, với shared skills có sẵn từ ~/.openclaw/skills. Xem Skills: per-agent vs shared.

Gateway có thể host một agent (mặc định) hoặc nhiều agents song song.

Lưu ý về Workspace: workspace của mỗi agent là default cwd, không phải sandbox cứng. Đường dẫn tương đối sẽ resolve bên trong workspace, nhưng đường dẫn tuyệt đối có thể truy cập các vị trí khác trên host trừ khi sandboxing được bật. Xem Sandboxing.

Paths (bản đồ nhanh)

  • Config: ~/.openclaw/openclaw.json (hoặc OPENCLAW_CONFIG_PATH)
  • State dir: ~/.openclaw (hoặc OPENCLAW_STATE_DIR)
  • Workspace: ~/.openclaw/workspace (hoặc ~/.openclaw/workspace-<agentId>)
  • Agent dir: ~/.openclaw/agents/<agentId>/agent (hoặc agents.list[].agentDir)
  • Sessions: ~/.openclaw/agents/<agentId>/sessions

Single-agent mode (mặc định)

Nếu các bạn không làm gì, OpenClaw sẽ chạy một agent duy nhất:

  • agentId mặc định là main.
  • Sessions được key là agent:main:<mainKey>.
  • Workspace mặc định là ~/.openclaw/workspace (hoặc ~/.openclaw/workspace-<profile> khi OPENCLAW_PROFILE được set).
  • State mặc định là ~/.openclaw/agents/main/agent.

Agent helper

Dùng agent wizard để thêm một agent độc lập mới:

openclaw agents add work

Sau đó thêm bindings (hoặc để wizard làm) để route tin nhắn đến.

Kiểm tra với:

openclaw agents list --bindings

Multiple agents = nhiều người, nhiều tính cách

Với multiple agents, mỗi agentId trở thành một persona hoàn toàn độc lập:

  • Số điện thoại/tài khoản khác nhau (per channel accountId).
  • Tính cách khác nhau (workspace files riêng như AGENTS.mdSOUL.md).
  • Auth + sessions riêng biệt (không cross-talk trừ khi được bật rõ ràng).

Điều này cho phép nhiều người share một Gateway server trong khi vẫn giữ “bộ não” AI và dữ liệu của họ độc lập.

Một số WhatsApp, nhiều người (DM split)

Các bạn có thể route các WhatsApp DM khác nhau tới các agent khác nhau trong khi vẫn dùng một tài khoản WhatsApp. Match theo sender E.164 (như +15551234567) với peer.kind: "dm". Replies vẫn đến từ cùng số WhatsApp (không có per-agent sender identity).

Chi tiết quan trọng: direct chats collapse về main session key của agent, nên để có isolation thực sự cần một agent cho mỗi người.

Ví dụ:

{
  agents: {
    list: [
      { id: "alex", workspace: "~/.openclaw/workspace-alex" },
      { id: "mia", workspace: "~/.openclaw/workspace-mia" },
    ],
  },
  bindings: [
    { agentId: "alex", match: { channel: "whatsapp", peer: { kind: "dm", id: "+15551230001" } } },
    { agentId: "mia", match: { channel: "whatsapp", peer: { kind: "dm", id: "+15551230002" } } },
  ],
  channels: {
    whatsapp: {
      dmPolicy: "allowlist",
      allowFrom: ["+15551230001", "+15551230002"],
    },
  },
}

Lưu ý:

  • DM access control là global per WhatsApp account (pairing/allowlist), không phải per agent.
  • Với shared groups, bind group đó tới một agent hoặc dùng Broadcast groups.

Routing rules (cách tin nhắn chọn agent)

Bindings là deterministicmost-specific wins:

  1. peer match (exact DM/group/channel id)
  2. guildId (Discord)
  3. teamId (Slack)
  4. accountId match cho một channel
  5. channel-level match (accountId: "*")
  6. fallback về default agent (agents.list[].default, nếu không thì entry đầu tiên, mặc định: main)

Multiple accounts / phone numbers

Channels hỗ trợ multiple accounts (ví dụ WhatsApp) dùng accountId để identify mỗi login. Mỗi accountId có thể được route tới một agent khác nhau, nên một server có thể host nhiều số điện thoại mà không bị trộn sessions.

Concepts

  • agentId: một “bộ não” (workspace, per-agent auth, per-agent session store).
  • accountId: một channel account instance (ví dụ WhatsApp account "personal" vs "biz").
  • binding: route tin nhắn đến tới một agentId theo (channel, accountId, peer) và tùy chọn guild/team ids.
  • Direct chats collapse về agent:<agentId>:<mainKey> (per-agent “main”; session.mainKey).

Ví dụ: hai WhatsApps → hai agents

~/.openclaw/openclaw.json (JSON5):

{
  agents: {
    list: [
      {
        id: "home",
        default: true,
        name: "Home",
        workspace: "~/.openclaw/workspace-home",
        agentDir: "~/.openclaw/agents/home/agent",
      },
      {
        id: "work",
        name: "Work",
        workspace: "~/.openclaw/workspace-work",
        agentDir: "~/.openclaw/agents/work/agent",
      },
    ],
  },

  // Deterministic routing: first match wins (most-specific first).
  bindings: [
    { agentId: "home", match: { channel: "whatsapp", accountId: "personal" } },
    { agentId: "work", match: { channel: "whatsapp", accountId: "biz" } },

    // Optional per-peer override (ví dụ: gửi một group cụ thể tới work agent).
    {
      agentId: "work",
      match: {
        channel: "whatsapp",
        accountId: "personal",
        peer: { kind: "group", id: "[email protected]" },
      },
    },
  ],

  // Tắt mặc định: agent-to-agent messaging phải được bật rõ ràng + allowlisted.
  tools: {
    agentToAgent: {
      enabled: false,
      allow: ["home", "work"],
    },
  },

  channels: {
    whatsapp: {
      accounts: {
        personal: {
          // Optional override. Mặc định: ~/.openclaw/credentials/whatsapp/personal
          // authDir: "~/.openclaw/credentials/whatsapp/personal",
        },
        biz: {
          // Optional override. Mặc định: ~/.openclaw/credentials/whatsapp/biz
          // authDir: "~/.openclaw/credentials/whatsapp/biz",
        },
      },
    },
  },
}

Ví dụ: WhatsApp chat hàng ngày + Telegram deep work

Chia theo channel: route WhatsApp tới agent nhanh hàng ngày và Telegram tới agent Opus.

{
  agents: {
    list: [
      {
        id: "chat",
        name: "Everyday",
        workspace: "~/.openclaw/workspace-chat",
        model: "anthropic/claude-sonnet-4-5",
      },
      {
        id: "opus",
        name: "Deep Work",
        workspace: "~/.openclaw/workspace-opus",
        model: "anthropic/claude-opus-4-5",
      },
    ],
  },
  bindings: [
    { agentId: "chat", match: { channel: "whatsapp" } },
    { agentId: "opus", match: { channel: "telegram" } },
  ],
}

Lưu ý:

  • Nếu các bạn có nhiều accounts cho một channel, thêm accountId vào binding (ví dụ { channel: "whatsapp", accountId: "personal" }).
  • Để route một DM/group cụ thể tới Opus trong khi giữ phần còn lại trên chat, thêm match.peer binding cho peer đó; peer matches luôn thắng channel-wide rules.

Ví dụ: cùng channel, một peer tới Opus

Giữ WhatsApp trên agent nhanh, nhưng route một DM tới Opus:

{
  agents: {
    list: [
      {
        id: "chat",
        name: "Everyday",
        workspace: "~/.openclaw/workspace-chat",
        model: "anthropic/claude-sonnet-4-5",
      },
      {
        id: "opus",
        name: "Deep Work",
        workspace: "~/.openclaw/workspace-opus",
        model: "anthropic/claude-opus-4-5",
      },
    ],
  },
  bindings: [
    { agentId: "opus", match: { channel: "whatsapp", peer: { kind: "dm", id: "+15551234567" } } },
    { agentId: "chat", match: { channel: "whatsapp" } },
  ],
}

Peer bindings luôn thắng, nên đặt chúng phía trên channel-wide rule.

Family agent bound tới một WhatsApp group

Bind một family agent chuyên dụng tới một WhatsApp group, với mention gating và tool policy chặt chẽ hơn:

{
  agents: {
    list: [
      {
        id: "family",
        name: "Family",
        workspace: "~/.openclaw/workspace-family",
        identity: { name: "Family Bot" },
        groupChat: {
          mentionPatterns: ["@family", "@familybot", "@Family Bot"],
        },
        sandbox: {
          mode: "all",
          scope: "agent",
        },
        tools: {
          allow: [
            "exec",
            "read",
            "sessions_list",
            "sessions_history",
            "sessions_send",
            "sessions_spawn",
            "session_status",
          ],
          deny: ["write", "edit", "apply_patch", "browser", "canvas", "nodes", "cron"],
        },
      },
    ],
  },
  bindings: [
    {
      agentId: "family",
      match: {
        channel: "whatsapp",
        peer: { kind: "group", id: "[email protected]" },
      },
    },
  ],
}

Lưu ý:

  • Tool allow/deny lists là tools, không phải skills. Nếu một skill cần chạy binary, đảm bảo exec được allow và binary tồn tại trong sandbox.
  • Để gating chặt chẽ hơn, set agents.list[].groupChat.mentionPatterns và giữ group allowlists enabled cho channel.

Per-Agent Sandbox và Tool Configuration

Từ v2026.1.6, mỗi agent có thể có sandbox và tool restrictions riêng:

{
  agents: {
    list: [
      {
        id: "personal",
        workspace: "~/.openclaw/workspace-personal",
        sandbox: {
          mode: "off",  // Không sandbox cho personal agent
        },
        // Không tool restrictions - tất cả tools đều available
      },
      {
        id: "family",
        workspace: "~/.openclaw/workspace-family",
        sandbox: {
          mode: "all",     // Luôn sandboxed
          scope: "agent",  // Một container per agent
          docker: {
            // Optional one-time setup sau khi tạo container
            setupCommand: "apt-get update && apt-get install -y git curl",
          },
        },
        tools: {
          allow: ["read"],                    // Chỉ read tool
          deny: ["exec", "write", "edit", "apply_patch"],    // Deny các tool khác
        },
      },
    ],
  },
}

Lưu ý: setupCommand nằm trong sandbox.docker và chạy một lần khi tạo container. Per-agent sandbox.docker.* overrides bị ignore khi resolved scope là "shared".

Lợi ích:

  • Security isolation: Hạn chế tools cho các agent không tin cậy
  • Resource control: Sandbox các agent cụ thể trong khi giữ các agent khác trên host
  • Flexible policies: Permissions khác nhau cho mỗi agent

Lưu ý: tools.elevatedglobal và dựa trên sender; không thể config per agent. Nếu cần per-agent boundaries, dùng agents.list[].tools để deny exec. Với group targeting, dùng agents.list[].groupChat.mentionPatterns để @mentions map rõ ràng tới agent mong muốn.

Xem Multi-Agent Sandbox & Tools để biết các ví dụ chi tiết.