Overview
Pipecat is an open-source Python framework for building real-time voice agents. You compose your agent as a pipeline of services (speech-to-text, LLM, text-to-speech) that stream audio and data frames to each other, and Pipecat handles the orchestration, including turn-taking, interruptions, and transports such as WebRTC, Daily, and telephony.AssemblyAITTSService speaks your agent’s replies with the Streaming TTS API. Use it with AssemblyAISTTService and the LLM Gateway, and every model in the agent runs on one AssemblyAI API key.
AssemblyAITTSService is on Pipecat’s main branch, with the assemblyai
extra, and ships in the first pipecat-ai release after 1.14.0. 1.14.0
and earlier don’t have it.- Streaming by sentence. Each sentence of the LLM’s reply is its own request, so the agent starts speaking after the first sentence rather than after the whole reply.
- One session per call. The service opens its WebSocket session when the pipeline starts and keeps it for every reply, sending a keepalive while the agent is quiet.
- Barge-in without reconnecting. When the user interrupts, the service cancels the audio still in flight and keeps the session.
- Word-timed context. Per-word timings drive Pipecat’s spoken-text frames, so an interrupted reply is saved to the LLM context only up to the word the user heard.
Quickstart
1
Install the packages
Install Pipecat with the AssemblyAI, OpenAI, and Silero extras, and the runner and WebRTC extras to talk to the agent in your browser. The OpenAI service connects the agent to the LLM Gateway, which speaks the OpenAI Chat Completions API.Once a
pipecat-ai release after 1.14.0 is out, install that release instead: pip install "pipecat-ai[assemblyai,openai,silero,runner,webrtc]>1.14.0" python-dotenv.2
Set your API key
Set your API key in a
.env file:3
Build the agent
Save this as
bot.py. It uses AssemblyAI for speech-to-text, the LLM, and text-to-speech:4
Talk to it
Run the agent:Open http://localhost:7860/client, allow the microphone, and press Connect. Use headphones, so the agent doesn’t hear its own voice. To run the agent in a Daily room or on a phone number, add their transports to
transport_params; see Pipecat’s transports.vad_force_turn_endpoint and mode, see Universal-3.6 Pro on Pipecat.
Reference agent
AssemblyAI voice agent starter for Pipecat
A starter agent that runs every model on AssemblyAI: Streaming TTS,
Universal-3.6 Pro, and the LLM Gateway. Every model setting is a building
block with a skill that teaches coding agents such as Claude Code when and how
to tune it, from the voice to turn detection and noise suppression. It comes
with tests and a Dockerfile for deploying to Pipecat Cloud. Fork it and make
it yours.
Parameters reference
AssemblyAITTSService.Settings:
Choose a voice
Pass a voice tovoice by its ID, a UUID. The default is Audrey, 49c443a4-8a1d-5f7e-b70b-98bdbd9823c3, which differs from the API’s own default, aai-jane. voice takes any voice your account can use:
- One of the AssemblyAI voices in the voice library, such as Audrey or Anna.
- A cloned voice: a voice you make in the AssemblyAI dashboard from a short reference recording of a speaker who consented to it. It belongs to your account, and it can be used for 60 days after its consent was last given unless you renew the consent.
aai-anna, or the slug of one of your cloned voices, works too, but a voice’s ID never changes.
A cloned voice works only on the host of the data zone it was created in.
Set the language
Setlanguage to the language of the text your LLM writes:
language takes a Pipecat Language (Language.ES), a language code ("es", "es-MX"), or the language’s English name ("spanish"). The service sends the server the English name the API expects, so you can use the same Language values you pass to AssemblyAISTTService. See Languages for the six supported languages.
assemblyai-tts-1 speaks every voice, an AssemblyAI voice or a cloned one, in all six languages, though results are usually worse than in the voice’s own language: for the best results, choose a voice whose own language is the language of your text, such as Constanza for Spanish. Leave language unset and the session speaks the voice’s own language, the language of its recording. The API doesn’t detect language, so set language whenever the text is in another language than the voice’s: with language unset, an English voice opens an English session whatever the language of the text. See Voice and language.
Keep data in the EU
url sets the data zone. It defaults to the US, wss://tts.us.assemblyai.com/v1/ws. To keep text and audio in the EU, point the TTS at the EU host, and the STT and LLM Gateway at theirs:
Interruptions and context
When the user interrupts, the service sendsCancel on the open session and drops the audio of the interrupted reply that is still in flight. The session stays open, so the next reply doesn’t wait for a new handshake.
The service always requests word boundaries and turns them into Pipecat’s spoken-text frames, timed to the audio. With no extra setting:
- The assistant’s transcript follows the agent’s speech word by word.
- When the user cuts the agent off, the assistant aggregator saves the reply to the LLM context only up to the word the user heard, so the LLM doesn’t think it said things it didn’t.
Latency
- The session opens when the pipeline starts. The service connects during setup, so the first reply doesn’t wait on the handshake.
- Greet with a
TTSSpeakFrame. A fixed greeting queued inon_client_connectedis spoken as soon as the user joins, without waiting for the LLM. - Keep replies short. The agent speaks after the first sentence, so a short first sentence starts the audio sooner.
- Keep the default sentence aggregation. The server starts speaking a sentence once it is complete, and the service already sends each sentence as soon as Pipecat sees its end. Streaming tokens with
TextAggregationMode.TOKENtherefore doesn’t start the audio of a short first sentence any sooner: in either mode, it starts once the sentence is complete. - Run the agent near its data zone. A reconnect or a session renewal costs a handshake of a few network round trips, which grows with the distance to the host; see Optimizing accuracy and latency. Use the host of the zone nearest your agent, with the STT and LLM Gateway in the same zone, as in Keep data in the EU.
Sessions and rate limits
AssemblyAI counts TTS sessions per account by new sessions per minute, not by sessions open at once. Because the service keeps one session for the whole call, a call usually opens one session.- Idle sessions. A session closes after two minutes with no frame either way, and an agent can be quiet that long while the user talks. The service sends a
KeepAliveevery 30 seconds to keep it open. - Long calls. A session lasts at most an hour. Between replies, the service replaces a session within two minutes of its end, so a reply doesn’t run into the session’s end.
- Errors. The service reconnects when the server marks an error as retryable, and waits as long as the server’s
retry_after_secondsasks first. An error that can’t be retried before the session starts, such as an invalid API key or an unknown voice, marks the service unusable, so the pipeline’sProcessorUnusablePolicyor a fallback service can act on it. See Error handling for the error codes.
Change the voice during a call
Push aTTSUpdateSettingsFrame to change the voice, language, or model:
Related
- Universal-3.6 Pro on Pipecat: speech-to-text, turn detection, and interruption settings for Pipecat agents.
- Voices: the AssemblyAI voices, languages, and how to find a voice’s ID.
- Voice cloning: clone a voice from a short recording.
- Word boundaries: the per-word timings behind word-timed context.
- Pipecat documentation: pipelines, transports, and deployment.