3 Multi-Agent Patterns in OpenClaw

A complete guide to building AI agent teams — from persistent teams that know each other, to an army of workers that spawn on-demand.

You want to run multiple AI agents on a single OpenClaw Gateway. But what does "multiple agents" actually look like?

A team of 4 agents chatting with each other? One boss that spawns 20 workers simultaneously? A combination of both?

There are three main patterns:

  1. Role-Based — A persistent team with personality, memory, and expertise
  2. Orchestrator + Workers — One smart brain that spawns ephemeral workers on-demand
  3. Hybrid — A persistent team that can also spawn workers

Each pattern has trade-offs. This article breaks down all three — architecture, config, use cases, and when to pick which.


Role-Based Pattern

A startup team — everyone has a role, they know each other, and they remember everything.

Think of it like a company org chart. There's a CEO, CTO, CMO. Each agent has its own desk, brain, and personality. They run persistently, communicate via session tools, and each one has a domain of expertise.

What makes this different from just "running multiple agents" is that these agents are always alive. They're not disposable. They remember. They have opinions.

Key characteristics

  • Persistent — always alive, not disposable
  • Specialized — each has a domain of expertise
  • Personalized — each has a personality via SOUL.md
  • Isolated — workspace, memory, and sessions are separate
  • Communicative — can message each other via sessions_send

Architecture

A single Gateway process handles all agents. The routing engine (bindings) decides which agent gets which message — Discord #coding goes to Bob, Telegram goes to Milo.

Here's an example team of four agents, each with a different model suited to its role:

AgentRoleModelChannel
MiloLeader / CoordinatorClaude Opus#general, Telegram
BobSenior DeveloperClaude Sonnet#coding
AngelaMarketing & ContentGemini Pro#marketing
JoshBusiness DevelopmentClaude Sonnet#business

The config looks like this:

{
  "agents": {
    "list": [
      {
        "id": "milo",
        "name": "Milo",
        "default": true,
        "workspace": "~/.openclaw/workspace-milo",
        "model": "anthropic/claude-opus-4-6",
      },
      {
        "id": "bob",
        "name": "Bob",
        "workspace": "~/.openclaw/workspace-bob",
        "model": "anthropic/claude-sonnet-4-6",
      },
      {
        "id": "angela",
        "name": "Angela",
        "workspace": "~/.openclaw/workspace-angela",
        "model": "google/gemini-2.5-pro",
        "tools": { "deny": ["terminal"] },
      },
      {
        "id": "josh",
        "name": "Josh",
        "workspace": "~/.openclaw/workspace-josh",
        "model": "anthropic/claude-sonnet-4-6",
        "tools": { "deny": ["terminal"] },
      },
    ],
  },
  "bindings": [
    {
      "agentId": "milo",
      "match": {
        "channel": "discord",
        "peer": { "kind": "channel", "id": "GENERAL_ID" },
      },
    },
    {
      "agentId": "bob",
      "match": {
        "channel": "discord",
        "peer": { "kind": "channel", "id": "CODING_ID" },
      },
    },
    {
      "agentId": "angela",
      "match": {
        "channel": "discord",
        "peer": { "kind": "channel", "id": "MARKETING_ID" },
      },
    },
    {
      "agentId": "josh",
      "match": {
        "channel": "discord",
        "peer": { "kind": "channel", "id": "BUSINESS_ID" },
      },
    },
    { "agentId": "milo", "match": { "channel": "telegram" } },
  ],
  "tools": {
    "agentToAgent": {
      "enabled": true,
      "allow": ["milo", "bob", "angela", "josh"],
    },
  },
}

What makes an agent "alive"

Each agent has a workspace. This is their brain:

~/.openclaw/workspace-milo/
├── SOUL.md       ← Who they are (personality)
├── AGENTS.md     ← SOPs and protocols
├── MEMORY.md     ← Long-term memory
├── memory/       ← Daily notes (auto-loaded)
└── skills/       ← Domain-specific skills

SOUL.md defines who the agent is. It's their personality, their rules, their identity:

# Milo — Team Leader

## Identity

You are Milo, the team leader. You manage Bob (dev), Angela (marketing), Josh (business).

## Personality

- Decisive, strategic, no fluff
- ALWAYS delegate coding to Bob, content to Angela, analysis to Josh
- YOU focus on coordination and reporting

Inter-agent communication

This is what makes Role-Based powerful. Agents can talk to each other:

Milo → Bob:    "Fix auth bug. Priority HIGH."        (sessions_send)
Bob  → Milo:   "Done. PR #45 ready for review."      (response)
Milo → Angela: "Write announcement for this fix."     (sessions_send)

The leader can broadcast to everyone, compile status, and report back. All automatic.

Memory — agents that remember

Each agent maintains its own memory system:

  • MEMORY.md — persistent notes, loaded every session
  • memory/YYYY-MM-DD.md — daily notes, auto-loaded for today and yesterday
  • Cross-agent search — the leader can search across all agents' memory

Bob remembers coding patterns. Angela remembers which content performs well. Milo remembers strategic decisions. Everything persists across sessions.

When to use Role-Based

Good fit:

  • Small team (2–6 agents) with different domain expertise
  • Need persistent memory per domain
  • Need personality and ongoing collaboration
  • Long-running operational work

Not ideal for:

  • One-off batch tasks that need parallelism
  • Hundreds of ephemeral workers
  • Very limited budget

Orchestrator + Workers

A project manager with freelancers — one smart brain, many fast hands.

One main agent (the Orchestrator) receives all tasks, breaks them into sub-tasks, then spawns worker agents on-demand via sessions_spawn.

Workers are ephemeral. They live for the duration of the task, report results, then die. This isn't a team that knows each other. This is a boss hiring freelancers.

How they compare

OrchestratorWorkers
Persistent (always alive)Ephemeral (per task)
1 agentDynamic — 1 up to 20+
Strongest model (Opus)Model suited to task
Has memory & personalityDisposable, no memory
Decompose + compileExecute single sub-task

Architecture

The lifecycle is simple: Spawn, Work, Report, Die. Workers have no memory. All learning lives in the Orchestrator.

Config

The setup is minimal. One agent. One workspace. Done.

{
  "agents": {
    "list": [
      {
        "id": "orchestrator",
        "name": "Orchestrator",
        "default": true,
        "workspace": "~/.openclaw/workspace",
        "model": "anthropic/claude-opus-4-6",
        "sandbox": "non-main",
      },
    ],
  },
  "tools": {
    "subAgents": { "enabled": true, "maxConcurrent": 10 },
  },
  "memory": { "enabled": true, "dailyNotes": true },
}

Compare that with Role-Based, which needs 4+ agent definitions and bindings.

External coding agents via ACP

The Orchestrator can also spawn external tools like Codex or Claude Code:

{
  "acp": {
    "enabled": true,
    "backend": "acpx",
    "agents": {
      "codex": { "type": "codex", "model": "codex-1" },
      "claude-code": { "type": "claude-code", "model": "claude-sonnet-4-6" },
    },
  },
}

Spawning patterns

There are three ways to spawn workers.

Parallel — for independent sub-tasks:

├── Spawn Worker 1: "Build registration endpoint"
├── Spawn Worker 2: "Build login endpoint"
├── Spawn Worker 3: "Build profile CRUD"
└── All run simultaneously → compile

Sequential — when output A feeds into input B:

Worker 1: Research → output
  └→ Worker 2: Outline (from research)
       └→ Worker 3: Full draft (from outline)

Fan-out / Fan-in — parallel execution, then compile:

┌── Worker 1: Research A ──┐
├── Worker 2: Research B ──┼── Worker 4: Compile report
└── Worker 3: Research C ──┘

Model selection

The Orchestrator picks the right model for each task:

TaskModelWhy
Code generationSonnetFast, great at code
Code reviewOpusDeep reasoning
ResearchGemini ProGood at synthesis
Simple textGPT-4.1-miniCheap
GitHub PRsCodex (ACP)Native integration

The Orchestrator's brain

The SOUL.md focuses entirely on decomposition and delegation:

# Orchestrator

## Principles

1. Decompose first — break into independent sub-tasks
2. Parallel when possible — don't serialize independent work
3. Right model for the job
4. Review before deliver — always QA worker output
5. Learn — log patterns in MEMORY.md

## You do NOT: code, research, or write content yourself

## You DO: plan, decompose, delegate, review, compile

And MEMORY.md holds accumulated wisdom from previous runs:

# Patterns Learned

- API features: (endpoints, tests, docs) → parallel
- Blog posts: (research → outline → draft → review) → sequential
- Don't spawn >10 workers at once — diminishing returns

Overnight automation

This is a community favorite. The Orchestrator works while you sleep:

cron: {
  jobs: [
    { name: "overnight-start", schedule: "0 23 * * *", agentId: "orchestrator",
      message: "Process all pending tasks in MEMORY.md." },
    { name: "morning-report", schedule: "0 7 * * *", agentId: "orchestrator",
      message: "Compile overnight results. Send morning brief." },
  ],
},
heartbeat: {
  agents: { orchestrator: { intervalHours: 2, message: "Check worker progress." } },
},

At 11 PM it spawns workers. Every 2 hours it checks progress. At 7 AM you get a morning brief.

When to use Orchestrator

Good fit:

  • Parallel tasks that can be decomposed
  • One-off batch jobs
  • Scale-out (spawn 10+ workers)
  • Mixed-model workflows
  • Cost optimization (workers pay per use)

Not ideal for:

  • Ongoing team collaboration
  • Tasks that need deep context across workers
  • Need persistent specialists with memory

Hybrid Pattern

A startup team with freelancers — a core team that can hire helpers on-demand.

This is where it gets interesting. You take a persistent team that knows each other (Role-Based) and add the ability to spawn workers when you need to scale (Orchestrator).

This is the most commonly used pattern in production. And for good reason.

Architecture

The key insight: every persistent agent can spawn its own workers. Bob spawns 5 coding workers. Angela spawns 3 content writers. Milo spawns cross-functional research workers.

How it works

Layer 1 — Persistent Team. The core team knows each other, has memory, and communicates via sessions_send:

  • Milo (leader) → coordinate
  • Bob (dev) → deep coding with context
  • Angela (marketing) → content with brand voice

Layer 2 — Ephemeral Workers. Persistent agents spawn workers when they need to scale:

User → Bob: "Refactor the entire auth module — 12 files"

Bob (thinks): "12 files sequential = too slow. Spawn workers."
├── sessions_spawn("Refactor auth/login.ts...")
├── sessions_spawn("Refactor auth/register.ts...")
├── sessions_spawn("Refactor auth/middleware.ts...")
└── ... (9 more workers, parallel)

Workers execute → Bob reviews all results → delivers

Layer 3 — Cross-Team + Workers. Milo combines persistent agents and ephemeral workers in a single plan:

User → Milo: "Launch the new pricing page"

Milo's plan:
1. sessions_send(bob, "Build pricing page frontend")       ← persistent
2. sessions_send(angela, "Write copy for pricing tiers")   ← persistent
3. sessions_spawn("Research top 10 SaaS pricing pages")    ← ephemeral
4. sessions_spawn("Check our page for SEO issues")         ← ephemeral

Deep work goes to persistent agents (they have context). Quick tasks go to ephemeral workers (they run in parallel).

### Config

```jsonc
{
  "agents": {
    "list": [
      {
        "id": "milo",
        "name": "Milo",
        "default": true,
        "workspace": "~/.openclaw/workspace-milo",
        "model": "anthropic/claude-opus-4-6",
        "sandbox": "non-main",
      },
      {
        "id": "bob",
        "name": "Bob",
        "workspace": "~/.openclaw/workspace-bob",
        "model": "anthropic/claude-sonnet-4-6",
        "sandbox": "non-main",
      },
      {
        "id": "angela",
        "name": "Angela",
        "workspace": "~/.openclaw/workspace-angela",
        "model": "google/gemini-2.5-pro",
        "tools": { "deny": ["terminal"] },
      },
    ],
  },
  "bindings": [
    {
      "agentId": "milo",
      "match": {
        "channel": "discord",
        "peer": { "kind": "channel", "id": "GENERAL_ID" },
      },
    },
    {
      "agentId": "bob",
      "match": {
        "channel": "discord",
        "peer": { "kind": "channel", "id": "CODING_ID" },
      },
    },
    {
      "agentId": "angela",
      "match": {
        "channel": "discord",
        "peer": { "kind": "channel", "id": "MARKETING_ID" },
      },
    },
    { "agentId": "milo", "match": { "channel": "telegram" } },
  ],
  "tools": {
    "agentToAgent": { "enabled": true, "allow": ["milo", "bob", "angela"] },
    "subAgents": { "enabled": true, "maxConcurrent": 15 },
  },
}

The difference from pure Role-Based? You added subAgents.enabled.
The difference from pure Orchestrator? Multiple agents, bindings, and agentToAgent.

Send vs Spawn — a decision framework

When should you use a persistent agent, and when should you spawn a worker?

Whensessions_sendsessions_spawn
Need domain expertiseYesNo
Need memory/contextYesNo
Ongoing collaborationYesNo
Simple, well-defined taskNoYes
Parallel grunt workNoYes
One-off executionNoYes

Rule of thumb: if the task needs judgment, send it to a persistent agent. If it needs execution, spawn a worker.

A real-world scenario: product launch

Day 1 — Planning (Role-Based layer)
────────────────────────────────────
Milo → Bob:    "Review codebase, create release checklist"
Milo → Angela: "Draft launch content plan"
All persistent agents work with full context. They remember past launches.

Day 3 — Execution (Worker layer)
─────────────────────────────────
Bob → spawns 5 workers: fix bug, migration script, API docs, security audit, changelog
Angela → spawns 4 workers: blog post, Twitter thread, LinkedIn post, press release
All workers parallel. Bob & Angela review results.

Day 5 — Delivery (Role-Based layer)
────────────────────────────────────
Milo collects status from everyone → compiles → reports to boss

When to use Hybrid

Almost always. Hybrid is the default recommendation unless:

  • You're just starting out — begin with Orchestrator, evolve to Hybrid
  • You only do batch processing — pure Orchestrator is enough
  • You have a very limited budget — pure Orchestrator with 1 agent

If you're seriously building an AI team for production, go Hybrid.


Putting It All Together

Side-by-side comparison

AspectRole-BasedOrchestratorHybrid
Persistent agentsAll (4+)1 onlyCore team (2-4)
Ephemeral workersNoneAll workersOn-demand
MemoryPer agentOrchestrator onlyPer persistent agent
PersonalityPer agentOrchestrator onlyPer persistent agent
Communicationsessions_sendsessions_spawnBoth
Config complexityHighLowMedium
ScalingLimited (fixed)High (spawn∞)Best of both
CostSteadyPay per workerBalanced
AnalogyStartup teamPM + freelancersTeam + freelancers

Decision tree

Need a "team" that knows each other & remembers?
├── Yes → Need scaling (spawn workers)?
│         ├── Yes → HYBRID
│         └── No  → ROLE-BASED
└── No  → Need parallel batch processing?
           ├── Yes → ORCHESTRATOR
           └── No  → A single agent is enough

Migration path

Starting from scratch:

  1. Start with 1 agent + worker spawning (Orchestrator)
  2. Notice repeating domains → promote to persistent agents
  3. Now you have Hybrid

Upgrading from Role-Based to Hybrid:
Add one line — tools: { subAgents: { enabled: true } }

Upgrading from Orchestrator to Hybrid:
Add persistent agents, bindings, and agentToAgent.


From the Community

Here's how real users are running their setups:

UserPatternSetup
@iamtrebuhRole-Based4 agents, VPS, Telegram, different models
@jdrhyneRole-Based15+ agents, 3 machines, 1 Discord server
@nateliasonOrchestratorSpawns Codex for PRs, Claude reviews
@bffmikeOrchestratorOvernight coding agents
@antonplexOrchestratorCron + scientist sub-agents
@danpeguineHybrid2 OpenClaw instances, 1 WhatsApp group

Final Thoughts

All three patterns have their place.

Role-Based is for when you want a team that's alive — agents that know each other and remember everything. The config is more involved, but the result is powerful.

Orchestrator + Workers is for when you want one smart brain that can parallelize work. Simple config, great scaling, pay-per-use economics.

Hybrid combines both. A persistent team that can spawn an army of workers when needed. This is the default recommendation for production.

The best part? You don't have to choose upfront. Start simple with one Orchestrator. As patterns emerge, promote repeating domains into persistent agents. Before you know it, you're running a Hybrid.

OpenClaw's flexibility lets you start from any pattern and migrate to another without rebuilding from scratch.