Skip to content

Build a realtime voice agent

A voice agent listens and talks at the same time: audio streams in while the model streams a reply out, the user can cut in mid-sentence, and tools run without pausing the conversation. Bidirectional streaming is the piece that makes this work. Instead of the request-then-response cycle of a standard agent, a BidiAgent holds a persistent connection to a realtime model and moves audio, text, and events across it continuously. This section covers building that agent, choosing a model provider that supports it, and handling the live stream.

The smallest real thing this section builds: a BidiAgent on a realtime model, reading from the microphone and playing back through the speakers. The run() loop streams audio both ways until you interrupt it.

import asyncio
from strands.experimental.bidi import BidiAgent, BidiAudioIO
from strands.experimental.bidi.models import BedrockNovaSonicModel
model = BedrockNovaSonicModel()
agent = BidiAgent(
model=model,
system_prompt="You are a helpful voice assistant. Keep replies short and natural.",
)
audio_io = BidiAudioIO()
async def main():
# Stream microphone audio in and speaker audio out until interrupted
await agent.run(inputs=[audio_io.input()], outputs=[audio_io.output()])
asyncio.run(main())

Bidirectional streaming is a Python-only experimental feature; install it with pip install "strands-agents[bidi-all]". The quickstart covers per-provider installs and credentials.

New here? Start with the quickstart to get a voice conversation running, then read BidiAgent to configure tools, prompts, and the connection lifecycle. Pick a model provider based on the provider you use and the session length you need.

Building for a server rather than a local machine? Read I/O channels to replace microphone-and-speaker I/O with your own transport, then streaming events and interruptions to drive the conversation from your own event loop.