Multi-Agent Routing

目標:1 つの実行中の Gateway で複数の isolated agent(separate workspace + agentDir + session)および複数の channel account(例:2 つの WhatsApp)。Inbound は binding を介して agent にルーティングされます。

"one agent" とは何か?

Agent は独自の以下を持つ完全にスコープされた brain です:

  • Workspace(file、AGENTS.md/SOUL.md/USER.md、local note、persona rule)。
  • State directoryagentDir):auth profile、model registry、per-agent config 用。
  • Session store(chat history + routing state):~/.openclaw/agents/<agentId>/sessions 下。

Auth profile は per-agent です。各 agent は独自のものから読み取ります:

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

Main agent credential は自動的に共有されません。複数の agent で agentDir を再利用しないでください(auth/session collision が発生します)。Credential を共有したい場合は、auth-profiles.json を他の agent の agentDir にコピーしてください。

Skill は各 workspace の skills/ folder を介して per-agent であり、shared skill は ~/.openclaw/skills から利用できます。Skills: per-agent vs shared を参照してください。

Gateway は one agent(デフォルト)または many agent を side-by-side でホストできます。

Workspace 注意:各 agent の workspace は default cwd であり、hard sandbox ではありません。Relative path は workspace 内で解決されますが、absolute path は sandboxing が有効でない限り、他の host location に到達できます。Sandboxing を参照してください。

Path(quick map)

  • Config:~/.openclaw/openclaw.json(または OPENCLAW_CONFIG_PATH
  • State dir:~/.openclaw(または OPENCLAW_STATE_DIR
  • Workspace:~/.openclaw/workspace(または ~/.openclaw/workspace-<agentId>
  • Agent dir:~/.openclaw/agents/<agentId>/agent(または agents.list[].agentDir
  • Session:~/.openclaw/agents/<agentId>/sessions

Single-agent mode(デフォルト)

何もしない場合、OpenClaw は single agent を実行します:

  • agentId はデフォルトで main
  • Session は agent:main:<mainKey> としてキー付けされます。
  • Workspace はデフォルトで ~/.openclaw/workspaceOPENCLAW_PROFILE が設定されている場合は ~/.openclaw/workspace-<profile>)。
  • State はデフォルトで ~/.openclaw/agents/main/agent

Agent helper

Agent wizard を使用して新しい isolated agent を追加します:

openclaw agents add work

次に binding を追加します(または wizard に任せます)して inbound message をルーティングします。

検証:

openclaw agents list --bindings

Multiple agent = 複数の人、複数の personality

Multiple agent では、各 agentId完全に分離された persona になります:

  • Different phone number/account(channel accountId ごと)。
  • Different personality(workspace file like AGENTS.mdSOUL.md による per-agent)。
  • Separate auth + session(明示的に有効にしない限り cross-talk なし)。

これにより、複数の人が 1 つの Gateway server を共有しながら、AI「brain」とデータを分離できます。

One WhatsApp number、複数の人(DM split)

1 つの WhatsApp account を維持しながら、異なる WhatsApp DM を異なる agent にルーティングできます。peer.kind: "dm" で sender E.164(+15551234567 など)に match します。Reply は依然として同じ WhatsApp number から送信されます(per-agent sender identity なし)。

重要な詳細:direct chat は agent の main session key に collapse するため、真の isolation には one agent per person が必要です。

例:

{
  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"]
    }
  }
}

注意:

  • DM access control は WhatsApp account ごとに global(pairing/allowlist)であり、per-agent ではありません。
  • Shared group の場合は、group を 1 つの agent に bind するか、Broadcast groups を使用してください。

Routing rule(message が agent を選択する方法)

Binding は deterministicmost-specific wins です:

  1. peer match(exact DM/group/channel id)
  2. guildId(Discord)
  3. teamId(Slack)
  4. channel の accountId match
  5. channel-level match(accountId: "*"
  6. default agent へのフォールバック(agents.list[].default、else 最初の list entry、デフォルト:main

Multiple account / phone number

Multiple account をサポートする channel(例:WhatsApp)は、各 login を識別するために accountId を使用します。各 accountId を異なる agent にルーティングできるため、1 つの server が session を混ぜずに複数の phone number をホストできます。

Concept

  • agentId:1 つの「brain」(workspace、per-agent auth、per-agent session store)。
  • accountId:1 つの channel account instance(例:WhatsApp account "personal" vs "biz")。
  • binding(channel, accountId, peer) と、オプションで guild/team id によって inbound message を agentId にルーティングします。
  • Direct chat は agent:<agentId>:<mainKey> に collapse します(per-agent「main」。session.mainKey)。

例:2 つの WhatsApp → 2 つの agent

~/.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 (example: send a specific group to work agent).
    {
      agentId: "work",
      match: {
        channel: "whatsapp",
        accountId: "personal",
        peer: { kind: "group", id: "[email protected]" },
      },
    },
  ],

  // Off by default: agent-to-agent messaging must be explicitly enabled + allowlisted.
  tools: {
    agentToAgent: {
      enabled: false,
      allow: ["home", "work"],
    },
  },

  channels: {
    whatsapp: {
      accounts: {
        personal: {
          // Optional override. Default: ~/.openclaw/credentials/whatsapp/personal
          // authDir: "~/.openclaw/credentials/whatsapp/personal",
        },
        biz: {
          // Optional override. Default: ~/.openclaw/credentials/whatsapp/biz
          // authDir: "~/.openclaw/credentials/whatsapp/biz",
        },
      },
    },
  },
}

例:WhatsApp daily chat + Telegram deep work

Channel で split:WhatsApp を fast everyday agent に、Telegram を Opus agent にルーティングします。

{
  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" } }
  ]
}

注意:

  • Channel に複数の account がある場合は、binding に accountId を追加します(例:{ channel: "whatsapp", accountId: "personal" })。
  • 残りを chat に保ちながら single DM/group を Opus にルーティングするには、その peer の match.peer binding を追加します。Peer match は常に channel-wide rule より優先されます。

例:同じ channel、1 つの peer を Opus に

WhatsApp を fast agent に保ちながら、1 つの DM を 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 binding は常に優先されるため、channel-wide rule の上に保ちます。

WhatsApp group に bind された family agent

Dedicated family agent を single WhatsApp group に bind し、mention gating とより厳格な tool policy を使用します:

{
  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]" }
      }
    }
  ]
}

注意:

  • Tool allow/deny list は tool であり、skill ではありません。Skill が binary を実行する必要がある場合は、exec が許可され、binary が sandbox に存在することを確認してください。
  • より厳格な gating のためには、agents.list[].groupChat.mentionPatterns を設定し、channel の group allowlist を有効に保ちます。

Per-Agent Sandbox and Tool Configuration

v2026.1.6 以降、各 agent は独自の sandbox と tool restriction を持つことができます:

{
  agents: {
    list: [
      {
        id: "personal",
        workspace: "~/.openclaw/workspace-personal",
        sandbox: {
          mode: "off",  // No sandbox for personal agent
        },
        // No tool restrictions - all tools available
      },
      {
        id: "family",
        workspace: "~/.openclaw/workspace-family",
        sandbox: {
          mode: "all",     // Always sandboxed
          scope: "agent",  // One container per agent
          docker: {
            // Optional one-time setup after container creation
            setupCommand: "apt-get update && apt-get install -y git curl",
          },
        },
        tools: {
          allow: ["read"],                    // Only read tool
          deny: ["exec", "write", "edit", "apply_patch"],    // Deny others
        },
      },
    ],
  },
}

注意:setupCommandsandbox.docker 下に存在し、container 作成時に 1 回実行されます。 Resolved scope が "shared" の場合、per-agent sandbox.docker.* override は無視されます。

利点:

  • Security isolation(セキュリティ分離):信頼できない agent の tool を制限
  • Resource control(リソース制御):特定の agent を sandbox 化しながら他を host に保つ
  • Flexible policy(柔軟なポリシー):agent ごとに異なる permission

注意:tools.elevatedglobal で sender-based です。agent ごとには設定できません。 Per-agent boundary が必要な場合は、agents.list[].tools を使用して exec を deny してください。 Group targeting には、agents.list[].groupChat.mentionPatterns を使用して、@mention が意図した agent に明確にマップされるようにします。

詳細な例については Multi-Agent Sandbox & Tools を参照してください。