Combining Tasks with Subagents in Claude Code

How to combine Claude Code's Task tool with the Tasks system for powerful multi-agent workflows. Main agent coordinates, subagents execute, tasks provide shared state.

Introduction

Claude Code gives you two powerful primitives: the Task tool for spawning subagents, and the Tasks system for tracking work items. Used separately, each is useful. Used together, they unlock a fundamentally different way of working: multi-agent orchestration with shared state.

The pattern is elegant. Your main agent acts as a coordinator, creating tasks that define what needs to be done. It spawns subagents to execute those tasks. The subagents claim tasks, do the work, and mark them complete. The main agent monitors progress and coordinates the overall flow.

This isn't just parallel execution. It's coordinated parallel execution. Subagents share a task list, which means they can see what others are working on, avoid duplicating effort, and pick up work as it becomes available. The task list becomes shared state that enables real collaboration between agents.

If you've used the Task tool but haven't combined it with the Tasks system, you're missing the coordination layer that makes multi-agent workflows truly powerful. This guide shows you how to put them together.

Understanding the Two "Task" Concepts

The terminology can be confusing because Claude Code uses "task" for two different things. Understanding the distinction is essential before combining them.

Task Tool: The Agent Launcher

The Task tool spawns subagents. When your main agent uses the Task tool, it creates a new Claude instance that runs in parallel. This subagent has its own context, its own conversation, and its own set of tools. It executes whatever instructions you give it and returns results to the main agent.

Think of the Task tool as a launcher. It creates workers. But those workers need to know what to work on, and they need a way to coordinate with each other. That's where the Tasks system comes in.

Task Tool Usage
// Main agent spawns a subagent
Task tool:
  description: "Implement user authentication"
  prompt: "Create the auth service with login, logout, and session management."

// This creates a new Claude instance that executes the prompt
// The subagent runs independently and returns when complete

Tasks System: The Todo List

The Tasks system (TaskCreate, TaskUpdate, TaskList) is a todo list manager. It creates work items, tracks their status, and maintains state across agents. Tasks have titles, descriptions, statuses, owners, and dependencies.

Think of the Tasks system as a shared whiteboard. Every agent can see it. Every agent can update it. It's the coordination mechanism that lets multiple agents work together without stepping on each other.

Tasks System Usage
// Create a task (work item)
TaskCreate:
  title: "Implement login form validation"
  description: "Add client-side validation for email and password fields"
  status: "pending"

// Update a task (change status, assign owner)
TaskUpdate:
  task_id: "task_123"
  status: "in_progress"
  owner: "frontend-agent"

// List all tasks (see what needs doing)
TaskList:
  // Returns all tasks with their current status

They Work Together But Are Different Things

The Task tool creates workers. The Tasks system tracks work. One launches agents; the other coordinates them. When you combine both, you get agents that know what to work on and can coordinate with each other through shared state.

The distinction matters because you'll use both in your workflows. The main agent uses Task tool to spawn subagents. Those subagents use the Tasks system to claim and complete work items. The main agent monitors the Tasks system to track overall progress.

Naming Confusion: Yes, it's confusing that both use "task" in their names. Think of it this way: Task tool = spawn agent, Tasks system = track work. The Task tool is a verb (do this). The Tasks system is a noun (work items).

How Subagents Use Tasks

The real power emerges when subagents interact with the Tasks system. Here's the typical flow for coordinated multi-agent work.

Main Agent Creates Tasks

The workflow starts with your main agent analyzing what needs to be done and creating tasks for each piece of work. These tasks live in the shared task list, visible to any agent with access.

Main Agent Creates Tasks
// Main agent breaks down the work
TaskCreate:
  title: "Create HTML form structure"
  description: "Build contact form with name, email, message fields"
  status: "pending"

TaskCreate:
  title: "Style contact form"
  description: "Add CSS styling matching design system"
  status: "pending"
  depends_on: ["task_form_structure"]

TaskCreate:
  title: "Add form validation"
  description: "Implement client-side validation with error messages"
  status: "pending"
  depends_on: ["task_form_structure"]

Main Agent Spawns Subagent

With tasks defined, the main agent spawns a subagent using the Task tool. The subagent receives instructions that include access to the task list.

Spawning a Subagent
// Main agent spawns subagent with task list access
Task tool:
  description: "Frontend work on contact form"
  prompt: |
    You have access to a shared task list.
    Use TaskList to see available work.
    Claim a pending task by updating its status to "in_progress" and setting yourself as owner.
    Complete the work, then mark the task "complete".
    Pick up the next available task when done.

Subagent Claims Task

The subagent checks the task list, finds a pending task it can work on, and claims it by updating the status and owner. This prevents other agents from working on the same task.

Subagent Claims Work
// Subagent sees available work
TaskList:
// Returns:
// - task_form_structure: pending
// - task_form_style: pending (blocked by task_form_structure)
// - task_form_validation: pending (blocked by task_form_structure)

// Subagent claims the unblocked task
TaskUpdate:
  task_id: "task_form_structure"
  status: "in_progress"
  owner: "frontend-subagent-1"

Subagent Does Work

With a task claimed, the subagent executes the work. It reads files, writes code, makes changes. This is the actual implementation phase. The subagent focuses entirely on completing its claimed task.

Subagent Marks Complete

When finished, the subagent updates the task status to complete. This signals to other agents (and the main agent) that the work is done. If other tasks depended on this one, they may now be unblocked.

Completing a Task
// Subagent finishes work and marks complete
TaskUpdate:
  task_id: "task_form_structure"
  status: "complete"
  notes: "Created form with semantic HTML, proper labels, and ARIA attributes"

// Other tasks that depended on this are now unblocked
// task_form_style: pending -> ready
// task_form_validation: pending -> ready
The Coordination Loop: Claim task, do work, mark complete, repeat. This simple loop, combined with shared state, enables sophisticated multi-agent workflows. Each agent follows the same pattern but works on different tasks.

Shared Task Lists Across Agents

The magic of combining Tasks with subagents is that they share the same task list. Updates from one agent are immediately visible to all others. This shared state enables real coordination.

Subagents Inherit the Task List ID

When you spawn a subagent, it can access the same task list as the main agent. There's no separate task list per agent. Everyone works from the same source of truth.

This inheritance is what makes coordination possible. When subagent A marks a task complete, subagent B sees it immediately. When the main agent checks progress, it sees the real-time state of all work.

Updates Broadcast to All Agents

Task updates are shared. When one agent changes a task's status, owner, or notes, every other agent sees the change on their next TaskList call. This creates a coordination protocol without explicit agent-to-agent communication.

Shared State in Action
Timeline:

T=0: Main agent creates tasks A, B, C (all pending)
T=1: Main agent spawns subagent-1 and subagent-2
T=2: subagent-1 claims task A (A: in_progress)
T=3: subagent-2 sees A claimed, claims task B (B: in_progress)
T=4: subagent-1 completes A (A: complete)
T=5: subagent-1 claims task C (C: in_progress)
T=6: subagent-2 completes B (B: complete)
T=7: Main agent checks progress: A complete, B complete, C in progress
T=8: subagent-1 completes C (C: complete)
T=9: Main agent sees all complete, reports success

No explicit coordination needed - shared task list handles it

Main Agent Can Monitor Progress

The main agent doesn't need to wait blindly for subagents to return. It can periodically call TaskList to check progress. This enables progress reporting, timeout handling, and dynamic replanning if needed.

Main Agent Monitoring
// Main agent monitors progress
TaskList:
// Returns:
// - task_form_structure: complete (owner: frontend-subagent-1)
// - task_form_style: in_progress (owner: frontend-subagent-1)
// - task_form_validation: in_progress (owner: frontend-subagent-2)

// Main agent can report: "2 of 3 tasks complete, 2 in progress"
// Or detect issues: "task_X has been in_progress for too long"

Parallel Execution Pattern

One of the most powerful patterns is parallel execution: multiple subagents working simultaneously on independent tasks. This dramatically speeds up complex work.

Create Multiple Tasks

Start by creating all the tasks that can be worked on independently. These are tasks without dependencies on each other. They might share a common ancestor task, but they don't block each other.

Creating Independent Tasks
// Three independent feature implementations
TaskCreate:
  title: "Implement user profile page"
  status: "pending"

TaskCreate:
  title: "Implement settings page"
  status: "pending"

TaskCreate:
  title: "Implement activity log page"
  status: "pending"

// No dependencies - all three can run in parallel

Spawn Multiple Subagents

With independent tasks defined, spawn multiple subagents. Each will claim an available task and start working. Because tasks are independent, there's no coordination needed beyond the claim mechanism.

Spawning Parallel Workers
// Spawn three subagents in parallel
Task tool:
  description: "Frontend worker 1"
  prompt: "Check TaskList, claim a pending task, complete it."

Task tool:
  description: "Frontend worker 2"
  prompt: "Check TaskList, claim a pending task, complete it."

Task tool:
  description: "Frontend worker 3"
  prompt: "Check TaskList, claim a pending task, complete it."

// All three run simultaneously, each working on different tasks

Each Claims an Available Task

The subagents race to claim tasks. The first one to update a task's status wins. Others see the task is claimed and move on to the next available one. This natural coordination prevents duplicate work.

Work Happens in Parallel

While the subagents work, genuine parallel execution occurs. Three tasks that would take 30 minutes sequentially might take 10 minutes in parallel. The shared task list handles coordination; you get the speed benefit of parallelism.

Race Condition Risk: If two subagents try to claim the same task simultaneously, you might get unexpected behavior. In practice, this is rare because the claim-check-work loop is fast. But for critical workflows, consider adding a lock or using the owner field to verify claims.

Pipeline Pattern

Not all work can be parallelized. Some tasks depend on others completing first. The pipeline pattern handles these dependencies gracefully.

Create Tasks with Dependencies

When creating tasks, specify dependencies. A task that depends on another won't be available until its dependency is complete. This models real-world workflows where Phase 2 can't start until Phase 1 finishes.

Tasks with Dependencies
// Pipeline: Structure -> Style -> Interactions
TaskCreate:
  id: "phase_1"
  title: "Create HTML structure"
  status: "pending"

TaskCreate:
  id: "phase_2"
  title: "Add CSS styling"
  status: "blocked"
  depends_on: ["phase_1"]

TaskCreate:
  id: "phase_3"
  title: "Add JavaScript interactions"
  status: "blocked"
  depends_on: ["phase_2"]

Spawn First Subagent for Phase 1

Start with a subagent for the first phase. It claims the only unblocked task and begins work. The other tasks remain blocked, invisible to workers.

When Complete, Phase 2 Auto-Unblocks

When Phase 1 completes, any task that depended solely on it becomes unblocked. The next subagent (or the same one if it's still running) can now claim Phase 2.

Pipeline Execution
// Phase 1 completes
TaskUpdate:
  task_id: "phase_1"
  status: "complete"

// System automatically unblocks phase_2
// phase_2: blocked -> pending

// Next worker claims phase_2
TaskUpdate:
  task_id: "phase_2"
  status: "in_progress"

// And so on through the pipeline...

Spawn Next Subagent for Phase 2

You can spawn subagents as phases complete, or spawn them upfront and let them wait for tasks to become available. Either approach works. The task list handles the coordination.

Combining Patterns: Real workflows often combine parallel and pipeline patterns. You might have parallel tasks within a phase, but phases themselves are sequential. Create the task graph that matches your actual dependencies.

Best Practices

Combining Tasks with subagents is powerful but requires discipline. These practices will help you avoid common pitfalls.

Keep Subagent Prompts Focused

Subagents work best with focused instructions. Don't ask a subagent to "build the entire feature." Ask it to "check TaskList, claim a pending task, and complete it." The task itself defines the work; the prompt defines the protocol.

Good vs Bad Prompts
// BAD: Too much responsibility
prompt: "Build the contact form with validation and styling and submission handling"

// GOOD: Protocol-focused
prompt: |
  You are a frontend worker.
  1. Call TaskList to see available tasks
  2. Claim a pending task by setting status to "in_progress"
  3. Complete the work described in the task
  4. Mark the task "complete" with notes about what you did
  5. If more tasks available, repeat from step 1

Use Clear Task Descriptions

Task descriptions are instructions to future subagents. Make them specific enough that any agent can understand what to do. Include file paths, acceptance criteria, and any constraints.

Clear Task Description
// BAD: Too vague
title: "Style the form"

// GOOD: Specific and actionable
title: "Style contact form in /src/pages/contact.html"
description: |
  Add CSS styling to the contact form:
  - Use existing color variables from /src/styles/tokens.css
  - Make responsive at 768px breakpoint
  - Match input styling to /src/components/input.css
  - Add focus states for accessibility
  - Do NOT modify the HTML structure

Let Tasks Handle Coordination

Don't try to coordinate subagents manually through complex prompts. Let the task list do the coordination. Subagents check what's available, claim work, and mark it done. The shared state handles the rest.

Don't Over-Parallelize

More subagents isn't always better. Each subagent consumes resources and context. If you spawn ten subagents for three tasks, seven will sit idle. Match your parallelism to your actual workload.

A good rule: spawn slightly fewer subagents than you have independent tasks. This ensures all subagents stay busy without wasting resources.

Parallelism Guidelines
Tasks available: 5 independent tasks

// TOO MANY: 10 subagents
// 5 will work, 5 will sit idle
// Wasted resources, slower overall

// TOO FEW: 1 subagent
// Sequential execution
// No parallelism benefit

// JUST RIGHT: 3-4 subagents
// All stay busy
// Good parallelism
// Efficient resource use
Context Limits Still Apply: Each subagent has its own context window. Long-running subagents that process many tasks will eventually hit context limits. For extended workflows, spawn fresh subagents periodically rather than reusing old ones.

The Missing Piece: Specialist Identity

Tasks plus subagents gives you orchestration. You can spawn workers, coordinate them through shared state, and execute complex workflows. But there's something missing: the subagents are generic.

Tasks + Subagents Handle Orchestration

The pattern we've described handles the mechanics of multi-agent work beautifully. Task creation, claiming, completion, dependencies, parallel execution, all of it works. But the subagents themselves are blank slates. They do whatever you tell them in the prompt.

But Subagents Are Generic

A generic subagent will write HTML, CSS, and JavaScript. It will mix concerns. It will make decisions that might conflict with your architecture. It brings no specialized expertise to any domain.

You can put constraints in the prompt, but prompts are suggestions. There's no structural enforcement. A subagent told "only write CSS" might still edit JavaScript if it seems helpful. The guardrails are soft.

What If Each Subagent Was a Specialist?

Imagine if instead of generic workers, your subagents were specialists. A frontend subagent that truly only touches HTML and CSS, with deep knowledge of design patterns and accessibility. A backend subagent that only writes server code, with expertise in security and performance. A JavaScript subagent that handles all client-side logic with mastery of modern patterns.

These specialists wouldn't just follow instructions. They would bring domain expertise. They would enforce architectural boundaries automatically. They would produce higher quality work because they're focused on their specialty.

What If They Had Baked-In Expertise?

Generic subagents start from zero each time. They don't remember your patterns. They don't know your design system. They don't understand your architecture. Every prompt needs to re-explain everything.

Specialist agents could have baked-in expertise. They could know your CSS architecture because it's part of their identity. They could follow your JavaScript patterns because that's who they are. The expertise persists across sessions, accumulating rather than resetting.

The Gap: Claude Code gives you the orchestration primitives (Task tool + Tasks system). But it doesn't give you specialist agents with persistent identity and enforced boundaries. That's the layer you need to build on top, or find a system that provides it.

Going Further: Claude Architect

The orchestration patterns in this guide are powerful. But they're just the foundation. What makes multi-agent development truly transformative is combining orchestration with specialist agents who have real identity and expertise.

We Built Specialist Agents on Top of This

Claude Architect takes the orchestration primitives we've discussed and adds the missing layer: specialist agents with persistent identity. Instead of generic subagents, you get a team of experts who know their domain deeply and respect architectural boundaries automatically.

PM, Frontend Designer, iOS Dev, Firebase Dev

The system includes pre-configured specialists:

  • Project Manager: Coordinates work, creates tasks, validates outputs. Never writes code.
  • Frontend Designer: HTML and CSS only. Deep knowledge of responsive design, accessibility, and visual patterns.
  • Web Developer: JavaScript only. Handles all client-side logic, API calls, and interactions.
  • iOS Developer: Swift only. Knows Apple frameworks, Human Interface Guidelines, and iOS patterns.
  • Firebase Developer: Backend only. Manages Cloud Functions, security rules, and server-side logic.

Each Has Identity and Expertise

These aren't just labels. Each agent has a comprehensive identity document that defines who they are, what they know, what they can do, and what they cannot do. The Frontend Designer has 15 years of CSS expertise baked in. The iOS Developer knows SwiftUI patterns intimately.

When you spawn a specialist, you get someone with genuine expertise, not a generic worker following instructions. The quality of output is dramatically higher because each agent is optimized for their domain.

Ready for Specialist Agents?

Claude Architect combines the orchestration power of Tasks and subagents with specialist identities that bring real expertise to each domain. Stop working with generic workers and start working with a team of experts.

See How Specialist Agents Work