Skip to main content
This guide demonstrates how to build a real-time voice agent using Pipecat, the open-source voice-agent framework created by Daily. Rime provides natural-sounding speech synthesis through Pipecat’s built-in Rime TTS service. You can mix and match different services for each component of your Pipecat pipeline. This tutorial uses:
  • silero for voice activity detection (VAD)
  • gpt-4o-transcribe for speech-to-text (STT)
  • gpt-4o-mini for generating responses
  • rime for text-to-speech (TTS)
The result is a working voice agent that runs locally and opens in your browser. Demo of a voice agent conversation using Pipecat and Rime The guide uses the following Pipecat terminology:
  • A pipeline is a sequence of frame processors. Audio frames flow in, are transcribed, processed by the LLM, and synthesized into speech, then flow back out.
  • A transport handles real-time audio input and output (I/O). Pipecat supports multiple transports, including WebRTC (browser), WebSocket, and local audio devices.
  • Frame processors are the building blocks. Each service (STT, LLM, and TTS, respectively) is a processor that transforms frames as they flow through the pipeline.
If you’d like to experiment directly with Rime’s TTS API before building a full voice agent, check out: TTS in five minutes.

Step 1: Prerequisites

Gather the following API keys and tools before starting:

1.1 A Rime API key

Sign up for a Rime account and copy your API key from the API Tokens page. This enables access to the Rime API for generating TTS.

1.2 An OpenAI API key

Create an OpenAI account and generate an API key from the API keys page. This key enables STT transcription and LLM responses.

1.3 Python

Install Python 3.11 or later (required by Pipecat 1.x). Verify your installation by running the following command in your terminal:

Step 2: Project setup

Set up your project folder, environment variables, and dependencies.

2.1 Create the project folder

Create a new folder for your project and navigate into it:

2.2 Set up environment variables

In the new directory, create a file called .env and add the keys that you gathered in Step 1:
Replace the placeholder values with your actual API keys.

2.3 Configure dependencies

Install the uv package manager:
Create a pyproject.toml file and add the following dependencies to it:
Pipecat uses a plugin system where each service integration is a separate package. In this code, the extras in brackets ([openai,rime,silero,webrtc,runner]) install the following plugins:
  • openai adds STT and LLM services for transcription and generating responses.
  • rime adds a TTS service for synthesizing speech.
  • silero adds VAD for detecting when the user starts and stops speaking.
  • webrtc provides the transport for browser-based audio via WebRTC.
  • runner adds a development runner that handles server setup and WebRTC connections, and includes a ready-to-use browser client for talking to your agent.
This guide targets Pipecat 1.x (verified against 1.5.0). Several APIs were renamed or moved in the 1.0 release, so code written for pipecat-ai 0.x won’t run unchanged.
Then, install the dependencies by running this command:

Step 3: Create the agent

Create an agent.py file to contain all the code that gets your agent talking. If you’re in a rush and just want to run it, skip to Step 3.5: Full agent code. Otherwise, continue reading to code the agent step-by-step.

3.1 Load environment variables and configure imports

Add the following imports and initialization code to agent.py:
Each import corresponds to a frame processor or utility:
  • Pipeline chains processors together in sequence.
  • PipelineRunner and PipelineWorker manage the event loop and run the pipeline.
  • LLMRunFrame triggers the LLM to respond when queued.
  • Services like OpenAISTTService, OpenAILLMService, and RimeTTSService are the frame processors that do the actual work.
  • LLMContext maintains conversation history across turns, and LLMContextAggregatorPair keeps it updated from both sides of the conversation.
  • SileroVADAnalyzer detects speech boundaries so the agent knows when you’ve finished talking.
  • create_transport and TransportParams set up the WebRTC transport for browser-based audio.
  • RunnerArguments provides connection details when a user connects to the agent.

3.2 Define the system prompt

Add the following configuration below the imports:
This system prompt defines your agent’s personality. It can be as simple or complex as you like. Later in the guide, you’ll see an example of a detailed system prompt that fully customizes the agent’s behavior.

3.3 Code the conversation pipeline

First, tell the runner how to configure the transport. Add the following below the system prompt:
This dictionary maps transport names to their configuration. The webrtc entry enables audio input and output for the browser-based WebRTC transport that this guide uses. Next, add the following bot function to agent.py:
The Pipecat runner automatically discovers any function named bot in your module. When a user connects via WebRTC, the runner calls this function and passes connection details through runner_args. Inside the bot function, create the transport:
create_transport matches the incoming connection against your transport_params dictionary and builds the right transport for it. Next, add the AI services for transcription, response generation, and speech synthesis:
These configure OpenAI for STT and LLM responses, and Rime’s flagship coda model for TTS. RimeTTSService works with all current Rime models (coda, arcana, mistv3, mistv2). Add the conversation context:
This maintains the conversation history, so the LLM can reference previous messages. The user-side aggregator also runs Silero VAD to detect when the user starts and stops speaking. Add the pipeline that connects all the components:
Frames flow through the processors in order.
  1. Audio in: Raw microphone input from the user
  2. Transcription: Converting speech to text via the STT provider
  3. User context: Aggregating the user’s message into the conversation history
  4. LLM response: Generating a reply based on the conversation so far
  5. Speech synthesis: Converting the LLM’s text response to audio via Rime TTS
  6. Audio out: Streaming the synthesized speech back to the user
  7. Assistant context: Recording the assistant’s response in the conversation history
The context aggregator appears twice to capture both sides of the conversation. Finally, add the pipeline worker and an event handler for greeting the user:
The on_client_connected event fires when a user connects to the agent. It appends a system message prompting the LLM to greet the user, then queues an LLMRunFrame to trigger an immediate response.

3.4 Create the main entrypoint

Add the following code at the bottom of agent.py:
Pipecat’s main helper from pipecat.runner.run automatically:
  • Discovers the bot function in your module
  • Starts a FastAPI server with WebRTC endpoints
  • Serves a prebuilt browser client at /client
  • Sets up the WebRTC connection and passes the connection to your bot function
When you run the agent, Pipecat starts a local HTTP server. Open the browser client to connect via WebRTC. The server runs locally, but the agent makes API calls to OpenAI and Rime.

3.5 Full agent code

At this point, your agent.py file should look like the complete example below:

Step 4: Test your agent

The full pipeline is now ready for you to test. You can run the agent from the terminal using uv and interact with it in your browser.

4.1 Start the agent

Run the following command to start your agent:
You’ll see output indicating the server is starting.

4.2 Connect to your agent

Open a browser and navigate to http://localhost:7860/client. Allow microphone access when prompted. You can now talk to your agent using your microphone.

Step 5: Customize your agent

Now that your agent is running, you can experiment with different voices and personalities.

5.1 Change the voice

Update the tts initialization in your bot function to try a different voice:
Rime offers many voices with different personalities. See the full list on the Voices page.

5.2 Fine-tune agent personalities

Create a new file called personality.py with the following content:
Update your agent.py to import and use this prompt:
Then update the on_client_connected handler to use your custom intro message:
Keeping the system prompt in a separate file lets you change the character without editing the agent logic.

Swap agent components

Pipecat components can be replaced independently:
  • Replacing OpenAI with another STT provider, such as Deepgram or AssemblyAI
  • Using a different LLM, such as Anthropic, Gemini, or a local model
  • Switching transports to use WebSocket for server-to-server or Daily’s hosted rooms for production deployments
The Pipecat documentation covers transports, deployment patterns, and advanced features. View Rime’s Pipecat demo agents for a ready-to-use multilingual agent example that switches languages dynamically.

Troubleshooting

Use these checks for common setup failures.

No audio output and other TTS errors

  • Check your TTS service class: Use RimeTTSService. It supports all current Rime models (coda, arcana, mistv3, mistv2). The older RimeNonJsonTTSService is deprecated and will be removed in Pipecat 2.0.
  • Verify your Rime API key: Ensure the key is valid and has TTS permissions.

Import errors when starting the agent

  • Check your Pipecat version: Errors like No module named 'pipecat.processors.aggregators.openai_llm_context' mean you’re running code written for Pipecat 0.x on a 1.x install (or vice versa). This guide requires pipecat-ai 1.5 or later: the 1.0 release renamed OpenAILLMContext to LLMContext, replaced llm.create_context_aggregator() with LLMContextAggregatorPair, and moved VAD configuration from TransportParams to LLMUserAggregatorParams.

The agent doesn’t respond to speech

  • Check microphone permissions: Ensure you’ve enabled microphone access in your browser.
  • Verify VAD is working: Look for logs indicating speech detection. If the logs are missing, check your Silero installation.
  • Test audio input: Use a different microphone or headset.

”API key not set” errors

  • Check environment variables: Ensure you set all keys correctly (with no extra spaces) in .env.
  • Verify the .env file location: The file should be in the same directory as agent.py.

Audio quality issues

  • Check your microphone: Test using a different input device or headset.
  • Reduce background noise: The VAD may struggle to detect speech in noisy environments.