> ## Documentation Index
> Fetch the complete documentation index at: https://docs.zeroruntime.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Subagents

> Split a call into focused roles, such as reception and billing.

A subagent is one role on a call, such as reception or billing. One is active at a time, and the caller hears a single conversation in one voice.

> [!NOTE]
>
> Subagents are available in the Python SDK. Without steps they run on any runtime; with steps, they need a runtime that supports workflows.

## Create Subagents

Give each subagent a `name`, `instructions`, and its own tools.

```python theme={null}
from zeroruntime import SubAgent, function_tool


class Reception(SubAgent):
    name = "reception"
    instructions = "Find out what the caller needs, then hand them over."

    @function_tool
    async def to_billing(self, summary: str) -> dict:
        """Hand the caller to billing.

        Args:
            summary: What they need, in a few words.
        """
        return await self.transfer_to("billing", reason=summary)


class Billing(SubAgent):
    name = "billing"
    instructions = "You handle invoices."
```

## Add Them to Your Agent

List them on your `Agent`. The first one opens the call.

```python theme={null}
import asyncio

from zeroruntime import Agent, Pipeline
from zeroruntime.inference import TurnDetector
from zeroruntime.plugins import CartesiaTTS, DeepgramSTT, GoogleLLM, SileroVAD


class Support(Agent):
    def __init__(self):
        super().__init__(
            instructions="You answer the phone at Nimbus Telecom.",
            pipeline=Pipeline(
                stt=DeepgramSTT(),
                llm=GoogleLLM(),
                tts=CartesiaTTS(),
                vad=SileroVAD(),
                turn_detector=TurnDetector(),
            ),
            subagents=[Reception(), Billing()],
        )

    @function_tool
    async def end_call(self) -> dict:
        """End the call once the caller has nothing else."""
        asyncio.create_task(self.hangup(reason="caller done"))
        return {"status": "ending_call"}
```

Everything on the `Agent` is shared: its instructions and tools work in every subagent. A call doesn't hang up by itself, so add a tool like `end_call` here.

## Move the Call

Return `self.transfer_to(...)` from a tool or hook. The model can't transfer on its own, so you decide when a move happens.

The next subagent keeps the conversation. Pass `inherit_context=False` to start it fresh; it still gets the answers recorded so far.

> [!WARNING]
>
> A move only works if you **return** it.

## Hooks

Override these to run code at key moments.

| Hook | Runs when | Return |
| :- | :- | :- |
| `on_enter(reason)` | The subagent becomes active | What the model should say next, or `None` |
| `on_exit()` | Its last step is done, and when the call ends | A move, a goodbye line, or `None` |

```python theme={null}
class Billing(SubAgent):
    name = "billing"
    instructions = "You handle invoices."

    async def on_enter(self, reason: str):
        return f"Say you can help with this: {reason}."

    async def on_exit(self):
        return "Thanks for calling Nimbus Telecom."
```

## What's Next

> [card] [Workflows and Steps](https://docs.zeroruntime.ai/runtime-sdk/build/workflows-and-steps.md)
>
> Give subagents ordered steps to follow.

> [card] [Support Desk Example](https://github.com/ZeroRuntimeAI/zeroruntime-python-examples/blob/main/workflow/support_desk.py)
>
> Three subagents handing a caller between them.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.