How to Best Create and Use Agents in OpenClaw
A practical guide to setting up isolated agents, routing messages, orchestrating sub-agents, and writing prompts that get great results.
OpenClaw’s agent model is one of its most powerful features — and one of its most misunderstood. Each agent gets its own brain, workspace, personality, and even phone number. Get the architecture right, and you can run an entire team. Get it wrong, and you’re fighting the framework. Here’s how to do it.
If you’ve spent any time with OpenClaw, you’ve probably seen the agents.list configuration and thought: “OK, I can have multiple agents. Cool. Now what?” The short answer is that agents aren’t just separate chatbots running side by side — they’re fully scoped, isolated “brains,” each with their own workspace files, session store, auth profiles, and personality. You can give one a Telegram bot, another a Discord account, and a third a completely different LLM model, and they never cross-contaminate.
But the real magic happens when you combine isolation with orchestration: spawning sub-agents to handle tasks in the background, routing messages across platforms with deterministic bindings, and using cron and heartbeat automation to keep everything running on autopilot. This guide covers the full spectrum — from your first agent to advanced multi-agent architectures.
TL;DR: OpenClaw agents are fully isolated brains with their own workspace, model, and personality. Create them via CLI wizard or config, route messages with bindings (most-specific-wins), spawn sub-agents for background tasks, and automate with cron and heartbeats. The key design principle: keep each agent focused on one role, use cheaper models for sub-agents, and let isolation do the heavy lifting instead of trying to thread everything through a single agent.
What Is an Agent, Really?
Before we configure anything, it helps to understand what an agent is inside OpenClaw’s architecture.
An agent is a fully scoped “brain.” It has:
- A workspace — the user-editable files that define who the agent is:
AGENTS.md(operating instructions),SOUL.md(personality and tone),USER.md(about you),IDENTITY.md(name, vibe, emoji), andTOOLS.md(environment-specific notes like camera names or SSH hosts). - A state directory — internal config at
~/.openclaw/agents/<agentId>/agent, including auth profiles and per-agent model registry. - A session store — chat history at
~/.openclaw/agents/<agentId>/sessions. - Bootstrap files — these workspace files are automatically injected at the start of every session, so the agent “remembers” who it is every time it wakes up.
The default agent is called main, and it lives at ~/.openclaw/workspace. But you can run as many agents as you want, side by side, completely isolated. Different personalities. Different phone numbers. Different models. No cross-talk unless you explicitly enable it.
Think of it this way: main is your personal assistant. alerts is the agent monitoring your inbox and pinging you on Telegram when something urgent arrives. coding is a dedicated developer agent that works on your projects in the background. None of them need to know what the others are doing — and that separation is what makes multi-agent setups actually practical instead of chaotic.
Creating Your First Agent
There are two ways to add agents to OpenClaw: the interactive CLI wizard, or by editing the config directly.
The CLI Wizard
The easiest way to get started:
openclaw agents add <agentId>
This creates a workspace with default templates, sets up the agent directory, and configures the session store. It’s a one-liner for a fully configured agent.
The Config Way
For more control, or when setting up multiple agents at once, edit ~/.openclaw/openclaw.json:
{
agents: {
list: [
{
id: "main",
default: true,
name: "Main Assistant",
workspace: "~/.openclaw/workspace",
},
{
id: "research",
name: "Researcher",
workspace: "~/.openclaw/workspace-research",
model: "anthropic/claude-sonnet-4-6",
},
{
id: "coding",
name: "Coder",
workspace: "~/.openclaw/workspace-coding",
},
],
},
}
After editing, restart the gateway:
openclaw gateway restart
Per-Agent Configuration
Each agent can override a surprising number of things:
| Setting | Where | What it controls |
|---|---|---|
model | agents.list[].model | The LLM this agent uses (override the default) |
agents | agents.list[].agentRuntime.id | Which agent runtime to use |
skills | agents.list[].skills | Skills available to this agent (replaces defaults) |
thinking | agents.list[].thinking | Thinking level (off, low, medium, high) |
The skills field is particularly interesting. If you set it on an agent, it replaces the default skill set entirely. To give all agents a shared baseline while letting specific agents add more, use agents.defaults.skills for the common set and override per-agent.
Routing Messages Between Agents
This is where things get interesting. OpenClaw uses bindings — a deterministic routing system that decides which agent handles a given message. The routing follows a “most-specific-wins” hierarchy:
- Peer match — exact DM or group ID
- ParentPeer match — thread inheritance (a message in a Discord thread inherits the parent channel’s routing)
- GuildId + Roles — route based on Discord role membership
- GuildId — route by Discord server
- TeamId — route by Slack team
- AccountId match — match by platform account
- Channel-level match — catch-all for a platform (
accountId: "*") - Default agent — the fallback
One Bot Per Agent (Telegram / Discord)
The simplest routing pattern: give each agent its own bot account.
{
bindings: [
{ agentId: "main", match: { channel: "telegram", accountId: "default" } },
{ agentId: "alerts", match: { channel: "telegram", accountId: "alerts" } },
],
channels: {
telegram: {
accounts: {
default: { botToken: "123456:ABC...", dmPolicy: "pairing" },
alerts: { botToken: "987654:XYZ...", dmPolicy: "allowlist", allowFrom: ["tg:123456789"] },
},
},
},
}
You’d create two bot tokens via BotFather on Telegram — one for your main assistant, one exclusively for alerts. The alerts bot could have a different model, a more terse SOUL.md, and a tighter allowlist. It never sees casual conversation; it only handles monitoring tasks.
Splitting WhatsApp by Sender
What if you want different agents to respond to different people on the same WhatsApp number? Bindings handle that:
{
bindings: [
{ agentId: "home", match: { channel: "whatsapp", peer: { kind: "direct", id: "+15551230001" } } },
{ agentId: "mia", match: { channel: "whatsapp", peer: { kind: "direct", id: "+15551230002" } } },
],
channels: { whatsapp: { dmPolicy: "allowlist", allowFrom: ["+15551230001", "+15551230002"] } },
}
Here, +15551230001 talks to the “home” agent (your personal assistant), while +15551230002 talks to “mia” (a different agent with a different personality). Same number, different brains.
Orchestrating Sub-Agents
Isolation handles the organization of agents. Sub-agent orchestration handles the workflow.
OpenClaw lets agents spawn child agents to handle background tasks. The key function is sessions_spawn:
sessions_spawn({
task: "Research topic X and save findings to /path/to/file.md",
label: "research-x",
agentId: "spark",
model: "default/Qwen3.6-35B-A3B",
context: "isolated",
mode: "run",
runTimeoutSeconds: 300,
})
Context Modes: Fork vs. Isolated
Every spawn needs a context setting, and picking the right one matters for both quality and cost:
isolated(default) — The child gets a clean transcript. It doesn’t see the parent’s conversation. Use this for independent tasks: research, writing articles, data processing. It uses fewer tokens because the child starts fresh.fork— The child inherits the parent’s conversation history. Use this when the task depends on context already discussed: debugging based on prior tool results, follow-up work that references earlier decisions.
Here’s the golden rule: use fork sparingly. It’s for context-sensitive delegation, not a default mode. If you can write a clear task prompt that describes everything the child needs, use isolated. It’s cheaper and keeps token usage predictable.
Thread-Bound Sessions
On Discord, sub-agents can bind to persistent threads. When a sub-agent spawns with thread: true and mode: "session", follow-up messages in that thread route back to the same session:
sessions_spawn({
task: "Debug the authentication flow in the auth module",
thread: true,
mode: "session",
agentId: "coding",
})
You can manage these sessions with slash commands: /focus, /unfocus, /agents, /session idle, /session max-age. It’s like having a dedicated developer working on a specific issue, accessible right in your Discord thread.
Nested Orchestration
You can also allow sub-agents to spawn their own children (nested orchestration):
{
agents: {
defaults: {
subagents: {
maxSpawnDepth: 2,
maxChildrenPerAgent: 5,
maxConcurrent: 8,
},
},
},
}
This enables patterns like: main → orchestrator sub-agent → worker sub-sub-agents. The orchestrator breaks a complex task into sub-tasks, each delegated to a worker. Depth 2 is a reasonable limit — deeper nesting tends to become hard to debug.
Allowlists and Safety
By default, not all agents can spawn sub-agents or target all agents. You control this with allowlists:
agents.list[].subagents.allowAgents— which agents this agent can spawnagents.defaults.subagents.requireAgentId— if true, forces explicitagentIdin spawns (prevents accidental routing to the wrong agent)- Use
["*"]for an allowlist that permits any agent, or enumerate specific ones for tighter control
Prompt Engineering for Agents
A sub-agent is only as good as the brief it receives. Writing effective task prompts is its own craft.
The Anatomy of a Good Task Prompt
A well-structured sub-agent prompt includes:
- Role definition — “You are Link, the writing agent for the Xplaination website.”
- Clear objective — “Research and compile comprehensive notes on how OpenClaw agents work.”
- Specific topics — Numbered or bulleted list of what to cover
- Output location — “Save to
/home/minime/.openclaw/workspace/xplaination-web/src/content/articles/openclaw-agents-guide.md” - Format requirements — Frontmatter fields, tone guidelines, length constraints
- Acceptance criteria — What does “done” look like?
Example: Writing an Article
Here’s what a good article-writing task prompt looks like:
You are Link, the writing and publishing agent for the Xplaination website.
Task: Write an article about creating and using agents in OpenClaw.
Steps:
1. Read the research notes at /home/minime/.openclaw/workspace/articles-research/openclaw-agents-guide-research.md
2. Read the style reference at /home/minime/.openclaw/workspace/xplaination-web/src/content/articles/ai-normal-science-vs-paradigm-breakthroughs.md
3. Write the article to /home/minime/.openclaw/workspace/xplaination-web/src/content/articles/openclaw-agents-guide.md
Requirements:
- Match the tone of the reference article: thoughtful, analytical, accessible but not dumbed-down
- Structure: H2 sections, H3 subsections where helpful
- Include code examples and practical tips
- Length: 2000-3500 words
- Start with a compelling intro, then a TL;DR paragraph
- IMPORTANT: The frontmatter title is already rendered as <h1> by the template. Do NOT start the body with a # heading.
- Tags: ['OpenClaw', 'Agents', 'Prompt Engineering', 'Tutorial']
Acceptance criteria:
- Article has proper frontmatter with pubDate
- Body has at least 5 H2 sections
- Includes at least 3 code examples
- Word count is between 2000-3500
Token Management Tips
- Keep bootstrap files concise. They’re injected at every session start. Bloat in
AGENTS.mdburns tokens on every turn. - Use
isolatedcontext when possible. Aforkcontext can dramatically increase token usage by carrying forward the parent’s entire conversation. - Set
runTimeoutSecondson sub-agents. A 5-minute timeout (300 seconds) prevents runaway token burn on complex tasks. - Use cheaper models for sub-agents. A sub-agent doing research or drafting doesn’t need the same model as your main agent.
Advanced Patterns
Once you’ve got the basics down, these patterns take multi-agent OpenClaw from “interesting” to “indispensable.”
TaskFlow
TaskFlow coordinates multi-step detached tasks with managed state, waits, and child task coordination. It’s defined in the taskflow skill and handles things like: “Run this sequence of tasks over time, wait for external input between steps, then produce a summary.” It’s particularly useful for workflows that span hours or days rather than minutes.
Cron Jobs
Schedule recurring tasks that run in isolated sessions:
cron({
action: "add",
job: {
name: "daily-report",
schedule: { kind: "cron", expr: "0 9 * * *", tz: "America/Indianapolis" },
payload: {
kind: "agentTurn",
message: "Generate and send the daily morning report",
},
delivery: { mode: "announce" },
},
})
This creates a cron job that runs every day at 9:00 AM Eastern, triggering an agent turn that generates a morning report and announces it to the channel.
Heartbeat Automation
Heartbeats are periodic checks that run during the main session. Add tasks to HEARTBEAT.md and the agent will batch-check things like email, calendar, and weather every ~30 minutes. Track what’s been checked in memory/heartbeat-state.json:
{
"lastChecks": {
"email": 1703275200,
"calendar": 1703260800,
"weather": null
}
}
The agent rotates through checks (2-4 times per day) and reaches out only when something important happens. Late night? Stays quiet unless urgent.
Agent-to-Agent Messaging
Beyond spawning, agents can send messages to each other directly:
sessions_send({
sessionKey: "agent:link:telegram:default:direct",
message: "Write an article about OpenClaw agents"
})
This must be explicitly enabled in config, and it’s useful when you want async communication between agents rather than the parent-child relationship of spawning.
Operational Best Practices
Model Selection Strategy
- Main agent: Keep it on a capable model. It handles interactive work, complex reasoning, and acts as the orchestrator.
- Sub-agents: Use cheaper models. A research sub-agent drafting notes doesn’t need Claude Sonnet — Qwen or a smaller model works fine.
- Per-agent override: Set
agents.list[].modelfor agents that genuinely need a different model than default. - Per-subagent override: Pass
modelinsessions_spawnwhen a specific task needs a specific model.
Cost Management
Sub-agents have independent token usage, which is great for control but means you need to be intentional:
- Configure
agents.defaults.subagents.modelto set a default for all sub-agents - Always set
runTimeoutSeconds— a 5-minute default prevents runaway tasks - Prefer
isolatedcontext overforkto keep token budgets predictable - Monitor your usage; OpenClaw doesn’t spend your money, but you should still watch it
Sandboxing
For maximum safety, sandbox agent sessions:
sandbox: "inherit"(default) — child inherits parent’s sandbox settingsandbox: "require"— rejects the spawn unless the child runtime is sandboxed
Sandboxed sessions can override their workspace root with agents.defaults.sandbox.workspaceRoot, giving you an extra layer of isolation.
Troubleshooting Quick Reference
| Problem | Likely Cause | Fix |
|---|---|---|
| Agent not receiving messages | Binding not configured or wrong order | Check bindings; most-specific-wins means order matters |
| Auth errors | Agent using wrong auth profile | Each agent has its own auth-profiles.json in its agentDir |
| Session stuck | Corrupted session state | Use /reset or start a new session with /new |
| Sub-agent not announcing | Delivery config issue | Check delivery config; ensure requester session is active |
| Agent seems to “forget” things | Bootstrap files too sparse | Ensure SOUL.md and AGENTS.md have enough context |
Backup Strategy
Your agent’s workspace is its memory. Treat it like a journal you’d never want to lose:
- Git init the workspace:
cd ~/.openclaw/workspace && git init && git add . && git commit -m "initial" - Push to a private remote. Your
MEMORY.mdand daily files are the agent’s continuity — they deserve version control. - Don’t share agentDirs. Each agent’s state directory contains auth profiles that should stay isolated.
Conclusion
OpenClaw’s agent model rewards a specific kind of thinking: think in roles, not in monoliths. Instead of one agent trying to do everything, you build a team where each member has a clear job, clear boundaries, and clear channels of communication.
The isolation model is the foundation. Bindings handle routing. Sub-agents handle delegation. Cron and heartbeats handle automation. And prompt engineering ties it all together — because even the most elegant architecture can’t compensate for a vague task brief.
Start simple: one main agent, one or two sub-agents, basic bindings. Get the feel for how isolation works. Then layer on complexity as your needs grow. The system scales with your architecture, not against it.
The agents that work best are the ones you can describe in a single sentence: “This one handles my inbox. This one writes code. This one watches for alerts.” Once you’ve got that clarity, the configuration follows naturally.
This guide covers the agent features available in OpenClaw as of May 2026. Configuration references ~/.openclaw/openclaw.json and the openclaw.json5 config format. For the latest docs, check the OpenClaw documentation.