Przewodnik ten zawiera obszerne informacje o możliwościach i konfiguracjach dostępnych w ramach interfejsu Live API. Na stronie Pierwsze kroki z interfejsem Live API znajdziesz omówienie i przykładowy kod dla typowych przypadków użycia.
Zanim zaczniesz
- Zapoznaj się z podstawowymi pojęciami: jeśli jeszcze tego nie zrobiono, przeczytaj najpierw stronę Pierwsze kroki z Live API . Poznasz podstawowe zasady działania interfejsu Live API oraz różnice między różnymi modelami i odpowiednimi metodami generowania dźwięku (natywny dźwięk lub półkaskady).
- Wypróbuj interfejs Live API w AI Studio: zanim zaczniesz tworzyć rozwiązanie, warto wypróbować interfejs Live API w Google AI Studio. Aby korzystać z Live API w Google AI Studio, wybierz Stream.
Nawiązywanie połączenia
Ten przykład pokazuje, jak utworzyć połączenie za pomocą klucza interfejsu API:
Python
import asyncio
from google import genai
client = genai.Client()
model = "gemini-live-2.5-flash-preview"
config = {"response_modalities": ["TEXT"]}
async def main():
async with client.aio.live.connect(model=model, config=config) as session:
print("Session started")
if __name__ == "__main__":
asyncio.run(main())
JavaScript
import { GoogleGenAI, Modality } from '@google/genai';
const ai = new GoogleGenAI({});
const model = 'gemini-live-2.5-flash-preview';
const config = { responseModalities: [Modality.TEXT] };
async function main() {
const session = await ai.live.connect({
model: model,
callbacks: {
onopen: function () {
console.debug('Opened');
},
onmessage: function (message) {
console.debug(message);
},
onerror: function (e) {
console.debug('Error:', e.message);
},
onclose: function (e) {
console.debug('Close:', e.reason);
},
},
config: config,
});
// Send content...
session.close();
}
main();
Interakcje
W następnych sekcjach znajdziesz przykłady i informacje dotyczące różnych trybów danych wejściowych i wyjściowych dostępnych w Live API.
Wysyłanie i odbieranie tekstu
Aby wysyłać i odbierać wiadomości tekstowe:
Python
import asyncio
from google import genai
client = genai.Client()
model = "gemini-live-2.5-flash-preview"
config = {"response_modalities": ["TEXT"]}
async def main():
async with client.aio.live.connect(model=model, config=config) as session:
message = "Hello, how are you?"
await session.send_client_content(
turns={"role": "user", "parts": [{"text": message}]}, turn_complete=True
)
async for response in session.receive():
if response.text is not None:
print(response.text, end="")
if __name__ == "__main__":
asyncio.run(main())
JavaScript
import { GoogleGenAI, Modality } from '@google/genai';
const ai = new GoogleGenAI({});
const model = 'gemini-live-2.5-flash-preview';
const config = { responseModalities: [Modality.TEXT] };
async function live() {
const responseQueue = [];
async function waitMessage() {
let done = false;
let message = undefined;
while (!done) {
message = responseQueue.shift();
if (message) {
done = true;
} else {
await new Promise((resolve) => setTimeout(resolve, 100));
}
}
return message;
}
async function handleTurn() {
const turns = [];
let done = false;
while (!done) {
const message = await waitMessage();
turns.push(message);
if (message.serverContent && message.serverContent.turnComplete) {
done = true;
}
}
return turns;
}
const session = await ai.live.connect({
model: model,
callbacks: {
onopen: function () {
console.debug('Opened');
},
onmessage: function (message) {
responseQueue.push(message);
},
onerror: function (e) {
console.debug('Error:', e.message);
},
onclose: function (e) {
console.debug('Close:', e.reason);
},
},
config: config,
});
const inputTurns = 'Hello how are you?';
session.sendClientContent({ turns: inputTurns });
const turns = await handleTurn();
for (const turn of turns) {
if (turn.text) {
console.debug('Received text: %s\n', turn.text);
}
else if (turn.data) {
console.debug('Received inline data: %s\n', turn.data);
}
}
session.close();
}
async function main() {
await live().catch((e) => console.error('got error', e));
}
main();
Przyrostowe aktualizacje treści
Używaj przyrostowych aktualizacji, aby wysyłać dane wejściowe tekstowe, ustalać kontekst sesji lub przywracać kontekst sesji. W przypadku krótkich kontekstów możesz wysyłać interakcje krok po kroku, aby reprezentować dokładną sekwencję zdarzeń:
Python
turns = [
{"role": "user", "parts": [{"text": "What is the capital of France?"}]},
{"role": "model", "parts": [{"text": "Paris"}]},
]
await session.send_client_content(turns=turns, turn_complete=False)
turns = [{"role": "user", "parts": [{"text": "What is the capital of Germany?"}]}]
await session.send_client_content(turns=turns, turn_complete=True)
JavaScript
let inputTurns = [
{ "role": "user", "parts": [{ "text": "What is the capital of France?" }] },
{ "role": "model", "parts": [{ "text": "Paris" }] },
]
session.sendClientContent({ turns: inputTurns, turnComplete: false })
inputTurns = [{ "role": "user", "parts": [{ "text": "What is the capital of Germany?" }] }]
session.sendClientContent({ turns: inputTurns, turnComplete: true })
W przypadku dłuższych kontekstów zalecamy podanie podsumowania w jednej wiadomości, aby zwolnić okno kontekstu na potrzeby kolejnych interakcji. Inną metodę wczytywania kontekstu sesji znajdziesz w sekcji Wznawianie sesji.
Wysyłanie i odbieranie dźwięku
Najczęstszy przykład, czyli przekształcanie dźwięku w dźwięk, jest omówiony w przewodniku dla początkujących.
Oto przykład transkrypcji audio, która odczytuje plik WAV, prześle go w prawidłowym formacie i wyświetli tekst:
Python
# Test file: https://storage.googleapis.com/generativeai-downloads/data/16000.wav
# Install helpers for converting files: pip install librosa soundfile
import asyncio
import io
from pathlib import Path
from google import genai
from google.genai import types
import soundfile as sf
import librosa
client = genai.Client()
model = "gemini-live-2.5-flash-preview"
config = {"response_modalities": ["TEXT"]}
async def main():
async with client.aio.live.connect(model=model, config=config) as session:
buffer = io.BytesIO()
y, sr = librosa.load("sample.wav", sr=16000)
sf.write(buffer, y, sr, format='RAW', subtype='PCM_16')
buffer.seek(0)
audio_bytes = buffer.read()
# If already in correct format, you can use this:
# audio_bytes = Path("sample.pcm").read_bytes()
await session.send_realtime_input(
audio=types.Blob(data=audio_bytes, mime_type="audio/pcm;rate=16000")
)
async for response in session.receive():
if response.text is not None:
print(response.text)
if __name__ == "__main__":
asyncio.run(main())
JavaScript
// Test file: https://storage.googleapis.com/generativeai-downloads/data/16000.wav
// Install helpers for converting files: npm install wavefile
import { GoogleGenAI, Modality } from '@google/genai';
import * as fs from "node:fs";
import pkg from 'wavefile';
const { WaveFile } = pkg;
const ai = new GoogleGenAI({});
const model = 'gemini-live-2.5-flash-preview';
const config = { responseModalities: [Modality.TEXT] };
async function live() {
const responseQueue = [];
async function waitMessage() {
let done = false;
let message = undefined;
while (!done) {
message = responseQueue.shift();
if (message) {
done = true;
} else {
await new Promise((resolve) => setTimeout(resolve, 100));
}
}
return message;
}
async function handleTurn() {
const turns = [];
let done = false;
while (!done) {
const message = await waitMessage();
turns.push(message);
if (message.serverContent && message.serverContent.turnComplete) {
done = true;
}
}
return turns;
}
const session = await ai.live.connect({
model: model,
callbacks: {
onopen: function () {
console.debug('Opened');
},
onmessage: function (message) {
responseQueue.push(message);
},
onerror: function (e) {
console.debug('Error:', e.message);
},
onclose: function (e) {
console.debug('Close:', e.reason);
},
},
config: config,
});
// Send Audio Chunk
const fileBuffer = fs.readFileSync("sample.wav");
// Ensure audio conforms to API requirements (16-bit PCM, 16kHz, mono)
const wav = new WaveFile();
wav.fromBuffer(fileBuffer);
wav.toSampleRate(16000);
wav.toBitDepth("16");
const base64Audio = wav.toBase64();
// If already in correct format, you can use this:
// const fileBuffer = fs.readFileSync("sample.pcm");
// const base64Audio = Buffer.from(fileBuffer).toString('base64');
session.sendRealtimeInput(
{
audio: {
data: base64Audio,
mimeType: "audio/pcm;rate=16000"
}
}
);
const turns = await handleTurn();
for (const turn of turns) {
if (turn.text) {
console.debug('Received text: %s\n', turn.text);
}
else if (turn.data) {
console.debug('Received inline data: %s\n', turn.data);
}
}
session.close();
}
async function main() {
await live().catch((e) => console.error('got error', e));
}
main();
Oto przykład konwersji tekstu na dźwięk.
Aby otrzymywać dźwięk, ustaw AUDIO
jako modalność odpowiedzi. W tym przykładzie dane są zapisywane jako plik WAV:
Python
import asyncio
import wave
from google import genai
client = genai.Client()
model = "gemini-live-2.5-flash-preview"
config = {"response_modalities": ["AUDIO"]}
async def main():
async with client.aio.live.connect(model=model, config=config) as session:
wf = wave.open("audio.wav", "wb")
wf.setnchannels(1)
wf.setsampwidth(2)
wf.setframerate(24000)
message = "Hello how are you?"
await session.send_client_content(
turns={"role": "user", "parts": [{"text": message}]}, turn_complete=True
)
async for response in session.receive():
if response.data is not None:
wf.writeframes(response.data)
# Un-comment this code to print audio data info
# if response.server_content.model_turn is not None:
# print(response.server_content.model_turn.parts[0].inline_data.mime_type)
wf.close()
if __name__ == "__main__":
asyncio.run(main())
JavaScript
import { GoogleGenAI, Modality } from '@google/genai';
import * as fs from "node:fs";
import pkg from 'wavefile';
const { WaveFile } = pkg;
const ai = new GoogleGenAI({});
const model = 'gemini-live-2.5-flash-preview';
const config = { responseModalities: [Modality.AUDIO] };
async function live() {
const responseQueue = [];
async function waitMessage() {
let done = false;
let message = undefined;
while (!done) {
message = responseQueue.shift();
if (message) {
done = true;
} else {
await new Promise((resolve) => setTimeout(resolve, 100));
}
}
return message;
}
async function handleTurn() {
const turns = [];
let done = false;
while (!done) {
const message = await waitMessage();
turns.push(message);
if (message.serverContent && message.serverContent.turnComplete) {
done = true;
}
}
return turns;
}
const session = await ai.live.connect({
model: model,
callbacks: {
onopen: function () {
console.debug('Opened');
},
onmessage: function (message) {
responseQueue.push(message);
},
onerror: function (e) {
console.debug('Error:', e.message);
},
onclose: function (e) {
console.debug('Close:', e.reason);
},
},
config: config,
});
const inputTurns = 'Hello how are you?';
session.sendClientContent({ turns: inputTurns });
const turns = await handleTurn();
// Combine audio data strings and save as wave file
const combinedAudio = turns.reduce((acc, turn) => {
if (turn.data) {
const buffer = Buffer.from(turn.data, 'base64');
const intArray = new Int16Array(buffer.buffer, buffer.byteOffset, buffer.byteLength / Int16Array.BYTES_PER_ELEMENT);
return acc.concat(Array.from(intArray));
}
return acc;
}, []);
const audioBuffer = new Int16Array(combinedAudio);
const wf = new WaveFile();
wf.fromScratch(1, 24000, '16', audioBuffer);
fs.writeFileSync('output.wav', wf.toBuffer());
session.close();
}
async function main() {
await live().catch((e) => console.error('got error', e));
}
main();
Formaty audio
Dane audio w Live API są zawsze w postaci surowych danych 16-bitowego formatu PCM w porządku little-endian. Wyjście audio zawsze używa częstotliwości próbkowania 24 kHz. Wejście audio ma domyślnie częstotliwość 16 kHz, ale interfejs Live API w razie potrzeby przepróbkuje sygnał, aby można było przesłać dowolną częstotliwość próbkowania. Aby przekazać częstotliwość próbkowania wejściowego dźwięku, ustaw typ MIME każdego bloba zawierającego dźwięk na wartość, np. audio/pcm;rate=16000
.
Zapisy tekstowe
Transkrypcję wyjścia audio modelu możesz włączyć, wysyłając output_audio_transcription
w konfiguracji konfiguracji. Język transkrypcji jest wywnioskowany na podstawie odpowiedzi modelu.
Python
import asyncio
from google import genai
from google.genai import types
client = genai.Client()
model = "gemini-live-2.5-flash-preview"
config = {"response_modalities": ["AUDIO"],
"output_audio_transcription": {}
}
async def main():
async with client.aio.live.connect(model=model, config=config) as session:
message = "Hello? Gemini are you there?"
await session.send_client_content(
turns={"role": "user", "parts": [{"text": message}]}, turn_complete=True
)
async for response in session.receive():
if response.server_content.model_turn:
print("Model turn:", response.server_content.model_turn)
if response.server_content.output_transcription:
print("Transcript:", response.server_content.output_transcription.text)
if __name__ == "__main__":
asyncio.run(main())
JavaScript
import { GoogleGenAI, Modality } from '@google/genai';
const ai = new GoogleGenAI({});
const model = 'gemini-live-2.5-flash-preview';
const config = {
responseModalities: [Modality.AUDIO],
outputAudioTranscription: {}
};
async function live() {
const responseQueue = [];
async function waitMessage() {
let done = false;
let message = undefined;
while (!done) {
message = responseQueue.shift();
if (message) {
done = true;
} else {
await new Promise((resolve) => setTimeout(resolve, 100));
}
}
return message;
}
async function handleTurn() {
const turns = [];
let done = false;
while (!done) {
const message = await waitMessage();
turns.push(message);
if (message.serverContent && message.serverContent.turnComplete) {
done = true;
}
}
return turns;
}
const session = await ai.live.connect({
model: model,
callbacks: {
onopen: function () {
console.debug('Opened');
},
onmessage: function (message) {
responseQueue.push(message);
},
onerror: function (e) {
console.debug('Error:', e.message);
},
onclose: function (e) {
console.debug('Close:', e.reason);
},
},
config: config,
});
const inputTurns = 'Hello how are you?';
session.sendClientContent({ turns: inputTurns });
const turns = await handleTurn();
for (const turn of turns) {
if (turn.serverContent && turn.serverContent.outputTranscription) {
console.debug('Received output transcription: %s\n', turn.serverContent.outputTranscription.text);
}
}
session.close();
}
async function main() {
await live().catch((e) => console.error('got error', e));
}
main();
Transkrypcję wejścia audio możesz włączyć, wysyłając input_audio_transcription
w konfiguracji konfiguracji.
Python
import asyncio
from pathlib import Path
from google import genai
from google.genai import types
client = genai.Client()
model = "gemini-live-2.5-flash-preview"
config = {
"response_modalities": ["TEXT"],
"input_audio_transcription": {},
}
async def main():
async with client.aio.live.connect(model=model, config=config) as session:
audio_data = Path("16000.pcm").read_bytes()
await session.send_realtime_input(
audio=types.Blob(data=audio_data, mime_type='audio/pcm;rate=16000')
)
async for msg in session.receive():
if msg.server_content.input_transcription:
print('Transcript:', msg.server_content.input_transcription.text)
if __name__ == "__main__":
asyncio.run(main())
JavaScript
import { GoogleGenAI, Modality } from '@google/genai';
import * as fs from "node:fs";
import pkg from 'wavefile';
const { WaveFile } = pkg;
const ai = new GoogleGenAI({});
const model = 'gemini-live-2.5-flash-preview';
const config = {
responseModalities: [Modality.TEXT],
inputAudioTranscription: {}
};
async function live() {
const responseQueue = [];
async function waitMessage() {
let done = false;
let message = undefined;
while (!done) {
message = responseQueue.shift();
if (message) {
done = true;
} else {
await new Promise((resolve) => setTimeout(resolve, 100));
}
}
return message;
}
async function handleTurn() {
const turns = [];
let done = false;
while (!done) {
const message = await waitMessage();
turns.push(message);
if (message.serverContent && message.serverContent.turnComplete) {
done = true;
}
}
return turns;
}
const session = await ai.live.connect({
model: model,
callbacks: {
onopen: function () {
console.debug('Opened');
},
onmessage: function (message) {
responseQueue.push(message);
},
onerror: function (e) {
console.debug('Error:', e.message);
},
onclose: function (e) {
console.debug('Close:', e.reason);
},
},
config: config,
});
// Send Audio Chunk
const fileBuffer = fs.readFileSync("16000.wav");
// Ensure audio conforms to API requirements (16-bit PCM, 16kHz, mono)
const wav = new WaveFile();
wav.fromBuffer(fileBuffer);
wav.toSampleRate(16000);
wav.toBitDepth("16");
const base64Audio = wav.toBase64();
// If already in correct format, you can use this:
// const fileBuffer = fs.readFileSync("sample.pcm");
// const base64Audio = Buffer.from(fileBuffer).toString('base64');
session.sendRealtimeInput(
{
audio: {
data: base64Audio,
mimeType: "audio/pcm;rate=16000"
}
}
);
const turns = await handleTurn();
for (const turn of turns) {
if (turn.serverContent && turn.serverContent.outputTranscription) {
console.log("Transcription")
console.log(turn.serverContent.outputTranscription.text);
}
}
for (const turn of turns) {
if (turn.text) {
console.debug('Received text: %s\n', turn.text);
}
else if (turn.data) {
console.debug('Received inline data: %s\n', turn.data);
}
else if (turn.serverContent && turn.serverContent.inputTranscription) {
console.debug('Received input transcription: %s\n', turn.serverContent.inputTranscription.text);
}
}
session.close();
}
async function main() {
await live().catch((e) => console.error('got error', e));
}
main();
strumieniowanie dźwięku i obrazu,
Zmiana głosu i języka
Poszczególne modele interfejsu Live API obsługują różne zestawy głosów. Ustawienie „półkaskady” obsługuje Puck, Charon, Kore, Fenrir, Aoede, Leda, Orus i Zephyr. Natywny dźwięk obsługuje znacznie dłuższą listę (identyczną z listą modeli TTS). Możesz posłuchać wszystkich głosów w AI Studio.
Aby określić głos, ustaw nazwę głosu w obiekcie speechConfig
w ramach konfiguracji sesji:
Python
config = {
"response_modalities": ["AUDIO"],
"speech_config": {
"voice_config": {"prebuilt_voice_config": {"voice_name": "Kore"}}
},
}
JavaScript
const config = {
responseModalities: [Modality.AUDIO],
speechConfig: { voiceConfig: { prebuiltVoiceConfig: { voiceName: "Kore" } } }
};
Interfejs Live API obsługuje wiele języków.
Aby zmienić język, skonfiguruj kod języka w obiekcie speechConfig
w ramach konfiguracji sesji:
Python
config = {
"response_modalities": ["AUDIO"],
"speech_config": {
"language_code": "de-DE"
}
}
JavaScript
const config = {
responseModalities: [Modality.AUDIO],
speechConfig: { languageCode: "de-DE" }
};
Funkcje natywnego dźwięku
Te funkcje są dostępne tylko w przypadku dźwięku natywnego. Więcej informacji o dźwięku natywnym znajdziesz w artykule Wybieranie modelu i generowanie dźwięku.
Jak korzystać z natywnego wyjścia audio
Aby korzystać z natywnego wyjścia audio, skonfiguruj jeden z natywnych modeli audio i ustaw wartość response_modalities
na AUDIO
.
Pełny przykład znajdziesz w artykule Wysyłanie i odbieranie plików audio.
Python
model = "gemini-2.5-flash-preview-native-audio-dialog"
config = types.LiveConnectConfig(response_modalities=["AUDIO"])
async with client.aio.live.connect(model=model, config=config) as session:
# Send audio input and receive audio
JavaScript
const model = 'gemini-2.5-flash-preview-native-audio-dialog';
const config = { responseModalities: [Modality.AUDIO] };
async function main() {
const session = await ai.live.connect({
model: model,
config: config,
callbacks: ...,
});
// Send audio input and receive audio
session.close();
}
main();
Afektywny dialog
Dzięki tej funkcji Gemini może dostosowywać styl odpowiedzi do wyrażenia i tonu rozmówcy.
Aby używać dialogu emocjonalnego, ustaw wersję interfejsu API na v1alpha
, a w wiadomości konfiguracyjnej ustaw enable_affective_dialog
na true
:
Python
client = genai.Client(http_options={"api_version": "v1alpha"})
config = types.LiveConnectConfig(
response_modalities=["AUDIO"],
enable_affective_dialog=True
)
JavaScript
const ai = new GoogleGenAI({ httpOptions: {"apiVersion": "v1alpha"} });
const config = {
responseModalities: [Modality.AUDIO],
enableAffectiveDialog: true
};
Pamiętaj, że dialog emocjonalny jest obecnie obsługiwany tylko przez modele natywnej obsługi dźwięku.
Proaktywny dźwięk
Gdy ta funkcja jest włączona, Gemini może z góry zdecydować, że nie odpowie, jeśli treści nie są istotne.
Aby go użyć, ustaw wersję interfejsu API na v1alpha
, skonfiguruj pole proactivity
w wiadomości konfiguracyjnej i ustaw wartość proactive_audio
na true
:
Python
client = genai.Client(http_options={"api_version": "v1alpha"})
config = types.LiveConnectConfig(
response_modalities=["AUDIO"],
proactivity={'proactive_audio': True}
)
JavaScript
const ai = new GoogleGenAI({ httpOptions: {"apiVersion": "v1alpha"} });
const config = {
responseModalities: [Modality.AUDIO],
proactivity: { proactiveAudio: true }
}
Proaktywny dźwięk jest obecnie obsługiwany tylko przez modele z natywnym wyjściem audio.
Natywne wyjście audio z dźwiękiem myśli
Natywna funkcja wyjścia audio obsługuje funkcje myślenia, dostępne w ramach osobnego modelu gemini-2.5-flash-exp-native-audio-thinking-dialog
.
Pełny przykład znajdziesz w artykule Wysyłanie i odbieranie plików audio.
Python
model = "gemini-2.5-flash-exp-native-audio-thinking-dialog"
config = types.LiveConnectConfig(response_modalities=["AUDIO"])
async with client.aio.live.connect(model=model, config=config) as session:
# Send audio input and receive audio
JavaScript
const model = 'gemini-2.5-flash-exp-native-audio-thinking-dialog';
const config = { responseModalities: [Modality.AUDIO] };
async function main() {
const session = await ai.live.connect({
model: model,
config: config,
callbacks: ...,
});
// Send audio input and receive audio
session.close();
}
main();
wykrywanie aktywności głosowej (VAD);
Wykrywanie aktywności głosowej (VAD) pozwala modelowi rozpoznawać momenty, w których użytkownik mówi. Jest to niezbędne do prowadzenia naturalnych rozmów, ponieważ pozwala użytkownikowi przerwać model w dowolnym momencie.
Gdy wykryje przerwanie, bieżące generowanie zostanie anulowane i odrzucone. W historii sesji są przechowywane tylko informacje już wysłane do klienta. Następnie serwer wysyła wiadomość BidiGenerateContentServerContent
, aby zgłosić przerwanie połączenia.
Serwer Gemini odrzuca oczekujące wywołania funkcji i wysyła wiadomość BidiGenerateContentServerContent
z identyfikatorami anulowanych wywołań.
Python
async for response in session.receive():
if response.server_content.interrupted is True:
# The generation was interrupted
# If realtime playback is implemented in your application,
# you should stop playing audio and clear queued playback here.
JavaScript
const turns = await handleTurn();
for (const turn of turns) {
if (turn.serverContent && turn.serverContent.interrupted) {
// The generation was interrupted
// If realtime playback is implemented in your application,
// you should stop playing audio and clear queued playback here.
}
}
Automatyczny VAD
Domyślnie model automatycznie wykonuje wykrywanie dźwięku w ciągłym strumieniu wejściowym dźwięku. Funkcję VAD można skonfigurować za pomocą pola realtimeInputConfig.automaticActivityDetection
w konfiguracji konfiguracji.
Gdy strumień audio jest wstrzymany przez ponad sekundę (np. dlatego, że użytkownik wyłączył mikrofon), należy wysłać zdarzenie audioStreamEnd
, aby opróżnić pamięć podręczną z dźwięku. Klient może wznowić wysyłanie danych audio w dowolnym momencie.
Python
# example audio file to try:
# URL = "https://storage.googleapis.com/generativeai-downloads/data/hello_are_you_there.pcm"
# !wget -q $URL -O sample.pcm
import asyncio
from pathlib import Path
from google import genai
from google.genai import types
client = genai.Client()
model = "gemini-live-2.5-flash-preview"
config = {"response_modalities": ["TEXT"]}
async def main():
async with client.aio.live.connect(model=model, config=config) as session:
audio_bytes = Path("sample.pcm").read_bytes()
await session.send_realtime_input(
audio=types.Blob(data=audio_bytes, mime_type="audio/pcm;rate=16000")
)
# if stream gets paused, send:
# await session.send_realtime_input(audio_stream_end=True)
async for response in session.receive():
if response.text is not None:
print(response.text)
if __name__ == "__main__":
asyncio.run(main())
JavaScript
// example audio file to try:
// URL = "https://storage.googleapis.com/generativeai-downloads/data/hello_are_you_there.pcm"
// !wget -q $URL -O sample.pcm
import { GoogleGenAI, Modality } from '@google/genai';
import * as fs from "node:fs";
const ai = new GoogleGenAI({});
const model = 'gemini-live-2.5-flash-preview';
const config = { responseModalities: [Modality.TEXT] };
async function live() {
const responseQueue = [];
async function waitMessage() {
let done = false;
let message = undefined;
while (!done) {
message = responseQueue.shift();
if (message) {
done = true;
} else {
await new Promise((resolve) => setTimeout(resolve, 100));
}
}
return message;
}
async function handleTurn() {
const turns = [];
let done = false;
while (!done) {
const message = await waitMessage();
turns.push(message);
if (message.serverContent && message.serverContent.turnComplete) {
done = true;
}
}
return turns;
}
const session = await ai.live.connect({
model: model,
callbacks: {
onopen: function () {
console.debug('Opened');
},
onmessage: function (message) {
responseQueue.push(message);
},
onerror: function (e) {
console.debug('Error:', e.message);
},
onclose: function (e) {
console.debug('Close:', e.reason);
},
},
config: config,
});
// Send Audio Chunk
const fileBuffer = fs.readFileSync("sample.pcm");
const base64Audio = Buffer.from(fileBuffer).toString('base64');
session.sendRealtimeInput(
{
audio: {
data: base64Audio,
mimeType: "audio/pcm;rate=16000"
}
}
);
// if stream gets paused, send:
// session.sendRealtimeInput({ audioStreamEnd: true })
const turns = await handleTurn();
for (const turn of turns) {
if (turn.text) {
console.debug('Received text: %s\n', turn.text);
}
else if (turn.data) {
console.debug('Received inline data: %s\n', turn.data);
}
}
session.close();
}
async function main() {
await live().catch((e) => console.error('got error', e));
}
main();
W przypadku send_realtime_input
interfejs API automatycznie reaguje na dźwięk na podstawie wykrywania mowy. Funkcja send_client_content
dodaje wiadomości do kontekstu modelu w kolejności, a funkcja send_realtime_input
jest zoptymalizowana pod kątem szybkości działania kosztem porządku decyzyjnego.
Automatyczna konfiguracja VAD
Aby uzyskać większą kontrolę nad działaniem funkcji VAD, możesz skonfigurować te parametry: Więcej informacji znajdziesz w dokumentacji interfejsu API.
Python
from google.genai import types
config = {
"response_modalities": ["TEXT"],
"realtime_input_config": {
"automatic_activity_detection": {
"disabled": False, # default
"start_of_speech_sensitivity": types.StartSensitivity.START_SENSITIVITY_LOW,
"end_of_speech_sensitivity": types.EndSensitivity.END_SENSITIVITY_LOW,
"prefix_padding_ms": 20,
"silence_duration_ms": 100,
}
}
}
JavaScript
import { GoogleGenAI, Modality, StartSensitivity, EndSensitivity } from '@google/genai';
const config = {
responseModalities: [Modality.TEXT],
realtimeInputConfig: {
automaticActivityDetection: {
disabled: false, // default
startOfSpeechSensitivity: StartSensitivity.START_SENSITIVITY_LOW,
endOfSpeechSensitivity: EndSensitivity.END_SENSITIVITY_LOW,
prefixPaddingMs: 20,
silenceDurationMs: 100,
}
}
};
Wyłączanie automatycznego wykrywania przerw
Automatyczne wykrywanie mowy można też wyłączyć, ustawiając wartość parametru realtimeInputConfig.automaticActivityDetection.disabled
na true
w wiadomości konfiguracyjnej. W tej konfiguracji klient odpowiada za wykrywanie mowy użytkownika i wysyłanie wiadomości activityStart
i activityEnd
w odpowiednich momentach. W tej konfiguracji nie jest wysyłana wiadomość audioStreamEnd
. Zamiast tego każde przerwanie strumienia jest oznaczane komunikatem activityEnd
.
Python
config = {
"response_modalities": ["TEXT"],
"realtime_input_config": {"automatic_activity_detection": {"disabled": True}},
}
async with client.aio.live.connect(model=model, config=config) as session:
# ...
await session.send_realtime_input(activity_start=types.ActivityStart())
await session.send_realtime_input(
audio=types.Blob(data=audio_bytes, mime_type="audio/pcm;rate=16000")
)
await session.send_realtime_input(activity_end=types.ActivityEnd())
# ...
JavaScript
const config = {
responseModalities: [Modality.TEXT],
realtimeInputConfig: {
automaticActivityDetection: {
disabled: true,
}
}
};
session.sendRealtimeInput({ activityStart: {} })
session.sendRealtimeInput(
{
audio: {
data: base64Audio,
mimeType: "audio/pcm;rate=16000"
}
}
);
session.sendRealtimeInput({ activityEnd: {} })
Liczba tokenów
Łączna liczba wykorzystanych tokenów znajduje się w polu usageMetadata zwracanego komunikatu serwera.
Python
async for message in session.receive():
# The server will periodically send messages that include UsageMetadata.
if message.usage_metadata:
usage = message.usage_metadata
print(
f"Used {usage.total_token_count} tokens in total. Response token breakdown:"
)
for detail in usage.response_tokens_details:
match detail:
case types.ModalityTokenCount(modality=modality, token_count=count):
print(f"{modality}: {count}")
JavaScript
const turns = await handleTurn();
for (const turn of turns) {
if (turn.usageMetadata) {
console.debug('Used %s tokens in total. Response token breakdown:\n', turn.usageMetadata.totalTokenCount);
for (const detail of turn.usageMetadata.responseTokensDetails) {
console.debug('%s\n', detail);
}
}
}
Rozdzielczość multimediów
Rozdzielczość multimediów wejściowych możesz określić, ustawiając pole mediaResolution
w ramach konfiguracji sesji:
Python
from google.genai import types
config = {
"response_modalities": ["AUDIO"],
"media_resolution": types.MediaResolution.MEDIA_RESOLUTION_LOW,
}
JavaScript
import { GoogleGenAI, Modality, MediaResolution } from '@google/genai';
const config = {
responseModalities: [Modality.TEXT],
mediaResolution: MediaResolution.MEDIA_RESOLUTION_LOW,
};
Ograniczenia
Podczas planowania projektu weź pod uwagę te ograniczenia interfejsu Live API:
Sposoby odpowiedzi
W ramach konfiguracji sesji możesz ustawić tylko 1 rodzaj odpowiedzi (TEXT
lub AUDIO
) na sesję. Ustawienie obu parametrów spowoduje wyświetlenie komunikatu o błędzie konfiguracji. Oznacza to, że możesz skonfigurować model tak, aby odpowiadał tekstem lub dźwiękiem, ale nie obydwoma w tej samej sesji.
Uwierzytelnianie klienta
Domyślnie interfejs Live API zapewnia tylko uwierzytelnianie w modelu serwer-serwer. Jeśli wdrażasz aplikację Live API za pomocą metody klient-serwer, musisz używać tokenów tymczasowych, aby ograniczyć zagrożenia bezpieczeństwa.
Czas trwania sesji
Sesje tylko z dźwiękiem są ograniczone do 15 minut, a sesje z dźwiękiem i obrazem do 2 minut. Możesz jednak skonfigurować różne techniki zarządzania sesją, aby nieograniczać czasu trwania sesji.
Okno kontekstu
Okno sesji ma limit:
- 128 KB tokenów w przypadku modeli z natywnym wyjściem audio
- 32 tys. tokenów w przypadku innych modeli Live API
Obsługiwane języki
Interfejs Live API obsługuje te języki:
Język | Kod BCP-47 | Język | Kod BCP-47 |
---|---|---|---|
niemiecki (Niemcy) | de-DE |
angielski (Australia)* | en-AU |
angielski (Wielka Brytania)* | en-GB |
angielski (Indie) | en-IN |
angielski (USA) | en-US |
Język hiszpański (USA) | es-US |
francuski (Francja) | fr-FR |
hindi (Indie) | hi-IN |
portugalski (Brazylia) | pt-BR |
arabski (ogólny) | ar-XA |
hiszpański (Hiszpania)* | es-ES |
francuski (Kanada)*, | fr-CA |
indonezyjski (Indonezja) | id-ID |
włoski (Włochy) | it-IT |
japoński (Japonia) | ja-JP |
turecki (Turcja) | tr-TR |
wietnamski (Wietnam) | vi-VN |
bengalski (Indie) | bn-IN |
gudżarati (Indie)* | gu-IN |
kannada (Indie)* | kn-IN |
marathi (Indie) | mr-IN |
malajalam (Indie)* | ml-IN |
tamilski (Indie) | ta-IN |
telugu (Indie) | te-IN |
niderlandzki (Holandia) | nl-NL |
koreański (Korea Południowa) | ko-KR |
mandaryński (Chiny)* | cmn-CN |
polski (Polska) | pl-PL |
rosyjski (Rosja) | ru-RU |
tajski (Tajlandia) | th-TH |
Języki oznaczone gwiazdką (*) nie są dostępne w przypadku dźwięku natywnego.
Co dalej?
- Aby dowiedzieć się więcej o skutecznym korzystaniu z interfejsu Live API, przeczytaj przewodniki Używanie narzędzia i Zarządzanie sesjami.
- Wypróbuj interfejs Live API w Google AI Studio.
- Więcej informacji o modelach interfejsu Live API znajdziesz na stronie Modele w przypadku modeli Gemini 2.0 Flash Live i Gemini 2.5 Flash Native Audio.
- Więcej przykładów znajdziesz w książce kucharskiej Live API, książce kucharskiej Narzędzia Live API i skrypcie Pierwsze kroki z interfejsem Live API.