Iron Law
ALWAYS USE WEBSOCKETS FOR LIVE API — NEVER POLLING; ALWAYS USE gemini-live-2.5-flash-native-audio FOR REAL-TIME, gemini-2.5-pro-tts-preview OR gemini-2.5-flash-tts-preview FOR TTS
Voice AI Development — Gemini Live API + TTS
When to Use This Skill
| Use Case |
This Skill |
gemini-api-dev skill |
| Real-time voice streaming |
✅ |
❌ |
| Barge-in / interrupt detection |
✅ |
❌ |
| Sub-second voice latency (<600ms) |
✅ |
❌ |
| Text-to-speech synthesis |
✅ |
❌ |
| Multi-speaker podcast/dialogue TTS |
✅ |
❌ |
| Voice + camera multimodal |
✅ |
❌ |
| LangGraph voice agent pipeline |
✅ |
❌ |
| ADK voice agent |
✅ |
❌ |
| Standard text/multimodal calls |
❌ |
✅ |
Models
Live API (Real-time Voice)
gemini-live-2.5-flash-native-audio — Primary model for real-time voice. Sub-second latency (~600ms). Barge-in, affective dialogue, multimodal (audio + camera). Always use this for real-time.
TTS Models
gemini-2.5-pro-tts-preview — Highest fidelity. Use for audiobooks, podcasts, production voiceovers.
gemini-2.5-flash-tts-preview — Faster and cheaper. Use for real-time TTS responses, e-learning, notifications.
TTS Model Selection Guide
| Scenario |
Model |
| Production audiobook / podcast |
gemini-2.5-pro-tts-preview |
| Real-time assistant reply |
gemini-2.5-flash-tts-preview |
| Multi-speaker dialogue |
Either (flash cheaper at scale) |
| Voice quality is demo-critical |
gemini-2.5-pro-tts-preview |
Preset Voices (Live API)
Available: Aoede, Lyra, Orion (5–8 distinct steerable voices total)
- Style transfer: can mimic speaking patterns and emotions
- Cannot clone custom/external voices
SDK
# Python — ALWAYS use google-genai, NEVER google-generativeai (deprecated)
uv add google-genai
# Verify
python -c "import google.genai; print(google.genai.__version__)"
Quick Scaffold
Live API — Real-time Voice (FastAPI WebSocket)
# See reference/gemini-live-api.md for full implementation
from google import genai
from google.genai import types
import asyncio
client = genai.Client()
async def stream_voice():
config = types.LiveConnectConfig(
response_modalities=["AUDIO"],
speech_config=types.SpeechConfig(
voice_config=types.VoiceConfig(
prebuilt_voice_config=types.PrebuiltVoiceConfig(voice_name="Aoede")
)
),
)
async with client.aio.live.connect(
model="gemini-live-2.5-flash-native-audio",
config=config
) as session:
await session.send(input="Hello, how can I help?", end_of_turn=True)
async for response in session.receive():
if response.data:
yield response.data # raw PCM bytes
TTS — Single Speaker
# See reference/gemini-tts.md for full implementation
from google import genai
client = genai.Client()
response = client.models.generate_content(
model="gemini-2.5-flash-tts-preview",
contents="Say this in a warm, friendly tone: Hello and welcome!",
config={"response_modalities": ["AUDIO"]},
)
audio_bytes = response.candidates[0].content.parts[0].inline_data.data
Process
- Choose modality — real-time streaming (Live API) vs batch TTS (TTS models)
- Load reference files —
gemini-live-api.md for streaming; gemini-tts.md for TTS
- Pick framework — LangGraph (
voice-langgraph-integration.md) or ADK (voice-adk-integration.md)
- Implement WebSocket transport — FastAPI WebSocket endpoint proxies audio bytes bidirectionally
- Add error handling — connection drops, rate limits, audio format validation (no silent failures)
- Test audio pipeline — verify raw PCM bytes received and playable before adding agent logic
- Dispatch reviewers —
security-reviewer (API key handling), code-reviewer (error path coverage)
Key Patterns
| Pattern |
When |
Reference |
| WebSocket proxy to Live API |
Real-time browser-to-Gemini audio |
gemini-live-api.md |
| Barge-in handling |
User interrupts assistant mid-speech |
gemini-live-api.md |
| Multi-speaker TTS |
Podcast/dialogue with named speakers |
gemini-tts.md |
| LangGraph voice StateGraph |
Transcribe → LLM → Synthesize pipeline |
voice-langgraph-integration.md |
| ADK SequentialAgent voice |
ADK-based transcription/response/synthesis agents |
voice-adk-integration.md |
| Style control via natural language |
"whispered mysterious tone", "enthusiastic Australian accent" |
gemini-tts.md |
| Mid-sentence language switch |
Multilingual TTS (70+ languages) |
gemini-tts.md |
| Multimodal voice + camera |
Live API audio + video frames |
gemini-live-api.md |
Documentation Sources
| Source |
URL |
Purpose |
| Live API overview |
https://ai.google.dev/gemini-api/docs/live.md.txt |
WebSocket protocol, connection lifecycle |
| TTS overview |
https://ai.google.dev/gemini-api/docs/speech.md.txt |
TTS models, voice config, multi-speaker |
| Audio understanding |
https://ai.google.dev/gemini-api/docs/audio.md.txt |
Sending audio to Gemini |
| Models reference |
https://ai.google.dev/gemini-api/docs/models.md.txt |
Current model IDs and capabilities |
| Doc index |
https://ai.google.dev/gemini-api/docs/llms.txt |
Discover all doc pages |
| google-genai Python SDK |
https://googleapis.github.io/python-genai/ |
SDK API reference |
Reference Files
| File |
Contents |
reference/gemini-live-api.md |
WebSocket setup, audio streaming, barge-in, multimodal, FastAPI proxy, LangGraph node |
reference/gemini-tts.md |
Single/multi-speaker TTS, style control, language switching, streaming TTS, FastAPI endpoint |
reference/voice-langgraph-integration.md |
LangGraph StateGraph: transcribe → LLM → synthesize, FastAPI streaming endpoint |
reference/voice-adk-integration.md |
ADK LlmAgent + SequentialAgent voice pipeline, FunctionTool audio processing, FastAPI runner |
Common Commands
# Install SDK
uv add google-genai
# Set API key (get from aistudio.google.com)
export GOOGLE_API_KEY=your_key_here
# Run FastAPI voice server
uvicorn main:app --reload --port 8000
# Test WebSocket connection (requires wscat: npm install -g wscat)
wscat -c ws://localhost:8000/ws/voice
# Test TTS endpoint
curl -X POST http://localhost:8000/tts \
-H "Content-Type: application/json" \
-d '{"text": "Hello world", "model": "gemini-2.5-flash-tts-preview"}' \
--output output.wav
# Check SDK version
python -c "import google.genai; print(google.genai.__version__)"
Error Handling
Connection drop (Live API WebSocket):
→ Catch asyncio.CancelledError and websockets.exceptions.ConnectionClosed
→ Log error with session context
→ Re-raise — do NOT silently reconnect without user awareness
Rate limit (429):
→ Log warning with retry-after header value
→ Implement exponential backoff (1s, 2s, 4s, max 32s)
→ Raise RateLimitError after max retries
Audio format error:
→ Validate input: PCM 16-bit, 16kHz, mono for Live API
→ Log format mismatch with received vs expected
→ Raise AudioFormatError — do NOT attempt to play malformed audio
Content policy block:
→ Log blocked content category (never log the content itself)
→ Return error state to caller — do NOT return silence as if successful
API key / auth (401):
→ Check GOOGLE_API_KEY env var is set
→ Log "API key missing or invalid" — never log the key value
→ Raise AuthenticationError immediately — no retry
Post-Code Review
After writing Gemini voice integration code, dispatch:
security-reviewer — API key handling, no keys in code, audio data sanitization
code-reviewer — WebSocket lifecycle, error path coverage, no silent failures
1---2name: voice-ai-development3description: Gemini voice AI development — real-time voice streaming with Gemini Live API (WebSocket), text-to-speech with Gemini TTS models, LangGraph voice agent pipelines, and Google ADK voice agents. Use when building voice assistants, real-time audio streaming, TTS synthesis, or multimodal voice applications.4---56## Iron Law78**ALWAYS USE WEBSOCKETS FOR LIVE API — NEVER POLLING; ALWAYS USE gemini-live-2.5-flash-native-audio FOR REAL-TIME, gemini-2.5-pro-tts-preview OR gemini-2.5-flash-tts-preview FOR TTS**910# Voice AI Development — Gemini Live API + TTS1112## When to Use This Skill1314| Use Case | This Skill | gemini-api-dev skill |15|----------|-----------|---------------------|16| Real-time voice streaming | ✅ | ❌ |17| Barge-in / interrupt detection | ✅ | ❌ |18| Sub-second voice latency (<600ms) | ✅ | ❌ |19| Text-to-speech synthesis | ✅ | ❌ |20| Multi-speaker podcast/dialogue TTS | ✅ | ❌ |21| Voice + camera multimodal | ✅ | ❌ |22| LangGraph voice agent pipeline | ✅ | ❌ |23| ADK voice agent | ✅ | ❌ |24| Standard text/multimodal calls | ❌ | ✅ |2526## Models2728### Live API (Real-time Voice)29- **`gemini-live-2.5-flash-native-audio`** — Primary model for real-time voice. Sub-second latency (~600ms). Barge-in, affective dialogue, multimodal (audio + camera). **Always use this for real-time.**3031### TTS Models32- **`gemini-2.5-pro-tts-preview`** — Highest fidelity. Use for audiobooks, podcasts, production voiceovers.33- **`gemini-2.5-flash-tts-preview`** — Faster and cheaper. Use for real-time TTS responses, e-learning, notifications.3435### TTS Model Selection Guide3637| Scenario | Model |38|----------|-------|39| Production audiobook / podcast | `gemini-2.5-pro-tts-preview` |40| Real-time assistant reply | `gemini-2.5-flash-tts-preview` |41| Multi-speaker dialogue | Either (flash cheaper at scale) |42| Voice quality is demo-critical | `gemini-2.5-pro-tts-preview` |4344## Preset Voices (Live API)4546Available: **Aoede**, **Lyra**, **Orion** (5–8 distinct steerable voices total)4748- Style transfer: can mimic speaking patterns and emotions49- Cannot clone custom/external voices5051## SDK5253```bash54# Python — ALWAYS use google-genai, NEVER google-generativeai (deprecated)55uv add google-genai5657# Verify58python -c "import google.genai; print(google.genai.__version__)"59```6061## Quick Scaffold6263### Live API — Real-time Voice (FastAPI WebSocket)64```python65# See reference/gemini-live-api.md for full implementation66from google import genai67from google.genai import types68import asyncio6970client = genai.Client()7172async def stream_voice():73 config = types.LiveConnectConfig(74 response_modalities=["AUDIO"],75 speech_config=types.SpeechConfig(76 voice_config=types.VoiceConfig(77 prebuilt_voice_config=types.PrebuiltVoiceConfig(voice_name="Aoede")78 )79 ),80 )81 async with client.aio.live.connect(82 model="gemini-live-2.5-flash-native-audio",83 config=config84 ) as session:85 await session.send(input="Hello, how can I help?", end_of_turn=True)86 async for response in session.receive():87 if response.data:88 yield response.data # raw PCM bytes89```9091### TTS — Single Speaker92```python93# See reference/gemini-tts.md for full implementation94from google import genai9596client = genai.Client()97response = client.models.generate_content(98 model="gemini-2.5-flash-tts-preview",99 contents="Say this in a warm, friendly tone: Hello and welcome!",100 config={"response_modalities": ["AUDIO"]},101)102audio_bytes = response.candidates[0].content.parts[0].inline_data.data103```104105## Process1061071. **Choose modality** — real-time streaming (Live API) vs batch TTS (TTS models)1082. **Load reference files** — `gemini-live-api.md` for streaming; `gemini-tts.md` for TTS1093. **Pick framework** — LangGraph (`voice-langgraph-integration.md`) or ADK (`voice-adk-integration.md`)1104. **Implement WebSocket transport** — FastAPI WebSocket endpoint proxies audio bytes bidirectionally1115. **Add error handling** — connection drops, rate limits, audio format validation (no silent failures)1126. **Test audio pipeline** — verify raw PCM bytes received and playable before adding agent logic1137. **Dispatch reviewers** — `security-reviewer` (API key handling), `code-reviewer` (error path coverage)114115## Key Patterns116117| Pattern | When | Reference |118|---------|------|-----------|119| WebSocket proxy to Live API | Real-time browser-to-Gemini audio | `gemini-live-api.md` |120| Barge-in handling | User interrupts assistant mid-speech | `gemini-live-api.md` |121| Multi-speaker TTS | Podcast/dialogue with named speakers | `gemini-tts.md` |122| LangGraph voice StateGraph | Transcribe → LLM → Synthesize pipeline | `voice-langgraph-integration.md` |123| ADK SequentialAgent voice | ADK-based transcription/response/synthesis agents | `voice-adk-integration.md` |124| Style control via natural language | "whispered mysterious tone", "enthusiastic Australian accent" | `gemini-tts.md` |125| Mid-sentence language switch | Multilingual TTS (70+ languages) | `gemini-tts.md` |126| Multimodal voice + camera | Live API audio + video frames | `gemini-live-api.md` |127128## Documentation Sources129130| Source | URL | Purpose |131|--------|-----|---------|132| Live API overview | `https://ai.google.dev/gemini-api/docs/live.md.txt` | WebSocket protocol, connection lifecycle |133| TTS overview | `https://ai.google.dev/gemini-api/docs/speech.md.txt` | TTS models, voice config, multi-speaker |134| Audio understanding | `https://ai.google.dev/gemini-api/docs/audio.md.txt` | Sending audio to Gemini |135| Models reference | `https://ai.google.dev/gemini-api/docs/models.md.txt` | Current model IDs and capabilities |136| Doc index | `https://ai.google.dev/gemini-api/docs/llms.txt` | Discover all doc pages |137| google-genai Python SDK | `https://googleapis.github.io/python-genai/` | SDK API reference |138139## Reference Files140141| File | Contents |142|------|----------|143| `reference/gemini-live-api.md` | WebSocket setup, audio streaming, barge-in, multimodal, FastAPI proxy, LangGraph node |144| `reference/gemini-tts.md` | Single/multi-speaker TTS, style control, language switching, streaming TTS, FastAPI endpoint |145| `reference/voice-langgraph-integration.md` | LangGraph StateGraph: transcribe → LLM → synthesize, FastAPI streaming endpoint |146| `reference/voice-adk-integration.md` | ADK LlmAgent + SequentialAgent voice pipeline, FunctionTool audio processing, FastAPI runner |147148## Common Commands149150```bash151# Install SDK152uv add google-genai153154# Set API key (get from aistudio.google.com)155export GOOGLE_API_KEY=your_key_here156157# Run FastAPI voice server158uvicorn main:app --reload --port 8000159160# Test WebSocket connection (requires wscat: npm install -g wscat)161wscat -c ws://localhost:8000/ws/voice162163# Test TTS endpoint164curl -X POST http://localhost:8000/tts \165 -H "Content-Type: application/json" \166 -d '{"text": "Hello world", "model": "gemini-2.5-flash-tts-preview"}' \167 --output output.wav168169# Check SDK version170python -c "import google.genai; print(google.genai.__version__)"171```172173## Error Handling174175```176Connection drop (Live API WebSocket):177 → Catch asyncio.CancelledError and websockets.exceptions.ConnectionClosed178 → Log error with session context179 → Re-raise — do NOT silently reconnect without user awareness180181Rate limit (429):182 → Log warning with retry-after header value183 → Implement exponential backoff (1s, 2s, 4s, max 32s)184 → Raise RateLimitError after max retries185186Audio format error:187 → Validate input: PCM 16-bit, 16kHz, mono for Live API188 → Log format mismatch with received vs expected189 → Raise AudioFormatError — do NOT attempt to play malformed audio190191Content policy block:192 → Log blocked content category (never log the content itself)193 → Return error state to caller — do NOT return silence as if successful194195API key / auth (401):196 → Check GOOGLE_API_KEY env var is set197 → Log "API key missing or invalid" — never log the key value198 → Raise AuthenticationError immediately — no retry199```200201## Post-Code Review202203After writing Gemini voice integration code, dispatch:204- `security-reviewer` — API key handling, no keys in code, audio data sanitization205- `code-reviewer` — WebSocket lifecycle, error path coverage, no silent failures