How to Create Sub-Agents that Delegate Tasks to Specialist Agents

Create sub-agents by implementing specialist wrappers that invoke the Anthropic API with domain-specific system prompts, expose them through orchestrator tools, and use dynamic spawning for parallelizable or context-heavy tasks.

The anthropics/cwc-workshops repository demonstrates a scalable pattern for building modular AI systems where a primary orchestrator delegates specific tasks to focused sub-agents. This architecture breaks complex workflows into discrete, testable components while maintaining transparent token accounting and cost tracking. By following the sub-agent delegation pattern, you can prevent context window overflow and improve response quality through specialized prompting.

Specialist Sub-Agents Architecture

Specialist sub-agents reside in agent-decomposition/agents/before/subagents.py and function as thin wrappers around Anthropic API calls. Each sub-agent targets a single domain—forecasting, procurement, or writing—and uses a dedicated system prompt to shape model behavior.

The repository defines three core specialist agents:

  • Forecasting sub-agent (forecasting_subagent): Accepts SKU sales history and returns a prose demand estimate. Located at lines 62–84 in subagents.py, this function constructs a specialized system prompt for inventory analysis and parses the model's text response.

  • Procurement sub-agent (procurement_subagent): Processes supplier quotes and returns prose recommendations. Implemented at lines 97–106, this agent evaluates vendor data against procurement criteria defined in its system prompt.

  • Writing sub-agent (writing_subagent): Generates Slack alerts or supplier emails based on structured payloads. Found at lines 123–135, it formats communications according to organizational tone guidelines.

A module-level token_counter (lines 20–38) tracks input tokens, output tokens, and call counts for each sub-agent invocation. This enables evaluation harnesses to attribute costs to specific domains and optimize expensive operations.


# From agents/before/subagents.py

def forecasting_subagent(sku: str, context_note: str = "") -> str:
    """Returns a prose demand forecast for the given SKU."""
    system = """You are a Demand Forecasting Analyst. Based on the provided 
    sales history, predict next month's demand and explain your reasoning."""
    user = f"SKU: {sku}\nNote: {context_note}"
    return _call(system, user, max_tokens=1000)

Exposing Sub-Agents to the Orchestrator

The orchestrator interacts with specialists through tool wrappers defined in agent-decomposition/agents/before/tools.py. These functions bridge the high-level agent interface with the low-level sub-agent implementations.

For example, the forecast_demand tool (lines 76–79) simply forwards its parameters to subagents.forecasting_subagent:


# From agents/before/tools.py

def forecast_demand(sku: str, note: str = "") -> str:
    """Tool exposed to the main agent; delegates to forecasting specialist."""
    return subagents.forecasting_subagent(sku, context_note=note)

This indirection allows the orchestrator—such as the StockPilot agent in agents/stockpilot.py—to call forecast_demand as a standard tool without managing API authentication or prompt templates directly. The pattern separates concerns: the orchestrator handles workflow logic while sub-agents handle domain expertise.

Dynamic Sub-Agent Creation

For tasks requiring fresh context windows or parallel execution, the repository provides a generic spawn_subagent tool in agent-decomposition/agents/cma.py. This mechanism creates transient worker sessions on demand.

The tool schema SPAWN_SUBAGENT_TOOL (lines 52–71) defines the expected payload structure:

SPAWN_SUBAGENT_TOOL = {
    "name": "spawn_subagent",
    "description": "Spawn a new sub-agent to handle a specific task",
    "input_schema": {
        "type": "object",
        "properties": {
            "prompt": {"type": "string", "description": "Task description"},
            "expects_json": {"type": "boolean", "description": "Whether to parse output as JSON"}
        },
        "required": ["prompt"]
    }
}

The _handle_spawn_subagent function (lines 2–36) implements the actual delegation:

  1. Spins up a fresh CMA worker session with its own context window
  2. Streams the user-provided prompt to the model
  3. Returns the final text or parsed JSON to the orchestrator

This approach prevents large data inputs—such as 90-day sales CSVs—from consuming the primary agent's context window. It also enables parallel processing by spawning multiple sub-agents simultaneously.


# Example: Dynamic sub-agent invocation from the orchestrator

payload = {
    "prompt": "Analyze the attached 90-day sales CSV and output a JSON summary of trends.",
    "expects_json": True,
}
response = spawn_subagent_tool(payload)  # Returns parsed JSON or text

Implementation Workflow

To implement sub-agent delegation in your own project, follow the three-layer architecture established in the repository:

  1. Define specialists in a dedicated module (e.g., subagents.py). Each function should accept typed parameters, construct a domain-specific system prompt, and return the model's response.

  2. Wrap specialists as tools in tools.py. Create thin adapter functions that match your orchestrator's tool-calling interface and forward arguments to the appropriate sub-agent.

  3. Handle complex delegation using the spawn_subagent pattern from cma.py. Reserve this for tasks that exceed context limits or require isolation from the main conversation thread.

The shared constants in agent-decomposition/agents/common.py—such as the default MODEL identifier—ensure consistency across all agent layers.

Summary

  • Specialist sub-agents are single-purpose functions in agents/before/subagents.py that wrap Anthropic API calls with domain-specific system prompts for forecasting, procurement, and writing tasks.
  • Token tracking via token_counter enables cost attribution and performance monitoring across all sub-agent invocations.
  • Tool wrappers in agents/before/tools.py expose sub-agents to the orchestrator through clean interfaces like forecast_demand and compare_supplier_quotes.
  • Dynamic spawning via spawn_subagent in agents/cma.py creates isolated worker sessions for context-heavy or parallelizable work, preventing primary agent context overflow.
  • This architecture separates workflow orchestration from domain expertise, making complex AI systems modular, testable, and cost-transparent.

Frequently Asked Questions

How do sub-agents handle token usage tracking?

Each sub-agent invocation in agents/before/subagents.py updates a module-level token_counter that records input tokens, output tokens, and call counts. This allows the evaluation harness to attribute costs to specific specialists like the forecasting or procurement agent, enabling precise budget management and optimization of expensive operations.

What is the difference between static and dynamic sub-agents?

Static sub-agents are predefined functions (e.g., forecasting_subagent) imported directly from subagents.py and wrapped in tools. Dynamic sub-agents are created on-demand using the spawn_subagent tool in agents/cma.py, which spins up fresh worker sessions with isolated context windows. Use static agents for recurring domain tasks and dynamic agents for one-off analysis or when processing large datasets that might overflow the primary context.

How does the orchestrator know which sub-agent to call?

The orchestrator does not directly select sub-agents; instead, it calls high-level tools defined in agents/before/tools.py. These tools—such as forecast_demand or draft_supplier_email—encapsulate the delegation logic and forward requests to the appropriate specialist function. This abstraction allows the orchestrator to focus on workflow sequencing while the tools handle domain routing.

Can sub-agents return structured data instead of prose?

Yes. While specialist sub-agents in subagents.py return prose by default, the dynamic spawn_subagent tool supports structured output through the expects_json parameter. When set to true, _handle_spawn_subagent parses the model response as JSON before returning it to the orchestrator, enabling programmatic consumption of sub-agent results.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →