멀티 에이전트 라우팅
목표: 완전히 격리된 여러 에이전트(별도의 워크스페이스 + agentDir + 세션)와 여러 채널 계정(예: WhatsApp 2개)을 하나의 게이트웨이에서 운영. 인바운드 메시지는 바인딩을 통해 에이전트로 라우팅됩니다.
”하나의 에이전트”란?
에이전트는 다음을 갖는 완전히 격리된 두뇌입니다:
- 워크스페이스 (파일, AGENTS.md/SOUL.md/USER.md, 로컬 메모, 페르소나 규칙).
- 상태 디렉터리 (
agentDir) — 인증 프로필, 모델 레지스트리, 에이전트별 설정. - 세션 스토어 (채팅 히스토리 + 라우팅 상태) —
~/.openclaw/agents/<agentId>/sessions하위.
인증 프로필은 에이전트별입니다. 각 에이전트는 자체 프로필을 읽습니다:
~/.openclaw/agents/<agentId>/agent/auth-profiles.json
메인 에이전트 자격 증명은 자동으로 공유되지 않습니다. 에이전트 간에 agentDir을 절대 재사용하지 마세요 (인증/세션 충돌 발생). 자격 증명을 공유하려면 auth-profiles.json을 다른 에이전트의 agentDir에 복사하세요.
스킬은 각 워크스페이스의 skills/ 폴더를 통해 에이전트별로 관리되며, 공유 스킬은 ~/.openclaw/skills에서 사용 가능합니다. 스킬: 에이전트별 vs 공유를 참고하세요.
게이트웨이는 하나의 에이전트 (기본값) 또는 여러 에이전트를 나란히 호스팅할 수 있습니다.
워크스페이스 참고: 각 에이전트의 워크스페이스는 기본 cwd이지 엄격한 샌드박스가 아닙니다. 상대 경로는 워크스페이스 내에서 해석되지만, 샌드박싱이 활성화되지 않는 한 절대 경로로 호스트의 다른 위치에 접근할 수 있습니다. 샌드박싱을 참고하세요.
경로 (빠른 맵)
- 설정:
~/.openclaw/openclaw.json(또는OPENCLAW_CONFIG_PATH) - 상태 디렉터리:
~/.openclaw(또는OPENCLAW_STATE_DIR) - 워크스페이스:
~/.openclaw/workspace(또는~/.openclaw/workspace-<agentId>) - 에이전트 디렉터리:
~/.openclaw/agents/<agentId>/agent(또는agents.list[].agentDir) - 세션:
~/.openclaw/agents/<agentId>/sessions
단일 에이전트 모드 (기본값)
별도 설정 없이 OpenClaw는 단일 에이전트를 실행합니다:
agentId기본값은main.- 세션 키는
agent:main:<mainKey>. - 워크스페이스 기본값은
~/.openclaw/workspace(OPENCLAW_PROFILE설정 시~/.openclaw/workspace-<profile>). - 상태 기본값은
~/.openclaw/agents/main/agent.
에이전트 도우미
에이전트 마법사로 새로운 격리 에이전트를 추가하세요:
openclaw agents add work
그런 다음 bindings를 추가하거나 (마법사에서 진행) 인바운드 메시지를 라우팅합니다.
확인:
openclaw agents list --bindings
빠른 시작
1단계: 각 에이전트 워크스페이스 생성
마법사를 사용하거나 워크스페이스를 수동으로 생성하세요:
openclaw agents add coding
openclaw agents add social
각 에이전트는 SOUL.md, AGENTS.md, 선택적 USER.md가 있는 자체 워크스페이스와 ~/.openclaw/agents/<agentId> 아래의 전용 agentDir 및 세션 스토어를 갖습니다.
2단계: 채널 계정 생성
선호하는 채널에서 에이전트당 하나의 계정을 생성하세요:
- Discord: 에이전트당 하나의 봇, Message Content Intent 활성화, 각 토큰 복사.
- Telegram: 에이전트당 BotFather를 통해 하나의 봇, 각 토큰 복사.
- WhatsApp: 계정당 각 전화번호 연결.
openclaw channels login --channel whatsapp --account work
채널 가이드 참고: Discord, Telegram, WhatsApp.
3단계: 에이전트, 계정, 바인딩 추가
agents.list 아래에 에이전트를, channels.<channel>.accounts 아래에 채널 계정을 추가하고, bindings로 연결합니다 (아래 예시).
4단계: 재시작 및 확인
openclaw gateway restart
openclaw agents list --bindings
openclaw channels status --probe
여러 에이전트 = 여러 사람, 여러 개성
여러 에이전트를 사용하면 각 agentId가 완전히 격리된 페르소나가 됩니다:
- 다른 전화번호/계정 (채널
accountId별). - 다른 개성 (에이전트별 워크스페이스 파일
AGENTS.md,SOUL.md등). - 별도 인증 + 세션 (명시적으로 활성화하지 않는 한 교차 통신 없음).
이를 통해 여러 사람이 하나의 게이트웨이 서버를 공유하면서 AI “두뇌”와 데이터를 격리할 수 있습니다.
하나의 WhatsApp 번호로 여러 사람 (DM 분리)
하나의 WhatsApp 계정에서 다른 WhatsApp DM을 다른 에이전트로 라우팅할 수 있습니다. 발신자 E.164(예: +15551234567)에 peer.kind: "direct"로 매칭합니다. 응답은 여전히 같은 WhatsApp 번호에서 발송됩니다 (에이전트별 발신자 ID 없음).
중요 세부사항: 1:1 채팅은 에이전트의 메인 세션 키로 통합되므로 진정한 격리를 위해서는 사람당 하나의 에이전트가 필요합니다.
예시:
{
agents: {
list: [
{ id: "alex", workspace: "~/.openclaw/workspace-alex" },
{ id: "mia", workspace: "~/.openclaw/workspace-mia" },
],
},
bindings: [
{
agentId: "alex",
match: { channel: "whatsapp", peer: { kind: "direct", id: "+15551230001" } },
},
{
agentId: "mia",
match: { channel: "whatsapp", peer: { kind: "direct", id: "+15551230002" } },
},
],
channels: {
whatsapp: {
dmPolicy: "allowlist",
allowFrom: ["+15551230001", "+15551230002"],
},
},
}
참고:
- DM 접근 제어는 에이전트별이 아닌 WhatsApp 계정별 전역입니다 (페어링/허용 목록).
- 공유 그룹은 하나의 에이전트에 바인딩하거나 브로드캐스트 그룹을 사용하세요.
라우팅 규칙 (메시지가 에이전트를 선택하는 방법)
바인딩은 결정적이며 가장 구체적인 것이 우선:
peer매칭 (정확한 DM/그룹/채널 ID)parentPeer매칭 (스레드 상속)guildId + roles(Discord 역할 라우팅)guildId(Discord)teamId(Slack)- 채널의
accountId매칭 - 채널 레벨 매칭 (
accountId: "*") - 기본 에이전트로 폴백 (
agents.list[].default, 없으면 첫 번째 목록 항목, 기본값:main)
같은 티어에서 여러 바인딩이 매칭되면 설정 순서에서 첫 번째가 우선합니다.
바인딩이 여러 매칭 필드를 설정하면 (예: peer + guildId) 지정된 모든 필드가 일치해야 합니다 (AND 의미론).
계정 범위 관련 중요 세부사항:
accountId를 생략한 바인딩은 기본 계정에만 매칭됩니다.- 모든 계정에 걸친 채널 전체 폴백에는
accountId: "*"를 사용하세요. - 나중에 같은 에이전트에 대해 명시적 계정 ID로 같은 바인딩을 추가하면, OpenClaw가 기존 채널 전용 바인딩을 중복 생성하는 대신 계정 범위로 업그레이드합니다.
여러 계정 / 전화번호
여러 계정을 지원하는 채널(예: WhatsApp)은 accountId로 각 로그인을 식별합니다. 각 accountId를 다른 에이전트로 라우팅하여 하나의 서버에서 세션을 섞지 않고 여러 전화번호를 호스팅할 수 있습니다.
accountId가 생략될 때 채널 전체 기본 계정을 원하면 channels.<channel>.defaultAccount를 설정하세요 (선택). 미설정 시 OpenClaw는 default가 있으면 사용하고, 그렇지 않으면 첫 번째 설정된 계정 ID (정렬 기준)로 폴백합니다.
이 패턴을 지원하는 일반적인 채널:
whatsapp,telegram,discord,slack,signal,imessageirc,line,googlechat,mattermost,matrix,nextcloud-talkbluebubbles,zalo,zalouser,nostr,feishu
개념
agentId: 하나의 “두뇌” (워크스페이스, 에이전트별 인증, 에이전트별 세션 스토어).accountId: 하나의 채널 계정 인스턴스 (예: WhatsApp 계정"personal"vs"biz").binding:(channel, accountId, peer)및 선택적 guild/team ID로 인바운드 메시지를agentId로 라우팅.- 1:1 채팅은
agent:<agentId>:<mainKey>로 통합 (에이전트별 “main”,session.mainKey).
플랫폼 예시
에이전트별 Discord 봇
각 Discord 봇 계정이 고유한 accountId에 매핑됩니다. 각 계정을 에이전트에 바인딩하고 봇별 허용 목록을 유지하세요.
{
agents: {
list: [
{ id: "main", workspace: "~/.openclaw/workspace-main" },
{ id: "coding", workspace: "~/.openclaw/workspace-coding" },
],
},
bindings: [
{ agentId: "main", match: { channel: "discord", accountId: "default" } },
{ agentId: "coding", match: { channel: "discord", accountId: "coding" } },
],
channels: {
discord: {
groupPolicy: "allowlist",
accounts: {
default: {
token: "DISCORD_BOT_TOKEN_MAIN",
guilds: {
"123456789012345678": {
channels: {
"222222222222222222": { allow: true, requireMention: false },
},
},
},
},
coding: {
token: "DISCORD_BOT_TOKEN_CODING",
guilds: {
"123456789012345678": {
channels: {
"333333333333333333": { allow: true, requireMention: false },
},
},
},
},
},
},
},
}
참고:
- 각 봇을 길드에 초대하고 Message Content Intent를 활성화하세요.
- 토큰은
channels.discord.accounts.<id>.token에 저장됩니다 (기본 계정은DISCORD_BOT_TOKEN사용 가능).
에이전트별 Telegram 봇
{
agents: {
list: [
{ id: "main", workspace: "~/.openclaw/workspace-main" },
{ id: "alerts", workspace: "~/.openclaw/workspace-alerts" },
],
},
bindings: [
{ agentId: "main", match: { channel: "telegram", accountId: "default" } },
{ agentId: "alerts", match: { channel: "telegram", accountId: "alerts" } },
],
channels: {
telegram: {
accounts: {
default: {
botToken: "123456:ABC...",
dmPolicy: "pairing",
},
alerts: {
botToken: "987654:XYZ...",
dmPolicy: "allowlist",
allowFrom: ["tg:123456789"],
},
},
},
},
}
참고:
- BotFather로 에이전트당 하나의 봇을 생성하고 각 토큰을 복사하세요.
- 토큰은
channels.telegram.accounts.<id>.botToken에 저장됩니다 (기본 계정은TELEGRAM_BOT_TOKEN사용 가능).
에이전트별 WhatsApp 번호
게이트웨이 시작 전에 각 계정을 연결하세요:
openclaw channels login --channel whatsapp --account personal
openclaw channels login --channel whatsapp --account biz
~/.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",
},
],
},
// 결정적 라우팅: 첫 번째 매칭이 우선 (가장 구체적인 것 먼저).
bindings: [
{ agentId: "home", match: { channel: "whatsapp", accountId: "personal" } },
{ agentId: "work", match: { channel: "whatsapp", accountId: "biz" } },
// 선택적 피어별 오버라이드 (예: 특정 그룹을 work 에이전트로 전송).
{
agentId: "work",
match: {
channel: "whatsapp",
accountId: "personal",
peer: { kind: "group", id: "[email protected]" },
},
},
],
// 기본 비활성: 에이전트 간 메시징은 명시적으로 활성화 + 허용 목록에 추가해야 합니다.
tools: {
agentToAgent: {
enabled: false,
allow: ["home", "work"],
},
},
channels: {
whatsapp: {
accounts: {
personal: {
// 선택적 오버라이드. 기본값: ~/.openclaw/credentials/whatsapp/personal
// authDir: "~/.openclaw/credentials/whatsapp/personal",
},
biz: {
// 선택적 오버라이드. 기본값: ~/.openclaw/credentials/whatsapp/biz
// authDir: "~/.openclaw/credentials/whatsapp/biz",
},
},
},
},
}
예시: WhatsApp 일상 채팅 + Telegram 딥 워크
채널별 분리: WhatsApp을 빠른 일상 에이전트로, Telegram을 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-6",
},
],
},
bindings: [
{ agentId: "chat", match: { channel: "whatsapp" } },
{ agentId: "opus", match: { channel: "telegram" } },
],
}
참고:
- 채널에 여러 계정이 있으면 바인딩에
accountId를 추가하세요 (예:{ channel: "whatsapp", accountId: "personal" }). - 하나의 DM/그룹을 Opus로 라우팅하고 나머지는 chat에 유지하려면 해당 피어에
match.peer바인딩을 추가하세요. 피어 매칭은 항상 채널 전체 규칙보다 우선합니다.
예시: 같은 채널에서 하나의 피어만 Opus로
WhatsApp을 빠른 에이전트에 유지하되, 하나의 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-6",
},
],
},
bindings: [
{
agentId: "opus",
match: { channel: "whatsapp", peer: { kind: "direct", id: "+15551234567" } },
},
{ agentId: "chat", match: { channel: "whatsapp" } },
],
}
피어 바인딩이 항상 우선하므로 채널 전체 규칙 위에 배치하세요.
WhatsApp 그룹에 바인딩된 가족 에이전트
전용 가족 에이전트를 단일 WhatsApp 그룹에 바인딩하고, 멘션 게이팅과 제한된 도구 정책을 적용합니다:
{
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]" },
},
},
],
}
참고:
- 도구 허용/거부 목록은 스킬이 아닌 도구입니다. 스킬이 바이너리를 실행해야 하면
exec이 허용되어 있고 샌드박스에 바이너리가 존재하는지 확인하세요. - 더 엄격한 게이팅을 위해
agents.list[].groupChat.mentionPatterns를 설정하고 채널에서 그룹 허용 목록을 활성화하세요.
에이전트별 샌드박스 및 도구 설정
v2026.1.6부터 각 에이전트가 자체 샌드박스와 도구 제한을 가질 수 있습니다:
{
agents: {
list: [
{
id: "personal",
workspace: "~/.openclaw/workspace-personal",
sandbox: {
mode: "off", // 개인 에이전트에는 샌드박스 없음
},
// 도구 제한 없음 - 모든 도구 사용 가능
},
{
id: "family",
workspace: "~/.openclaw/workspace-family",
sandbox: {
mode: "all", // 항상 샌드박스
scope: "agent", // 에이전트당 하나의 컨테이너
docker: {
// 선택적 일회성 설정 (컨테이너 생성 후)
setupCommand: "apt-get update && apt-get install -y git curl",
},
},
tools: {
allow: ["read"], // read 도구만
deny: ["exec", "write", "edit", "apply_patch"], // 나머지 거부
},
},
],
},
}
참고: setupCommand는 sandbox.docker 아래에 있으며 컨테이너 생성 시 한 번만 실행됩니다.
확인된 범위가 "shared"이면 에이전트별 sandbox.docker.* 오버라이드는 무시됩니다.
장점:
- 보안 격리: 신뢰할 수 없는 에이전트의 도구 제한
- 리소스 제어: 특정 에이전트만 샌드박싱하고 나머지는 호스트에서 유지
- 유연한 정책: 에이전트별 다른 권한
참고: tools.elevated는 전역이며 발신자 기반입니다. 에이전트별로 설정할 수 없습니다.
에이전트별 경계가 필요하면 agents.list[].tools로 exec을 거부하세요.
그룹 타겟팅에는 agents.list[].groupChat.mentionPatterns를 사용하여 @멘션이 의도한 에이전트에 깔끔하게 매핑되도록 하세요.
자세한 예시는 멀티 에이전트 샌드박스 & 도구를 참고하세요.