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 un código de muestra de 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 Cómo comenzar a usar la API de Live . Aquí se te presentarán los principios fundamentales de la API de Live, su funcionamiento y la distinción entre los diferentes modelos y sus correspondientes métodos de generación de audio (audio nativo o media cascada).
- Prueba la API en vivo en AI Studio: Te recomendamos que pruebes la API en vivo en Google AI Studio antes de comenzar a crear. Para usar la API de Live en Google AI Studio, selecciona Transmitir.
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-live-2.5-flash-preview"
config = {"response_modalities": ["TEXT"]}
async def main():
async with client.aio.live.connect(model=model, config=config) as session:
print("Session started")
if __name__ == "__main__":
asyncio.run(main())
JavaScript
import { GoogleGenAI, Modality } from '@google/genai';
const ai = new GoogleGenAI({});
const model = 'gemini-live-2.5-flash-preview';
const config = { responseModalities: [Modality.TEXT] };
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,
});
// 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 y recibir mensajes de texto
Sigue estos pasos para enviar y recibir mensajes de texto:
Python
import asyncio
from google import genai
client = genai.Client()
model = "gemini-live-2.5-flash-preview"
config = {"response_modalities": ["TEXT"]}
async def main():
async with client.aio.live.connect(model=model, config=config) as session:
message = "Hello, how are you?"
await session.send_client_content(
turns={"role": "user", "parts": [{"text": message}]}, turn_complete=True
)
async for response in session.receive():
if response.text is not None:
print(response.text, end="")
if __name__ == "__main__":
asyncio.run(main())
JavaScript
import { GoogleGenAI, Modality } from '@google/genai';
const ai = new GoogleGenAI({});
const model = 'gemini-live-2.5-flash-preview';
const config = { responseModalities: [Modality.TEXT] };
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.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();
Actualizaciones de contenido incrementales
Usa actualizaciones incrementales para enviar entradas de texto, establecer el contexto de la sesión o restablecerlo. Para contextos cortos, 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 interacciones posteriores. Consulta Reanudación de sesión para conocer otro método para cargar el contexto de la sesión.
Cómo enviar y recibir audio
El ejemplo de audio más común, audio a audio, se incluye en la guía de Introducción.
Este es un ejemplo de audio a texto que lee un archivo WAV, lo envía en el formato correcto y recibe un resultado de texto:
Python
# Test file: https://storage.googleapis.com/generativeai-downloads/data/16000.wav
# Install helpers for converting files: pip install librosa soundfile
import asyncio
import io
from pathlib import Path
from google import genai
from google.genai import types
import soundfile as sf
import librosa
client = genai.Client()
model = "gemini-live-2.5-flash-preview"
config = {"response_modalities": ["TEXT"]}
async def main():
async with client.aio.live.connect(model=model, config=config) as session:
buffer = io.BytesIO()
y, sr = librosa.load("sample.wav", sr=16000)
sf.write(buffer, y, sr, format='RAW', subtype='PCM_16')
buffer.seek(0)
audio_bytes = buffer.read()
# If already in correct format, you can use this:
# audio_bytes = Path("sample.pcm").read_bytes()
await session.send_realtime_input(
audio=types.Blob(data=audio_bytes, mime_type="audio/pcm;rate=16000")
)
async for response in session.receive():
if response.text is not None:
print(response.text)
if __name__ == "__main__":
asyncio.run(main())
JavaScript
// Test file: https://storage.googleapis.com/generativeai-downloads/data/16000.wav
// Install helpers for converting files: npm install wavefile
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-live-2.5-flash-preview';
const config = { responseModalities: [Modality.TEXT] };
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.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);
}
}
session.close();
}
async function main() {
await live().catch((e) => console.error('got error', e));
}
main();
Este es un ejemplo de texto a audio.
Para recibir audio, configura AUDIO
como modalidad de respuesta. En este ejemplo, se guardan los datos recibidos como archivo WAV:
Python
import asyncio
import wave
from google import genai
client = genai.Client()
model = "gemini-live-2.5-flash-preview"
config = {"response_modalities": ["AUDIO"]}
async def main():
async with client.aio.live.connect(model=model, config=config) as session:
wf = wave.open("audio.wav", "wb")
wf.setnchannels(1)
wf.setsampwidth(2)
wf.setframerate(24000)
message = "Hello how are you?"
await session.send_client_content(
turns={"role": "user", "parts": [{"text": message}]}, turn_complete=True
)
async for response in session.receive():
if response.data is not None:
wf.writeframes(response.data)
# Un-comment this code to print audio data info
# if response.server_content.model_turn is not None:
# print(response.server_content.model_turn.parts[0].inline_data.mime_type)
wf.close()
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-live-2.5-flash-preview';
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,
});
const inputTurns = 'Hello how are you?';
session.sendClientContent({ turns: inputTurns });
const turns = await handleTurn();
// Combine audio data strings and save as wave file
const combinedAudio = turns.reduce((acc, turn) => {
if (turn.data) {
const buffer = Buffer.from(turn.data, 'base64');
const intArray = new Int16Array(buffer.buffer, buffer.byteOffset, buffer.byteLength / Int16Array.BYTES_PER_ELEMENT);
return acc.concat(Array.from(intArray));
}
return acc;
}, []);
const audioBuffer = new Int16Array(combinedAudio);
const wf = new WaveFile();
wf.fromScratch(1, 24000, '16', audioBuffer);
fs.writeFileSync('output.wav', wf.toBuffer());
session.close();
}
async function main() {
await live().catch((e) => console.error('got error', e));
}
main();
Formatos de audio
Los datos de audio de la API de Live siempre son PCM sin procesar, de formato little-endian y de 16 bits. La salida de audio siempre usa una tasa 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 para que se pueda enviar cualquier tasa de muestreo. Para transmitir la tasa de muestreo del audio de entrada, establece el tipo MIME de cada BLOB que contiene audio en un valor como audio/pcm;rate=16000
.
Transcripción de audio
Para habilitar la transcripción de la salida de audio del modelo, envía output_audio_transcription
en la configuración de 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-live-2.5-flash-preview"
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-live-2.5-flash-preview';
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, envía input_audio_transcription
en la configuración de configuración.
Python
import asyncio
from pathlib import Path
from google import genai
from google.genai import types
client = genai.Client()
model = "gemini-live-2.5-flash-preview"
config = {
"response_modalities": ["TEXT"],
"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-live-2.5-flash-preview';
const config = {
responseModalities: [Modality.TEXT],
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.serverContent && turn.serverContent.outputTranscription) {
console.log("Transcription")
console.log(turn.serverContent.outputTranscription.text);
}
}
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 transmitir audio y video
Cómo cambiar la voz y el idioma
Cada modelo de la API de Live admite un conjunto diferente de voces. La mitad en cascada admite Puck, Charon, Kore, Fenrir, Aoede, Leda, Orus y Zephyr. El audio nativo admite una lista mucho más larga (idéntica a la lista de modelos de TTS). Puedes escuchar todas las voces en AI Studio.
Para especificar una voz, establece 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.
Para cambiar el idioma, establece el código de idioma dentro del objeto speechConfig
como parte de la configuración de la sesión:
Python
config = {
"response_modalities": ["AUDIO"],
"speech_config": {
"language_code": "de-DE"
}
}
JavaScript
const config = {
responseModalities: [Modality.AUDIO],
speechConfig: { languageCode: "de-DE" }
};
Funciones de audio nativas
Las siguientes funciones solo están disponibles con audio nativo. Puedes obtener más información sobre el audio nativo en Elige un modelo y una generación de audio.
Cómo usar la salida de audio nativa
Para usar la salida de audio nativa, configura uno de los modelos de audio nativos y establece response_modalities
en AUDIO
.
Consulta Cómo enviar y recibir audio para ver un ejemplo completo.
Python
model = "gemini-2.5-flash-preview-native-audio-dialog"
config = types.LiveConnectConfig(response_modalities=["AUDIO"])
async with client.aio.live.connect(model=model, config=config) as session:
# Send audio input and receive audio
JavaScript
const model = 'gemini-2.5-flash-preview-native-audio-dialog';
const config = { responseModalities: [Modality.AUDIO] };
async function main() {
const session = await ai.live.connect({
model: model,
config: config,
callbacks: ...,
});
// Send audio input and receive audio
session.close();
}
main();
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 v1alpha
y enable_affective_dialog
en true
en el mensaje de configuración:
Python
client = genai.Client(http_options={"api_version": "v1alpha"})
config = types.LiveConnectConfig(
response_modalities=["AUDIO"],
enable_affective_dialog=True
)
JavaScript
const ai = new GoogleGenAI({ httpOptions: {"apiVersion": "v1alpha"} });
const config = {
responseModalities: [Modality.AUDIO],
enableAffectiveDialog: true
};
Ten en cuenta que, por el momento, el diálogo afectivo solo es compatible con los modelos de salida de audio nativos.
Audio proactivo
Cuando esta función está habilitada, Gemini puede decidir de forma proactiva no responder si el contenido no es relevante.
Para usarlo, configura la versión de la API en v1alpha
y configura el campo proactivity
en el mensaje de configuración y establece proactive_audio
en true
:
Python
client = genai.Client(http_options={"api_version": "v1alpha"})
config = types.LiveConnectConfig(
response_modalities=["AUDIO"],
proactivity={'proactive_audio': True}
)
JavaScript
const ai = new GoogleGenAI({ httpOptions: {"apiVersion": "v1alpha"} });
const config = {
responseModalities: [Modality.AUDIO],
proactivity: { proactiveAudio: true }
}
Ten en cuenta que, por el momento, el audio proactivo solo es compatible con los modelos de salida de audio nativo.
Salida de audio nativa con procesamiento
La salida de audio nativa admite funciones de pensamiento, que están disponibles a través de un modelo gemini-2.5-flash-exp-native-audio-thinking-dialog
independiente.
Consulta Cómo enviar y recibir audio para ver un ejemplo completo.
Python
model = "gemini-2.5-flash-exp-native-audio-thinking-dialog"
config = types.LiveConnectConfig(response_modalities=["AUDIO"])
async with client.aio.live.connect(model=model, config=config) as session:
# Send audio input and receive audio
JavaScript
const model = 'gemini-2.5-flash-exp-native-audio-thinking-dialog';
const config = { responseModalities: [Modality.AUDIO] };
async function main() {
const session = await ai.live.connect({
model: model,
config: config,
callbacks: ...,
});
// Send audio input and receive audio
session.close();
}
main();
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 esencial para crear conversaciones naturales, ya que permite que un usuario interrumpa el modelo en cualquier momento.
Cuando el VAD detecta una interrupción, se cancela y se descarta la generación en curso. Solo la información que ya se envió al cliente se retiene en el historial de la sesión. Luego, el servidor envía un mensaje BidiGenerateContentServerContent
para informar la interrupción.
Luego, el servidor de Gemini descarta las llamadas a función pendientes 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ática
De forma predeterminada, el modelo realiza automáticamente la VAD en un flujo de entrada de audio continuo. La VAD se puede configurar con el campo realtimeInputConfig.automaticActivityDetection
de la configuración de configuració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 borrar 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-live-2.5-flash-preview"
config = {"response_modalities": ["TEXT"]}
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-live-2.5-flash-preview';
const config = { responseModalities: [Modality.TEXT] };
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. Mientras que send_client_content
agrega mensajes al contexto del modelo en orden, send_realtime_input
está optimizado para la capacidad de respuesta a expensas del orden determinista.
Configuración automática de VAD
Para tener más control sobre la actividad de 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": ["TEXT"],
"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.TEXT],
realtimeInputConfig: {
automaticActivityDetection: {
disabled: false, // default
startOfSpeechSensitivity: StartSensitivity.START_SENSITIVITY_LOW,
endOfSpeechSensitivity: EndSensitivity.END_SENSITIVITY_LOW,
prefixPaddingMs: 20,
silenceDurationMs: 100,
}
}
};
Inhabilita la VAD automática
Como alternativa, puedes inhabilitar la VAD automática configurando realtimeInputConfig.automaticActivityDetection.disabled
como true
en el mensaje de configuración. En esta configuración, el cliente es responsable de detectar la voz del usuario y enviar mensajes 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": ["TEXT"],
"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.TEXT],
realtimeInputConfig: {
automaticActivityDetection: {
disabled: true,
}
}
};
session.sendRealtimeInput({ activityStart: {} })
session.sendRealtimeInput(
{
audio: {
data: base64Audio,
mimeType: "audio/pcm;rate=16000"
}
}
);
session.sendRealtimeInput({ activityEnd: {} })
Recuento de tokens
Puedes encontrar la cantidad total de tokens consumidos en el campo usageMetadata del mensaje del servidor que se muestra.
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
Para especificar la resolución de contenido multimedia de entrada, configura 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.TEXT],
mediaResolution: MediaResolution.MEDIA_RESOLUTION_LOW,
};
Limitaciones
Ten en cuenta las siguientes limitaciones de la API de Live cuando planifiques tu proyecto.
Modalidades de respuesta
Solo puedes establecer una modalidad de respuesta (TEXT
o AUDIO
) por sesión en la configuración de la sesión. Establecer ambos resultados en un mensaje de error de configuración Esto significa que puedes configurar el modelo para que responda con texto o audio, pero no con ambos en la misma sesión.
Autenticación de clientes
La API de Live solo proporciona autenticación de servidor a servidor de forma predeterminada. Si implementas tu aplicación de API en vivo con un enfoque de cliente a servidor, debes usar tokens efímeros para mitigar los riesgos de seguridad.
Duración de la sesión
Las sesiones de solo audio tienen un límite de 15 minutos, mientras que las sesiones de audio y video tienen un límite de 2 minutos. Sin embargo, puedes configurar diferentes técnicas de administración de sesiones para obtener 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:
- 128,000 tokens para modelos de salida de audio nativa
- 32,000 tokens para otros modelos de la API de Live
Idiomas admitidos
La API de Live admite los siguientes idiomas.
Idioma | Código BCP-47 | Idioma | Código BCP-47 |
---|---|---|---|
Alemán (Alemania) | de-DE |
Inglés (Australia)* | en-AU |
Inglés (Reino Unido)* | en-GB |
Inglés (India) | en-IN |
Inglés (EE.UU.) | en-US |
Español (EE.UU.) | es-US |
Francés (Francia) | fr-FR |
Hindi (India) | hi-IN |
Portugués (Brasil) | pt-BR |
Árabe (genérico) | ar-XA |
Español (España)* | es-ES |
Francés (Canadá)* | fr-CA |
Indonesio (Indonesia) | id-ID |
Italiano (Italia) | it-IT |
Japonés (Japón) | ja-JP |
Turco (Türkiye) | tr-TR |
Vietnamita (Vietnam) | vi-VN |
Bengalí (India) | bn-IN |
Guyaratí (India)* | gu-IN |
Canarés (India)* | kn-IN |
Maratí (India) | mr-IN |
Malabar (India)* | ml-IN |
Tamil (India) | ta-IN |
Telugu (India) | te-IN |
Neerlandés (Países Bajos) | nl-NL |
Coreano (Corea del Sur) | ko-KR |
Chino mandarín (China)* | cmn-CN |
Polaco (Polonia) | pl-PL |
Ruso (Rusia) | ru-RU |
Tailandés (Tailandia) | th-TH |
Los idiomas marcados con un asterisco (*) no están disponibles para el audio nativo.
¿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 contenido en vivo, consulta Gemini 2.0 Flash Live y Gemini 2.5 Flash Native Audio en la página Modelos.
- Prueba más ejemplos en la guía de soluciones de la API de Live, la guía de soluciones de herramientas de la API de Live y la secuencia de comandos de Introducción a la API de Live.