Run multiple isolated agents — each with its own workspace, state directory (Documentation Index
Fetch the complete documentation index at: https://docs.openclaw.ai/llms.txt
Use this file to discover all available pages before exploring further.
agentDir), and session history — plus multiple channel accounts (e.g. two WhatsApps) in one running Gateway. Inbound messages are routed to the right agent through bindings.
An agent here is the full per-persona scope: workspace files, auth profiles, model registry, and session store. agentDir is the on-disk state directory that holds this per-agent config at ~/.openclaw/agents/<agentId>/. A binding maps a channel account (e.g. a Slack workspace or a WhatsApp number) to one of those agents.
What is “one agent”?
An agent is a fully scoped brain with its own:- Workspace (files, AGENTS.md/SOUL.md/USER.md, local notes, persona rules).
- State directory (
agentDir) for auth profiles, model registry, and per-agent config. - Session store (chat history + routing state) under
~/.openclaw/agents/<agentId>/sessions.
sessions_history is the safer cross-session recall path here too: it returns a bounded, sanitized view, not a raw transcript dump. Assistant recall strips thinking tags, <relevant-memories> scaffolding, plain-text tool-call XML payloads (including <tool_call>...</tool_call>, <function_call>...</function_call>, <tool_calls>...</tool_calls>, <function_calls>...</function_calls>, and truncated tool-call blocks), downgraded tool-call scaffolding, leaked ASCII/full-width model control tokens, and malformed MiniMax tool-call XML before redaction/truncation.~/.openclaw/skills, then filtered by the effective agent skill allowlist when configured. Use agents.defaults.skills for a shared baseline and agents.list[].skills for per-agent replacement. See Skills: per-agent vs shared and Skills: agent skill allowlists.
The Gateway can host one agent (default) or many agents side-by-side.
Workspace note: each agent’s workspace is the default cwd, not a hard sandbox. Relative paths resolve inside the workspace, but absolute paths can reach other host locations unless sandboxing is enabled. See Sandboxing.
Paths (quick map)
- Config:
~/.openclaw/openclaw.json(orOPENCLAW_CONFIG_PATH) - State dir:
~/.openclaw(orOPENCLAW_STATE_DIR) - Workspace:
~/.openclaw/workspace(or~/.openclaw/workspace-<agentId>) - Agent dir:
~/.openclaw/agents/<agentId>/agent(oragents.list[].agentDir) - Sessions:
~/.openclaw/agents/<agentId>/sessions
Single-agent mode (default)
If you do nothing, OpenClaw runs a single agent:agentIddefaults tomain.- Sessions are keyed as
agent:main:<mainKey>. - Workspace defaults to
~/.openclaw/workspace(or~/.openclaw/workspace-<profile>whenOPENCLAW_PROFILEis set). - State defaults to
~/.openclaw/agents/main/agent.
Agent helper
Use the agent wizard to add a new isolated agent:bindings (or let the wizard do it) to route inbound messages.
Verify with:
Quick start
Create each agent workspace
Use the wizard or create workspaces manually:Each agent gets its own workspace with
SOUL.md, AGENTS.md, and optional USER.md, plus a dedicated agentDir and session store under ~/.openclaw/agents/<agentId>.Create channel accounts
Add agents, accounts, and bindings
Add agents under
agents.list, channel accounts under channels.<channel>.accounts, and connect them with bindings (examples below).Multiple agents = multiple people, multiple personalities
With multiple agents, eachagentId becomes a fully isolated persona:
- Different phone numbers/accounts (per channel
accountId). - Different personalities (per-agent workspace files like
AGENTS.mdandSOUL.md). - Separate auth + sessions (no cross-talk unless explicitly enabled).
Cross-agent QMD memory search
If one agent should search another agent’s QMD session transcripts, add extra collections underagents.list[].memorySearch.qmd.extraCollections. Use agents.defaults.memorySearch.qmd.extraCollections only when every agent should inherit the same shared transcript collections.
One WhatsApp number, multiple people (DM split)
You can route different WhatsApp DMs to different agents while staying on one WhatsApp account. Match on sender E.164 (like+15551234567) with peer.kind: "direct". Replies still come from the same WhatsApp number (no per-agent sender identity).
Direct chats collapse to the agent’s main session key, so true isolation requires one agent per person.
- DM access control is global per WhatsApp account (pairing/allowlist), not per agent.
- For shared groups, bind the group to one agent or use Broadcast groups.
Routing rules (how messages pick an agent)
Bindings are deterministic and most-specific wins:Tie-breaking and AND semantics
Tie-breaking and AND semantics
- If multiple bindings match in the same tier, the first one in config order wins.
- If a binding sets multiple match fields (for example
peer+guildId), all specified fields are required (ANDsemantics).
Account-scope detail
Account-scope detail
- A binding that omits
accountIdmatches the default account only. - Use
accountId: "*"for a channel-wide fallback across all accounts. - If you later add the same binding for the same agent with an explicit account id, OpenClaw upgrades the existing channel-only binding to account-scoped instead of duplicating it.
Multiple accounts / phone numbers
Channels that support multiple accounts (e.g. WhatsApp) useaccountId to identify each login. Each accountId can be routed to a different agent, so one server can host multiple phone numbers without mixing sessions.
If you want a channel-wide default account when accountId is omitted, set channels.<channel>.defaultAccount (optional). When unset, OpenClaw falls back to default if present, otherwise the first configured account id (sorted).
Common channels supporting this pattern include:
whatsapp,telegram,discord,slack,signal,imessageirc,line,googlechat,mattermost,matrix,nextcloud-talkbluebubbles,zalo,zalouser,nostr,feishu
Concepts
agentId: one “brain” (workspace, per-agent auth, per-agent session store).accountId: one channel account instance (e.g. WhatsApp account"personal"vs"biz").binding: routes inbound messages to anagentIdby(channel, accountId, peer)and optionally guild/team ids.- Direct chats collapse to
agent:<agentId>:<mainKey>(per-agent “main”;session.mainKey).
Platform examples
Discord bots per agent
Discord bots per agent
Each Discord bot account maps to a unique
accountId. Bind each account to an agent and keep allowlists per bot.- Invite each bot to the guild and enable Message Content Intent.
- Tokens live in
channels.discord.accounts.<id>.token(default account can useDISCORD_BOT_TOKEN).
Telegram bots per agent
Telegram bots per agent
- Create one bot per agent with BotFather and copy each token.
- Tokens live in
channels.telegram.accounts.<id>.botToken(default account can useTELEGRAM_BOT_TOKEN).
WhatsApp numbers per agent
WhatsApp numbers per agent
Link each account before starting the gateway:
~/.openclaw/openclaw.json (JSON5):Common patterns
- WhatsApp daily + Telegram deep work
- Same channel, one peer to Opus
- Family agent bound to a WhatsApp group
Split by channel: route WhatsApp to a fast everyday agent and Telegram to an Opus agent.Notes:
- If you have multiple accounts for a channel, add
accountIdto the binding (for example{ channel: "whatsapp", accountId: "personal" }). - To route a single DM/group to Opus while keeping the rest on chat, add a
match.peerbinding for that peer; peer matches always win over channel-wide rules.
Per-agent sandbox and tool configuration
Each agent can have its own sandbox and tool restrictions:setupCommand lives under sandbox.docker and runs once on container creation. Per-agent sandbox.docker.* overrides are ignored when the resolved scope is "shared".- Security isolation: restrict tools for untrusted agents.
- Resource control: sandbox specific agents while keeping others on host.
- Flexible policies: different permissions per agent.
tools.elevated is global and sender-based; it is not configurable per agent. If you need per-agent boundaries, use agents.list[].tools to deny exec. For group targeting, use agents.list[].groupChat.mentionPatterns so @mentions map cleanly to the intended agent.Related
- ACP agents — running external coding harnesses
- Channel routing — how messages route to agents
- Presence — agent presence and availability
- Session — session isolation and routing
- Sub-agents — spawning background agent runs