Multi-Agent Routing
목표는 하나의 실행 중인 Gateway 안에서 여러 개의 isolated agent (서로 다른 workspace +agentDir + session)를 운영하고,
여러 channel account(예: WhatsApp 두 개)를 함께 붙인 뒤 binding으로 inbound message를
적절한 agent에 routing하는 것입니다.
What is “one agent”?
하나의 agent는 다음 요소를 모두 가진 완전한 독립 단위입니다.- Workspace
(file,
AGENTS.md/SOUL.md/USER.md, local note, persona rule) - auth profile, model registry, per-agent config를 담는 state directory
(
agentDir) ~/.openclaw/agents/<agentId>/sessions아래의 session store (chat history + routing state)
agentDir를 agent끼리
재사용하면 auth/session collision이 발생하므로 절대 공유하지 마세요. credential을
공유해야 하면 다른 agent의 agentDir로 auth-profiles.json을 복사하세요.
skill은 각 workspace의 skills/를 통해 agent별로 둘 수 있고, shared skill은
~/.openclaw/skills에서 함께 사용할 수 있습니다. 자세한 내용은
Skills: per-agent vs shared를 참고하세요.
Gateway는 기본적으로 one agent만 호스팅할 수도 있고, 여러 agent를 나란히
운영할 수도 있습니다.
Workspace note: 각 agent의 workspace는 default cwd이지 hard sandbox는
아닙니다. relative path는 workspace 안에서 해석되지만, sandbox가 꺼져 있으면
absolute path로 host의 다른 위치에 접근할 수 있습니다.
Sandboxing을 참고하세요.
Paths (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) - Sessions:
~/.openclaw/agents/<agentId>/sessions
Single-agent mode (default)
아무 설정도 하지 않으면 OpenClaw는 single-agent mode로 동작합니다.agentId기본값은main- session key는
agent:main:<mainKey> - workspace 기본값은
~/.openclaw/workspace(OPENCLAW_PROFILE이 있으면~/.openclaw/workspace-<profile>) - state 기본값은
~/.openclaw/agents/main/agent
Agent helper
새 isolated agent를 추가하려면 agent wizard를 사용하세요.bindings를 추가합니다.
확인은 다음 명령으로 할 수 있습니다.
Quick start
Create each agent workspace
wizard를 쓰거나 workspace를 직접 만들 수 있습니다.각 agent는 자신만의 workspace와
SOUL.md, AGENTS.md, optional USER.md,
그리고 ~/.openclaw/agents/<agentId> 아래의 dedicated agentDir와 session store를
갖습니다.Add agents, accounts, and bindings
agents.list에 agent를 추가하고, channels.<channel>.accounts에 account를 정의한 뒤,
bindings로 둘을 연결합니다.Multiple agents = multiple people, multiple personalities
여러 agent를 운영하면 각agentId는 완전히 분리된 persona가 됩니다.
- channel마다 다른 phone number/account
- workspace file(
AGENTS.md,SOUL.md)마다 다른 personality - 분리된 auth + session (명시적으로 허용하지 않는 한 서로 섞이지 않음)
One WhatsApp number, multiple people (DM split)
하나의 WhatsApp account를 유지한 채, 서로 다른 WhatsApp DM을 서로 다른 agent로 보낼 수 있습니다.peer.kind: "direct"와 sender E.164
(예: +15551234567)를 기준으로 route합니다. 단, reply는 모두 같은 WhatsApp
number에서 나갑니다. agent별 sender identity는 없습니다.
중요한 점: direct chat은 agent의 main session key로 합쳐지므로, 진짜로 완전히
분리하려면 사람마다 agent 하나씩 두는 편이 맞습니다.
예시:
- DM access control은 agent별이 아니라 WhatsApp account 전체 기준입니다 (pairing/allowlist)
- shared group은 한 agent에 bind하거나 Broadcast groups를 사용하세요
Routing rules (how messages pick an agent)
binding은 deterministic하며, 더 구체적인 규칙이 우선합니다.peermatch (정확한 DM/group/channel id)parentPeermatch (thread inheritance)guildId + roles(Discord role routing)guildId(Discord)teamId(Slack)- channel의
accountIdmatch - channel-level match (
accountId: "*") - default agent fallback
(
agents.list[].default, 없으면 첫 항목, 기본값은main)
peer + guildId처럼 여러 field를 지정하면, 지정한 field는 모두
일치해야 합니다 (AND semantics).
중요한 account-scope detail:
accountId를 생략한 binding은 default account에만 적용됩니다- channel 전체 fallback을 원하면
accountId: "*"를 사용하세요 - 나중에 같은 agent에 대해 explicit
accountIdbinding을 추가하면, OpenClaw는 기존의 channel-only binding을 복제하지 않고 account-scoped binding으로 승격시킵니다
Multiple accounts / phone numbers
여러 account를 지원하는 channel (예: WhatsApp)은accountId로 각 login을 식별합니다.
각 accountId를 서로 다른 agent에 binding할 수 있으므로, 한 server에서 여러 phone
number를 운영해도 session이 섞이지 않습니다.
accountId가 생략됐을 때 channel-wide default account를 두고 싶다면
channels.<channel>.defaultAccount를 설정하세요. 설정하지 않으면 default가 있으면
그것을 쓰고, 없으면 정렬 순서상 첫 configured account id를 사용합니다.
이 패턴을 지원하는 대표 channel:
whatsapp,telegram,discord,slack,signal,imessageirc,line,googlechat,mattermost,matrix,nextcloud-talkbluebubbles,zalo,zalouser,nostr,feishu
Concepts
agentId: workspace, per-agent auth, per-agent session store를 가진 하나의 “brain”accountId: channel account 인스턴스 하나 (예: WhatsApp"personal"vs"biz")binding:(channel, accountId, peer)와 필요 시 guild/team id로 inbound message를 특정agentId에 route하는 규칙- direct chat은
agent:<agentId>:<mainKey>로 collapse됨 (agent별 main session,session.mainKey)
Platform examples
Discord bots per agent
각 Discord bot account는 고유한accountId에 매핑됩니다. 각 account를 하나의 agent에
bind하고 bot별 allowlist를 유지하세요.
- 각 bot을 guild에 초대하고 Message Content Intent를 켜세요
- token은
channels.discord.accounts.<id>.token에 들어갑니다 (default account는DISCORD_BOT_TOKEN도 사용 가능)
Telegram bots per agent
- BotFather로 agent마다 bot을 만들고 각 token을 복사하세요
- token은
channels.telegram.accounts.<id>.botToken에 들어갑니다 (default account는TELEGRAM_BOT_TOKEN사용 가능)
WhatsApp numbers per agent
gateway를 시작하기 전에 account마다 link합니다.~/.openclaw/openclaw.json (JSON5):
Example: WhatsApp daily chat + Telegram deep work
channel 기준으로 분리해, WhatsApp은 빠른 everyday agent로, Telegram은 Opus agent로 route합니다.- channel에 여러 account가 있으면 binding에
accountId를 추가하세요 (예:{ channel: "whatsapp", accountId: "personal" }) - WhatsApp의 특정 DM/group만 Opus로 보내고 나머지는 chat에 남기려면 그 peer에 대한
match.peerbinding을 추가하세요. peer match는 channel-wide rule보다 항상 우선합니다
Example: same channel, one peer to Opus
WhatsApp 전체는 빠른 agent로 유지하되, 특정 DM 하나만 Opus로 route할 수 있습니다.Family agent bound to a WhatsApp group
전용 family agent를 하나의 WhatsApp group에 bind하고, mention gating과 더 엄격한 tool policy를 적용할 수 있습니다.- tool allow/deny list는 skill이 아니라 tool을 제한합니다. skill이 binary 실행이
필요하다면
exec가 허용돼 있고 binary가 sandbox에 존재해야 합니다 - 더 엄격하게 제한하려면
agents.list[].groupChat.mentionPatterns를 설정하고, channel의 group allowlist도 유지하세요
Per-Agent Sandbox and Tool Configuration
v2026.1.6부터는 agent마다 sandbox와 tool restriction을 따로 둘 수 있습니다.setupCommand는 sandbox.docker 아래에 있으며 container가 생성될 때 한 번만
실행됩니다. resolved scope가 "shared"이면 agent별 sandbox.docker.* override는
무시됩니다.
Benefits:
- Security isolation: 신뢰할 수 없는 agent의 tool을 제한
- Resource control: 특정 agent만 sandbox에 두고 다른 agent는 host에서 유지
- Flexible policies: agent마다 다른 permission 적용
tools.elevated는 global하고 sender-based인 설정이므로 agent별로 나눌 수
없습니다. agent별 경계를 원한다면 agents.list[].tools에서 exec 등을 deny하세요.
group targeting에는 agents.list[].groupChat.mentionPatterns를 사용하면 @mention이
의도한 agent에 깔끔하게 매핑됩니다.
자세한 예시는
Multi-Agent Sandbox & Tools를 참고하세요.