name: three-brain-setup description: Set up a three-model multi-agent OpenClaw system with GPT-5.2 as the fast communicator/coordinator, Claude Sonnet 4.5 as the tester/reviewer, and Claude Opus 4.6 as the deep coder/architect. All three agents get their own Telegram bots and can delegate work to each other via sessions_spawn. Use when setting up multi-agent orchestration, a three-brain system, or a coordinator/tester/coder agent team.
Three-Brain Multi-Agent Setup
This guide turns a stock OpenClaw installation into a three-agent system:
| Agent | Model | Role | Telegram Bot |
|---|---|---|---|
| coordinator | openai/gpt-5.2 |
Fast triage, communication, delegation | Your main bot |
| tester | anthropic-1m/claude-sonnet-4-5 |
Code review, testing, image/vision tasks | Second bot |
| coder | anthropic-1m/claude-opus-4-6 |
Deep coding, architecture, heavy reasoning | Third bot |
Prerequisites
- OpenClaw installed and running (
openclaw gateway statusreturns OK) - API keys for OpenAI and Anthropic
- A Telegram account (to create 3 bots via @BotFather)
Step 1: Create Three Telegram Bots
Open Telegram, chat with @BotFather, and create three bots:
/newbot→ name it something like "MyCoordinator" → username likemy_coordinator_bot/newbot→ name it something like "MyTester" → username likemy_tester_bot/newbot→ name it something like "MyCoder" → username likemy_coder_bot
Copy each bot token. You'll need all three.
Important: For each bot, also run /setprivacy → Disable if you want them to see all messages in groups (not just @mentions).
Step 2: Set API Keys
Make sure your API keys are in the OpenClaw config. Run:
openclaw configure
Or set them as environment variables in your shell profile:
export OPENAI_API_KEY="sk-proj-..."
export ANTHROPIC_API_KEY="sk-ant-..."
Or put them directly in ~/.openclaw/openclaw.json under env.vars:
{
env: {
vars: {
OPENAI_API_KEY: "sk-proj-...",
ANTHROPIC_API_KEY: "sk-ant-..."
}
}
}
Step 3: Configure openclaw.json
This is the core step. Open ~/.openclaw/openclaw.json and set up the full config.
Below is the complete, working config. Replace the placeholder values marked with <...>.
{
// ── API Keys ──
env: {
vars: {
OPENAI_API_KEY: "<your-openai-api-key>",
ANTHROPIC_API_KEY: "<your-anthropic-api-key>"
}
},
// ── Auth Profiles ──
// Tell OpenClaw how to authenticate with each provider.
auth: {
profiles: {
"openai:default": {
provider: "openai",
mode: "token"
},
"anthropic:default": {
provider: "anthropic",
mode: "token"
},
"anthropic-1m:manual": {
provider: "anthropic-1m",
mode: "token"
}
}
},
// ── Model Providers ──
// Define the Anthropic 1M-context provider (for Sonnet + Opus with large context).
// OpenAI is built-in and doesn't need explicit provider config.
models: {
providers: {
"anthropic-1m": {
baseUrl: "https://api.anthropic.com",
api: "anthropic-messages",
models: [
{
id: "claude-opus-4-6",
name: "Claude Opus 4.6 (1M context)",
reasoning: true,
input: ["text", "image"],
cost: { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 },
contextWindow: 1000000,
maxTokens: 32000
},
{
id: "claude-sonnet-4-5",
name: "Claude Sonnet 4.5",
reasoning: true,
input: ["text", "image"],
cost: { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 3.75 },
contextWindow: 200000,
maxTokens: 16000
}
]
}
}
},
// ── Agents ──
agents: {
defaults: {
// Shared workspace — all three agents see the same files.
// Change to separate workspaces if you want isolation.
workspace: "~/.openclaw/workspace",
skipBootstrap: true,
maxConcurrent: 4,
subagents: {
maxConcurrent: 8
}
},
list: [
{
id: "coordinator",
name: "coordinator",
workspace: "~/.openclaw/workspace",
model: "openai/gpt-5.2",
// Coordinator can delegate to tester and coder
subagents: {
allowAgents: ["tester", "coder"]
}
},
{
id: "tester",
name: "tester",
workspace: "~/.openclaw/workspace",
model: "anthropic-1m/claude-sonnet-4-5",
// Tester can delegate to coordinator and coder
subagents: {
allowAgents: ["coordinator", "coder"]
}
},
{
id: "coder",
name: "coder",
workspace: "~/.openclaw/workspace",
model: "anthropic-1m/claude-opus-4-6",
// Coder can delegate to coordinator and tester
subagents: {
allowAgents: ["coordinator", "tester"]
}
}
]
},
// ── Channel Bindings ──
// Route each Telegram bot to the correct agent.
bindings: [
{
agentId: "coordinator",
match: { channel: "webchat" }
},
{
agentId: "coordinator",
match: { channel: "telegram", accountId: "default" }
},
{
agentId: "tester",
match: { channel: "telegram", accountId: "tester" }
},
{
agentId: "coder",
match: { channel: "telegram", accountId: "coder" }
}
],
// ── Telegram Channel ──
channels: {
telegram: {
enabled: true,
botToken: "<coordinator-bot-token>",
dmPolicy: "pairing",
groupPolicy: "allowlist",
streamMode: "partial",
accounts: {
tester: {
dmPolicy: "pairing",
botToken: "<tester-bot-token>",
groupPolicy: "allowlist",
streamMode: "partial"
},
coder: {
dmPolicy: "pairing",
botToken: "<coder-bot-token>",
groupPolicy: "allowlist",
streamMode: "partial"
}
}
}
},
// ── Gateway ──
gateway: {
port: 18789,
mode: "local",
auth: {
mode: "token"
// A token is auto-generated on first start. Or set your own:
// token: "your-secret-token-here"
}
},
// ── Plugins ──
plugins: {
entries: {
telegram: { enabled: true }
}
}
}
What each section does
env.vars: API keys available to all agents as environment variables.auth.profiles: Tells OpenClaw which auth method to use per provider.anthropic-1m:manualuses the sameANTHROPIC_API_KEYbut routes to the 1M-context endpoint.models.providers: Defines theanthropic-1mprovider with explicit model specs. OpenAI and standardanthropicare built-in and auto-detected.agents.list: Three agents, each with a model andsubagents.allowAgentsspecifying which other agents they can spawn.bindings: Routes Telegram messages from each bot to the correct agent. ThedefaultaccountId is the mainbotToken; named accounts (tester,coder) use tokens fromchannels.telegram.accounts.channels.telegram: Main bot token at top level, additional bots underaccounts.
Step 4: Set Up Workspace Files
All three agents share a workspace. The workspace files teach each agent who it is and how to delegate.
AGENTS.md
Create/update ~/.openclaw/workspace/AGENTS.md:
# AGENTS.md
## Multi-Agent System
You are part of a three-agent team. Each agent has a specialty.
### The Team
| Agent | Model | Strength | When to use |
|-------|-------|----------|-------------|
| **coordinator** | GPT-5.2 | Fast, cheap, good communicator | Triage, coordination, simple tasks, user-facing replies |
| **tester** | Sonnet 4.5 | Vision, code review, solid reasoning | Testing, reviewing code, analyzing images, medium tasks |
| **coder** | Opus 4.6 | Best reasoning, deep coding | Writing code, architecture, complex problems, refactoring |
### How to Delegate
Use `sessions_spawn` to hand off work:
sessions_spawn( agentId="coder", task="Write a Python script that...", cleanup="delete" )
The spawned agent works in the background and announces results when done.
Use `agents_list` to see which agents you can delegate to.
### Delegation Rules
- **coordinator**: You're the front door. Talk to the user. For code tasks, delegate to **coder**. For reviews/testing, delegate to **tester**. Only do simple tasks yourself.
- **tester**: You review and test. If you find something that needs a rewrite, delegate to **coder**. Report results back clearly.
- **coder**: You write code. If you need clarification from the user, your announce will reach them through the coordinator's channel. Focus on quality implementation.
### Cost Awareness
- coordinator (GPT-5.2): $1.75/$14 per M tokens — cheap, use freely
- tester (Sonnet 4.5): $3/$15 per M tokens — moderate, use for real work
- coder (Opus 4.6): $5/$25 per M tokens — expensive, use for actual coding/architecture
Don't delegate trivially. If the coordinator can answer "what time is it?" — just answer it.
SOUL.md
Create/update ~/.openclaw/workspace/SOUL.md with your preferred personality. Each agent reads this, so write it for all three:
# SOUL.md
Be helpful, be direct. Skip the filler.
When you're the **coordinator**: be conversational and fast. Triage requests and delegate heavy work.
When you're the **tester**: be thorough and critical. Find problems.
When you're the **coder**: be precise and clean. Write good code the first time.
All agents: don't ask questions you can answer yourself. Check files, search the web, try things. Only ask the user as a last resort.
Step 5: Restart and Pair
Restart the gateway to pick up the new config:
openclaw gateway restart
Now DM each of the three Telegram bots. Each will send a pairing code. Approve them:
openclaw pairing list telegram
openclaw pairing approve telegram <CODE_1>
openclaw pairing approve telegram <CODE_2>
openclaw pairing approve telegram <CODE_3>
You may need to specify the account for non-default bots:
openclaw pairing list telegram --account tester
openclaw pairing approve telegram <CODE> --account tester
openclaw pairing list telegram --account coder
openclaw pairing approve telegram <CODE> --account coder
Step 6: Test It
DM the coordinator bot and say: "Write me a Python script that generates Fibonacci numbers"
- The coordinator should delegate to the coder agent via
sessions_spawn - The coder works in the background and announces results
- The coordinator should delegate to the coder agent via
DM the tester bot and say: "Review this code:
def fib(n): return n if n < 2 else fib(n-1) + fib(n-2)"- The tester should analyze it directly (code review is its job)
DM the coder bot and say: "Build a FastAPI endpoint that returns the current time"
- The coder should write it directly (coding is its job)
DM the coordinator and say: "Can you have the tester review this code?" with a code snippet
- The coordinator should delegate to the tester
How It Works Under the Hood
┌─────────────┐
Telegram │ coordinator │ ← GPT-5.2 (fast/cheap)
Bot #1 ──────► │ agent │
└──────┬──────┘
│ sessions_spawn(agentId="coder", task="...")
│ sessions_spawn(agentId="tester", task="...")
▼
┌────────────────────────┐
│ │
┌────────┴───────┐ ┌───────────┴──────┐
│ tester │ │ coder │
│ agent │ │ agent │
│ Sonnet 4.5 │ │ Opus 4.6 │
└────────┬────────┘ └──────────┬────────┘
│ │
Telegram Bot #2 Telegram Bot #3
- Each agent is a fully isolated brain with its own sessions and Telegram bot.
sessions_spawncreates an isolated sub-session, runs the task, and announces the result back to the requester's chat channel.- All agents share the same workspace (files, memory) but have separate conversation histories.
- The
subagents.allowAgentslist controls who can delegate to whom — it's a full mesh here (everyone can reach everyone).
Customization
Separate Workspaces
If you want each agent to have its own personality and memory:
{
agents: {
list: [
{ id: "coordinator", workspace: "~/.openclaw/workspace-coordinator", /* ... */ },
{ id: "tester", workspace: "~/.openclaw/workspace-tester", /* ... */ },
{ id: "coder", workspace: "~/.openclaw/workspace-coder", /* ... */ }
]
}
}
Then create separate AGENTS.md, SOUL.md, USER.md in each workspace.
Adding to a Group Chat
To have all three bots in a Telegram group where users can @mention them:
- Add all three bots to the group
- Get the group chat ID (forward a group message to
@userinfobot) - Add group config:
{
channels: {
telegram: {
groups: {
"<group-chat-id>": {
groupPolicy: "open",
requireMention: true // respond when @mentioned
}
},
// Also add the group to each account:
accounts: {
tester: {
// ... existing config ...
groups: {
"<group-chat-id>": {
groupPolicy: "open",
requireMention: true
}
}
},
coder: {
// ... existing config ...
groups: {
"<group-chat-id>": {
groupPolicy: "open",
requireMention: true
}
}
}
}
}
}
}
Using Different Models
Swap any model for what you have access to:
- Local models via Ollama:
ollama/llama3.3,ollama/qwen3-next:80b,ollama/deepseek-r1:70b - Standard Anthropic (200K context):
anthropic/claude-sonnet-4-5,anthropic/claude-opus-4-6 - OpenAI cheaper:
openai/gpt-5-mini,openai/gpt-4o-mini - OpenRouter (many models):
openrouter/anthropic/claude-sonnet-4-5
Just change the model field on each agent in agents.list.
Adjusting Delegation Permissions
To make it one-directional (only coordinator delegates):
{
agents: {
list: [
{ id: "coordinator", subagents: { allowAgents: ["tester", "coder"] } },
{ id: "tester", subagents: { allowAgents: [] } },
{ id: "coder", subagents: { allowAgents: [] } }
]
}
}
Troubleshooting
"Model is not allowed"
If you set agents.defaults.models (the allowlist), make sure all three models are listed. Or remove it entirely to allow any configured model.
Bot doesn't respond
- Check
openclaw gateway status— is it running? - Check
openclaw logs --follow— look for errors - Did you approve pairing for that bot? (
openclaw pairing list telegram) - Is the bot token correct?
Sub-agent spawn fails
- Check
agents.list[].subagents.allowAgents— does it include the target agent? - Run
agents_listfrom within a chat to see allowed targets - Check that the target agent's model provider has valid auth (
openclaw models status)
Only one bot responds
- Make sure
bindingshas entries for all three bots - Make sure
channels.telegram.accountshas tokens fortesterandcoder - The
defaultaccountId corresponds to the top-levelbotToken; named accounts useaccounts.<name>.botToken
Auth errors for Anthropic
- The
anthropic-1mprovider uses the sameANTHROPIC_API_KEY— it just routes to the 1M-context endpoint - Make sure
auth.profilesincludes an entry foranthropic-1m:manual - Run
openclaw models statusto verify all providers have valid credentials