agentleFS
kumaran-iskumaran-is/claude-code-onboarding/.claude/skills/voice-ai-development/SKILL.md

voice-ai-development

Skill35 starsChanged 6 months agoMITView on GitHub

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.

  • Reads credentials
  • Installs packages
  • Sends data out

3 other projects use a version of this.

Adopted by

Most recently taken up by

The file

We split this skill into the rules it gives an agent

1 rule. 0 are common, 1 is distinctive, and 0 are very specific to this project.

  • 0

    Common

    Most of the 3 edited versions we read keep these.

  • 1

    Distinctive

    This author's own choices. Worth a look.

  • 0

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    After writing Gemini voice integration code, dispatch:

    line 212

“Common” is measured: kept by at least 6 in 10 of the 3 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

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 CaseThis Skillgemini-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

ScenarioModel
Production audiobook / podcastgemini-2.5-pro-tts-preview
Real-time assistant replygemini-2.5-flash-tts-preview
Multi-speaker dialogueEither (flash cheaper at scale)
Voice quality is demo-criticalgemini-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

  1. Choose modality — real-time streaming (Live API) vs batch TTS (TTS models)
  2. Load reference files — gemini-live-api.md for streaming; gemini-tts.md for TTS
  3. Pick framework — LangGraph (voice-langgraph-integration.md) or ADK (voice-adk-integration.md)
  4. Implement WebSocket transport — FastAPI WebSocket endpoint proxies audio bytes bidirectionally
  5. Add error handling — connection drops, rate limits, audio format validation (no silent failures)
  6. Test audio pipeline — verify raw PCM bytes received and playable before adding agent logic
  7. Dispatch reviewers — security-reviewer (API key handling), code-reviewer (error path coverage)

Key Patterns

PatternWhenReference
WebSocket proxy to Live APIReal-time browser-to-Gemini audiogemini-live-api.md
Barge-in handlingUser interrupts assistant mid-speechgemini-live-api.md
Multi-speaker TTSPodcast/dialogue with named speakersgemini-tts.md
LangGraph voice StateGraphTranscribe → LLM → Synthesize pipelinevoice-langgraph-integration.md
ADK SequentialAgent voiceADK-based transcription/response/synthesis agentsvoice-adk-integration.md
Style control via natural language"whispered mysterious tone", "enthusiastic Australian accent"gemini-tts.md
Mid-sentence language switchMultilingual TTS (70+ languages)gemini-tts.md
Multimodal voice + cameraLive API audio + video framesgemini-live-api.md

Documentation Sources

SourceURLPurpose
Live API overviewhttps://ai.google.dev/gemini-api/docs/live.md.txtWebSocket protocol, connection lifecycle
TTS overviewhttps://ai.google.dev/gemini-api/docs/speech.md.txtTTS models, voice config, multi-speaker
Audio understandinghttps://ai.google.dev/gemini-api/docs/audio.md.txtSending audio to Gemini
Models referencehttps://ai.google.dev/gemini-api/docs/models.md.txtCurrent model IDs and capabilities
Doc indexhttps://ai.google.dev/gemini-api/docs/llms.txtDiscover all doc pages
google-genai Python SDKhttps://googleapis.github.io/python-genai/SDK API reference

Reference Files

FileContents
reference/gemini-live-api.mdWebSocket setup, audio streaming, barge-in, multimodal, FastAPI proxy, LangGraph node
reference/gemini-tts.mdSingle/multi-speaker TTS, style control, language switching, streaming TTS, FastAPI endpoint
reference/voice-langgraph-integration.mdLangGraph StateGraph: transcribe → LLM → synthesize, FastAPI streaming endpoint
reference/voice-adk-integration.mdADK 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

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.