| 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 status returns 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 like my_coordinator_bot
/newbot → name it something like "MyTester" → username like my_tester_bot
/newbot → name it something like "MyCoder" → username like my_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:manual uses the same ANTHROPIC_API_KEY but routes to the 1M-context endpoint.
models.providers: Defines the anthropic-1m provider with explicit model specs. OpenAI and standard anthropic are built-in and auto-detected.
agents.list: Three agents, each with a model and subagents.allowAgents specifying which other agents they can spawn.
bindings: Routes Telegram messages from each bot to the correct agent. The default accountId is the main botToken; named accounts (tester, coder) use tokens from channels.telegram.accounts.
channels.telegram: Main bot token at top level, additional bots under accounts.
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
-
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_spawn creates 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.allowAgents list 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_list from 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
bindings has entries for all three bots
- Make sure
channels.telegram.accounts has tokens for tester and coder
- The
default accountId corresponds to the top-level botToken; named accounts use accounts.<name>.botToken
Auth errors for Anthropic
- The
anthropic-1m provider uses the same ANTHROPIC_API_KEY — it just routes to the 1M-context endpoint
- Make sure
auth.profiles includes an entry for anthropic-1m:manual
- Run
openclaw models status to verify all providers have valid credentials