three-brain-setup

star 2

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.

austintgriffith By austintgriffith schedule Updated 2/9/2026

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:

  1. /newbot → name it something like "MyCoordinator" → username like my_coordinator_bot
  2. /newbot → name it something like "MyTester" → username like my_tester_bot
  3. /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 /setprivacyDisable 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

  1. 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
  2. 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)
  3. 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)
  4. 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:

  1. Add all three bots to the group
  2. Get the group chat ID (forward a group message to @userinfobot)
  3. 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
Install via CLI
npx skills add https://github.com/austintgriffith/three-brain-setup --skill three-brain-setup
Repository Details
star Stars 2
call_split Forks 1
navigation Branch main
article Path SKILL.md
More from Creator
austintgriffith
austintgriffith Explore all skills →