A API Live permite interações de voz e vídeo bidirecionais de baixa latência com o Gemini, permitindo que você converse com o Gemini ao vivo enquanto transmite a entrada de vídeo ou compartilha sua tela. Com a API Live, você pode oferecer aos usuários finais a experiência de conversas por voz naturais e semelhantes às humanas.
Você pode testar a API Live no Google AI Studio. Para usar a API Live no Google AI Studio, selecione Stream.
Como a API Live funciona
Streaming
A API Live usa um modelo de streaming em uma conexão WebSocket. Quando você interage com a API, uma conexão persistente é criada. Sua entrada (áudio, vídeo ou texto) é transmitida continuamente para o modelo, e a resposta do modelo (texto ou áudio) é transmitida de volta em tempo real pela mesma conexão.
Esse streaming bidirecional garante baixa latência e oferece suporte a recursos como detecção de atividade de voz, uso de ferramentas e geração de fala.
Para mais informações sobre a API WebSockets, consulte a referência da API WebSockets.
Geração de saídas
A API Live processa entradas multimodais (texto, áudio, vídeo) para gerar texto ou áudio em tempo real. Ele vem com um mecanismo integrado para gerar áudio e, dependendo da versão do modelo que você usa, ele usa um dos dois métodos de geração de áudio:
- Meia cascata: o modelo recebe a entrada de áudio nativa e usa uma cascata de modelos especializados diferentes para processar a entrada e gerar a saída de áudio.
- Nativo: o Gemini 2.5 apresenta a geração de áudio nativa, que gera diretamente a saída de áudio, oferecendo um som mais natural, vozes mais expressivas, mais consciência do contexto, por exemplo, tom e respostas mais proativas.
Como criar com a API Live
Antes de começar a criar com a API Live, escolha a abordagem de geração de áudio que melhor atenda às suas necessidades.
Como estabelecer uma conexão
O exemplo a seguir mostra como criar uma conexão com uma chave 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, 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 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();
Enviar e receber mensagens de texto
Veja como enviar e receber mensagens 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 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();
Enviar e receber áudio
É possível enviar áudio convertendo-o para o formato PCM de 16 bits, 16 kHz, mono. Este exemplo lê um arquivo WAV e o envia no formato correto:
# 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();
É possível receber áudio definindo AUDIO
como modalidade de resposta. Este exemplo
salva os dados recebidos como um arquivo 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 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())
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.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 áudio
Os dados de áudio na API Live são sempre brutos, little-endian,
PCM de 16 bits. A saída de áudio sempre usa uma taxa de amostragem de 24 kHz. O áudio de entrada
é nativo de 16 kHz, mas a API Live vai fazer uma nova amostragem, se necessário,
para que qualquer taxa de amostragem possa ser enviada. Para transmitir a taxa de amostragem do áudio de entrada, defina
o tipo MIME de cada Blob que contém áudio para um valor
como audio/pcm;rate=16000
.
Como receber transcrições de áudio
É possível ativar a transcrição da saída de áudio do modelo enviando
output_audio_transcription
na configuração de configuração. O idioma da transcrição é
inferido da resposta do 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())
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],
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();
É possível ativar a transcrição da entrada de áudio enviando
input_audio_transcription
na configuração de configuração.
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"],
"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())
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],
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();
Streaming de áudio e vídeo
Instruções do sistema
As instruções do sistema permitem orientar o comportamento de um modelo com base nas suas necessidades e casos de uso específicos. As instruções do sistema podem ser definidas na configuração de configuração e permanecem em vigor durante toda a sessão.
config = {
"system_instruction": "You are a helpful assistant and answer in a friendly tone.",
"response_modalities": ["TEXT"],
}
const config = {
responseModalities: [Modality.TEXT],
systemInstruction: "You are a helpful assistant and answer in a friendly tone."
};
Atualizações incrementais de conteúdo
Use atualizações incrementais para enviar entrada de texto, estabelecer o contexto da sessão ou restaurar o contexto da sessão. Para contextos curtos, você pode enviar interações passo a passo para representar a sequência exata 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)
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 mais longos, é recomendável fornecer um único resumo de mensagem para liberar a janela de contexto para interações subsequentes.
Como mudar a voz e o idioma
A API Live é compatível com as seguintes vozes: Puck, Charon, Kore, Fenrir, Aoede, Leda, Orus e Zephyr.
Para especificar uma voz, defina o nome da voz no objeto speechConfig
como parte
da configuração da sessão:
config = {
"response_modalities": ["AUDIO"],
"speech_config": {
"voice_config": {"prebuilt_voice_config": {"voice_name": "Kore"}}
},
}
const config = {
responseModalities: [Modality.AUDIO],
speechConfig: { voiceConfig: { prebuiltVoiceConfig: { voiceName: "Kore" } } }
};
A API Live oferece suporte a vários idiomas.
Para mudar o idioma, defina o código do idioma no objeto speechConfig
como parte da configuração da sessão:
config = {
"response_modalities": ["AUDIO"],
"speech_config": {
"language_code": "de-DE"
}
}
const config = {
responseModalities: [Modality.AUDIO],
speechConfig: { languageCode: "de-DE" }
};
Saída de áudio nativa
Com a API Live, você também pode acessar modelos que permitem saída de áudio nativa, além de entrada de áudio nativa. Isso permite saídas de áudio de maior qualidade com melhor ritmo, naturalidade da voz, verbosidade e humor.
A saída de áudio nativa é compatível com os seguintes modelos de áudio nativo:
gemini-2.5-flash-preview-native-audio-dialog
gemini-2.5-flash-exp-native-audio-thinking-dialog
Como usar a saída de áudio nativa
Para usar a saída de áudio nativa, configure um dos modelos de áudio nativos
e defina response_modalities
como AUDIO
.
Consulte Enviar e receber áudio para conferir um exemplo completo.
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
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();
Computação afetiva
Esse recurso permite que o Gemini adapte o estilo de resposta à expressão e ao tom de entrada.
Para usar a caixa de diálogo afetiva, defina a versão da API como v1alpha
e defina
enable_affective_dialog
como true
na mensagem de configuração:
client = genai.Client(api_key="GOOGLE_API_KEY", http_options={"api_version": "v1alpha"})
config = types.LiveConnectConfig(
response_modalities=["AUDIO"],
enable_affective_dialog=True
)
const ai = new GoogleGenAI({ apiKey: "GOOGLE_API_KEY", httpOptions: {"apiVersion": "v1alpha"} });
const config = {
responseModalities: [Modality.AUDIO],
enableAffectiveDialog: true
};
No momento, a caixa de diálogo afetiva tem suporte apenas nos modelos de saída de áudio nativos.
Áudio proativo
Quando esse recurso está ativado, o Gemini pode decidir proativamente não responder se o conteúdo não for relevante.
Para usá-lo, defina a versão da API como v1alpha
e configure o campo proactivity
na mensagem de configuração e defina
proactive_audio
como true
:
client = genai.Client(api_key="GOOGLE_API_KEY", http_options={"api_version": "v1alpha"})
config = types.LiveConnectConfig(
response_modalities=["AUDIO"],
proactivity={'proactive_audio': True}
)
const ai = new GoogleGenAI({ apiKey: "GOOGLE_API_KEY", httpOptions: {"apiVersion": "v1alpha"} });
const config = {
responseModalities: [Modality.AUDIO],
proactivity: { proactiveAudio: true }
}
No momento, o áudio proativo tem suporte apenas nos modelos de saída de áudio nativo.
Saída de áudio nativa com pensamento
A saída de áudio nativa oferece suporte a recursos de pensamento,
disponível em um modelo separado gemini-2.5-flash-exp-native-audio-thinking-dialog
.
Consulte Enviar e receber áudio para conferir um exemplo completo.
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
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();
Uso da ferramenta com a API Live
É possível definir ferramentas como Chamada de função, Execução de código e Pesquisa Google com a API Live.
Visão geral das ferramentas compatíveis
Confira uma breve visão geral das ferramentas disponíveis para cada modelo:
Ferramenta | Modelos em cascatagemini-2.0-flash-live-001 |
gemini-2.5-flash-preview-native-audio-dialog |
gemini-2.5-flash-exp-native-audio-thinking-dialog |
---|---|---|---|
Pesquisa | Sim | Sim | Sim |
Chamadas de função | Sim | Sim | Não |
Execução de código | Sim | Não | Não |
Contexto de URL | Sim | Não | Não |
Chamadas de função
É possível definir declarações de função como parte da configuração da sessão. Consulte o tutorial de chamada de função para saber mais.
Depois de receber chamadas de ferramentas, o cliente precisa responder com uma lista de
objetos FunctionResponse
usando o 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 chunk.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())
import { GoogleGenAI, Modality } from '@google/genai';
const ai = new GoogleGenAI({ apiKey: "GOOGLE_API_KEY" });
const model = 'gemini-2.0-flash-live-001';
// Simple function definitions
const turn_on_the_lights = { name: "turn_on_the_lights" } // , description: '...', parameters: { ... }
const turn_off_the_lights = { name: "turn_off_the_lights" }
const tools = [{ functionDeclarations: [turn_on_the_lights, turn_off_the_lights] }]
const config = {
responseModalities: [Modality.TEXT],
tools: tools
}
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;
} else if (message.toolCall) {
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 = 'Turn on the lights please';
session.sendClientContent({ turns: inputTurns });
let turns = await handleTurn();
for (const turn of turns) {
if (turn.serverContent && turn.serverContent.modelTurn && turn.serverContent.modelTurn.parts) {
for (const part of turn.serverContent.modelTurn.parts) {
if (part.text) {
console.debug('Received text: %s\n', part.text);
}
}
}
else if (turn.toolCall) {
const functionResponses = [];
for (const fc of turn.toolCall.functionCalls) {
functionResponses.push({
id: fc.id,
name: fc.name,
response: { result: "ok" } // simple, hard-coded function response
});
}
console.debug('Sending tool response...\n');
session.sendToolResponse({ functionResponses: functionResponses });
}
}
// Check again for new messages
turns = await handleTurn();
for (const turn of turns) {
if (turn.serverContent && turn.serverContent.modelTurn && turn.serverContent.modelTurn.parts) {
for (const part of turn.serverContent.modelTurn.parts) {
if (part.text) {
console.debug('Received text: %s\n', part.text);
}
}
}
}
session.close();
}
async function main() {
await live().catch((e) => console.error('got error', e));
}
main();
Com um único comando, o modelo pode gerar várias chamadas de função e o código necessário para encadear as saídas. Esse código é executado em um ambiente de sandbox, gerando mensagens BidiGenerateContentToolCall posteriores.
Chamada de função assíncrona
Por padrão, a execução é pausada até que os resultados de cada chamada de função estejam disponíveis, o que garante o processamento sequencial. Isso significa que você não poderá continuar interagindo com o modelo enquanto as funções estiverem sendo executadas.
Se você não quiser bloquear a conversa, poderá pedir ao modelo para executar as funções de forma assíncrona.
Para fazer isso, primeiro adicione um behavior
às definições
de função:
# 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
import { GoogleGenAI, Modality, Behavior } from '@google/genai';
// Non-blocking function definitions
const turn_on_the_lights = {name: "turn_on_the_lights", behavior: Behavior.NON_BLOCKING}
// Blocking function definitions
const turn_off_the_lights = {name: "turn_off_the_lights"}
const tools = [{ functionDeclarations: [turn_on_the_lights, turn_off_the_lights] }]
NON-BLOCKING
garante que a função seja executada de forma assíncrona enquanto você pode
continuar interagindo com o modelo.
Em seguida, é necessário informar ao modelo como se comportar quando ele receber o
FunctionResponse
usando o parâmetro scheduling
. Ele pode:
- Interromper o que está fazendo e informar a resposta recebida imediatamente
(
scheduling="INTERRUPT"
), - Aguarde até que ele termine o que está fazendo
(
scheduling="WHEN_IDLE"
), Ou não faça nada e use esse conhecimento mais tarde na discussão (
scheduling="SILENT"
)
# for a non-blocking function definition, apply scheduling in the function response:
function_response = types.FunctionResponse(
id=fc.id,
name=fc.name,
response={
"result": "ok",
"scheduling": "INTERRUPT" # Can also be WHEN_IDLE or SILENT
}
)
import { GoogleGenAI, Modality, Behavior, FunctionResponseScheduling } from '@google/genai';
// for a non-blocking function definition, apply scheduling in the function response:
const functionResponse = {
id: fc.id,
name: fc.name,
response: {
result: "ok",
scheduling: FunctionResponseScheduling.INTERRUPT // Can also be WHEN_IDLE or SILENT
}
}
Execução de código
É possível definir a execução do código como parte da configuração da sessão. Consulte o tutorial de execução de código para saber mais.
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())
import { GoogleGenAI, Modality } from '@google/genai';
const ai = new GoogleGenAI({ apiKey: "GOOGLE_API_KEY" });
const model = 'gemini-2.0-flash-live-001';
const tools = [{codeExecution: {}}]
const config = {
responseModalities: [Modality.TEXT],
tools: tools
}
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;
} else if (message.toolCall) {
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 = 'Compute the largest prime palindrome under 100000.';
session.sendClientContent({ turns: inputTurns });
const turns = await handleTurn();
for (const turn of turns) {
if (turn.serverContent && turn.serverContent.modelTurn && turn.serverContent.modelTurn.parts) {
for (const part of turn.serverContent.modelTurn.parts) {
if (part.text) {
console.debug('Received text: %s\n', part.text);
}
else if (part.executableCode) {
console.debug('executableCode: %s\n', part.executableCode.code);
}
else if (part.codeExecutionResult) {
console.debug('codeExecutionResult: %s\n', part.codeExecutionResult.output);
}
}
}
}
session.close();
}
async function main() {
await live().catch((e) => console.error('got error', e));
}
main();
Embasamento com a Pesquisa Google
É possível ativar o embasamento com a Pesquisa Google como parte da configuração da sessão. Consulte o tutorial de embasamento para saber mais.
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())
import { GoogleGenAI, Modality } from '@google/genai';
const ai = new GoogleGenAI({ apiKey: "GOOGLE_API_KEY" });
const model = 'gemini-2.0-flash-live-001';
const tools = [{googleSearch: {}}]
const config = {
responseModalities: [Modality.TEXT],
tools: tools
}
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;
} else if (message.toolCall) {
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 = 'When did the last Brazil vs. Argentina soccer match happen?';
session.sendClientContent({ turns: inputTurns });
const turns = await handleTurn();
for (const turn of turns) {
if (turn.serverContent && turn.serverContent.modelTurn && turn.serverContent.modelTurn.parts) {
for (const part of turn.serverContent.modelTurn.parts) {
if (part.text) {
console.debug('Received text: %s\n', part.text);
}
else if (part.executableCode) {
console.debug('executableCode: %s\n', part.executableCode.code);
}
else if (part.codeExecutionResult) {
console.debug('codeExecutionResult: %s\n', part.codeExecutionResult.output);
}
}
}
}
session.close();
}
async function main() {
await live().catch((e) => console.error('got error', e));
}
main();
Combinar várias ferramentas
É possível combinar várias ferramentas na API 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}
const 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!
`
const tools = [
{ googleSearch: {} },
{ codeExecution: {} },
{ functionDeclarations: [turn_on_the_lights, turn_off_the_lights] }
]
const config = {
responseModalities: [Modality.TEXT],
tools: tools
}
Como lidar com interrupções
Os usuários podem interromper a saída do modelo a qualquer momento. Quando a detecção de atividade de voz (VAD) detecta uma interrupção, a geração em andamento é cancelada e descartada. Somente as informações já enviadas ao cliente são retidas no histórico da sessão. O servidor envia uma mensagem BidiGenerateContentServerContent para informar a interrupção.
Além disso, o servidor Gemini descarta todas as chamadas de função pendentes e envia
uma mensagem BidiGenerateContentServerContent
com os IDs das chamadas canceladas.
async for response in session.receive():
if response.server_content.interrupted is True:
# The generation was interrupted
const turns = await handleTurn();
for (const turn of turns) {
if (turn.serverContent && turn.serverContent.interrupted) {
// The generation was interrupted
}
}
Detecção de atividade de voz (VAD)
Você pode configurar ou desativar a detecção de atividade de voz (VAD).
Como usar o VAD automático
Por padrão, o modelo realiza a VAD automaticamente em
um fluxo de entrada de áudio contínuo. O VAD pode ser configurado com o campo
realtimeInputConfig.automaticActivityDetection
da configuração de configuração.
Quando o fluxo de áudio é pausado por mais de um segundo (por exemplo,
porque o usuário desativou o microfone), um evento
audioStreamEnd
precisa ser enviado para limpar todo o áudio em cache. O cliente pode retomar o envio
de dados de áudio a qualquer 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())
// 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({ 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.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();
Com send_realtime_input
, a API vai responder ao áudio automaticamente com base
no VAD. Enquanto send_client_content
adiciona mensagens ao contexto do modelo em
ordem, send_realtime_input
é otimizado para resposta à custa de
ordenação determinística.
Como configurar o VAD automático
Para ter mais controle sobre a atividade de VAD, configure os seguintes parâmetros. Consulte a referência da API para mais informações.
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,
}
}
}
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,
}
}
};
Como desativar o VAD automático
Como alternativa, o VAD automático pode ser desativado definindo
realtimeInputConfig.automaticActivityDetection.disabled
como true
na mensagem
de configuração. Nessa configuração, o cliente é responsável por detectar a fala do usuário
e enviar mensagens
activityStart
e activityEnd
nos momentos apropriados. Um audioStreamEnd
não é enviado nesta
configuração. Em vez disso, qualquer interrupção do fluxo é marcada por
uma mensagem 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())
# ...
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: {} })
Contagem de tokens
Você pode encontrar o número total de tokens consumidos no campo usageMetadata da mensagem do servidor retornada.
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}")
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);
}
}
}
Como estender a duração da sessão
A duração máxima da sessão pode ser estendida para ilimitada com dois mecanismos:
Além disso, você vai receber uma mensagem de saída antes do término da sessão, permitindo que você realize outras ações.
Compactação da janela de contexto
Para permitir sessões mais longas e evitar o encerramento abrupto da conexão, ative a compressão da janela de contexto definindo o campo contextWindowCompression como parte da configuração da sessão.
Em ContextWindowCompressionConfig, é possível configurar um mecanismo de janela deslizante e o número de tokens que aciona a compactação.
from google.genai import types
config = {
"response_modalities": ["AUDIO"],
"context_window_compression": (
# Configures compression with default parameters.
types.ContextWindowCompressionConfig(
sliding_window=types.SlidingWindow(),
)
),
}
const config = {
responseModalities: [Modality.AUDIO],
contextWindowCompression: { slidingWindow: {} }
};
Retomada da sessão
Para evitar o encerramento da sessão quando o servidor redefinir periodicamente a conexão WebSocket, configure o campo sessionResumption na configuração de configuração.
A transmissão dessa configuração faz com que o
servidor envie mensagens SessionResumptionUpdate, que podem ser usadas para retomar a sessão transmitindo o último token
de retomada como SessionResumptionConfig.handle
da conexão subsequente.
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():
if message.session_resumption_update:
update = message.session_resumption_update
if update.resumable and update.new_handle:
newHandle = update.new_handle
# TODO: store newHandle and start new session with this handle
# ...
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';
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;
}
console.debug('Connecting to the service with handle %s...', previousSessionHandle)
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: {
responseModalities: [Modality.TEXT],
sessionResumption: { handle: previousSessionHandle }
// The handle of the session to resume is passed here, or else null to start a new session.
}
});
const inputTurns = 'Hello how are you?';
session.sendClientContent({ turns: inputTurns });
const turns = await handleTurn();
for (const turn of turns) {
if (turn.sessionResumptionUpdate) {
if (turn.sessionResumptionUpdate.resumable && turn.sessionResumptionUpdate.newHandle) {
let newHandle = turn.sessionResumptionUpdate.newHandle
// TODO: store newHandle and start new session with this handle
// ...
}
}
}
session.close();
}
async function main() {
await live().catch((e) => console.error('got error', e));
}
main();
Receber uma mensagem antes da desconexão da sessão
O servidor envia uma mensagem GoAway que sinaliza que a conexão atual será encerrada em breve. Essa mensagem inclui o timeLeft, que indica o tempo restante e permite que você tome outras medidas antes que a conexão seja encerrada 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)
const turns = await handleTurn();
for (const turn of turns) {
if (turn.goAway) {
console.debug('Time left: %s\n', turn.goAway.timeLeft);
}
}
Receber uma mensagem quando a geração for concluída
O servidor envia uma mensagem generationComplete que indica que o modelo terminou de gerar a resposta.
async for response in session.receive():
if response.server_content.generation_complete is True:
# The generation is complete
const turns = await handleTurn();
for (const turn of turns) {
if (turn.serverContent && turn.serverContent.generationComplete) {
// The generation is complete
}
}
Resolução da mídia
É possível especificar a resolução da mídia de entrada definindo o
campo mediaResolution
como parte da configuração da sessão:
from google.genai import types
config = {
"response_modalities": ["AUDIO"],
"media_resolution": types.MediaResolution.MEDIA_RESOLUTION_LOW,
}
import { GoogleGenAI, Modality, MediaResolution } from '@google/genai';
const config = {
responseModalities: [Modality.TEXT],
mediaResolution: MediaResolution.MEDIA_RESOLUTION_LOW,
};
Limitações
Considere as seguintes limitações da API Live ao planejar seu projeto.
Modalidades de resposta
Só é possível definir uma modalidade de resposta (TEXT
ou AUDIO
) por sessão na
configuração da sessão. Definir os dois resultados em uma mensagem de erro de configuração. Isso
significa que você pode configurar o modelo para responder com texto ou áudio,
mas não com os dois na mesma sessão.
Autenticação do cliente
A API Live só oferece autenticação de servidor para servidor e não é recomendada para uso direto do cliente. A entrada do cliente precisa ser roteada por um servidor de aplicativo intermediário para autenticação segura com a API Live.
Duração da sessão
A duração da sessão pode ser estendida para um número ilimitado ativando a compressão. Sem compressão, as sessões somente de áudio são limitadas a 15 minutos, e as sessões de áudio e vídeo são limitadas a 2 minutos. Exceder esses limites sem compressão encerrará a conexão.
Além disso, é possível configurar a retomada de sessão para permitir que o cliente retome uma sessão encerrada.
Janela de contexto
Uma sessão tem um limite de janela de contexto de:
- 128 mil tokens para modelos de saída de áudio nativa
- Tokens de 32 mil para outros modelos de API ativa
Idiomas aceitos
A API Live é compatível com os seguintes idiomas.
Idioma | Código BCP-47 |
---|---|
Alemão (Alemanha) | de-DE |
Inglês (Austrália) | en-AU |
Inglês (Reino Unido) | en-GB |
Inglês (Índia) | en-IN |
Inglês (EUA) | en-US |
Espanhol (Estados Unidos) | es-US |
Francês (França) | fr-FR |
Híndi (Índia) | hi-IN |
Português (Brasil) | pt-BR |
Árabe (genérico) | ar-XA |
Espanhol (Espanha) | es-ES |
Francês (Canadá) | fr-CA |
Indonésio (Indonésia) | id-ID |
Italiano (Itália) | it-IT |
Japonês (Japão) | ja-JP |
Turco (Turquia) | tr-TR |
Vietnamita (Vietnã) | vi-VN |
Bengali (Índia) | bn-IN |
Gujarati (Índia) | gu-IN |
Canarês (Índia) | kn-IN |
Malaiala (Índia) | ml-IN |
Marati (Índia) | mr-IN |
Tâmil (Índia) | ta-IN |
Telugo (Índia) | te-IN |
Holandês (Holanda) | nl-NL |
Coreano (Coreia do Sul) | ko-KR |
Chinês mandarim (China) | cmn-CN |
Polonês (Polônia) | pl-PL |
Russo (Rússia) | ru-RU |
Tailandês (Tailândia) | th-TH |
Integrações de terceiros
Para implantações de apps da Web e para dispositivos móveis, confira as opções em:
- Diariamente
- Livekit (em inglês)
A seguir
- Teste a API Live no Google AI Studio.
- Para mais informações sobre o Gemini 2.0 Flash Live, consulte a página do modelo.
- Confira mais exemplos no livro de receitas da API Live, no livro de receitas das ferramentas da API Live e no script de início da API Live.