Esta es una guía integral que abarca las capacidades y configuraciones disponibles con la API de Live. Consulta la página Comienza a usar la API de Live para obtener una descripción general y código de muestra para casos de uso comunes.
Antes de comenzar
- Familiarízate con los conceptos básicos: Si aún no lo hiciste, primero lee la página Comienza a usar la API de Live . En esta guía, se presentan los principios fundamentales de la API de Live, cómo funciona y los diferentes enfoques de implementación.
- Prueba la API en vivo en AI Studio: Puede ser útil probar la API en vivo en Google AI Studio antes de comenzar a compilar. Para usar la API de Live en Google AI Studio, selecciona Stream.
Comparación de modelos
En la siguiente tabla, se resumen las diferencias clave entre los modelos Gemini 3.8 Live, Gemini 3.8 Live Extended Thinking y Gemini 3.1 Flash Live Preview:
| Función | Gemini 3.8 Live | Gemini 3.8 Live Extended Thinking | Versión preliminar de Gemini 3.1 Flash Live |
|---|---|---|---|
| Recomendado para | Es la opción predeterminada para la mayoría de las experiencias de agentes de voz de baja latencia. | Se recomienda cuando se requiere un razonamiento en segundo plano más profundo. | Es el modelo de vista previa heredado. Te recomendamos que actualices a Gemini 3.8 Live. |
| Pensamiento | Compatible (razonamiento intercalado). thinkingLevel no es compatible (omítelo de la configuración). |
Compatible. Razonamiento en segundo plano configurable (thinkingLevel: low, medium, high; no se admite minimal). |
Usa thinkingLevel para controlar la profundidad del pensamiento con parámetros de configuración como minimal, low, medium y high. El valor predeterminado es minimal para optimizar la latencia más baja. Consulta Cómo pensar en la API de Live. |
| Recepción de la respuesta | Un solo evento del servidor puede contener varias partes de contenido de forma simultánea. | Un solo evento del servidor puede contener varias partes de contenido de forma simultánea. Cuando el razonamiento asíncrono está activo, turnComplete: true no indica una sesión inactiva. Usa interaction_status (IN_PROGRESS en lugar de IDLE). |
Un solo evento del servidor puede contener varias partes de contenido de forma simultánea (por ejemplo, inlineData y transcripción). Asegúrate de que tu código procese todas las partes de cada evento para no perder contenido. |
| Contenido del cliente | send_client_content se admite durante todo el ciclo de vida de la sesión con roles explícitos (user o model). turn_complete=true interrumpe la generación de forma incondicional. |
send_client_content se admite durante todo el ciclo de vida de la sesión con roles explícitos (user o model). turn_complete=true interrumpe la generación de forma incondicional. |
send_client_content se admite durante todo el ciclo de vida de la sesión con roles explícitos (user o model). turn_complete=true interrumpe la generación de forma incondicional. |
Llamada a función asíncrona (behavior: NON_BLOCKING) |
Compatible (predeterminado). Establece behavior: NON_BLOCKING o usa el modo de bloqueo retrocompatible con behavior: BLOCKING. Se admite la programación de funciones (SILENT, WHEN_IDLE, INTERRUPTED). |
Admitido (solo de forma asíncrona). Solo se admite la ejecución de NON_BLOCKING. No se admiten el modo de bloqueo ni la programación de funciones. |
No compatible. La llamada a función solo es secuencial. El modelo no comenzará a responder hasta que envíes la respuesta de la herramienta. |
Para migrar a Gemini 3.8 Live, consulta la guía de migración. Para obtener más información sobre Thinking, consulta la guía de Thinking y la guía de actualización.
Cómo establecer una conexión
En el siguiente ejemplo, se muestra cómo crear una conexión con una clave de API:
Python
import asyncio
from google import genai
client = genai.Client()
model = "gemini-3.8-live"
config = {"response_modalities": ["AUDIO"]}
async def main():
async with client.aio.live.connect(model=model, config=config) as session:
print("Session started")
# Send content...
if __name__ == "__main__":
asyncio.run(main())
JavaScript
import { GoogleGenAI, Modality } from '@google/genai';
const ai = new GoogleGenAI({});
const model = 'gemini-3.8-live';
const config = { responseModalities: [Modality.AUDIO] };
async function main() {
const session = await ai.live.connect({
model: model,
callbacks: {
onopen: function () {
console.debug('Opened');
},
onmessage: function (message) {
console.debug(message);
},
onerror: function (e) {
console.debug('Error:', e.message);
},
onclose: function (e) {
console.debug('Close:', e.reason);
},
},
config: config,
});
console.debug("Session started");
// Send content...
session.close();
}
main();
Modalidades de interacción
En las siguientes secciones, se proporcionan ejemplos y contexto de respaldo para las diferentes modalidades de entrada y salida disponibles en la API de Live.
Cómo enviar audio
El audio debe enviarse como datos PCM sin procesar (audio PCM sin procesar de 16 bits, 16 kHz, little-endian).
Python
# Assuming 'chunk' is your raw PCM audio bytes
await session.send_realtime_input(
audio=types.Blob(
data=chunk,
mime_type="audio/pcm;rate=16000"
)
)
JavaScript
// Assuming 'chunk' is a Buffer of raw PCM audio
session.sendRealtimeInput({
audio: {
data: chunk.toString('base64'),
mimeType: 'audio/pcm;rate=16000'
}
});
Formatos de audio
Los datos de audio en la API de Live siempre son PCM sin procesar, little-endian y de 16 bits. La salida de audio siempre usa una frecuencia de muestreo de 24 kHz. El audio de entrada es de 16 kHz de forma nativa, pero la API de Live volverá a muestrear si es necesario, por lo que se puede enviar cualquier frecuencia de muestreo. Para transmitir la tasa de muestreo del audio de entrada, establece el tipo de MIME de cada Blob que contenga audio en un valor como audio/pcm;rate=16000.
Cómo recibir audio
Las respuestas de audio del modelo se reciben como fragmentos de datos.
Python
async for response in session.receive():
if response.server_content and response.server_content.model_turn:
for part in response.server_content.model_turn.parts:
if part.inline_data:
audio_data = part.inline_data.data
# Process or play the audio data
JavaScript
// Inside the onmessage callback
const content = response.serverContent;
if (content?.modelTurn?.parts) {
for (const part of content.modelTurn.parts) {
if (part.inlineData) {
const audioData = part.inlineData.data;
// Process or play audioData (base64 encoded string)
}
}
}
Enviando mensaje de texto
El texto se puede enviar con send_realtime_input (Python) o sendRealtimeInput (JavaScript).
Python
await session.send_realtime_input(text="Hello, how are you?")
JavaScript
session.sendRealtimeInput({
text: 'Hello, how are you?'
});
Enviando video
Los fotogramas de video se envían como imágenes individuales (p.ej., JPEG o PNG) a una velocidad de fotogramas específica (máximo 1 fotograma por segundo).
Python
# Assuming 'frame' is your JPEG-encoded image bytes
await session.send_realtime_input(
video=types.Blob(
data=frame,
mime_type="image/jpeg"
)
)
JavaScript
// Assuming 'frame' is a Buffer of JPEG-encoded image data
session.sendRealtimeInput({
video: {
data: frame.toString('base64'),
mimeType: 'image/jpeg'
}
});
Actualizaciones incrementales de contenido
Usa actualizaciones incrementales para enviar entradas de texto, establecer el contexto de la sesión o restablecer el contexto de la sesión. En el caso de contextos breves, puedes enviar interacciones paso a paso para representar la secuencia exacta de eventos:
Python
turns = [
{"role": "user", "parts": [{"text": "What is the capital of France?"}]},
{"role": "model", "parts": [{"text": "Paris"}]},
]
await session.send_client_content(turns=turns, turn_complete=False)
turns = [{"role": "user", "parts": [{"text": "What is the capital of Germany?"}]}]
await session.send_client_content(turns=turns, turn_complete=True)
JavaScript
let inputTurns = [
{ "role": "user", "parts": [{ "text": "What is the capital of France?" }] },
{ "role": "model", "parts": [{ "text": "Paris" }] },
]
session.sendClientContent({ turns: inputTurns, turnComplete: false })
inputTurns = [{ "role": "user", "parts": [{ "text": "What is the capital of Germany?" }] }]
session.sendClientContent({ turns: inputTurns, turnComplete: true })
Para contextos más largos, se recomienda proporcionar un solo resumen del mensaje para liberar la ventana de contexto para las interacciones posteriores. Consulta Reanudación de sesión para conocer otro método para cargar el contexto de la sesión.
Transcripción de audio
Además de la respuesta del modelo, también puedes recibir transcripciones de la entrada y la salida de audio.
Para habilitar la transcripción del audio de salida del modelo, envía output_audio_transcription en la configuración. El idioma de transcripción se infiere de la respuesta del modelo.
Python
import asyncio
from google import genai
from google.genai import types
client = genai.Client()
model = "gemini-3.8-live"
config = {
"response_modalities": ["AUDIO"],
"output_audio_transcription": {}
}
async def main():
async with client.aio.live.connect(model=model, config=config) as session:
message = "Hello? Gemini are you there?"
await session.send_client_content(
turns={"role": "user", "parts": [{"text": message}]}, turn_complete=True
)
async for response in session.receive():
if response.server_content.model_turn:
print("Model turn:", response.server_content.model_turn)
if response.server_content.output_transcription:
print("Transcript:", response.server_content.output_transcription.text)
if __name__ == "__main__":
asyncio.run(main())
JavaScript
import { GoogleGenAI, Modality } from '@google/genai';
const ai = new GoogleGenAI({});
const model = 'gemini-3.8-live';
const config = {
responseModalities: [Modality.AUDIO],
outputAudioTranscription: {}
};
async function live() {
const responseQueue = [];
async function waitMessage() {
let done = false;
let message = undefined;
while (!done) {
message = responseQueue.shift();
if (message) {
done = true;
} else {
await new Promise((resolve) => setTimeout(resolve, 100));
}
}
return message;
}
async function handleTurn() {
const turns = [];
let done = false;
while (!done) {
const message = await waitMessage();
turns.push(message);
if (message.serverContent && message.serverContent.turnComplete) {
done = true;
}
}
return turns;
}
const session = await ai.live.connect({
model: model,
callbacks: {
onopen: function () {
console.debug('Opened');
},
onmessage: function (message) {
responseQueue.push(message);
},
onerror: function (e) {
console.debug('Error:', e.message);
},
onclose: function (e) {
console.debug('Close:', e.reason);
},
},
config: config,
});
const inputTurns = 'Hello how are you?';
session.sendClientContent({ turns: inputTurns });
const turns = await handleTurn();
for (const turn of turns) {
if (turn.serverContent && turn.serverContent.outputTranscription) {
console.debug('Received output transcription: %s\n', turn.serverContent.outputTranscription.text);
}
}
session.close();
}
async function main() {
await live().catch((e) => console.error('got error', e));
}
main();
Para habilitar la transcripción de la entrada de audio del modelo, envía input_audio_transcription en la configuración.
Python
import asyncio
from pathlib import Path
from google import genai
from google.genai import types
client = genai.Client()
model = "gemini-3.8-live"
config = {
"response_modalities": ["AUDIO"],
"input_audio_transcription": {},
}
async def main():
async with client.aio.live.connect(model=model, config=config) as session:
audio_data = Path("16000.pcm").read_bytes()
await session.send_realtime_input(
audio=types.Blob(data=audio_data, mime_type='audio/pcm;rate=16000')
)
async for msg in session.receive():
if msg.server_content.input_transcription:
print('Transcript:', msg.server_content.input_transcription.text)
if __name__ == "__main__":
asyncio.run(main())
JavaScript
import { GoogleGenAI, Modality } from '@google/genai';
import * as fs from "node:fs";
import pkg from 'wavefile';
const { WaveFile } = pkg;
const ai = new GoogleGenAI({});
const model = 'gemini-3.8-live';
const config = {
responseModalities: [Modality.AUDIO],
inputAudioTranscription: {}
};
async function live() {
const responseQueue = [];
async function waitMessage() {
let done = false;
let message = undefined;
while (!done) {
message = responseQueue.shift();
if (message) {
done = true;
} else {
await new Promise((resolve) => setTimeout(resolve, 100));
}
}
return message;
}
async function handleTurn() {
const turns = [];
let done = false;
while (!done) {
const message = await waitMessage();
turns.push(message);
if (message.serverContent && message.serverContent.turnComplete) {
done = true;
}
}
return turns;
}
const session = await ai.live.connect({
model: model,
callbacks: {
onopen: function () {
console.debug('Opened');
},
onmessage: function (message) {
responseQueue.push(message);
},
onerror: function (e) {
console.debug('Error:', e.message);
},
onclose: function (e) {
console.debug('Close:', e.reason);
},
},
config: config,
});
// Send Audio Chunk
const fileBuffer = fs.readFileSync("16000.wav");
// Ensure audio conforms to API requirements (16-bit PCM, 16kHz, mono)
const wav = new WaveFile();
wav.fromBuffer(fileBuffer);
wav.toSampleRate(16000);
wav.toBitDepth("16");
const base64Audio = wav.toBase64();
// If already in correct format, you can use this:
// const fileBuffer = fs.readFileSync("sample.pcm");
// const base64Audio = Buffer.from(fileBuffer).toString('base64');
session.sendRealtimeInput(
{
audio: {
data: base64Audio,
mimeType: "audio/pcm;rate=16000"
}
}
);
const turns = await handleTurn();
for (const turn of turns) {
if (turn.text) {
console.debug('Received text: %s\n', turn.text);
}
else if (turn.data) {
console.debug('Received inline data: %s\n', turn.data);
}
else if (turn.serverContent && turn.serverContent.inputTranscription) {
console.debug('Received input transcription: %s\n', turn.serverContent.inputTranscription.text);
}
}
session.close();
}
async function main() {
await live().catch((e) => console.error('got error', e));
}
main();
Cómo cambiar la voz y el idioma
Los modelos de salida de audio nativa admiten cualquiera de las voces disponibles para nuestros modelos de texto a voz (TTS). Puedes escuchar todas las voces en AI Studio.
Para especificar una voz, configura el nombre de la voz dentro del objeto speechConfig como parte de la configuración de la sesión:
Python
config = {
"response_modalities": ["AUDIO"],
"speech_config": {
"voice_config": {"prebuilt_voice_config": {"voice_name": "Kore"}}
},
}
JavaScript
const config = {
responseModalities: [Modality.AUDIO],
speechConfig: { voiceConfig: { prebuiltVoiceConfig: { voiceName: "Kore" } } }
};
La API de Live admite varios idiomas. Los modelos de salida de audio nativa eligen automáticamente el idioma adecuado y no admiten la configuración explícita del código de idioma.
Capacidades de audio nativas
Nuestros modelos más recientes incluyen la salida de audio nativa, que proporciona un habla natural y realista, y un mejor rendimiento multilingüe.
Pensar
Los modelos Gemini 3.8 Live Extended Thinking y Gemini 3.1 usan thinkingLevel para controlar la profundidad del pensamiento. Para gemini-3.8-live, no se admite thinkingLevel y se debe omitir en la configuración. Gemini 3.8 Live Extended Thinking admite low, medium y high (no se admite minimal). Los modelos de Gemini 3.1 admiten minimal, low, medium y high. Para obtener más detalles, consulta Cómo pensar en la API de Live.
Python
model = "gemini-3.8-live-extended-thinking"
config = types.LiveConnectConfig(
response_modalities=["AUDIO"]
thinking_config=types.ThinkingConfig(
thinking_level="low",
)
)
async with client.aio.live.connect(model=model, config=config) as session:
# Send audio input and receive audio
JavaScript
const model = 'gemini-3.8-live-extended-thinking';
const config = {
responseModalities: [Modality.AUDIO],
thinkingConfig: {
thinkingLevel: 'low',
},
};
async function main() {
const session = await ai.live.connect({
model: model,
config: config,
callbacks: ...,
});
// Send audio input and receive audio
session.close();
}
main();
Además, puedes habilitar los resúmenes de pensamientos estableciendo includeThoughts en true en tu configuración. Consulta los resúmenes de pensamientos para obtener más información:
Python
model = "gemini-3.8-live-extended-thinking"
config = types.LiveConnectConfig(
response_modalities=["AUDIO"]
thinking_config=types.ThinkingConfig(
thinking_level="low",
include_thoughts=True
)
)
JavaScript
const model = 'gemini-3.8-live-extended-thinking';
const config = {
responseModalities: [Modality.AUDIO],
thinkingConfig: {
thinkingLevel: 'low',
includeThoughts: true,
},
};
Diálogo basado en emociones detectadas
Esta función permite que Gemini adapte el estilo de su respuesta al tono y la expresión de entrada.
Para usar el diálogo afectivo, establece la versión de la API en v1beta y configura enable_affective_dialog en true en el mensaje de configuración:
Python
client = genai.Client(http_options={"api_version": "v1beta"})
config = types.LiveConnectConfig(
response_modalities=["AUDIO"],
enable_affective_dialog=True
)
JavaScript
const ai = new GoogleGenAI({ httpOptions: {"apiVersion": "v1beta"} });
const config = {
responseModalities: [Modality.AUDIO],
enableAffectiveDialog: true
};
Audio proactivo
Cuando esta función está habilitada, Gemini puede decidir de forma proactiva no responder si el contenido no es pertinente.
Para usarla, configura la versión de la API como v1beta, configura el campo proactivity en el mensaje de configuración y establece proactive_audio como true:
Python
client = genai.Client(http_options={"api_version": "v1beta"})
config = types.LiveConnectConfig(
response_modalities=["AUDIO"],
proactivity={'proactive_audio': True}
)
JavaScript
const ai = new GoogleGenAI({ httpOptions: {"apiVersion": "v1beta"} });
const config = {
responseModalities: [Modality.AUDIO],
proactivity: { proactiveAudio: true }
}
Traducción en vivo
La API de Live admite la traducción en tiempo real y de baja latencia de conversaciones habladas. Esta capacidad te permite crear aplicaciones de traducción de voz a voz en tiempo real.
Para obtener más información y ejemplos, consulta la guía de Live Translation.
Detección de actividad de voz (VAD)
La detección de actividad de voz (VAD) permite que el modelo reconozca cuando una persona está hablando. Esto es fundamental para crear conversaciones naturales, ya que permite que el usuario interrumpa el modelo en cualquier momento.
Cuando el VAD detecta una interrupción, se cancela y descarta la generación en curso. En el historial de la sesión, solo se conserva la información que ya se envió al cliente. Luego, el servidor envía un mensaje BidiGenerateContentServerContent para informar la interrupción.
Luego, el servidor de Gemini descarta cualquier llamada a función pendiente y envía un mensaje BidiGenerateContentServerContent con los IDs de las llamadas canceladas.
Python
async for response in session.receive():
if response.server_content.interrupted is True:
# The generation was interrupted
# If realtime playback is implemented in your application,
# you should stop playing audio and clear queued playback here.
JavaScript
const turns = await handleTurn();
for (const turn of turns) {
if (turn.serverContent && turn.serverContent.interrupted) {
// The generation was interrupted
// If realtime playback is implemented in your application,
// you should stop playing audio and clear queued playback here.
}
}
VAD automático
De forma predeterminada, el modelo realiza automáticamente la detección de voz en un flujo de entrada de audio continuo. El VAD se puede configurar con el campo realtimeInputConfig.automaticActivityDetection de la configuración de la instalación.
Cuando la transmisión de audio se pausa durante más de un segundo (por ejemplo, porque el usuario apagó el micrófono), se debe enviar un evento audioStreamEnd para vaciar el audio almacenado en caché. El cliente puede reanudar el envío de datos de audio en cualquier momento.
Python
# example audio file to try:
# URL = "https://storage.googleapis.com/generativeai-downloads/data/hello_are_you_there.pcm"
# !wget -q $URL -O sample.pcm
import asyncio
from pathlib import Path
from google import genai
from google.genai import types
client = genai.Client()
model = "gemini-3.8-live"
config = {"response_modalities": ["AUDIO"]}
async def main():
async with client.aio.live.connect(model=model, config=config) as session:
audio_bytes = Path("sample.pcm").read_bytes()
await session.send_realtime_input(
audio=types.Blob(data=audio_bytes, mime_type="audio/pcm;rate=16000")
)
# if stream gets paused, send:
# await session.send_realtime_input(audio_stream_end=True)
async for response in session.receive():
if response.text is not None:
print(response.text)
if __name__ == "__main__":
asyncio.run(main())
JavaScript
// example audio file to try:
// URL = "https://storage.googleapis.com/generativeai-downloads/data/hello_are_you_there.pcm"
// !wget -q $URL -O sample.pcm
import { GoogleGenAI, Modality } from '@google/genai';
import * as fs from "node:fs";
const ai = new GoogleGenAI({});
const model = 'gemini-3.8-live';
const config = { responseModalities: [Modality.AUDIO] };
async function live() {
const responseQueue = [];
async function waitMessage() {
let done = false;
let message = undefined;
while (!done) {
message = responseQueue.shift();
if (message) {
done = true;
} else {
await new Promise((resolve) => setTimeout(resolve, 100));
}
}
return message;
}
async function handleTurn() {
const turns = [];
let done = false;
while (!done) {
const message = await waitMessage();
turns.push(message);
if (message.serverContent && message.serverContent.turnComplete) {
done = true;
}
}
return turns;
}
const session = await ai.live.connect({
model: model,
callbacks: {
onopen: function () {
console.debug('Opened');
},
onmessage: function (message) {
responseQueue.push(message);
},
onerror: function (e) {
console.debug('Error:', e.message);
},
onclose: function (e) {
console.debug('Close:', e.reason);
},
},
config: config,
});
// Send Audio Chunk
const fileBuffer = fs.readFileSync("sample.pcm");
const base64Audio = Buffer.from(fileBuffer).toString('base64');
session.sendRealtimeInput(
{
audio: {
data: base64Audio,
mimeType: "audio/pcm;rate=16000"
}
}
);
// if stream gets paused, send:
// session.sendRealtimeInput({ audioStreamEnd: true })
const turns = await handleTurn();
for (const turn of turns) {
if (turn.text) {
console.debug('Received text: %s\n', turn.text);
}
else if (turn.data) {
console.debug('Received inline data: %s\n', turn.data);
}
}
session.close();
}
async function main() {
await live().catch((e) => console.error('got error', e));
}
main();
Con send_realtime_input, la API responderá al audio automáticamente según el VAD. Si bien send_client_content agrega mensajes al contexto del modelo en orden, send_realtime_input se optimiza para la capacidad de respuesta a expensas del orden determinístico.
Configuración automática del VAD
Para tener más control sobre la actividad del VAD, puedes configurar los siguientes parámetros. Consulta la referencia de la API para obtener más información.
Python
from google.genai import types
config = {
"response_modalities": ["AUDIO"],
"realtime_input_config": {
"automatic_activity_detection": {
"disabled": False, # default
"start_of_speech_sensitivity": types.StartSensitivity.START_SENSITIVITY_LOW,
"end_of_speech_sensitivity": types.EndSensitivity.END_SENSITIVITY_LOW,
"prefix_padding_ms": 20,
"silence_duration_ms": 100,
}
}
}
JavaScript
import { GoogleGenAI, Modality, StartSensitivity, EndSensitivity } from '@google/genai';
const config = {
responseModalities: [Modality.AUDIO],
realtimeInputConfig: {
automaticActivityDetection: {
disabled: false, // default
startOfSpeechSensitivity: StartSensitivity.START_SENSITIVITY_LOW,
endOfSpeechSensitivity: EndSensitivity.END_SENSITIVITY_LOW,
prefixPaddingMs: 20,
silenceDurationMs: 100,
}
}
};
VAD híbrido
El VAD híbrido combina los beneficios del VAD automático (detección robusta del inicio del habla) y el VAD manual (finalización de la respuesta de baja latencia).
En esta configuración, se dan las siguientes situaciones:
- La opción Automatic VAD remains enabled permanece habilitada en el servidor. El servidor detecta automáticamente el inicio del habla del usuario con un relleno de prefijo para evitar que se corte el comienzo de las expresiones.
- El cliente usa un VAD del cliente para detectar cuándo el usuario deja de hablar.
- Cuando el VAD del cliente detecta el final del discurso, envía un
audio_stream_endal servidor. - El servidor trata el indicador
audio_stream_endcomo una instrucción de finalización inmediata, omite la demora predeterminada de detección de silencio del servidor y devuelve la transcripción y la respuesta del modelo con una latencia mínima. - Si el VAD del cliente no se activa, el VAD del servidor actúa como alternativa para detectar el final del discurso.
Ten en cuenta que, si el umbral del VAD del cliente se establece de forma demasiado agresiva, es posible que se produzcan cortes en el habla. Sin embargo, este enfoque evita los problemas de truncamiento frontal que podrían ocurrir con el VAD manual.
Python
# Set up with automatic VAD enabled (default)
config = {
"response_modalities": ["AUDIO"],
}
async with client.aio.live.connect(model=model, config=config) as session:
# Send audio data normally
await session.send_realtime_input(
audio=types.Blob(data=audio_bytes, mime_type="audio/pcm;rate=16000")
)
# When client-side VAD detects the end of speech, send:
await session.send_realtime_input(audio_stream_end=True)
JavaScript
// Set up with automatic VAD enabled (default)
const config = {
responseModalities: [Modality.AUDIO],
};
// Send audio data normally
session.sendRealtimeInput({
audio: {
data: base64Audio,
mimeType: "audio/pcm;rate=16000"
}
});
// When client-side VAD detects the end of speech, send:
session.sendRealtimeInput({ audioStreamEnd: true });
Inhabilita la VAD automática
Como alternativa, puedes inhabilitar el VAD automático configurando realtimeInputConfig.automaticActivityDetection.disabled como true en el mensaje de configuración. En esta configuración, el cliente es responsable de detectar el habla del usuario y enviar mensajes de activityStart y activityEnd en los momentos adecuados. No se envía un audioStreamEnd en esta configuración. En cambio, cualquier interrupción de la transmisión se marca con un mensaje activityEnd.
Python
config = {
"response_modalities": ["AUDIO"],
"realtime_input_config": {"automatic_activity_detection": {"disabled": True}},
}
async with client.aio.live.connect(model=model, config=config) as session:
# ...
await session.send_realtime_input(activity_start=types.ActivityStart())
await session.send_realtime_input(
audio=types.Blob(data=audio_bytes, mime_type="audio/pcm;rate=16000")
)
await session.send_realtime_input(activity_end=types.ActivityEnd())
# ...
JavaScript
const config = {
responseModalities: [Modality.AUDIO],
realtimeInputConfig: {
automaticActivityDetection: {
disabled: true,
}
}
};
session.sendRealtimeInput({ activityStart: {} })
session.sendRealtimeInput(
{
audio: {
data: base64Audio,
mimeType: "audio/pcm;rate=16000"
}
}
);
session.sendRealtimeInput({ activityEnd: {} })
Información sobre los parámetros del VAD y su impacto en la calidad
Cuando se usa el VAD automático, dos parámetros clave controlan cómo se segmenta el audio en turnos de habla antes de enviarse al modelo:
prefixPaddingMs: Es la cantidad de audio que se debe incluir antes de que se detecte el habla. Este "repaso" garantiza que el modelo capture el inicio completo del habla, incluida la primera sílaba, que puede comenzar antes de que se activen los activadores del VAD. Un valor de0puede hacer que se trunquen los comienzos de las palabras.silenceDurationMs: Es el tiempo que espera el servidor en silencio antes de finalizar un turno de voz. Esto determina la tolerancia del sistema a las pausas naturales en medio de la oración (p.ej., pensar, respirar o límites de cláusulas).
Impacto de silenceDurationMs en la calidad del audio
El valor de silenceDurationMs afecta directamente el tamaño y la integridad de los fragmentos de audio que recibe el modelo para su procesamiento:
- Recomendado (500 ms a 800 ms): Proporciona un buen equilibrio: el modelo recibe fragmentos de audio completos y enriquecidos contextualmente, a la vez que mantiene una latencia razonable. El valor predeterminado interno del servidor es de aproximadamente 800 ms.
- Demasiado bajo (p.ej., de 100 a 200 ms): El sistema finaliza los turnos de voz durante las pausas naturales, lo que divide una sola expresión en varios fragmentos de audio pequeños. El modelo recibe estos fragmentos de forma individual, por lo que pierde el contexto entre fragmentos y genera una menor calidad de transcripción y respuesta.
- Demasiado alto (p.ej., más de 2,000 ms): El sistema espera mucho tiempo después de que el usuario deja de hablar, lo que aumenta la latencia percibida antes de que responda el modelo.
Prácticas recomendadas para el VAD manual (del cliente)
Cuando inhabilitas la VAD automática y administras los indicadores de activityStart/activityEnd desde tu propia detección de voz del cliente, ten en cuenta que se omiten los mecanismos integrados de almacenamiento en búfer de audio del servidor. Esto significa lo siguiente:
- Sin búfer previo al habla: El servidor ya no antepone audio antes del inicio del habla detectada. Tu cliente debe incluir suficiente contexto de audio antes de enviar
activityStart. - Sin tolerancia al silencio: El servidor actúa de inmediato en tu indicador
activityEndsin espera adicional. Si tu VAD del cliente usa un umbral agresivo de fin de voz (p.ej., 200 ms de silencio), es posible que la voz se corte a mitad de la oración durante las pausas naturales.
Para conservar la calidad del audio con el VAD manual, usa un umbral de silencio al final del discurso de, al menos, 500 ms en el detector de actividad de voz de tu cliente. Los umbrales por debajo de este valor suelen provocar un audio fragmentado que degrada la calidad de la transcripción y la respuesta del modelo.
Recuento de tokens
Puedes encontrar la cantidad total de tokens consumidos en el campo usageMetadata del mensaje del servidor que se devolvió.
Python
async for message in session.receive():
# The server will periodically send messages that include UsageMetadata.
if message.usage_metadata:
usage = message.usage_metadata
print(
f"Used {usage.total_token_count} tokens in total. Response token breakdown:"
)
for detail in usage.response_tokens_details:
match detail:
case types.ModalityTokenCount(modality=modality, token_count=count):
print(f"{modality}: {count}")
JavaScript
const turns = await handleTurn();
for (const turn of turns) {
if (turn.usageMetadata) {
console.debug('Used %s tokens in total. Response token breakdown:\n', turn.usageMetadata.totalTokenCount);
for (const detail of turn.usageMetadata.responseTokensDetails) {
console.debug('%s\n', detail);
}
}
}
Resolución de contenido multimedia
Puedes especificar la resolución de los medios de entrada configurando el campo mediaResolution como parte de la configuración de la sesión:
Python
from google.genai import types
config = {
"response_modalities": ["AUDIO"],
"media_resolution": types.MediaResolution.MEDIA_RESOLUTION_LOW,
}
JavaScript
import { GoogleGenAI, Modality, MediaResolution } from '@google/genai';
const config = {
responseModalities: [Modality.AUDIO],
mediaResolution: MediaResolution.MEDIA_RESOLUTION_LOW,
};
Limitaciones
Ten en cuenta las siguientes limitaciones de la API de Live cuando planifiques tu proyecto.
Modalidades de respuesta
Los modelos de audio nativos solo admiten la modalidad de respuesta `AUDIO`. Si necesitas la respuesta del modelo como texto, usa la función transcripción de audio de salida.
Autenticación de clientes
De forma predeterminada, la API de Live solo proporciona autenticación de servidor a servidor. Si implementas tu aplicación de la API de Live con un enfoque de cliente a servidor, debes usar tokens efímeros para mitigar los riesgos de seguridad.
Duración de las sesiones
Las sesiones solo de audio se limitan a 15 minutos, y las sesiones de audio y video se limitan a 2 minutos. Sin embargo, puedes configurar diferentes técnicas de administración de sesiones para extensiones ilimitadas en la duración de la sesión.
Ventana de contexto
Una sesión tiene un límite de ventana de contexto de lo siguiente:
- 128 000 tokens para los modelos de salida de audio nativo
- 32,000 tokens para otros modelos de la API de Live
Idiomas admitidos
La API de Live admite los siguientes 97 idiomas.
| Idioma | Código BCP-47 | Idioma | Código BCP-47 |
|---|---|---|---|
| Afrikaans | af |
Letón | lv |
| Akan | ak |
Lituano | lt |
| Albanés | sq |
Macedonio | mk |
| Amárico | am |
Malayo | ms |
| Árabe | ar |
Malayalam | ml |
| Armenio | hy |
Maltés | mt |
| Asamés | as |
Maorí | mi |
| Azerí | az |
Maratí | mr |
| Euskara | eu |
Mongol | mn |
| Bielorruso | be |
Nepalí | ne |
| Bengalí | bn |
Noruego | no |
| Bosnio | bs |
Oriya | or |
| Búlgaro | bg |
Oromo | om |
| Birmano | my |
Pastún | ps |
| Catalán | ca |
Persa | fa |
| Cebuano | ceb |
Polaco | pl |
| Chino | zh |
Portugués | pt |
| Croata | hr |
Punyabí | pa |
| Checo | cs |
Quechua | qu |
| Danés | da |
Rumano | ro |
| Holandés | nl |
Romanche | rm |
| Inglés | en |
Ruso | ru |
| Estonio | et |
Serbio | sr |
| Feroés | fo |
Sindhi | sd |
| Filipino | fil |
Cingalés | si |
| Finlandés | fi |
Eslovaco | sk |
| Francés | fr |
Esloveno | sl |
| Gallego | gl |
Somalí | so |
| Georgiano | ka |
Sesoto meridional | st |
| Alemán | de |
Español | es |
| Griego | el |
Suajili | sw |
| Gujarati | gu |
Sueco | sv |
| Hausa | ha |
Tayiko | tg |
| Hebreo | iw |
Tamil | ta |
| Hindi | hi |
Telugu | te |
| Húngaro | hu |
Tailandés | th |
| Islandés | is |
Setsuana | tn |
| Indonesio | id |
Turco | tr |
| Irlandés | ga |
Turkmeno | tk |
| Italiano | it |
Ucraniano | uk |
| Japonés | ja |
Urdu | ur |
| Canarés | kn |
Uzbeko | uz |
| Kazajo | kk |
Vietnamita | vi |
| Jemer | km |
Galés | cy |
| Kiñarwanda | rw |
Frisón occidental | fy |
| Coreano | ko |
Wólof | wo |
| Kurdo | ku |
Yoruba | yo |
| Kirguís | ky |
Zulú | zu |
| Laosiano | lo |
¿Qué sigue?
- Lee las guías de Uso de herramientas y Administración de sesiones para obtener información esencial sobre el uso eficaz de la API de Live.
- Prueba la API en vivo en Google AI Studio.
- Para obtener más información sobre los modelos de la API de Live, consulta las páginas de los modelos Gemini 3.8 Live y Gemini 3.8 Live Extended Thinking.
- Prueba más ejemplos en la guía de soluciones de la API de Live, la guía de soluciones de las herramientas de la API de Live y el script de introducción a la API de Live.