La API de Live habilita interacciones de voz y video bidireccionales de baja latencia con Gemini, lo que te permite hablar con Gemini en vivo mientras transmites la entrada de video o compartes tu pantalla. Con la API de Live, puedes proporcionar a los usuarios finales la experiencia de conversaciones de voz naturales y similares a las humanas.
Puedes probar la API de Live en Google AI Studio. Para usar la API de Live en Google AI Studio, selecciona Transmitir.
Cómo funciona la API de Live
Transmisión
La API de Live usa un modelo de transmisión a través de una conexión WebSocket. Cuando interactúas con la API, se crea una conexión persistente. Tu entrada (audio, video o texto) se transmite de forma continua al modelo, y la respuesta del modelo (texto o audio) se vuelve a transmitir en tiempo real a través de la misma conexión.
Esta transmisión bidireccional garantiza una latencia baja y admite funciones como la detección de actividad de voz, el uso de herramientas y la generación de voz.
Para obtener más información sobre la API subyacente de WebSockets, consulta la referencia de la API de WebSockets.
Compilación con la API de Live {:#building-with-live-api}ß
Cómo establecer una conexión
En el siguiente ejemplo, se muestra cómo crear una conexión con una clave de API:
import asyncio
from google import genai
client = genai.Client(api_key="GEMINI_API_KEY")
model = "gemini-2.0-flash-live-001"
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())
import { GoogleGenAI } from '@google/genai';
const ai = new GoogleGenAI({ apiKey: "GOOGLE_API_KEY" });
const model = 'gemini-2.0-flash-live-001';
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();
Cómo enviar y recibir mensajes de texto
Sigue estos pasos para enviar y recibir mensajes de texto:
import asyncio
from google import genai
client = genai.Client(api_key="GEMINI_API_KEY")
model = "gemini-2.0-flash-live-001"
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())
import { GoogleGenAI, Modality } from '@google/genai';
const ai = new GoogleGenAI({ apiKey: "GOOGLE_API_KEY" });
const model = 'gemini-2.0-flash-live-001';
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 simple = 'Hello how are you?';
session.sendClientContent({ turns: simple });
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();
Cómo enviar y recibir audio
Para enviar audio, convértelo a PCM de 16 bits, 16 kHz y mono. En este ejemplo, se lee un archivo WAV y se envía en el formato correcto:
# 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(api_key="GEMINI_API_KEY")
model = "gemini-2.0-flash-live-001"
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())
// 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({ apiKey: "GOOGLE_API_KEY" });
const model = 'gemini-2.0-flash-live-001';
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();
Para recibir audio, configura AUDIO
como modalidad de respuesta. En este ejemplo, se guardan los datos recibidos como archivo WAV:
import asyncio
import wave
from google import genai
client = genai.Client(api_key="GEMINI_API_KEY")
model = "gemini-2.0-flash-live-001"
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 idx,response in async_enumerate(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())
import { GoogleGenAI, Modality } from '@google/genai';
const ai = new GoogleGenAI({ apiKey: "GOOGLE_API_KEY" });
const model = 'gemini-2.0-flash-live-001';
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 simple = 'Hello how are you?';
session.sendClientContent({ turns: simple });
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
.
Cómo recibir transcripciones 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 a partir de la respuesta del modelo.
import asyncio
from google import genai
from google.genai import types
client = genai.Client(api_key="GEMINI_API_KEY")
model = "gemini-2.0-flash-live-001"
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())
Para habilitar la transcripción de la entrada de audio, envía input_audio_transcription
en la configuración de configuración.
import asyncio
from google import genai
from google.genai import types
client = genai.Client(api_key="GEMINI_API_KEY")
model = "gemini-2.0-flash-live-001"
config = {"response_modalities": ["TEXT"],
"realtime_input_config": {
"automatic_activity_detection": {"disabled": True},
"activity_handling": "NO_INTERRUPTION",
},
"input_audio_transcription": {},
}
async def main():
async with client.aio.live.connect(model=model, config=config) as session:
audio_data = Path("sample.pcm").read_bytes()
await session.send_realtime_input(activity_start=types.ActivityStart())
await session.send_realtime_input(
audio=types.Blob(data=audio_data, mime_type='audio/pcm;rate=16000')
)
await session.send_realtime_input(activity_end=types.ActivityEnd())
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())
Transmisión de audio y video
Instrucciones del sistema
Las instrucciones del sistema te permiten dirigir el comportamiento de un modelo según tus necesidades y casos de uso específicos. Las instrucciones del sistema se pueden establecer en la configuración de configuración y permanecerán vigentes durante toda la sesión.
from google.genai import types
config = {
"system_instruction": types.Content(
parts=[
types.Part(
text="You are a helpful assistant and answer in a friendly tone."
)
]
),
"response_modalities": ["TEXT"],
}
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:
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)
{
"clientContent": {
"turns": [
{
"parts":[
{
"text": ""
}
],
"role":"user"
},
{
"parts":[
{
"text": ""
}
],
"role":"model"
}
],
"turnComplete": true
}
}
Para contextos más largos, se recomienda proporcionar un solo resumen del mensaje para liberar la ventana de contexto para interacciones posteriores.
Cómo cambiar la voz y el idioma
La API de Live admite las siguientes voces: Puck, Charon, Kore, Fenrir, Aoede, Leda, Orus y Zephyr.
Para especificar una voz, establece el nombre de la voz dentro del objeto speechConfig
como parte de la configuración de la sesión:
from google.genai import types
config = types.LiveConnectConfig(
response_modalities=["AUDIO"],
speech_config=types.SpeechConfig(
voice_config=types.VoiceConfig(
prebuilt_voice_config=types.PrebuiltVoiceConfig(voice_name="Kore")
)
)
)
{
"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:
from google.genai import types
config = types.LiveConnectConfig(
response_modalities=["AUDIO"],
speech_config=types.SpeechConfig(
language_code="de-DE",
)
)
Uso de herramientas con la API de Live
Puedes definir herramientas como Llamadas a funciones, Ejecución de código y Búsqueda de Google con la API en vivo.
Llamadas a funciones
Puedes definir declaraciones de funciones como parte de la configuración de la sesión. Consulta el instructivo de llamadas a funciones para obtener más información.
Después de recibir llamadas de herramientas, el cliente debe responder con una lista de objetos FunctionResponse
con el método session.send_tool_response
.
import asyncio
from google import genai
from google.genai import types
client = genai.Client(api_key="GEMINI_API_KEY")
model = "gemini-2.0-flash-live-001"
# Simple function definitions
turn_on_the_lights = {"name": "turn_on_the_lights"}
turn_off_the_lights = {"name": "turn_off_the_lights"}
tools = [{"function_declarations": [turn_on_the_lights, turn_off_the_lights]}]
config = {"response_modalities": ["TEXT"], "tools": tools}
async def main():
async with client.aio.live.connect(model=model, config=config) as session:
prompt = "Turn on the lights please"
await session.send_client_content(turns={"parts": [{"text": prompt}]})
async for chunk in session.receive():
if chunk.server_content:
if chunk.text is not None:
print(chunk.text)
elif chunk.tool_call:
function_responses = []
for fc in tool_call.function_calls:
function_response = types.FunctionResponse(
id=fc.id,
name=fc.name,
response={ "result": "ok" } # simple, hard-coded function response
)
function_responses.append(function_response)
await session.send_tool_response(function_responses=function_responses)
if __name__ == "__main__":
asyncio.run(main())
A partir de una sola instrucción, el modelo puede generar varias llamadas a funciones y el código necesario para encadenar sus resultados. Este código se ejecuta en un entorno de zona de pruebas y genera mensajes BidiGenerateContentToolCall posteriores.
Llamadas a funciones asíncronas
De forma predeterminada, la ejecución se pausa hasta que los resultados de cada llamada a función están disponibles, lo que garantiza el procesamiento secuencial. Esto significa que no podrás seguir interactuando con el modelo mientras se ejecutan las funciones.
Si no quieres bloquear la conversación, puedes indicarle al modelo que ejecute las funciones de forma asíncrona.
Para ello, primero debes agregar un behavior
a las definiciones de la función:
# Non-blocking function definitions
turn_on_the_lights = {"name": "turn_on_the_lights", "behavior": "NON_BLOCKING"} # turn_on_the_lights will run asynchronously
turn_off_the_lights = {"name": "turn_off_the_lights"} # turn_off_the_lights will still pause all interactions with the model
NON-BLOCKING
se asegurará de que la función se ejecute de forma asíncrona mientras puedes
continuar interactuando con el modelo.
Luego, debes indicarle al modelo cómo comportarse cuando recibe el FunctionResponse
con el parámetro scheduling
. Puede hacer lo siguiente:
- Interrumpir lo que está haciendo y decirte sobre la respuesta que recibió de inmediato (
scheduling="INTERRUPT"
), - Espera a que termine lo que está haciendo (
scheduling="WHEN_IDLE"
). - O bien no hacer nada y usar ese conocimiento más adelante en la conversación (
scheduling="SILENT"
).
# Non-blocking function definitions
function_response = types.FunctionResponse(
id=fc.id,
name=fc.name,
response={
"result": "ok",
"scheduling": "INTERRUPT" # Can also be WHEN_IDLE or SILENT
}
)
Ejecución de código
Puedes definir la ejecución de código como parte de la configuración de la sesión. Consulta el instructivo de ejecución de código para obtener más información.
import asyncio
from google import genai
from google.genai import types
client = genai.Client(api_key="GEMINI_API_KEY")
model = "gemini-2.0-flash-live-001"
tools = [{'code_execution': {}}]
config = {"response_modalities": ["TEXT"], "tools": tools}
async def main():
async with client.aio.live.connect(model=model, config=config) as session:
prompt = "Compute the largest prime palindrome under 100000."
await session.send_client_content(turns={"parts": [{"text": prompt}]})
async for chunk in session.receive():
if chunk.server_content:
if chunk.text is not None:
print(chunk.text)
model_turn = chunk.server_content.model_turn
if model_turn:
for part in model_turn.parts:
if part.executable_code is not None:
print(part.executable_code.code)
if part.code_execution_result is not None:
print(part.code_execution_result.output)
if __name__ == "__main__":
asyncio.run(main())
Fundamentación con la Búsqueda de Google
Puedes habilitar la vinculación con la Búsqueda de Google como parte de la configuración de la sesión. Consulta el instructivo de puesta a tierra para obtener más información.
import asyncio
from google import genai
from google.genai import types
client = genai.Client(api_key="GEMINI_API_KEY")
model = "gemini-2.0-flash-live-001"
tools = [{'google_search': {}}]
config = {"response_modalities": ["TEXT"], "tools": tools}
async def main():
async with client.aio.live.connect(model=model, config=config) as session:
prompt = "When did the last Brazil vs. Argentina soccer match happen?"
await session.send_client_content(turns={"parts": [{"text": prompt}]})
async for chunk in session.receive():
if chunk.server_content:
if chunk.text is not None:
print(chunk.text)
# The model might generate and execute Python code to use Search
model_turn = chunk.server_content.model_turn
if model_turn:
for part in model_turn.parts:
if part.executable_code is not None:
print(part.executable_code.code)
if part.code_execution_result is not None:
print(part.code_execution_result.output)
if __name__ == "__main__":
asyncio.run(main())
Combinación de varias herramientas
Puedes combinar varias herramientas dentro de la API de Live:
prompt = """
Hey, I need you to do three things for me.
1. Compute the largest prime palindrome under 100000.
2. Then use Google Search to look up information about the largest earthquake in California the week of Dec 5 2024?
3. Turn on the lights
Thanks!
"""
tools = [
{"google_search": {}},
{"code_execution": {}},
{"function_declarations": [turn_on_the_lights, turn_off_the_lights]},
]
config = {"response_modalities": ["TEXT"], "tools": tools}
Cómo controlar las interrupciones
Los usuarios pueden interrumpir la salida del modelo en cualquier momento. Cuando la detección de actividad de voz (VAD) detecta una interrupción, se cancela y descarta la generación en curso. Solo la información que ya se envió al cliente se conserva en el historial de la sesión. Luego, el servidor envía un mensaje BidiGenerateContentServerContent para informar la interrupción.
Además, el servidor de Gemini descarta las llamadas a funciones pendientes y envía
un mensaje BidiGenerateContentServerContent
con los IDs de las llamadas canceladas.
async for response in session.receive():
if response.server_content.interrupted is True:
# The generation was interrupted
Detección de actividad de voz (VAD)
Puedes configurar o inhabilitar la detección de actividad de voz (VAD).
Cómo usar el VAD automático
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.
# 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(api_key="GEMINI_API_KEY")
model = "gemini-2.0-flash-live-001"
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())
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.
Cómo configurar la VAD automática
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.
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,
}
}
}
Cómo inhabilitar 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
.
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())
# ...
Recuento de tokens
Puedes encontrar la cantidad total de tokens consumidos en el campo usageMetadata del mensaje del servidor que se muestra.
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}")
Cómo extender la duración de la sesión
La duración máxima de la sesión se puede extender a ilimitada con dos mecanismos:
Además, recibirás un mensaje GoAway antes de que finalice la sesión, lo que te permitirá realizar más acciones.
Compresión de la ventana de contexto
Para habilitar sesiones más largas y evitar la terminación abrupta de la conexión, puedes habilitar la compresión de la ventana de contexto configurando el campo contextWindowCompression como parte de la configuración de la sesión.
En ContextWindowCompressionConfig, puedes configurar un mecanismo de ventana deslizante y la cantidad de tokens que activa la compresión.
from google.genai import types
config = types.LiveConnectConfig(
response_modalities=["AUDIO"],
context_window_compression=(
# Configures compression with default parameters.
types.ContextWindowCompressionConfig(
sliding_window=types.SlidingWindow(),
)
),
)
Reanudación de la sesión
Para evitar que se cierre la sesión cuando el servidor restablezca periódicamente la conexión de WebSocket, configura el campo sessionResumption dentro de la configuración de configuración.
Si pasas esta configuración, el servidor enviará mensajes SessionResumptionUpdate, que se pueden usar para reanudar la sesión pasando el último token de reanudación como SessionResumptionConfig.handle
de la conexión posterior.
import asyncio
from google import genai
from google.genai import types
client = genai.Client(api_key="GEMINI_API_KEY")
model = "gemini-2.0-flash-live-001"
async def main():
print(f"Connecting to the service with handle {previous_session_handle}...")
async with client.aio.live.connect(
model=model,
config=types.LiveConnectConfig(
response_modalities=["AUDIO"],
session_resumption=types.SessionResumptionConfig(
# The handle of the session to resume is passed here,
# or else None to start a new session.
handle=previous_session_handle
),
),
) as session:
while True:
await session.send_client_content(
turns=types.Content(
role="user", parts=[types.Part(text="Hello world!")]
)
)
async for message in session.receive():
# Periodically, the server will send update messages that may
# contain a handle for the current state of the session.
if message.session_resumption_update:
update = message.session_resumption_update
if update.resumable and update.new_handle:
# The handle should be retained and linked to the session.
return update.new_handle
# For the purposes of this example, placeholder input is continually fed
# to the model. In non-sample code, the model inputs would come from
# the user.
if message.server_content and message.server_content.turn_complete:
break
if __name__ == "__main__":
asyncio.run(main())
Recibir un mensaje antes de que se desconecte la sesión
El servidor envía un mensaje GoAway que indica que la conexión actual se finalizará pronto. Este mensaje incluye timeLeft, que indica el tiempo restante y te permite realizar más acciones antes de que la conexión se cierre como ABORTED.
async for response in session.receive():
if response.go_away is not None:
# The connection will soon be terminated
print(response.go_away.time_left)
Recibir un mensaje cuando se complete la generación
El servidor envía un mensaje generationComplete que indica que el modelo terminó de generar la respuesta.
async for response in session.receive():
if response.server_content.generation_complete is True:
# The generation is complete
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:
from google.genai import types
config = types.LiveConnectConfig(
response_modalities=["AUDIO"],
media_resolution=types.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 y no se recomienda para el uso directo de clientes. La entrada del cliente debe enrutarse a través de un servidor de aplicaciones intermedio para una autenticación segura con la API de Live.
Duración de la sesión
Si habilitas la compresión de la sesión, puedes extender su duración hasta un tiempo ilimitado. Sin compresión, las sesiones de solo audio se limitan a 15 minutos, y las sesiones de audio y video se limitan a 2 minutos. Si superas estos límites sin compresión, se finalizará la conexión.
Además, puedes configurar la reanudación de la sesión para permitir que el cliente reanude una sesión que se cerró.
Ventana de contexto
Una sesión tiene un límite de ventana de contexto de 32,000 tokens.
Idiomas admitidos
La API de Live admite los siguientes idiomas.
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 (Estados Unidos) | 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 (Turquía) | tr-TR |
Vietnamita (Vietnam) | vi-VN |
Bengalí (India) | bn-IN |
Guyaratí (India) | gu-IN |
Canarés (India) | kn-IN |
Malabar (India) | ml-IN |
Maratí (India) | mr-IN |
Tamil (India) | ta-IN |
Telugu (India) | te-IN |
Holandé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 |
Integraciones de terceros
Para implementaciones de aplicaciones web y para dispositivos móviles, puedes explorar las siguientes opciones:
¿Qué sigue?
- Implementa la comunicación cliente-servidor con tokens efímeros.
- Prueba la API en vivo en Google AI Studio.
- Para obtener más información sobre Gemini 2.0 Flash en vivo, consulta la página del modelo.
- 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.