Skip to main content
Many phrases in a voice agent never change: the greeting, the “let me check that for you” hold message, the goodbye. Synthesizing them through a TTS provider on every call costs roughly 300 to 800 ms per phrase and burns provider credits. Synthesize each one once, keep the PCM bytes, and replay them on every subsequent session.say().

How it works

session.say() accepts an audio_data argument: pre-synthesized PCM that bypasses TTS entirely. When it is set, the runtime plays your bytes instead of calling the provider, so playback starts immediately. text is still required alongside audio_data. It is what lands in the transcript and the chat context; the audio is only what the caller hears.
The bytes must be PCM in the room’s audio format. What produces them is up to you: your TTS vendor’s SDK, a file you decoded ahead of time, or a fetch from your own storage. The runtime plays what it is given.

Cache the phrases

Wrap a synthesizer in a cache that stores each phrase on first use. Later calls for the same phrase return the stored bytes without touching the provider, concurrent calls for one phrase share a single synthesis, and entries fall out LRU past max_entries.
Python
Warm the fixed phrases before the first caller arrives, so nobody pays the synthesis:
Python

Supplying the synthesizer

The pipeline’s TTS plugin is a configuration object, not a synthesizer: synthesis happens on the runtime, so the plugin cannot produce audio in your process. The cache needs its own coroutine that returns raw PCM at the agent track’s sample rate, 24 kHz mono 16-bit signed. Name the model and voice once and pass them to both the plugin and the synthesizer, or cached lines will sound like a different speaker than the agent’s dynamic speech.
Python
Any vendor works. The cache only needs a coroutine returning raw PCM at the track’s sample rate.

Replay in on_enter and on_exit

The agent’s fixed opening and closing lines are the clearest win: both are known before the call starts, and both sit on the critical path where latency is most audible.
Python

Overlap a hold phrase with a slow operation

Cached audio suits filler speech during database lookups, API calls, or RAG retrieval. Start the phrase as a task and let it play while the work runs, rather than waiting for it to finish first. Pass add_to_chat_context=False so the filler line does not enter the LLM’s context.
Python

Pre-recorded audio

The same slot plays produced or branded audio, a recorded human voice or an IVR jingle. Decode the file to 24 kHz mono 16-bit PCM first, then pass the bytes; no TTS provider is involved either way.
Python

Parameters

session.say(text, *, interrupt=False, interruptible=None, add_to_chat_context=None, audio_data=None)

What’s Next

Background Audio

Play thinking sounds and ambient audio.

Audio Customization

Tune the agent’s voice.

References

Examples

Cached TTS

Replay fixed phrases without a TTS round trip.