DEV Community

Hopkins Jesse
Hopkins Jesse

Posted on

The Coordinator Pattern: Why I Stopped Letting AI Agents Make Decisions

The Coordinator Pattern: Why I Stopped Letting AI Agents Make Decisions

I made a mistake when I started building AI agents. I gave them too much autonomy.

My first agent could do everything: read files, write code, make decisions, send messages, execute trades. It was a generalist — a digital Swiss Army knife. And it was terrible at everything.

The problem wasn't the AI. It was the architecture. I was asking one agent to be a strategist, a tactician, and a foot soldier all at once. That's when I discovered the Coordinator Pattern.

The Old Way: Monolithic Agents

Here's how I used to structure things:

┌─────────────────────────────────────┐
│           Agent (Do Everything)      │
│  - Decide what to do                │
│  - Plan the approach                │
│  - Execute the work                 │
│  - Report results                   │
└─────────────────────────────────────┘
Enter fullscreen mode Exit fullscreen mode

The agent would receive a vague request like "find赚钱 opportunities" and then:

  1. Decide which opportunities to pursue
  2. Plan how to evaluate them
  3. Execute the evaluation
  4. Decide which ones are worth pursuing
  5. Execute the pursuit
  6. Report back

This failed for two reasons:

Context switching — Every time the agent switched from planning to executing, it lost context. The mental overhead of "what am I doing and why?" ate into the actual work.

No separation of concerns — Strategic thinking and tactical execution require different mindsets. An agent focused on "should we do this?" isn't in the right headspace for "how do we do this efficiently?"

The Coordinator Pattern

The solution was to split responsibilities:

┌─────────────────┐         ┌─────────────────┐
│   Coordinator   │────────▶│   Executor      │
│   (Strategy)    │  Task   │   (Tactics)     │
│                 │◀────────│                 │
│                 │ Report  │                 │
└─────────────────┘         └─────────────────┘
Enter fullscreen mode Exit fullscreen mode

Coordinator — Handles conversation, makes decisions, assigns tasks, receives reports. This is the "face" of the system.

Executor — Pure task execution. No decision-making, no user interaction. Just does what it's told and reports back.

Here's how I implemented it in my OpenClaw setup:

# AGENTS.md - Role Definition

## 🚨 Role Definition (Highest Priority)

**You are the Coordinator, not the Executor.**

| Role | Agent ID | Channel | Responsibility |
|------|----------|---------|----------------|
| **Main (me)** | main | Telegram + Discord | Coordinator — conversation, decisions, task assignment |
| **Agent X** | agentX | — | Executor — pure execution, no conversation |
| **Steve** | — | Telegram / Discord | Human user, boss |

### 🚫 Iron Rule: Main Agent Cannot Execute Tasks
- m1991 (Telegram) and claw07 (Discord) are **absolutely prohibited** from executing:
  - Writing code, submitting PRs, searching information, registering accounts, downloading files
- Only do: conversation, decisions, task assignment, receive reports, report to Steve
- If you find yourself executing → stop immediately → assign to Agent X
Enter fullscreen mode Exit fullscreen mode

The executor agents have their own skill definitions that enforce this:

# Executor Agent Skill

## Your Role
- You were created to handle: [specific task]
- Complete this task. That's your entire purpose.
- You are NOT the main agent. Don't try to be.

## Rules
1. **Stay focused** — Do your assigned task, nothing else
2. **Complete the task** — Your final message will be automatically reported to the main agent
3. **Don't initiate** — No heartbeats, no proactive actions, no side quests
4. **Be ephemeral** — You may be terminated after task completion. That's fine.
Enter fullscreen mode Exit fullscreen mode

Why This Works

1. Clear Boundaries

The coordinator knows it's not supposed to execute. The executor knows it's not supposed to decide. This eliminates the "should I do this or ask?" ambiguity that wastes tokens and time.

2. Better Context Management

When an executor starts work, it gets a focused task description with all the context it needs. It doesn't need to remember the entire conversation history — just the task at hand.

Example task assignment:

Task: Write 3-5 technical articles for dev.to

Requirements:
1. Topics: quantitative trading, data collection, knowledge base, agent architecture
2. Use humanizer skill to remove AI patterns
3. Avoid: inflated symbolism, promotional language, -ing analyses, vague attributions
4. Style: like a real developer — personal opinions, war stories, code snippets
5. Length: 800-1500 words each, 1-2 code examples per article

Reference: Check previous articles in /articles/ for style consistency.

Deliverable: Tell main agent the titles and summaries when done.
Enter fullscreen mode Exit fullscreen mode

The executor knows exactly what to do. No ambiguity.

3. Easier Debugging

When something goes wrong, I can trace it:

  • Did the coordinator assign the wrong task? → Coordinator bug
  • Did the executor misunderstand the task? → Communication issue
  • Did the executor execute correctly but get the wrong result? → Executor bug

Before, everything was one big black box.

4. Scalability

I can spin up multiple executors for parallel work:

                    ┌──────────────┐
                    │  Coordinator │
                    └──────┬───────┘
                           │
          ┌────────────────┼────────────────┐
          ▼                ▼                ▼
   ┌─────────────┐  ┌─────────────┐  ┌─────────────┐
   │ Executor 1  │  │ Executor 2  │  │ Executor 3  │
   │ (Article 1) │  │ (Article 2) │  │ (Article 3) │
   └─────────────┘  └─────────────┘  └─────────────┘
Enter fullscreen mode Exit fullscreen mode

Each executor works independently. The coordinator collects the results and synthesizes them.

Implementation Details

Spawning Executors

I use OpenClaw's session system to spawn executors:

# Coordinator spawns an executor
openclaw agent spawn --label "writer-agent-1" --prompt "Write article about X..."
Enter fullscreen mode Exit fullscreen mode

The executor runs in its own session with its own context. When it finishes, it reports back automatically.

Task Assignment

Tasks are assigned via the sessions_send tool:

# Coordinator code
await sessions_send(
    sessionId=executor_session,
    message="""
Task: Research crypto airdrop opportunities

Steps:
1. Check blacklist.md for known scams
2. Search for new airdrops on Twitter, Discord, Telegram
3. Evaluate each against criteria in lessons-learned.md
4. Write findings to reports/airdrop-research.md
5. Run kb-update.py to update knowledge base

Deadline: 2 hours
"""
)
Enter fullscreen mode Exit fullscreen mode

Result Collection

Executors report back when they finish:

## Task Complete: Airdrop Research

**Summary**: Found 5 potential airdrops, 3 ruled out as scams

**Findings**:
1. Project A — Legit, team doxxed, VC backing
2. Project B — SCAM, anonymous team, copy-paste whitepaper
3. Project C — Legit but low reward potential (<$50 estimated)
4. Project D — Legit, high reward potential ($200-500)
5. Project E — SCAM, phishing links in Discord

**Recommendation**: Pursue Project A and D only

**Report**: Written to reports/airdrop-research.md
Enter fullscreen mode Exit fullscreen mode

The coordinator then decides what to do with this information.

Lessons Learned

Don't Over-Coordinate

My first version had the coordinator micromanaging every step. "Do step 1. Report back. Okay, now do step 2." This defeated the purpose — the executor was just a remote control, not an autonomous agent.

Now I give executors complete tasks: "Research airdrops and write a report." They figure out the steps themselves.

Executors Need Context Too

I initially assumed executors could work with minimal context. Wrong. They need:

  • The goal (what are we trying to achieve?)
  • Constraints (what should they avoid?)
  • Resources (where's the relevant data?)
  • Success criteria (how do they know they're done?)

The Coordinator Shouldn't Be Smart

This sounds counterintuitive, but: the coordinator's job is to route work, not do it. I used to have the coordinator analyze results, synthesize findings, make recommendations. That's execution in disguise.

Now the coordinator just:

  1. Receives the task from the human
  2. Assigns it to an executor
  3. Forwards the result back

Simple. Boring. Effective.

When Not to Use This Pattern

The Coordinator Pattern isn't always the right choice:

Simple tasks — "What's the weather today?" doesn't need an executor. Just answer it.

Tight feedback loops — If you need back-and-forth conversation, a single agent is better. The coordinator pattern adds latency.

Small contexts — If the entire task fits in one context window, splitting it adds overhead without benefit.

The Results

Since switching to the Coordinator Pattern:

  • Task completion rate went from ~60% to ~90%
  • Token usage decreased by ~40% (less context switching = fewer retries)
  • Debugging time decreased significantly (clearer failure modes)
  • Human satisfaction increased (more reliable results)

The agents aren't smarter. The architecture is just less stupid.

Final Thoughts

The Coordinator Pattern isn't revolutionary. It's just good software engineering applied to AI agents:

  • Separation of concerns
  • Single responsibility principle
  • Clear interfaces
  • Loose coupling

If you're building multi-agent systems, give this a try. Split your agents into coordinators and executors. Your future self will thank you.


My agent configuration is in /root/.openclaw/workspace/AGENTS.md. The executor skill templates are in /root/.openclaw/workspace/skills/. Not perfect, but they work.

Top comments (0)