Sub-Agents Mastery: Parallel Workflows That Actually Work
Learn when and how to use sub-agents for complex tasks. Fan-out patterns, monitoring, error handling, and real-world examples.
#Sub-Agents Mastery: Parallel Workflows That Actually Work
Sub-agents let you break complex tasks into parallel workflows. Instead of doing everything sequentially, you spawn multiple agents to work simultaneously—then combine their results.
#What Are Sub-Agents?
A sub-agent is a separate OpenClaw session spawned to handle a specific task. Your main agent delegates work to sub-agents, monitors their progress, and combines their outputs.
When to use sub-agents:
- Research requiring multiple sources simultaneously
- Code reviews across multiple files
- Content generation (bulk blog posts, variations)
- Multi-step tasks that can run in parallel
- Tasks requiring different models or thinking levels
When NOT to use sub-agents:
- Simple sequential tasks (overhead isn't worth it)
- Tasks requiring shared state throughout
- Quick one-off queries
#The Three Types of Sub-Agents
#1. sessions_spawn (Built-in)
OpenClaw's native sub-agent spawning via the sessions_spawn tool.
// Spawn a research sub-agentconst result = await sessions_spawn({ task: "Research the latest React Server Components best practices. Find 5 authoritative sources and summarize key points.", agentId: "anthropic/claude-sonnet-4-6", timeoutSeconds: 300, cleanup: "delete" // or "keep"});Pros: Built-in, simple, auto-announces results Cons: Limited control, one-shot (no steering mid-task)
#2. Claude Code / Codex Agents
Spawn Claude Code or Codex for coding-heavy tasks.
// Spawn Claude Code for a coding taskconst result = await sessions_spawn({ task: "Implement a Redis caching layer for the user service. Write the code, tests, and documentation.", agentId: "openai-codex/gpt-5.3-codex", timeoutSeconds: 600, thinking: "high"});Pros: Specialized for coding, can work on large codebases Cons: Higher cost, longer runtime
#3. Coding-Agent Skill
Use the coding-agent skill to delegate coding tasks with more control.
# From within a skillopenclaw agent spawn \ --skill coding-agent \ --task "Refactor the authentication module" \ --model codex53 \ --dir /tmp/refactor-taskPros: Skill-based, reusable, can chain multiple Cons: Requires skill installation
#Fan-Out Patterns
#Pattern 1: Parallel Research
Spawn multiple sub-agents to research different aspects simultaneously.
// Research a topic from multiple anglesconst researchTasks = [ "Research technical implementation of edge functions", "Research pricing and cost considerations for edge deployment", "Research security implications of edge computing", "Find case studies of companies using edge functions successfully"];const results = await Promise.all( researchTasks.map(task => sessions_spawn({ task, agentId: "anthropic/claude-sonnet-4-6", timeoutSeconds: 300 })));// Combine results into comprehensive reportconst report = synthesizeResearch(results);Use case: Due diligence, technology evaluation, competitive analysis
#Pattern 2: Multi-File Code Review
Review different aspects of a PR in parallel.
// Review different aspects of a codebaseconst reviewTasks = [ { aspect: "security", focus: "auth, injection vulnerabilities, secrets" }, { aspect: "performance", focus: "n+1 queries, caching, big O" }, { aspect: "style", focus: "naming, consistency, comments" }, { aspect: "testing", focus: "coverage, edge cases, mocks" }];const reviews = await Promise.all( reviewTasks.map(({ aspect, focus }) => sessions_spawn({ task: `Review this PR for ${aspect} issues. Focus on: ${focus}. Provide specific line-by-line feedback.`, agentId: "openai-codex/gpt-5.3-codex", timeoutSeconds: 400 })));// Aggregate into single comprehensive reviewconst finalReview = aggregateReviews(reviews);Use case: Thorough PR reviews without waiting hours
#Pattern 3: Bulk Content Generation
Generate multiple content pieces simultaneously.
// Generate blog post variationsconst topics = [ "OpenClaw for beginners", "Advanced OpenClaw workflows", "OpenClaw vs ChatGPT", "Building skills for OpenClaw"];const posts = await Promise.all( topics.map(topic => sessions_spawn({ task: `Write a 1000-word blog post about "${topic}". Include introduction, 3 main sections with examples, and conclusion.`, agentId: "anthropic/claude-sonnet-4-6", timeoutSeconds: 600 })));Use case: Content marketing, documentation, variations testing
#Error Handling
Sub-agents can fail. Handle it gracefully:
async function spawnWithFallback(task, primaryModel, fallbackModel) { try { return await sessions_spawn({ task, agentId: primaryModel, timeoutSeconds: 300 }); } catch (error) { console.log(`Primary agent failed: ${error.message}. Trying fallback...`); return await sessions_spawn({ task, agentId: fallbackModel, timeoutSeconds: 300 }); }}// Usageconst result = await spawnWithFallback( "Complex research task...", "anthropic/claude-opus-4-6", "anthropic/claude-sonnet-4-6");Strategies:
- Retry with same model
- Fallback to cheaper model
- Fallback to sequential (no sub-agent)
- Queue for later retry
#Monitoring and Steering
#Check Sub-Agent Status
// List running sub-agentsconst activeAgents = await subagents({ action: "list" });// Check specific agentconst status = await subagents({ action: "poll", target: "agent-session-key", timeout: 30000 });#Kill a Stuck Agent
// If an agent is taking too longawait subagents({ action: "kill", target: "agent-session-key" });#Send Mid-Task Instructions
// Steer an agent mid-task (if supported)await subagents({ action: "steer", target: "agent-session-key", message: "Focus more on security aspects, less on performance"});#Cost Optimization
Sub-agents can get expensive. Optimize with these strategies:
#1. Right-Size Your Models
// Don't use Opus for simple tasksconst modelMap = { "research": "anthropic/claude-sonnet-4-6", "coding": "openai-codex/gpt-5.3-codex", "summarization": "anthropic/claude-haiku-4", "creative": "anthropic/claude-sonnet-4-6"};const result = await sessions_spawn({ task, agentId: modelMap[taskType], timeoutSeconds: 300});#2. Set Aggressive Timeouts
// Don't let agents run foreverconst result = await sessions_spawn({ task: "Quick research...", agentId: "anthropic/claude-sonnet-4-6", timeoutSeconds: 120 // 2 minutes max});#3. Use Cleanup: Delete
// Clean up sessions to save resourcesconst result = await sessions_spawn({ task, agentId: "anthropic/claude-sonnet-4-6", cleanup: "delete" // Remove session after completion});#4. Batch Small Tasks
// Instead of 10 tiny sub-agents, batch themconst result = await sessions_spawn({ task: "Process these 10 small tasks in sequence: [list tasks]", agentId: "anthropic/claude-haiku-4", // Use cheap model timeoutSeconds: 300});#Real-World Example: Competitive Analysis
Here's a complete workflow for competitive analysis:
// Step 1: Spawn parallel research agentsconst competitors = ["CompetitorA", "CompetitorB", "CompetitorC"];const researchResults = await Promise.all( competitors.map(competitor => sessions_spawn({ task: `Research ${competitor}. Find: pricing, key features, customer reviews (positive and negative), recent news/updates, target market. Provide structured report.`, agentId: "anthropic/claude-sonnet-4-6", timeoutSeconds: 400 })));// Step 2: Spawn analysis agent to compareconst comparison = await sessions_spawn({ task: `Compare these three competitors: ${JSON.stringify(researchResults)}. Create a feature matrix, identify their strengths/weaknesses, and recommend our positioning strategy.`, agentId: "anthropic/claude-opus-4-6", timeoutSeconds: 300});// Step 3: Spawn content agent to create deliverableconst presentation = await sessions_spawn({ task: `Create a competitive analysis slide deck based on: ${comparison}. Include title slide, competitor overview slides, feature comparison table, and strategic recommendations.`, agentId: "anthropic/claude-sonnet-4-6", timeoutSeconds: 400});// Total time: ~15 minutes instead of 2+ hours sequentially// Cost: ~$2-3 vs $5-8 if done as one long Opus session#Common Mistakes
Mistake 1: Over-parallelizing
// BAD: Spawning 50 sub-agentsconst results = await Promise.all( items.map(item => sessions_spawn({ task: item })) // 50 agents!);// Result: Rate limits, high costs, confusion// GOOD: Batch into reasonable groupsconst batches = chunk(items, 5);for (const batch of batches) { const results = await Promise.all( batch.map(item => sessions_spawn({ task: item })) ); await processBatch(results);}Mistake 2: Not handling failures
// BAD: Assuming all succeedconst results = await Promise.all(tasks.map(t => sessions_spawn(t)));// GOOD: Graceful degradationconst results = await Promise.allSettled(tasks.map(t => sessions_spawn(t)));const successful = results.filter(r => r.status === "fulfilled");Mistake 3: Wrong model for the task
// BAD: Using Opus for simple summarizationsessions_spawn({ agentId: "anthropic/claude-opus-4-6", task: "Summarize this paragraph" });// GOOD: Use appropriate modelsessions_spawn({ agentId: "anthropic/claude-haiku-4", task: "Summarize this paragraph" });#Sub-Agent Skill Template
Want to build a reusable sub-agent workflow? Use this SKILL.md template:
# Multi-Reviewer Skill## OverviewSpawn parallel code review sub-agents for comprehensive PR analysis.## Tools- sessions_spawn- github## Workflow1. Fetch PR diff using GitHub skill2. Spawn 4 review sub-agents (security, performance, style, tests)3. Collect all reviews4. Aggregate into final review comment5. Post to GitHub## ConfigurationSet REVIEW_ASPECTS in your SOUL.md or environment.#What's Next?
- Cost Optimization Guide — keep sub-agent bills under control
- Workflow Recipes — more copy-paste sub-agent patterns
- Building Custom Skills — package your sub-agent workflows as reusable skills
Start with simple parallel research tasks, then move to more complex orchestration. The key is starting small and adding complexity only when you need it.