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 available in pipecat-ai 1.14.0+, with the assemblyai extra.- 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.
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. Unset, the session speaks with the server’s default voice, Jane (95e643fb-dd55-577f-80ec-134c3118efcc). voice takes any voice your account can use:
- One of the AssemblyAI voices, which speak all six supported languages.
- A voice from the AssemblyAI voice library. These speak one language, the language of their recording.
- A voice you cloned in the AssemblyAI dashboard.
aai-anna 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.
Choose a voice that speaks the language. The AssemblyAI voices speak all six. A library or cloned voice speaks only the language it was recorded in: leave language unset and the session speaks the voice’s language. The API doesn’t detect language, so an AssemblyAI voice speaks English unless you set 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. To start before a sentence is complete, set
text_aggregation_mode=TextAggregationMode.TOKEN(frompipecat.services.tts_service).
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 that is about to expire, so a reply is never cut off by 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.