Live API

Interfejs Live API umożliwia dwukierunkowe interakcje z użyciem głosu i wideo z Gemini z niewielkimi opóźnieniami. Dzięki temu możesz rozmawiać z Gemini na żywo, jednocześnie przesyłając dane wideo lub udostępniając ekran. Dzięki interfejsowi Live API możesz zapewnić użytkownikom naturalne rozmowy głosowe przypominające rozmowy z ludźmi.

Interfejs Live API możesz wypróbować w Google AI Studio. Aby korzystać z interfejsu Live API w Google AI Studio, kliknij Strumień.

Jak działa interfejs Live API

Streaming

Interfejs Live API korzysta z modelu strumieniowego przez połączenie WebSocket. Gdy wchodzisz w interakcję z interfejsem API, tworzone jest trwałe połączenie. Dane wejściowe (dźwięk, wideo lub tekst) są przesyłane w ciągu do modelu, a odpowiedź modelu (tekst lub dźwięk) jest przesyłana z powrotem w czasie rzeczywistym przez to samo połączenie.

Ten dwukierunkowy streaming zapewnia niskie opóźnienie i obsługuje funkcje takie jak wykrywanie aktywności głosowej, korzystanie z narzędzi i generowanie mowy.

Omówienie interfejsu Live API

Więcej informacji o interfejsie WebSockets API znajdziesz w dokumentacji referencyjnej interfejsu WebSockets API.

Generowanie danych wyjściowych

Interfejs Live API przetwarza dane wejściowe multimodalne (tekst, dźwięk, wideo), aby generować tekst lub dźwięk w czasie rzeczywistym. Model ten ma wbudowany mechanizm generowania dźwięku i w zależności od wersji modelu używa jednej z 2 metod generowania dźwięku:

  • Półkaskadia: model otrzymuje natywne dane wejściowe audio i wykorzystuje specjalną kaskadę modeli do przetwarzania danych wejściowych i generowania danych wyjściowych w postaci dźwięku.
  • Natywna: Gemini 2.5 wprowadza natywną generację dźwięku, która bezpośrednio generuje dane wyjściowe dźwięku, zapewniając bardziej naturalne brzmienie, bardziej ekspresyjne głosy, większą świadomość dodatkowego kontekstu, np. ton, oraz bardziej aktywne odpowiedzi.

Tworzenie za pomocą interfejsu Live API

Zanim zaczniesz tworzyć treści za pomocą interfejsu Live API, wybierz metodę generowania dźwięku, która najlepiej odpowiada Twoim potrzebom.

Nawiązywanie połączenia

Ten przykład pokazuje, jak utworzyć połączenie za pomocą klucza interfejsu 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();

Wysyłanie i odbieranie tekstu

Aby wysyłać i odbierać wiadomości tekstowe:

import asyncio
from google import genai

client = genai.Client(api_key="GEMINI_API_KEY")
model = "gemini-2.0-flash-live-001"

config = {"response_modalities": ["TEXT"]}

async def main():
    async with client.aio.live.connect(model=model, config=config) as session:
        message = "Hello, how are you?"
        await session.send_client_content(
            turns={"role": "user", "parts": [{"text": message}]}, turn_complete=True
        )

        async for response in session.receive():
            if response.text is not None:
                print(response.text, end="")

if __name__ == "__main__":
    asyncio.run(main())
import { GoogleGenAI, Modality } from '@google/genai';

const ai = new GoogleGenAI({ apiKey: "GOOGLE_API_KEY" });
const model = 'gemini-2.0-flash-live-001';
const config = { responseModalities: [Modality.TEXT] };

async function live() {
    const responseQueue = [];

    async function waitMessage() {
        let done = false;
        let message = undefined;
        while (!done) {
            message = responseQueue.shift();
            if (message) {
                done = true;
            } else {
                await new Promise((resolve) => setTimeout(resolve, 100));
            }
        }
        return message;
    }

    async function handleTurn() {
        const turns = [];
        let done = false;
        while (!done) {
            const message = await waitMessage();
            turns.push(message);
            if (message.serverContent && message.serverContent.turnComplete) {
                done = true;
            }
        }
        return turns;
    }

    const session = await ai.live.connect({
        model: model,
        callbacks: {
            onopen: function () {
                console.debug('Opened');
            },
            onmessage: function (message) {
                responseQueue.push(message);
            },
            onerror: function (e) {
                console.debug('Error:', e.message);
            },
            onclose: function (e) {
                console.debug('Close:', e.reason);
            },
        },
        config: config,
    });

    const simple = 'Hello how are you?';
    session.sendClientContent({ turns: simple });

    const turns = await handleTurn();
    for (const turn of turns) {
        if (turn.text) {
            console.debug('Received text: %s\n', turn.text);
        }
        else if (turn.data) {
            console.debug('Received inline data: %s\n', turn.data);
        }
    }

    session.close();
}

async function main() {
    await live().catch((e) => console.error('got error', e));
}

main();

Wysyłanie i odbieranie dźwięku

Możesz wysłać dźwięk, konwertując go na 16-bitowy format PCM 16 kHz mono. Ten przykład odczytuje plik WAV i wyśle go w poprawnym formacie:

# 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();

Aby otrzymywać dźwięk, ustaw AUDIO jako modalność odpowiedzi. W tym przykładzie dane są zapisywane jako plik 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';

const ai = new GoogleGenAI({ apiKey: "GOOGLE_API_KEY" });
const model = 'gemini-2.0-flash-live-001';
const config = { responseModalities: [Modality.AUDIO] };

async function live() {
    const responseQueue = [];

    async function waitMessage() {
        let done = false;
        let message = undefined;
        while (!done) {
            message = responseQueue.shift();
            if (message) {
                done = true;
            } else {
                await new Promise((resolve) => setTimeout(resolve, 100));
            }
        }
        return message;
    }

    async function handleTurn() {
        const turns = [];
        let done = false;
        while (!done) {
            const message = await waitMessage();
            turns.push(message);
            if (message.serverContent && message.serverContent.turnComplete) {
                done = true;
            }
        }
        return turns;
    }

    const session = await ai.live.connect({
        model: model,
        callbacks: {
            onopen: function () {
                console.debug('Opened');
            },
            onmessage: function (message) {
                responseQueue.push(message);
            },
            onerror: function (e) {
                console.debug('Error:', e.message);
            },
            onclose: function (e) {
                console.debug('Close:', e.reason);
            },
        },
        config: config,
    });

    const simple = 'Hello how are you?';
    session.sendClientContent({ turns: simple });

    const turns = await handleTurn();

    // Combine audio data strings and save as wave file
    const combinedAudio = turns.reduce((acc, turn) => {
        if (turn.data) {
            const buffer = Buffer.from(turn.data, 'base64');
            const intArray = new Int16Array(buffer.buffer, buffer.byteOffset, buffer.byteLength / Int16Array.BYTES_PER_ELEMENT);
            return acc.concat(Array.from(intArray));
        }
        return acc;
    }, []);

    const audioBuffer = new Int16Array(combinedAudio);

    const wf = new WaveFile();
    wf.fromScratch(1, 24000, '16', audioBuffer);
    fs.writeFileSync('output.wav', wf.toBuffer());

    session.close();
}

async function main() {
    await live().catch((e) => console.error('got error', e));
}

main();

Formaty audio

Dane audio w Live API są zawsze w postaci surowych danych 16-bitowego formatu PCM w systemie 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.

Odbieranie zapisów tekstowych

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.

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())

Transkrypcję wejścia audio możesz włączyć, wysyłając input_audio_transcription w konfiguracji konfiguracji.

import asyncio
from google import genai
from google.genai import types

client = genai.Client(api_key="GEMINI_API_KEY")
model = "gemini-2.0-flash-live-001"

config = {"response_modalities": ["TEXT"],
    "realtime_input_config": {
        "automatic_activity_detection": {"disabled": True},
        "activity_handling": "NO_INTERRUPTION",
    },
    "input_audio_transcription": {},
}

async def main():
    async with client.aio.live.connect(model=model, config=config) as session:
        audio_data = Path("sample.pcm").read_bytes()

        await session.send_realtime_input(activity_start=types.ActivityStart())
        await session.send_realtime_input(
            audio=types.Blob(data=audio_data, mime_type='audio/pcm;rate=16000')
        )
        await session.send_realtime_input(activity_end=types.ActivityEnd())

        async for msg in session.receive():
            if msg.server_content.input_transcription:
                print('Transcript:', msg.server_content.input_transcription.text)

if __name__ == "__main__":
    asyncio.run(main())

Strumieniowe przesyłanie dźwięku i wideo

Instrukcje systemowe

Instrukcje systemu umożliwiają kierowanie działaniem modelu na podstawie konkretnych potrzeb i przypadków użycia. Instrukcje dotyczące systemu można ustawić w konfiguracji i będą one obowiązywać przez całą sesję.

from google.genai import types

config = {
    "system_instruction": types.Content(
        parts=[
            types.Part(
                text="You are a helpful assistant and answer in a friendly tone."
            )
        ]
    ),
    "response_modalities": ["TEXT"],
}

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ń:

PythonJSON
turns = [
    {"role": "user", "parts": [{"text": "What is the capital of France?"}]},
    {"role": "model", "parts": [{"text": "Paris"}]},
]

await session.send_client_content(turns=turns, turn_complete=False)

turns = [{"role": "user", "parts": [{"text": "What is the capital of Germany?"}]}]

await session.send_client_content(turns=turns, turn_complete=True)
{
  "clientContent": {
    "turns": [
      {
        "parts":[
          {
            "text": ""
          }
        ],
        "role":"user"
      },
      {
        "parts":[
          {
            "text": ""
          }
        ],
        "role":"model"
      }
    ],
    "turnComplete": true
  }
}

W przypadku dłuższych kontekstów zalecamy podanie podsumowania w jednej wiadomości, aby zwolnić okno kontekstu na potrzeby kolejnych interakcji.

Zmienianie głosu i języka

Interfejs Live API obsługuje te głosy: Puck, Charon, Kore, Fenrir, Aoede, Leda, Orus i Zephyr.

Aby określić głos, ustaw nazwę głosu w obiekcie speechConfig w ramach konfiguracji sesji:

PythonJSON
from google.genai import types

config = types.LiveConnectConfig(
    response_modalities=["AUDIO"],
    speech_config=types.SpeechConfig(
        voice_config=types.VoiceConfig(
            prebuilt_voice_config=types.PrebuiltVoiceConfig(voice_name="Kore")
        )
    )
)
{
  "voiceConfig": {
    "prebuiltVoiceConfig": {
      "voiceName": "Kore"
    }
  }
}

Interfejs Live API obsługuje wiele języków.

Aby zmienić język, skonfiguruj kod języka w obiekcie speechConfig w ramach konfiguracji sesji:

from google.genai import types

config = types.LiveConnectConfig(
    response_modalities=["AUDIO"],
    speech_config=types.SpeechConfig(
        language_code="de-DE",
    )
)

Natywne wyjście audio

Za pomocą interfejsu Live API możesz też uzyskać dostęp do modeli, które oprócz natywnego wejścia audio obsługują też natywne wyjście audio. Dzięki temu można uzyskać wyższą jakość dźwięku z lepszym tempem, naturalnym brzmieniem głosu, zwięzłością i nastrojem.

Natywny sygnał audio jest obsługiwany przez te modele natywne:

  • gemini-2.5-flash-preview-native-audio-dialog
  • gemini-2.5-flash-exp-native-audio-thinking-dialog

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 sekcji Wysyłanie i odbieranie dźwięku.

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();

Okno dialogowe dotyczące emocji

Dzięki tej funkcji Gemini może dostosować styl odpowiedzi do wyrażenia i tonu wypowiedzi.

Aby używać dialogu emocjonalnego, ustaw wersję interfejsu API na v1alpha, a w wiadomości konfiguracyjnej ustaw enable_affective_dialog na true:

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
};

Pamiętaj, że dialog emocjonalny jest obecnie obsługiwany tylko przez modele z natywnym wyjściem audio.

Proaktywny dźwięk

Gdy ta funkcja jest włączona, Gemini może z wyprzedzeniem 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:

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 }
}

Pamiętaj, że 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 sekcji Wysyłanie i odbieranie dźwięku.

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();

Korzystanie z narzędzia w połączeniu z interfejsem Live API

Za pomocą interfejsu Live API możesz definiować narzędzia takie jak wywoływanie funkcji, wykonywanie koduwyszukiwarka Google.

Omówienie obsługiwanych narzędzi

Oto krótki przegląd dostępnych narzędzi dla każdego modelu:

Narzędzie Modele kaskadowe
gemini-2.0-flash-live-001
gemini-2.5-flash-preview-native-audio-dialog gemini-2.5-flash-exp-native-audio-thinking-dialog
Wyszukiwarka Tak Tak Tak
Wywoływanie funkcji Tak Tak Nie
Wykonanie kodu Tak Nie Nie
Kontekst adresu URL Tak Nie Nie

Wywoływanie funkcji

Deklaracje funkcji możesz definiować w ramach konfiguracji sesji. Więcej informacji znajdziesz w samouczku dotyczącym wywoływania funkcji.

Po otrzymaniu wywołań narzędzia klient powinien odpowiedzieć listą obiektów FunctionResponse za pomocą metody session.send_tool_response.

import asyncio
from google import genai
from google.genai import types

client = genai.Client(api_key="GEMINI_API_KEY")
model = "gemini-2.0-flash-live-001"

# Simple function definitions
turn_on_the_lights = {"name": "turn_on_the_lights"}
turn_off_the_lights = {"name": "turn_off_the_lights"}

tools = [{"function_declarations": [turn_on_the_lights, turn_off_the_lights]}]
config = {"response_modalities": ["TEXT"], "tools": tools}

async def main():
    async with client.aio.live.connect(model=model, config=config) as session:
        prompt = "Turn on the lights please"
        await session.send_client_content(turns={"parts": [{"text": prompt}]})

        async for chunk in session.receive():
            if chunk.server_content:
                if chunk.text is not None:
                    print(chunk.text)
            elif chunk.tool_call:
                function_responses = []
                for fc in tool_call.function_calls:
                    function_response = types.FunctionResponse(
                        id=fc.id,
                        name=fc.name,
                        response={ "result": "ok" } # simple, hard-coded function response
                    )
                    function_responses.append(function_response)

                await session.send_tool_response(function_responses=function_responses)


if __name__ == "__main__":
    asyncio.run(main())

Na podstawie jednego prompta model może wygenerować wiele wywołań funkcji i kodu niezbędnego do połączenia ich danych wyjściowych. Ten kod jest wykonywany w środowisku piaskownicy, generując kolejne wiadomości BidiGenerateContentToolCall.

Asynchroniczne wywoływanie funkcji

Domyślnie wykonywanie kodu jest wstrzymywane do momentu, gdy będą dostępne wyniki wywołania każdej funkcji, co zapewnia przetwarzanie sekwencyjne. Oznacza to, że nie będzie można kontynuować interakcji z modelem podczas wykonywania funkcji.

Jeśli nie chcesz blokować rozmowy, możesz zlecić modelowi wykonywanie funkcji asynchronicznie.

Aby to zrobić, musisz najpierw dodać behavior do definicji funkcji:

  # Non-blocking function definitions
  turn_on_the_lights = {"name": "turn_on_the_lights", "behavior": "NON_BLOCKING"} # turn_on_the_lights will run asynchronously
  turn_off_the_lights = {"name": "turn_off_the_lights"} # turn_off_the_lights will still pause all interactions with the model

NON-BLOCKING zapewni, że funkcja będzie działać asynchronicznie, a Ty będziesz mieć możliwość dalszej interakcji z modelem.

Następnie musisz określić, jak model ma się zachowywać, gdy otrzyma dane FunctionResponse, używając parametru scheduling. Możesz:

  • Przerwać działanie i natychmiast przekazać Ci otrzymaną odpowiedź (scheduling="INTERRUPT"),
  • Zaczekaj, aż skończy wykonywać bieżące zadanie (scheduling="WHEN_IDLE"),
  • Możesz też nie podejmować żadnych działań i wykorzystać tę wiedzę później w trakcie dyskusji.(scheduling="SILENT")
# Non-blocking function definitions
  function_response = types.FunctionResponse(
      id=fc.id,
      name=fc.name,
      response={
          "result": "ok",
          "scheduling": "INTERRUPT" # Can also be WHEN_IDLE or SILENT
      }
  )

Wykonanie kodu

Wykonywanie kodu możesz zdefiniować w ramach konfiguracji sesji. Więcej informacji znajdziesz w samouczku dotyczącym wykonywania kodu.

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())

Funkcję Grounding z użyciem wyszukiwarki Google możesz włączyć w ramach konfiguracji sesji. Więcej informacji znajdziesz w samouczku na temat technik uziemienia.

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())

Łączenie wielu narzędzi

Możesz łączyć różne narzędzia w ramach interfejsu Live API:

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}

Obsługa przerw

Użytkownicy mogą w dowolnym momencie przerwać działanie modelu. Gdy wykrywanie aktywności związanej z głosem (VAD) 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.

Dodatkowo serwer Gemini odrzuca wszystkie oczekujące wywołania funkcji i wysyła wiadomość BidiGenerateContentServerContent z identyfikatorami anulowanych połączeń.

async for response in session.receive():
    if response.server_content.interrupted is True:
        # The generation was interrupted

wykrywanie aktywności głosowej (VAD);

Możesz skonfigurować wykrywanie aktywności głosowej (VAD) lub je wyłączyć.

Korzystanie z automatycznego wykrywania dźwięku

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ę (na przykład 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.

# 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())

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.

Konfigurowanie automatycznego wykrywania dźwięku

Aby uzyskać większą kontrolę nad działaniem funkcji VAD, możesz skonfigurować te parametry: Więcej informacji znajdziesz w dokumentacji interfejsu API.

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,
        }
    }
}

Wyłączanie automatycznego wykrywania dźwięku

Automatyczny VAD 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 activityStartactivityEnd w odpowiednich momentach. W ramach tej konfiguracji nie jest wysyłana wiadomość audioStreamEnd. Zamiast tego każde przerwanie strumienia jest oznaczane komunikatem 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())
    # ...

Liczba tokenów

Łączną liczbę wykorzystanych tokenów znajdziesz w polu usageMetadata zwracanego komunikatu serwera.

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}")

Wydłużanie czasu trwania sesji

Maksymalny czas trwania sesji można wydłużyć do nieograniczonego za pomocą 2 mechanizmów:

Ponadto przed zakończeniem sesji otrzymasz wiadomość GoAway, która umożliwi Ci podjęcie dalszych działań.

Kompresja okna kontekstu

Aby umożliwić dłuższe sesje i uniknąć nagłego zakończenia połączenia, możesz włączyć kompresję okna kontekstowego, ustawiając pole contextWindowCompression w ramach konfiguracji sesji.

ContextWindowCompressionConfig możesz skonfigurować mechanizm okna przesuwającego oraz liczbę tokenów, które uruchamiają kompresję.

from google.genai import types

config = types.LiveConnectConfig(
    response_modalities=["AUDIO"],
    context_window_compression=(
        # Configures compression with default parameters.
        types.ContextWindowCompressionConfig(
            sliding_window=types.SlidingWindow(),
        )
    ),
)

Wznowienie sesji

Aby zapobiec zakończeniu sesji, gdy serwer okresowo resetuje połączenie WebSocket, skonfiguruj pole sessionResumption w konfiguracji konfiguracji.

Przekazanie tej konfiguracji powoduje, że serwer wysyła wiadomości SessionResumptionUpdate, których można użyć do wznowienia sesji, przekazując ostatni token wznowienia jako SessionResumptionConfig.handle kolejnego połączenia.

import asyncio
from google import genai
from google.genai import types

client = genai.Client(api_key="GEMINI_API_KEY")
model = "gemini-2.0-flash-live-001"

async def main():
    print(f"Connecting to the service with handle {previous_session_handle}...")
    async with client.aio.live.connect(
        model=model,
        config=types.LiveConnectConfig(
            response_modalities=["AUDIO"],
            session_resumption=types.SessionResumptionConfig(
                # The handle of the session to resume is passed here,
                # or else None to start a new session.
                handle=previous_session_handle
            ),
        ),
    ) as session:
        while True:
            await session.send_client_content(
                turns=types.Content(
                    role="user", parts=[types.Part(text="Hello world!")]
                )
            )
            async for message in session.receive():
                # Periodically, the server will send update messages that may
                # contain a handle for the current state of the session.
                if message.session_resumption_update:
                    update = message.session_resumption_update
                    if update.resumable and update.new_handle:
                        # The handle should be retained and linked to the session.
                        return update.new_handle

                # For the purposes of this example, placeholder input is continually fed
                # to the model. In non-sample code, the model inputs would come from
                # the user.
                if message.server_content and message.server_content.turn_complete:
                    break

if __name__ == "__main__":
    asyncio.run(main())

Otrzymywanie wiadomości przed zakończeniem sesji

Serwer wysyła wiadomość GoAway, która sygnalizuje, że bieżące połączenie zostanie wkrótce zakończone. Wiadomość zawiera timeLeft, czyli pozostały czas, oraz umożliwia podjęcie dalszych działań, zanim połączenie zostanie zakończone jako 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)

otrzymywanie wiadomości po zakończeniu generowania.

Serwer wysyła wiadomość generationComplete, która sygnalizuje, że model zakończył generowanie odpowiedzi.

async for response in session.receive():
    if response.server_content.generation_complete is True:
        # The generation is complete

Rozdzielczość multimediów

Rozdzielczość multimediów wejściowych możesz określić, ustawiając pole mediaResolution w ramach konfiguracji sesji:

from google.genai import types

config = types.LiveConnectConfig(
    response_modalities=["AUDIO"],
    media_resolution=types.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

Interfejs Live API zapewnia uwierzytelnianie serwera z serwerem i nie jest zalecany do bezpośredniego korzystania przez klienta. Dane wejściowe klienta powinny być kierowane przez pośredni serwer aplikacji, aby zapewnić bezpieczne uwierzytelnianie za pomocą interfejsu Live API.

Czas trwania sesji

Czas trwania sesji można wydłużyć do nieograniczonego, włączając kompresję sesji. Bez kompresji sesje z tylko dźwiękiem są ograniczone do 15 minut, a sesje z dźwiękiem i wideo do 2 minut. Przekroczenie tych limitów bez kompresji spowoduje przerwanie połączenia.

Możesz też skonfigurować wznawianie sesji, aby umożliwić klientowi wznowienie zakończonej sesji.

Okno kontekstu

Okno sesji ma limit:

Obsługiwane języki

Interfejs Live API obsługuje te języki:

Język Kod BCP-47
niemiecki (Niemcy) de-DE
angielski (Australia) en-AU
angielski (UK) en-GB
angielski (Indie) en-IN
angielski (USA) en-US
hiszpański (Stany Zjednoczone) es-US
Język 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
malajalam (Indie) ml-IN
marathi (Indie) mr-IN
tamilski (Indie) ta-IN
telugu (Indie) te-IN
niderlandzki (Holandia) nl-NL
koreański (Korea Południowa) ko-KR
chiński mandaryński (Chiny), cmn-CN
polski (Polska) pl-PL
rosyjski (Rosja) ru-RU
tajski (Tajlandia) th-TH

Integracje z rozwiązaniami innych firm

W przypadku wdrożeń aplikacji internetowych i mobilnych możesz zapoznać się z opcjami dostępnymi w tych usługach:

Co dalej?