Agent class is the foundation for every voice agent you build. You define a custom agent by subclassing Agent, give it instructions, and override its lifecycle hooks to act when it joins or leaves a session.
Architecture
TheAgent defines behavior and carries its Pipeline (the STT, LLM, and TTS components). You register the agent with zrt.serve(), and zrt.invoke() starts a session for it; the runtime orchestrates both into a running workflow inside a session.
Initialization
Every custom agent callssuper().__init__() inside its own __init__, passing its instructions, a unique agent_id (required: it’s the handle callers reach the agent by), and the pipeline it runs on. This runs the base Agent so it can register lifecycle hooks and tools, prepare internal state, and store the system prompt.
Instructions
Provide a clear system prompt via theinstructions argument. Describe the agent’s role, tone, and constraints; it is sent with every conversation turn.
Lifecycle
Agents provide two async lifecycle hooks you override to act on join and leave:on_enter (runs after the agent joins) and on_exit (runs before it leaves). Together with instructions, both hooks are expected on every agent you define.
on_enter()
on_enter is called once when the agent successfully joins the session. A common use case is greeting participants with session.say().
Limitation: it runs only after the room connection succeeds, so it cannot be used for pre-connection setup.
on_exit()
on_exit is called when the agent is about to leave the session. A common use case is saying goodbye or running cleanup tasks.
Limitation: the session is shutting down, so long-running work may not complete before resources are released.
Example
A full agent you can run directly. It builds a cascade pipeline, registers the agent withzrt.serve(), and starts a playground session with zrt.invoke().
What’s Next
Configure a Pipeline
Wire up STT, LLM, and TTS.
Run Your Agent
Register and serve the agent.