La API de Gemini Live habilita interacciones de voz y video bidireccionales de baja latencia con Gemini. Con la API de Live, puedes proporcionar a los usuarios finales la experiencia de conversaciones de voz naturales y similares a las humanas, y la capacidad de interrumpir las respuestas del modelo con comandos por voz. La API de Live puede procesar entradas de texto, audio y video, y puede proporcionar salidas de texto y audio.
Funciones
La API de Live tiene las siguientes especificaciones técnicas:
- Entradas: Texto, audio y video
- Salidas: Texto y audio (voz sintetizada)
- Duración predeterminada de la sesión: 10 minutos
- La duración de la sesión se puede extender en incrementos de 10 minutos según sea necesario.
- Ventana de contexto: 32,000 tokens
- Selección entre 8 voces para las respuestas
- Compatibilidad con respuestas en 31 idiomas
Usa la API de Live
En las siguientes secciones, se proporcionan ejemplos sobre cómo usar las funciones de la API de Live.
Para obtener más información, consulta la guía de referencia de la API de Gemini Live.
Cómo enviar texto y recibir audio
SDK de IA generativa para Python
voice_name = "Aoede" # @param ["Aoede", "Puck", "Charon", "Kore", "Fenrir", "Leda", "Orus", "Zephyr"] config = LiveConnectConfig( response_modalities=["AUDIO"], speech_config=SpeechConfig( voice_config=VoiceConfig( prebuilt_voice_config=PrebuiltVoiceConfig( voice_name=voice_name, ) ), ), ) async with client.aio.live.connect( model=MODEL_ID, config=config, ) as session: text_input = "Hello? Gemini are you there?" display(Markdown(f"**Input:** {text_input}")) await session.send_client_content( turns=Content(role="user", parts=[Part(text=text_input)])) audio_data = [] async for message in session.receive(): if ( message.server_content.model_turn and message.server_content.model_turn.parts ): for part in message.server_content.model_turn.parts: if part.inline_data: audio_data.append( np.frombuffer(part.inline_data.data, dtype=np.int16) ) if audio_data: display(Audio(np.concatenate(audio_data), rate=24000, autoplay=True))
Cómo enviar y recibir mensajes de texto
Gen AI SDK for Python
Instalar
pip install --upgrade google-genai
Establece variables de entorno para usar el SDK de Gen AI con Vertex AI:
# Replace the `GOOGLE_CLOUD_PROJECT` and `GOOGLE_CLOUD_LOCATION` values # with appropriate values for your project. export GOOGLE_CLOUD_PROJECT=GOOGLE_CLOUD_PROJECT export GOOGLE_CLOUD_LOCATION=us-central1 export GOOGLE_GENAI_USE_VERTEXAI=True
Cómo enviar audio
SDK de IA generativa para Python
import asyncio import wave from google import genai client = genai.Client(api_key="GEMINI_API_KEY", http_options={'api_version': 'v1alpha'}) model = "gemini-2.0-flash-live-preview-04-09" 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? Gemini are you there?" await session.send_client_content( turns=Content(role="user", parts=[Part(text=message)])) 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())
La API de Live admite los siguientes formatos de audio:
- Formato de audio de entrada: Audio PCM sin procesar de 16 bits a 16 kHz en formato little-endian
- Formato de audio de salida: Audio PCM sin procesar de 16 bits a 24 kHz en formato little-endian
Transcripción de audio
La API de Live puede transcribir audio de entrada y salida:
SDK de IA generativa para Python
# Set model generation_config CONFIG = { 'response_modalities': ['AUDIO'], } headers = { "Content-Type": "application/json", "Authorization": f"Bearer {bearer_token[0]}", } # Connect to the server async with connect(SERVICE_URL, additional_headers=headers) as ws: # Setup the session await ws.send( json.dumps( { "setup": { "model": "gemini-2.0-flash-live-preview-04-09", "generation_config": CONFIG, 'input_audio_transcription': {}, 'output_audio_transcription': {} } } ) ) # Receive setup response raw_response = await ws.recv(decode=False) setup_response = json.loads(raw_response.decode("ascii")) # Send text message text_input = "Hello? Gemini are you there?" display(Markdown(f"**Input:** {text_input}")) msg = { "client_content": { "turns": [{"role": "user", "parts": [{"text": text_input}]}], "turn_complete": True, } } await ws.send(json.dumps(msg)) responses = [] input_transcriptions = [] output_transcriptions = [] # Receive chucks of server response async for raw_response in ws: response = json.loads(raw_response.decode()) server_content = response.pop("serverContent", None) if server_content is None: break if (input_transcription := server_content.get("inputTranscription")) is not None: if (text := input_transcription.get("text")) is not None: input_transcriptions.append(text) if (output_transcription := server_content.get("outputTranscription")) is not None: if (text := output_transcription.get("text")) is not None: output_transcriptions.append(text) model_turn = server_content.pop("modelTurn", None) if model_turn is not None: parts = model_turn.pop("parts", None) if parts is not None: for part in parts: pcm_data = base64.b64decode(part["inlineData"]["data"]) responses.append(np.frombuffer(pcm_data, dtype=np.int16)) # End of turn turn_complete = server_content.pop("turnComplete", None) if turn_complete: break if input_transcriptions: display(Markdown(f"**Input transcription >** {''.join(input_transcriptions)}")) if responses: # Play the returned audio message display(Audio(np.concatenate(responses), rate=24000, autoplay=True)) if output_transcriptions: display(Markdown(f"**Output transcription >** {''.join(output_transcriptions)}"))
Cómo cambiar la configuración de idioma y voz
La API de Live usa Chirp 3 para admitir respuestas de voz sintetizada en 8 voces de alta definición y 31 idiomas.
Puedes elegir entre las siguientes voces:
Aoede
(mujer)Charon
(hombre)Fenrir
(hombre)Kore
(mujer)Leda
(mujer)Orus
(hombre)Puck
(hombre)Zephyr
(mujer)
Para ver demostraciones de cómo suenan estas voces y obtener la lista completa de los idiomas disponibles, consulta Chirp 3: Voces en HD.
Para establecer la voz y el idioma de la respuesta, haz lo siguiente:
SDK de IA generativa para Python
config = LiveConnectConfig( response_modalities=["AUDIO"], speech_config=SpeechConfig( voice_config=VoiceConfig( prebuilt_voice_config=PrebuiltVoiceConfig( voice_name=voice_name, ) ), language_code="en-US", ), )
Console
- Abre Vertex AI Studio > API en vivo.
- En el expansor Salidas, selecciona una voz del menú desplegable Voz.
- En el mismo expansor, selecciona un idioma en el menú desplegable Idioma.
- Haz clic en Iniciar sesión para comenzar la sesión.
Para obtener los mejores resultados cuando le pidas al modelo que responda en un idioma que no sea inglés, incluye lo siguiente como parte de las instrucciones del sistema:
RESPOND IN LANGUAGE. YOU MUST RESPOND UNMISTAKABLY IN LANGUAGE.
Tener una conversación transmitida
SDK de IA generativa para Python
Configura una conversación con la API que te permita enviar instrucciones de texto y recibir respuestas de audio:
# Set model generation_config CONFIG = {"response_modalities": ["AUDIO"]} headers = { "Content-Type": "application/json", "Authorization": f"Bearer {bearer_token[0]}", } async def main() -> None: # Connect to the server async with connect(SERVICE_URL, additional_headers=headers) as ws: # Setup the session async def setup() -> None: await ws.send( json.dumps( { "setup": { "model": "gemini-2.0-flash-live-preview-04-09", "generation_config": CONFIG, } } ) ) # Receive setup response raw_response = await ws.recv(decode=False) setup_response = json.loads(raw_response.decode("ascii")) print(f"Connected: {setup_response}") return # Send text message async def send() -> bool: text_input = input("Input > ") if text_input.lower() in ("q", "quit", "exit"): return False msg = { "client_content": { "turns": [{"role": "user", "parts": [{"text": text_input}]}], "turn_complete": True, } } await ws.send(json.dumps(msg)) return True # Receive server response async def receive() -> None: responses = [] # Receive chucks of server response async for raw_response in ws: response = json.loads(raw_response.decode()) server_content = response.pop("serverContent", None) if server_content is None: break model_turn = server_content.pop("modelTurn", None) if model_turn is not None: parts = model_turn.pop("parts", None) if parts is not None: for part in parts: pcm_data = base64.b64decode(part["inlineData"]["data"]) responses.append(np.frombuffer(pcm_data, dtype=np.int16)) # End of turn turn_complete = server_content.pop("turnComplete", None) if turn_complete: break # Play the returned audio message display(Markdown("**Response >**")) display(Audio(np.concatenate(responses), rate=24000, autoplay=True)) return await setup() while True: if not await send(): break await receive()
Inicia la conversación, ingresa tus instrucciones o escribe q
, quit
o exit
para salir.
await main()
Console
- Abre Vertex AI Studio > API en vivo.
- Haz clic en Iniciar sesión para iniciar la sesión de conversación.
Para finalizar la sesión, haz clic en
Detener sesión.Duración de la sesión
La duración máxima predeterminada de una sesión de conversación es de 10 minutos. Se enviará una notificación go_away
(BidiGenerateContentServerMessage.go_away
) al cliente 60 segundos antes de que finalice la sesión.
Cuando usas la API, puedes extender la duración de la sesión en incrementos de 10 minutos. No hay límite para la cantidad de veces que puedes extender una sesión. Para ver un ejemplo de cómo extender la duración de la sesión, consulta Habilita e inhabilita la reanudación de la sesión. Actualmente, esta función solo está disponible en la API, no en Vertex AI Studio.
Ventana de contexto
La longitud máxima del contexto de una sesión en la API de Live es de 32,768 tokens de forma predeterminada, que se asignan para almacenar datos en tiempo real que se transmiten a una velocidad de 25 tokens por segundo (TPS) para audio y 258 TPS para video, y otro contenido, incluidas entradas basadas en texto, salidas de modelos, etcétera.
Si la ventana de contexto supera la longitud máxima, se truncarán los contextos de los giros más antiguos de la ventana de contexto, de modo que el tamaño general de la ventana de contexto esté por debajo de la limitación.
La longitud de contexto predeterminada de la sesión y la longitud de contexto objetivo después de la truncación se pueden configurar con los campos context_window_compression.trigger_tokens
y context_window_compression.sliding_window.target_tokens
del mensaje de configuración, respectivamente.
Sesiones simultáneas
De forma predeterminada, puedes tener hasta 10 sesiones simultáneas por proyecto.
Actualiza las instrucciones del sistema durante la sesión
La API de Live te permite actualizar las instrucciones del sistema en medio de una sesión activa. Puedes usar esto para adaptar las respuestas del modelo durante la sesión, por ejemplo, cambiar el idioma en el que responde el modelo a otro idioma o modificar el tono con el que quieres que responda.
Cómo cambiar la configuración de detección de actividad de voz
De forma predeterminada, el modelo realiza automáticamente la detección de actividad de voz (VAD) en una transmisión de entrada de audio continua. La VAD se puede configurar con el campo realtimeInputConfig.automaticActivityDetection
del mensaje 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.
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
.
Habilita e inhabilita la reanudación de la sesión
Esta función está inhabilitada de forma predeterminada. El usuario debe habilitarla cada vez que llama a la API especificando el campo en la solicitud a la API, y se aplica la privacidad a nivel del proyecto para los datos almacenados en caché. Si habilitas la reanudación de la sesión, el usuario puede volver a conectarse a una sesión anterior en un plazo de 24 horas almacenando datos almacenados en caché, incluidos los datos de instrucciones de texto, video y audio, y los resultados del modelo, durante un máximo de 24 horas. Para lograr una retención de datos nula, no habilites esta función.
Para habilitar la función de reanudación de la sesión, configura el campo session_resumption
del mensaje BidiGenerateContentSetup
. Si está habilitado, el servidor tomará periódicamente una instantánea de los contextos de sesión almacenados en caché actuales y los almacenará en el almacenamiento interno. Cuando se tome una instantánea correctamente, se mostrará un resumption_update
con el ID de control que puedes registrar y usar más adelante para reanudar la sesión desde la instantánea.
Este es un ejemplo de cómo habilitar la función de reanudación de la sesión y recopilar la información del ID de control:
SDK de IA generativa para Python
# Set model generation_config CONFIG = {"response_modalities": ["TEXT"]} headers = { "Content-Type": "application/json", "Authorization": f"Bearer {bearer_token[0]}", } # Connect to the server async with connect(SERVICE_URL, additional_headers=headers) as ws: # Setup the session await ws.send( json.dumps( { "setup": { "model": "gemini-2.0-flash-live-preview-04-09", "generation_config": CONFIG, # Enable session resumption. "session_resumption": {}, } } ) ) # Receive setup response raw_response = await ws.recv(decode=False) setup_response = json.loads(raw_response.decode("ascii")) # Send text message text_input = "Hello? Gemini are you there?" display(Markdown(f"**Input:** {text_input}")) msg = { "client_content": { "turns": [{"role": "user", "parts": [{"text": text_input}]}], "turn_complete": True, } } await ws.send(json.dumps(msg)) responses = [] handle_id = "" turn_completed = False resumption_received = False # Receive chucks of server response, # wait for turn completion and resumption handle. async for raw_response in ws: response = json.loads(raw_response.decode()) server_content = response.pop("serverContent", None) resumption_update = response.pop("sessionResumptionUpdate", None) if server_content is not None: model_turn = server_content.pop("modelTurn", None) if model_turn is not None: parts = model_turn.pop("parts", None) if parts is not None: responses.append(parts[0]["text"]) # End of turn turn_complete = server_content.pop("turnComplete", None) if turn_complete: turn_completed = True elif resumption_update is not None: handle_id = resumption_update['newHandle'] resumption_received = True else: continue if turn_complete and resumption_received: break # Print the server response display(Markdown(f"**Response >** {''.join(responses)}")) display(Markdown(f"**Session Handle ID >** {handle_id}"))
Si deseas reanudar la sesión anterior, puedes establecer el campo handle
de la configuración de setup.session_resumption
en el ID de control registrado anteriormente:
SDK de IA generativa para Python
# Set model generation_config CONFIG = {"response_modalities": ["TEXT"]} headers = { "Content-Type": "application/json", "Authorization": f"Bearer {bearer_token[0]}", } # Connect to the server async with connect(SERVICE_URL, additional_headers=headers) as ws: # Setup the session await ws.send( json.dumps( { "setup": { "model": "gemini-2.0-flash-live-preview-04-09", "generation_config": CONFIG, # Enable session resumption. "session_resumption": { "handle": handle_id, }, } } ) ) # Receive setup response raw_response = await ws.recv(decode=False) setup_response = json.loads(raw_response.decode("ascii")) # Send text message text_input = "What was the last question I asked?" display(Markdown(f"**Input:** {text_input}")) msg = { "client_content": { "turns": [{"role": "user", "parts": [{"text": text_input}]}], "turn_complete": True, } } await ws.send(json.dumps(msg)) responses = [] handle_id = "" turn_completed = False resumption_received = False # Receive chucks of server response, # wait for turn completion and resumption handle. async for raw_response in ws: response = json.loads(raw_response.decode()) server_content = response.pop("serverContent", None) resumption_update = response.pop("sessionResumptionUpdate", None) if server_content is not None: model_turn = server_content.pop("modelTurn", None) if model_turn is not None: parts = model_turn.pop("parts", None) if parts is not None: responses.append(parts[0]["text"]) # End of turn turn_complete = server_content.pop("turnComplete", None) if turn_complete: turn_completed = True elif resumption_update is not None: handle_id = resumption_update['newHandle'] resumption_received = True else: continue if turn_complete and resumption_received: break # Print the server response # Expected answer: "You just asked if I was there." display(Markdown(f"**Response >** {''.join(responses)}")) display(Markdown(f"**Session Handle >** {resumption_update}"))
Si deseas lograr una reanudación de sesión sin interrupciones, puedes habilitar el modo transparente:
SDK de IA generativa para Python
await ws.send( json.dumps( { "setup": { "model": "gemini-2.0-flash-live-preview-04-09", "generation_config": CONFIG, # Enable session resumption. "session_resumption": { "transparent": True, }, } } ) )
Usa llamadas a función
Puedes usar las llamadas a función para crear una descripción de una función y, luego, pasar esa descripción al modelo en una solicitud. La respuesta del modelo incluye el nombre de una función que coincide con la descripción y los argumentos con los que se la llama.
Todas las funciones deben declararse al comienzo de la sesión. Para ello, se deben enviar definiciones de herramientas como parte del mensaje setup
.
SDK de IA generativa para Python
# Set model generation_config CONFIG = {"response_modalities": ["TEXT"]} # Define function declarations TOOLS = { "function_declarations": { "name": "get_current_weather", "description": "Get the current weather in the given location", "parameters": { "type": "OBJECT", "properties": {"location": {"type": "STRING"}}, }, } } headers = { "Content-Type": "application/json", "Authorization": f"Bearer {bearer_token[0]}", } # Connect to the server async with connect(SERVICE_URL, additional_headers=headers) as ws: # Setup the session await ws.send( json.dumps( { "setup": { "model": "gemini-2.0-flash-live-preview-04-09", "generation_config": CONFIG, "tools": TOOLS, } } ) ) # Receive setup response raw_response = await ws.recv(decode=False) setup_response = json.loads(raw_response.decode()) # Send text message text_input = "Get the current weather in Santa Clara, San Jose and Mountain View" display(Markdown(f"**Input:** {text_input}")) msg = { "client_content": { "turns": [{"role": "user", "parts": [{"text": text_input}]}], "turn_complete": True, } } await ws.send(json.dumps(msg)) responses = [] # Receive chucks of server response async for raw_response in ws: response = json.loads(raw_response.decode("UTF-8")) if (tool_call := response.get("toolCall")) is not None: for function_call in tool_call["functionCalls"]: responses.append(f"FunctionCall: {str(function_call)}\n") if (server_content := response.get("serverContent")) is not None: if server_content.get("turnComplete", True): break # Print the server response display(Markdown("**Response >** {}".format("\n".join(responses))))
Usa la ejecución de código
Puedes usar la ejecución de código con la API de Live para generar y ejecutar código de Python directamente.
SDK de IA generativa para Python
# Set model generation_config CONFIG = {"response_modalities": ["TEXT"]} # Set code execution TOOLS = {"code_execution": {}} headers = { "Content-Type": "application/json", "Authorization": f"Bearer {bearer_token[0]}", } # Connect to the server async with connect(SERVICE_URL, additional_headers=headers) as ws: # Setup the session await ws.send( json.dumps( { "setup": { "model": "gemini-2.0-flash-live-preview-04-09", "generation_config": CONFIG, "tools": TOOLS, } } ) ) # Receive setup response raw_response = await ws.recv(decode=False) setup_response = json.loads(raw_response.decode()) # Send text message text_input = "Write code to calculate the 15th fibonacci number then find the nearest palindrome to it" display(Markdown(f"**Input:** {text_input}")) msg = { "client_content": { "turns": [{"role": "user", "parts": [{"text": text_input}]}], "turn_complete": True, } } await ws.send(json.dumps(msg)) responses = [] # Receive chucks of server response async for raw_response in ws: response = json.loads(raw_response.decode("UTF-8")) if (server_content := response.get("serverContent")) is not None: if (model_turn:= server_content.get("modelTurn")) is not None: if (parts := model_turn.get("parts")) is not None: if parts[0].get("text"): responses.append(parts[0]["text"]) for part in parts: if (executable_code := part.get("executableCode")) is not None: display( Markdown( f"""**Executable code:** ```py {executable_code.get("code")} ``` """ ) ) if server_content.get("turnComplete", False): break # Print the server response display(Markdown(f"**Response >** {''.join(responses)}"))
Usa la fundamentación con la Búsqueda de Google
Puedes usar la conexión a tierra con la Búsqueda de Google con la API de Live mediante google_search
:
SDK de IA generativa para Python
# Set model generation_config CONFIG = {"response_modalities": ["TEXT"]} # Set google search TOOLS = {"google_search": {}} headers = { "Content-Type": "application/json", "Authorization": f"Bearer {bearer_token[0]}", } # Connect to the server async with connect(SERVICE_URL, additional_headers=headers) as ws: # Setup the session await ws.send( json.dumps( { "setup": { "model": "gemini-2.0-flash-live-preview-04-09", "generation_config": CONFIG, "tools": TOOLS, } } ) ) # Receive setup response raw_response = await ws.recv(decode=False) setup_response = json.loads(raw_response.decode()) # Send text message text_input = "What is the current weather in San Jose, CA?" display(Markdown(f"**Input:** {text_input}")) msg = { "client_content": { "turns": [{"role": "user", "parts": [{"text": text_input}]}], "turn_complete": True, } } await ws.send(json.dumps(msg)) responses = [] # Receive chucks of server response async for raw_response in ws: response = json.loads(raw_response.decode()) server_content = response.pop("serverContent", None) if server_content is None: break model_turn = server_content.pop("modelTurn", None) if model_turn is not None: parts = model_turn.pop("parts", None) if parts is not None: responses.append(parts[0]["text"]) # End of turn turn_complete = server_content.pop("turnComplete", None) if turn_complete: break # Print the server response display(Markdown("**Response >** {}".format("\n".join(responses))))
Limitaciones
Consulta la sección de limitaciones de la API de Gemini Live de nuestra documentación de referencia para obtener la lista completa de las limitaciones actuales de la API de Live.
Precios
Consulta nuestra página de precios para obtener más detalles.
Más información
Para obtener más información sobre la API en vivo, como la referencia de la API de WebSocket
, consulta la documentación de la API de Gemini.