Skip to content

Subagents

A subagent is a child agent that the parent can invoke as a tool. Register an AgentSpec and caw exposes it to the parent automatically; when the parent calls it, the subagent runs its own session and its full trajectory is captured.

from caw import Agent, AgentSpec

reviewer = AgentSpec(
    name="security_reviewer",
    description="Reviews code for security issues",
    system_prompt="You are a security expert. Review the given code.",
)

agent = Agent()
agent.add_subagent(reviewer)
traj = agent.completion("Review the auth module for vulnerabilities")

Nested trajectories and usage roll-up

Each subagent invocation attaches a nested Trajectory to the parent's ToolUse block, so you can inspect what the child did:

for sub in traj.subagent_trajectories:
    print(f"  subagent: {sub.agent}, {sub.num_turns} turns, ${sub.usage.cost_usd:.4f}")

Usage rolls up: traj.usage is the parent's own consumption, while traj.total_usage is the parent plus all nested subagents (recursively). This is the number to use for total cost.

Configuring a subagent

AgentSpec carries the same knobs as an Agent: system_prompt, model, reasoning, tools, plus its own tool_servers, mcp_servers, and even nested subagents. That means a subagent can have its own tools and its own children.

AgentSpec(
    name="researcher",
    description="Searches the web and summarizes findings",
    system_prompt="You research topics thoroughly.",
    model="opus",
    tools=ToolGroup.READER | ToolGroup.WEB,
)

Full example

examples/subagent.py shows a senior-engineer agent delegating code review to a subagent and inspecting the nested trajectory:

"""Subagent demo: a parent agent delegates code review to a subagent."""

import os

os.environ["CAW_LOG"] = "full"

from caw import Agent, AgentSpec


def main():
    reviewer = AgentSpec(
        name="Code Reviewer",
        description="Review code for correctness and style issues.",
        system_prompt="You are a code reviewer. Given code, identify bugs and style issues. Be concise.",
    )

    agent = Agent(
        system_prompt="You are a senior engineer. Use the Code Reviewer tool to review code when asked.",
        data_dir="caw_data",
    )
    agent.add_subagent(reviewer)

    with agent.start_session() as session:
        turn = session.send("Review this Python function:\n\ndef add(a, b):\n    return a - b\n")

        traj = session.trajectory
        print(f"\nParent own usage: ${traj.usage.cost_usd:.4f}")
        print(f"Parent total usage (with subagents): ${traj.total_usage.cost_usd:.4f}")
        print(f"Parent total tokens: {traj.total_usage.total_tokens}")

        for tc in turn.tool_calls:
            if tc.subagent_trajectory:
                st = tc.subagent_trajectory
                print(f"\n  Subagent '{tc.name}':")
                print(f"    Model: {st.model}")
                print(f"    System prompt: {st.system_prompt[:60]}...")
                print(f"    Tool calls: {st.total_tool_calls}")
                print(f"    Usage: ${st.usage.cost_usd:.4f} ({st.usage.total_tokens} tokens)")


if __name__ == "__main__":
    main()