Most people start with one AI agent. That's fine — one agent handling your Slack, your tasks, your coding is already a force multiplier. But at some point you hit a wall. One agent can't be everywhere at once, and one personality doesn't fit every context.
OpenClaw solves this with multi-agent routing: multiple fully isolated agents running inside a single gateway process, each with its own workspace, persona, channel accounts, and session history. From the outside they look like a coordinated team. Under the hood they're cleanly separated — no cross-talk unless you explicitly enable it.
This guide walks you through how to build that team — from the concepts to real config examples to spawning ACP coding sessions.
What "one agent" actually means
In OpenClaw, an agent is a fully scoped runtime with its own:
-
Workspace — the directory where its files live:
SOUL.md,AGENTS.md,USER.md, memory files, and any workspace-level skills -
State directory (
agentDir) — auth profiles, model registry, per-agent config -
Session store — chat history under
~/.openclaw/agents/<agentId>/sessions/
Each agent reads from its own ~/.openclaw/agents/<agentId>/agent/auth-profiles.json. Credentials are not shared automatically. If two agents need the same credentials, you copy the file explicitly.
The default setup is single-agent: one agent with id main, workspace at ~/.openclaw/workspace. When you add more agents, they sit alongside main — same process, separate brains.
Why you'd want multiple agents
A few patterns that push people toward multi-agent setups:
-
Different channels, different personalities. Your work agent on Telegram should feel different from your personal agent on WhatsApp. Different
SOUL.md, different model, different tool access. - Different people, same server. Multiple people can share one OpenClaw host while keeping their AI data fully isolated — each person gets their own agent, their own session history, their own credentials.
- Specialization. One fast Sonnet agent for quick replies, one Opus agent for deep work. Route by channel or by specific contacts.
- Security isolation. A sandboxed agent for untrusted channels (family groups, public bots) alongside an unsandboxed agent for your personal use.
Adding a second agent
The quickest path is the wizard:
openclaw agents add coding
openclaw agents add social
Each command creates a workspace with the standard bootstrap files, a dedicated agentDir, and a session store. Then verify:
openclaw agents list --bindings
How routing works
Messages are routed to agents via bindings. A binding matches an inbound message by channel, account, and peer (DM or group id), then sends it to the specified agentId.
Bindings are deterministic — most-specific match wins:
- Exact peer match (specific DM or group id)
- Parent peer match (thread inheritance)
- Guild + roles (Discord role routing)
- Guild-level (Discord server)
- Team-level (Slack team)
- Account-level (specific account id for a channel)
- Channel-wide fallback (
accountId: "*") - Default agent (first in list, or marked
default: true)
If multiple bindings match at the same specificity, the first one in config order wins. Multiple match fields in a single binding use AND semantics — all specified fields must match.
Example: fast agent on WhatsApp, deep-work agent on Telegram
A clean two-agent split by channel:
{
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-6",
},
],
},
bindings: [
{ agentId: "chat", match: { channel: "whatsapp" } },
{ agentId: "opus", match: { channel: "telegram" } },
],
}
Every WhatsApp message hits the Sonnet agent. Every Telegram message hits Opus. Each has its own workspace, so they get different SOUL.md files — different personalities, different operating instructions.
Example: routing one DM to a different agent
Keep WhatsApp on the fast agent, but route one specific contact to Opus:
{
bindings: [
{
agentId: "opus",
match: {
channel: "whatsapp",
peer: { kind: "direct", id: "+15551234567" },
},
},
{ agentId: "chat", match: { channel: "whatsapp" } },
],
}
Peer bindings always win over channel-wide rules, so order them first in the config.
Example: multiple Discord bots, multiple agents
Each Discord bot account maps to a unique accountId. Bind each to a different agent using separate bot tokens. The coding agent can have its SOUL.md tuned for technical work while the main agent handles general conversation.
Per-agent sandbox and tool restrictions
You can lock down specific agents without affecting others. This is useful for untrusted contexts — a public-facing bot or a family group chat shouldn't have the same tool access as your personal agent:
{
agents: {
list: [
{
id: "personal",
sandbox: { mode: "off" },
},
{
id: "family",
sandbox: {
mode: "all",
scope: "agent",
},
tools: {
allow: ["read", "sessions_list", "sessions_history"],
deny: ["exec", "write", "edit", "browser"],
},
},
],
},
}
The family agent runs in a Docker sandbox, can only read files and list sessions — no exec, no writes, no browser access. The personal agent runs unrestricted on the host.
ACP coding sessions: agents that write code
OpenClaw supports ACP (Agent Client Protocol) — a way to run external coding harnesses like Claude Code, Codex, Gemini CLI, and Pi through your agent.
The practical difference:
- Sub-agents: OpenClaw-native delegated runs. Use for general task delegation.
- ACP sessions: External harness runtimes (Codex, Claude Code, etc.). Use when you need a full coding agent with file access and shell execution.
Starting an ACP session from chat:
/acp spawn codex --mode persistent --thread auto
This creates a persistent Codex session and binds it to the current thread. Supported harnesses: pi, claude (Claude Code), codex, opencode, gemini, kimi.
Install the backend plugin first:
openclaw plugins install acpx
openclaw config set plugins.entries.acpx.enabled true
Agent-to-agent messaging
By default, agents cannot message each other — this is intentional for isolation. To enable it explicitly:
{
tools: {
agentToAgent: {
enabled: true,
allow: ["main", "coding"],
},
},
}
Only agents listed in allow can communicate. This lets you build orchestration patterns — your main agent spawning a coding agent to handle a task, then receiving the result — while keeping the blast radius controlled.
One thing people get wrong
Auth profiles are per-agent. If you add a second agent and wonder why it can't access your Slack or GitHub — it's because credentials aren't shared. Copy ~/.openclaw/agents/main/agent/auth-profiles.json to the new agent's agentDir, or re-run the relevant auth setup for that agent explicitly.
Similarly: never share the same agentDir between two agents. It causes session and auth collisions that are annoying to debug.
Final thoughts
The jump from one agent to a team isn't that big — it's mostly config. What changes is the mental model. You stop thinking about "my AI agent" as a single thing and start thinking about it as a staffing problem: who handles what, with what access, on what channel.
Once you've been running two or three agents for a week, going back to one feels like losing a team member.
Originally published at openclawplaybook.ai. Get The OpenClaw Playbook — $9.99
Top comments (0)