Skip to content

Subagents ​

Subagents give agents the ability to spawn, delegate to, and merge results from child agents — each with its own model, capability set, and memory isolation scope. This is multi-agent orchestration without a proprietary message bus: the subagent protocol is standardized, so any A2E-compatible host can run it.

Overview ​

The subagents capability provides multi-agent orchestration — spawning, delegating tasks to, communicating with, and merging results from child agents. Subagents run as independent agent instances with their own model, system prompt, capabilities, and execution scope.

Key concepts:

  • Spawn — Create a new subagent with a specific configuration
  • Delegate — Assign a task to a spawned subagent
  • Await — Block until a subagent completes its task
  • Message — Send inter-agent messages between subagents
  • Merge — Combine results from multiple subagents
  • Cancel/Terminate — Stop a running subagent gracefully or forcefully

Isolation Model ​

Each subagent operates within a configurable isolation boundary:

Memory Scope ​

ScopeDescriptionUse Case
sharedSubagent shares parent's memoryCollaborative tasks needing shared context
isolatedSubagent has its own memory namespaceIndependent tasks with no cross-contamination
snapshotSubagent gets a copy of parent's memory at spawn timeTasks that need initial context but produce independent results

Tool Scope ​

ScopeDescriptionUse Case
sharedFull access to parent's toolsTrusted subagents that need all capabilities
restrictedLimited tool access (host policy)Default — safe for most tasks
isolatedCompletely separate tool namespaceSandboxed execution with custom tool sets

Protocol Messages (12 types) ​

Type StringModelDirection
SUBAGENT_SPAWN_REQSubagentSpawnRequestParent → Host
SUBAGENT_SPAWN_RESPSubagentSpawnResponseHost → Parent
SUBAGENT_DELEGATE_REQSubagentDelegateRequestParent → Host
SUBAGENT_DELEGATE_RESPSubagentDelegateResponseHost → Parent
SUBAGENT_AWAIT_REQSubagentAwaitRequestParent → Host
SUBAGENT_AWAIT_RESPSubagentAwaitResponseHost → Parent
SUBAGENT_MESSAGE_REQSubagentMessageRequestAgent → Host
SUBAGENT_MESSAGE_RESPSubagentMessageResponseHost → Sender
SUBAGENT_LIST_REQSubagentListRequestAgent → Host
SUBAGENT_LIST_RESPSubagentListResponseHost → Agent
SUBAGENT_CANCEL_REQSubagentCancelRequestAgent → Host
SUBAGENT_TERMINATE_REQSubagentTerminateRequestAgent → Host
SUBAGENT_MERGE_REQSubagentMergeRequestAgent → Host
SUBAGENT_MERGE_RESPSubagentMergeResponseHost → Agent
SUBAGENT_EVENTSubagentEventHost → Agent (streaming)

SubagentConfig ​

FieldTypeRequiredDefaultDescription
namestrYes—Subagent name
rolestrNoNoneRole descriptor
modelstrYes—LLM model identifier
system_promptstrNoNoneCustom system prompt
capabilitieslist[str]No[]Enabled capabilities
memory_scopeMemoryScopeNosharedMemory isolation level
tool_scopeToolScopeNorestrictedTool access level
max_stepsintNo40Maximum agent steps
timeout_secondsintNo600Execution timeout
metadatadictNo{}Additional metadata

TaskDefinition ​

FieldTypeRequiredDefaultDescription
namestrYes—Task name
instructionstrYes—Task instruction for the subagent
success_criterialist[str]No[]Criteria for task completion
metadatadictNo{}Additional task metadata

SubagentInfo ​

FieldTypeDescription
subagent_idstrSubagent identifier
namestrDisplay name
statusSubagentStatusCurrent status
parent_agent_idstr or NoneParent agent
root_agent_idstr or NoneRoot agent
depthintNesting depth
configSubagentConfigFull configuration

SubagentStatus ​

ValueDescription
READYSpawned but not yet executing a task
RUNNINGActively executing a delegated task
WAITINGWaiting for input or another subagent
COMPLETEDTask finished successfully
FAILEDTask finished with error
CANCELLEDTask was gracefully cancelled
TERMINATEDTask was forcefully terminated

Merge Strategies ​

StrategyDescription
hierarchical_summaryParent summarizes child results
votingMajority vote across results
customHost-defined merge strategy

SubagentPlugin ​

python
from a2e.caps.subagents.plugin import SubagentPlugin, SubagentRuntime

class SubagentPlugin:
    def __init__(self):
        self.subagents: Dict[str, SubagentRuntime] = {}

    async def spawn(self, request: SubagentSpawnRequest) -> SubagentSpawnResponse: ...
    async def delegate(self, request: SubagentDelegateRequest) -> SubagentDelegateResponse: ...
    async def await_result(self, subagent_id: str) -> SubagentAwaitResponse: ...
    async def list_subagents(self) -> list[SubagentInfo]: ...
    async def terminate(self, subagent_id: str) -> None: ...

SubagentRuntime ​

Each subagent is managed by a SubagentRuntime instance:

FieldTypeDescription
subagent_idstrUnique identifier
configSubagentConfigConfiguration
parent_agent_idstr or NoneParent reference
root_agent_idstr or NoneRoot reference
depthintNesting depth
statusSubagentStatusCurrent status
resultdict or NoneTask result
task_handleasyncio.Task or NoneRunning task handle

Lifecycle ​

  1. Spawn: Create runtime, set status = READY
  2. Delegate: Create asyncio.Task for run_task(), set status = RUNNING
  3. Execute: Agent adapter runs the task
  4. Complete: Set status = COMPLETED, store result
  5. Fail: Set status = FAILED, store error
  6. Cancel: Cancel asyncio.Task, set status = CANCELLED
  7. Terminate: Cancel asyncio.Task, set status = TERMINATED

SubagentClient (Client) ​

python
from a2e.caps.subagents.client import SubagentClient

subagents = SubagentClient(transport)

# Spawn a new subagent
spawn_resp = await subagents.spawn(
    name="researcher",
    model="claude-3.5-sonnet",
    role="research",
    system_prompt="You are a research assistant",
    capabilities=["tools", "memory"],
)

# Delegate a task
delegate_resp = await subagents.delegate(
    subagent_id=spawn_resp.subagent_id,
    task_name="research_topic",
    instruction="Research the latest developments in quantum computing",
    success_criteria=["Include at least 3 recent papers"],
)

# Await the result
result = await subagents.await_result(spawn_resp.subagent_id)
print(result.status)   # "COMPLETED"
print(result.result)   # {"summary": "...", "papers": [...]}

# Convenience: spawn + delegate + await in one call
result = await subagents.run(
    name="coder",
    model="gpt-4",
    task_name="implement_feature",
    instruction="Implement the login API endpoint",
)

Convenience Method ​

MethodDescription
run(name, model, task_name, instruction)Spawn + delegate + await in one call

Security Considerations ​

  1. Depth limiting: Host must enforce maximum nesting depth to prevent recursive spawning
  2. Memory isolation: isolated and snapshot scopes prevent cross-agent data leakage
  3. Tool restriction: restricted and isolated scopes limit dangerous tool access
  4. Timeout enforcement: timeout_seconds prevents runaway subagents
  5. Step limiting: max_steps prevents infinite agent loops
  6. Cancellation propagation: Cancel requests must propagate to all child subagents
  7. Resource quotas: Host should enforce per-session subagent count limits

See Security & Trust for the full security model.

Relationship to Other Capabilities ​

  • memory: memory_scope controls whether subagents share, isolate, or snapshot parent memory
  • tools: tool_scope controls tool access; restricted subagents see a filtered tool list
  • chains: Chains orchestrate tools/data within one agent; subagents orchestrate across multiple agents
  • mcp: Subagents with shared tool scope can access MCP-bridged tools

For a complete walkthrough of building a subagent orchestration plugin and client, see Subagent Orchestrator (Plugin & Client).

A2E Protocol v1.0 — Released under the MIT License.