
Building a Sub-Second Voice Agent with Gemini Omni Flash
Voice agents die if they have latency. I used Gemini Omni Flash to build a real-time conversational agent that responds in under 500 milliseconds.
Building a text-based chatbot is forgiving. If a model takes three seconds to type out a response, users don't mind. They are used to watching the typing indicator. Voice is entirely different. If you pause for three seconds during a phone call, the human on the other end assumes the call dropped and starts saying "Hello?"
To build a voice agent, you need raw speed. I tested the new Gemini Omni Flash model specifically because it was designed for ultra-low-latency multimodal tasks. This tutorial covers how to build a voice agent step-by-step that bypasses traditional transcription layers and responds in under 500 milliseconds.
The Latency Problem with Traditional Pipelines
If you build a voice agent using the standard stack, your pipeline looks like this:
- Speech-to-Text (STT): User speaks -> Stream audio to Whisper/Deepgram -> Wait for text transcription (200ms - 500ms).
- LLM Inference: Send text to GPT-4/Claude -> Wait for the first token of the response (500ms - 1000ms).
- Text-to-Speech (TTS): Stream the LLM text to ElevenLabs -> Wait for the first audio byte (200ms - 400ms).
Best case scenario, you are looking at 1 to 2 seconds of silence before the bot replies. Gemini Omni Flash changes this architecture. It natively understands audio inputs. You don't need the STT layer. You just stream the raw microphone bytes directly into the model's context window.
Here is how to build it, step-by-step.
Step 1: Install Dependencies
To follow along, you need Python 3.10+, a Google Gemini API Key, and a microphone attached to your machine. First, install the required libraries for interacting with the Google API and capturing local audio.
pip install google-genai pyaudio asyncio
Step 2: Configure the Microphone
We need to capture raw audio from the microphone. We will use pyaudio to handle the hardware interface. We configure it to capture 16kHz, 16-bit PCM audio, which is the standard format expected by most voice models.
import pyaudio
# Audio configuration constants
FORMAT = pyaudio.paInt16
CHANNELS = 1
RATE = 16000
CHUNK = 1024
def setup_microphone():
"""Initializes the PyAudio stream for microphone input."""
audio = pyaudio.PyAudio()
stream = audio.open(
format=FORMAT,
channels=CHANNELS,
rate=RATE,
input=True,
frames_per_buffer=CHUNK
)
return stream
Step 3: Capture the Audio Stream
In a production application, you would implement Voice Activity Detection (VAD) to only send audio when the user is speaking. For this tutorial, we will capture a fixed 3-second block of audio.
def capture_audio(stream, seconds=3):
"""Reads raw audio chunks from the microphone for a set duration."""
print(f"Listening for {seconds} seconds...")
frames = []
# Calculate how many chunks we need to read to hit our target duration
total_chunks = int(RATE / CHUNK * seconds)
for _ in range(0, total_chunks):
data = stream.read(CHUNK)
frames.append(data)
# Combine the chunks into a single byte string
return b''.join(frames)
Step 4: Stream to Gemini Omni Flash
Here is where the magic happens. We take the raw bytes from the microphone and hand them directly to the gemini-omni-flash model. We bypass transcription entirely.
import google.genai as genai
import asyncio
# Initialize the ultra-fast Omni Flash model client
client = genai.Client(api_key="YOUR_GEMINI_API_KEY")
MODEL_ID = 'gemini-omni-flash'
async def ask_gemini(audio_data):
"""Sends the raw audio payload to Gemini and awaits a text response."""
print("Sending raw audio to Omni Flash...")
response = await client.models.generate_content_async(
model=MODEL_ID,
contents=[
"You are a helpful voice assistant. Keep your response under two sentences. Reply naturally to the audio provided.",
{"mime_type": "audio/wav", "data": audio_data}
],
config={"temperature": 0.3}
)
print(f"Agent Reply: {response.text}")
return response.text
Step 5: Put It Together and Connect TTS
Now we wire the pieces together. When you run this, notice how quickly the text comes back. To complete the voice loop, you would stream this resulting text back into a fast TTS engine.
async def main():
# 1. Setup Mic
stream = setup_microphone()
# 2. Record
audio_data = capture_audio(stream)
# 3. Get LLM response instantly
text_reply = await ask_gemini(audio_data)
# 4. Stream to Text-to-Speech (Pseudo-code integration)
# tts_socket = await connect_elevenlabs()
# await tts_socket.send(text_reply)
# ... play response through speakers
if __name__ == "__main__":
asyncio.run(main())
Why This Architecture Wins
When you run this code, the speed is jarring. Because Omni Flash does not have to wait for an external STT model to process a temporary .wav file, the Time-to-First-Token (TTFT) drops drastically. The model starts generating the text response almost exactly when the audio stream ends.
By avoiding transcription, you also preserve the acoustic features of the user's voice. The model can hear tone, emotion, and background noise. If the user sounds angry, the model knows it immediately. If you are building an AI receptionist or a real-time language tutor, drop the transcription layer. Let the model listen.
Related reading
If your app already runs on Cloudflare, you can execute untrusted agent code right next to it — no separate container host or VPC. This builds an agent tool on the Cloudflare Sandbox SDK, from the Dockerfile and wrangler bindings to streamed output.
A locked-down container stops the obvious attacks. Here are the controls that stop a determined one: a non-root user, a tight seccomp profile, resource ulimits, a network egress allowlist, and a real kernel boundary with gVisor.
One-shot code execution can't build software. An autonomous coding agent needs a filesystem that survives across turns — to install dependencies, edit files, run the test suite, read the failures, and open a pull request. This builds that with a persistent E2B sandbox.
Let's build something great.
Have a project in mind? We are an elite software and AI development studio ready to bring your ideas to production. Let's talk about your roadmap.