Skip to main content

Introduction

Subagents allow one agent to delegate part of its work to another agent that runs in complete isolation. Each child agent has its own state, system prompt, tool set, resource budget, and LLM configuration. The parent agent decides when to delegate by calling the spawn_subagent tool, and the child’s final output is returned to the parent as a tool result. This delegation model is useful when different parts of a task require different expertise, tool access, or resource limits. A code review agent might spawn a “security reviewer” subagent with read-only file access and a tight step budget, while also spawning a “style checker” subagent with different instructions. The parent orchestrates the overall workflow without needing to know the implementation details of each child.

Quick Start

The following example sets up a parent agent with file tools and a “reviewer” subagent that can only read files:
The parent model decides on its own when to call spawn_subagent. The tool schema includes a description of all available subagents and their purposes, giving the LLM the information it needs to choose the right one.

How Delegation Works

When the parent agent calls spawn_subagent(subagent: 'reviewer', prompt: 'Review this file...'), the following sequence occurs:
  1. Depth check — the system verifies that the current nesting depth has not exceeded the configured maximum. If it has, a SubagentDepthExceededException is thrown and returned to the parent as a tool error.
  2. Definition lookup — the AgentDefinitionRegistry resolves the named AgentDefinition. If the name is not found, a SubagentNotFoundException is thrown.
  3. Tool filtering — the child’s tool set is determined by applying the definition’s tools allow-list and toolsDeny deny-list against the parent’s available tools.
  4. Driver resolution — the child inherits the parent’s tool-use driver. If the definition specifies an llmConfig and the driver supports CanAcceptLLMConfig, the child’s driver is reconfigured with the specified model/provider.
  5. Budget application — if the definition declares an ExecutionBudget, UseGuards is applied to the child’s builder with the budget’s limits.
  6. Loop construction — an AgentBuilder assembles the child AgentLoop from the filtered tools, configured driver, and guards.
  7. State initialization — a fresh AgentState is created with the definition’s system prompt and the caller’s prompt as the user message. If the definition has skills, they are injected as additional system messages.
  8. Execution — the child loop runs to completion. If the child fails (ExecutionStatus::Failed), a SubagentExecutionException is thrown.
  9. Result return — the child’s final AgentState is returned to the parent as the tool call result. The parent continues its execution with this information.

Defining Subagents

Subagents are defined using the same AgentDefinition class used by agent templates. You can register them programmatically or load them from files.

Programmatic Registration

File-Based Registration

Definitions can be loaded from .md, .yaml, or .json files:
See Agent Templates for the full file format specification.

Tool Visibility

Tool visibility is one of the most important aspects of subagent design. It determines what a child agent can do, and more importantly, what it cannot.

Inheriting All Parent Tools

By default (when tools is null), the child inherits every tool the parent has, including spawn_subagent itself:

Allow-List

Setting tools to a NameList creates a strict allow-list. Only the named tools are available to the child:

Deny-List

The toolsDeny field removes specific tools from whatever set the child would otherwise have. This is useful when you want to inherit most tools but block a few dangerous ones:

spawn_subagent in Children

If the child inherits spawn_subagent, the tool is automatically replaced with a nested version that tracks depth. This means children can spawn their own subagents, subject to the depth policy. If you want to prevent this, add spawn_subagent to the deny list:

Depth Control

Subagents can spawn their own subagents, creating a recursive hierarchy. The SubagentPolicy controls the maximum nesting depth to prevent unbounded recursion.

Using SubagentPolicy

The default maxDepth is 3. A depth of 0 means the parent itself; a depth of 2 means the parent can spawn children, and those children can spawn grandchildren, but no further.

Convenience Factory

For simple depth configuration, use the static forDepth() factory:

Depth Exceeded Behavior

When a subagent attempts to spawn at a depth that exceeds the policy, a SubagentDepthExceededException is thrown. This exception is returned to the calling agent as a tool error, allowing it to handle the situation gracefully (typically by performing the work itself).

Child Budgets and Models

Each child agent can declare its own resource budget and LLM configuration independently from the parent.

Custom Budget

If no budget is declared, the child runs without guards (unless the parent’s guards indirectly limit it through total token accounting).

Custom Model

Children can use a different model or provider than the parent. This is useful for cost optimization — simple tasks can use a cheaper model while complex analysis uses a more capable one.
If no llmConfig is specified, the child inherits the parent’s LLM configuration. You can also pass just a driver name as a string:

Skill Injection

Subagents can reference named skills from a SkillLibrary. When skills are specified in the definition, their rendered content is injected as additional system messages before the user prompt.

Events

The subagent lifecycle emits two events through the parent’s event dispatcher, providing visibility into delegation activity.

SubagentSpawning

Dispatched when a parent agent is about to spawn a child. Contains context for tracing the delegation hierarchy.
The event includes:
  • parentAgentId — the parent’s agent ID
  • subagentName — the name of the subagent being spawned
  • prompt — the task/question sent to the child
  • depth / maxDepth — current and maximum nesting depth
  • parentExecutionId, parentStepNumber, toolCallId — correlation IDs for tracing

SubagentCompleted

Dispatched when a child agent finishes execution, regardless of success or failure.
The event includes:
  • parentAgentId — the parent’s agent ID
  • subagentName — the name of the completed subagent
  • subagentId — the child’s unique agent ID
  • status — the ExecutionStatus (completed, failed, etc.)
  • steps — total steps the child took
  • usage — token usage data (nullable)
  • startedAt / completedAt — timestamps for duration calculation
  • parentExecutionId, parentStepNumber, toolCallId — correlation IDs for tracing

Error Handling

The subagent system defines three specific exception types: All three are returned to the parent agent as tool errors, so the parent can decide how to proceed — retry with different instructions, try a different subagent, or handle the task itself.

The Tool Schema

The spawn_subagent tool automatically generates its schema from the registry. The schema includes:
  • A subagent parameter as an enum of all available agent names
  • A prompt parameter for the task or question
  • A description that lists all available subagents with their descriptions and tool access
This means the LLM can see which subagents are available, what each one does, and what tools each has access to, all from the tool schema alone.