Live API

באמצעות Live API אפשר לנהל אינטראקציות דו-כיווניות בקול ובווידאו עם Gemini בזמן אמת, עם זמן אחזור קצר. כך תוכלו לדבר עם Gemini בשידור חי תוך כדי סטרימינג של קלט וידאו או שיתוף המסך. באמצעות Live API, אתם יכולים לספק למשתמשי הקצה חוויה של שיחות קוליות טבעיות דמויות-אנושיות.

אפשר לנסות את Live API ב-Google AI Studio. כדי להשתמש ב-Live API ב-Google AI Studio, בוחרים באפשרות Stream.

איך פועל Live API

סטרימינג

ב-Live API נעשה שימוש במודל סטרימינג דרך חיבור WebSocket. כשאתם יוצרים אינטראקציה עם ה-API, נוצר חיבור מתמיד. הקלט (אודיו, וידאו או טקסט) מועבר לסטרימינג באופן רציף למודל, והתגובה של המודל (טקסט או אודיו) מועברת בחזרה בסטרימינג בזמן אמת באותו חיבור.

הסטרימינג הדו-כיווני הזה מבטיח זמן אחזור קצר ותומך בתכונות כמו זיהוי פעילות קולית, שימוש בכלים ויצירת דיבור.

סקירה כללית על Live API

למידע נוסף על WebSockets API הבסיסי, תוכלו לקרוא את החומר העזר בנושא WebSockets API.

יצירת פלט

‏Live API מעבד קלט מולטי-מודאלי (טקסט, אודיו, וידאו) כדי ליצור טקסט או אודיו בזמן אמת. הוא כולל מנגנון מובנה ליצירת אודיו, ובהתאם לגרסה של הדגם שבו אתם משתמשים, הוא משתמש באחת משתי שיטות היצירה של אודיו:

  • מחצית מפל: המודל מקבל קלט אודיו מקורי ומשתמש במפל מודלים מיוחד של מודלים נפרדים כדי לעבד את הקלט וליצור פלט אודיו.
  • טבעי: ב-Gemini 2.5 יש יצירת אודיו טבעית, שמאפשרת ליצור ישירות פלט אודיו. התוצאה היא אודיו שנשמע טבעי יותר, קולות ייחודיים יותר, מודעוּת רבה יותר להקשר נוסף, למשל הטון, ותשובות יזום יותר.

פיתוח באמצעות Live API

לפני שמתחילים לפתח באמצעות Live API, צריך לבחור את גישת היצירה של האודיו שמתאימה ביותר לצרכים שלכם.

יצירת חיבור

בדוגמה הבאה מוסבר איך יוצרים חיבור באמצעות מפתח API:

import asyncio
from google import genai

client = genai.Client(api_key="GEMINI_API_KEY")

model = "gemini-2.0-flash-live-001"
config = {"response_modalities": ["TEXT"]}

async def main():
    async with client.aio.live.connect(model=model, config=config) as session:
        print("Session started")

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

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

async function main() {

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

    // Send content...

    session.close();
}

main();

שליחה וקבלה של טקסט

כך שולחים ומקבלים הודעות טקסט:

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

שליחה וקבלה של אודיו

אפשר לשלוח אודיו על ידי המרתו לפורמט PCM 16 ביט, 16kHz, מונו. בדוגמה הזו קוראים קובץ WAV ושולחים אותו בפורמט הנכון:

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

כדי לקבל אודיו, צריך להגדיר את AUDIO כסוג התגובה. בדוגמה הזו הנתונים שהתקבלו נשמרים כקובץ WAV:

import asyncio
import wave
from google import genai

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

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

async def main():
    async with client.aio.live.connect(model=model, config=config) as session:
        wf = wave.open("audio.wav", "wb")
        wf.setnchannels(1)
        wf.setsampwidth(2)
        wf.setframerate(24000)

        message = "Hello how are you?"
        await session.send_client_content(
            turns={"role": "user", "parts": [{"text": message}]}, turn_complete=True
        )

        async for idx,response in async_enumerate(session.receive()):
            if response.data is not None:
                wf.writeframes(response.data)

            # Un-comment this code to print audio data info
            # if response.server_content.model_turn is not None:
            #      print(response.server_content.model_turn.parts[0].inline_data.mime_type)

        wf.close()

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

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

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

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

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

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

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

    const turns = await handleTurn();

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

    const audioBuffer = new Int16Array(combinedAudio);

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

    session.close();
}

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

main();

פורמטים של אודיו

נתוני האודיו ב-Live API הם תמיד נתונים גולמיים של PCM ב-16 ביט, בסדר קטן-גדול (little-endian). תדירות הדגימה של פלט האודיו היא תמיד 24kHz. אודיו הקלט הוא 16kHz באופן מקורי, אבל ה-Live API יבצע דגימה מחדש אם יהיה צורך כדי שניתן יהיה לשלוח כל תדירות דגימה. כדי להעביר את תדירות הדגימה של אודיו הקלט, צריך להגדיר את סוג ה-MIME של כל Blob שמכיל אודיו לערך כמו audio/pcm;rate=16000.

קבלת תמלילי אודיו

כדי להפעיל תמלול של פלט האודיו של המודל, שולחים את הערך output_audio_transcription בהגדרות ההגדרה. שפת התמליל נובעת מהתגובה של המודל.

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

כדי להפעיל תמלול של קלט האודיו, שולחים את הערך input_audio_transcription בתצורת ההגדרה.

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

סטרימינג של אודיו ווידאו

הוראות למערכת

הוראות המערכת מאפשרות לכם לקבוע את ההתנהגות של מודל על סמך הצרכים הספציפיים שלכם ותרחישי השימוש שלכם. אפשר להגדיר הוראות למערכת בתצורת ההגדרה, והן יישארו בתוקף לכל אורך הסשן.

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

עדכוני תוכן מצטברים

משתמשים בעדכונים מצטברים כדי לשלוח קלט טקסט, ליצור הקשר של סשן או לשחזר הקשר של סשן. בהקשרים קצרים, אפשר לשלוח אינטראקציות מפורטות כדי לייצג את רצף האירועים המדויק:

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

בהקשרים ארוכים יותר, מומלץ לספק סיכום של ההודעה כדי לפנות מקום בחלון הקשר לאינטראקציות הבאות.

שינוי הקול והשפה

ה-Live API תומך בקולות הבאים: Puck,‏ Charon,‏ Kore,‏ Fenrir,‏ Aoede,‏ Leda,‏ Orus ו-Zephyr.

כדי לציין קול, מגדירים את שם הקול באובייקט speechConfig כחלק מהגדרת הסשן:

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

ב-Live API יש תמיכה במספר שפות.

כדי לשנות את השפה, מגדירים את קוד השפה באובייקט speechConfig כחלק מהגדרת הסשן:

from google.genai import types

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

פלט אודיו מקורי

דרך Live API אפשר גם לגשת למודלים שמאפשרים פלט אודיו מקורי בנוסף לקלט אודיו מקורי. כך אפשר לייצר פלט אודיו באיכות גבוהה יותר עם קצב טוב יותר, טבעיות של הקול, מילוליות ומצב רוח.

המודלים הבאים של אודיו מותאם תומכים בפלט אודיו מותאם:

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

איך משתמשים בפלט אודיו מקורי

כדי להשתמש בפלט אודיו מקורי, מגדירים את אחד ממודלי האודיו המקומיים ומגדירים את response_modalities לערך AUDIO:

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

שיחה עם רגשות

התכונה הזו מאפשרת ל-Gemini להתאים את סגנון התשובה שלו לביטוי ולסגנון של הקלט.

כדי להשתמש בדו-שיח רגשי, צריך להגדיר את enable_affective_dialog ל-true בהודעת ההגדרה:

config = types.LiveConnectConfig(
    response_modalities=["AUDIO"],
    enable_affective_dialog=True
)

לתשומת ליבכם: בשלב הזה יש תמיכה בדו-שיח רגשי רק במודלים של פלט אודיו מקורי.

אודיו יזום

כשהתכונה הזו מופעלת, Gemini יכול להחליט מראש לא להגיב אם התוכן לא רלוונטי.

כדי להשתמש בו, צריך להגדיר את השדה proactivity בהודעת ההגדרה ולהגדיר את proactive_audio לערך true:

config = types.LiveConnectConfig(
    response_modalities=["AUDIO"],
    proactivity={'proactive_audio': True}
)

לתשומת ליבכם: בשלב הזה יש תמיכה באודיו יזום רק במודלים של פלט אודיו מקורי.

פלט אודיו מקורי עם 'מחשבה'

פלט אודיו מקורי תומך ביכולות חשיבה, שזמינות דרך מודל נפרד gemini-2.5-flash-exp-native-audio-thinking-dialog.

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

שימוש בכלי עם Live API

אפשר להגדיר כלים כמו קריאה לפונקציות, הרצת קוד וחיפוש Google באמצעות Live API.

סקירה כללית על הכלים הנתמכים

לפניכם סקירה כללית קצרה של הכלים הזמינים לכל מודל:

כלי מודלים מדורגים
gemini-2.0-flash-live-001
gemini-2.5-flash-preview-native-audio-dialog gemini-2.5-flash-exp-native-audio-thinking-dialog
חיפוש כן כן כן
קריאה לפונקציה כן כן לא
ביצוע קוד כן לא לא
הקשר של כתובת ה-URL כן לא לא

קריאה לפונקציה

אפשר להגדיר הצהרות על פונקציות כחלק מהגדרת הסשן. מידע נוסף זמין במדריך בנושא קריאה לפונקציות.

אחרי קבלת קריאות מהכלי, הלקוח צריך להשיב עם רשימה של אובייקטים מסוג FunctionResponse באמצעות השיטה 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())

מהנחיה אחת, המודל יכול ליצור מספר קריאות לפונקציות ואת הקוד הנדרש כדי לשרשר את הפלט שלהן. הקוד הזה מופעל בסביבת חול, ויוצר הודעות BidiGenerateContentToolCall.

קריאה אסינכרונית לפונקציות

כברירת מחדל, הביצועים מושהים עד שהתוצאות של כל קריאה לפונקציה יהיו זמינות, וכך מובטח עיבוד רציף. המשמעות היא שלא תוכלו להמשיך לבצע פעולות במודל בזמן שהפונקציות פועלות.

אם אתם לא רוצים לחסום את השיחה, תוכלו להורות למודל להריץ את הפונקציות באופן אסינכרוני.

כדי לעשות זאת, קודם צריך להוסיף behavior להגדרות הפונקציות:

  # 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 יבטיח שהפונקציה תפעל באופן אסינכרוני, ותוכלו להמשיך לבצע פעולות עם המודל.

לאחר מכן, צריך להגדיר את התנהגות המודל כשהוא מקבל את הערך FunctionResponse באמצעות הפרמטר scheduling. יכול:

  • להפריע למה שהוא עושה ולעדכן אתכם מיד בתגובה שהוא קיבל (scheduling="INTERRUPT"),
  • ממתינים עד שהפעולה הנוכחית תסתיים (scheduling="WHEN_IDLE"),
  • לחלופין, אפשר לא לעשות דבר ולהשתמש בידע הזה בהמשך הדיון (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
      }
  )

ביצוע קוד

אפשר להגדיר את ביצוע הקוד כחלק מהגדרת הסשן. מידע נוסף זמין במדריך לביצוע קוד.

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

אפשר להפעיל את התכונה 'התמקדות' באמצעות חיפוש Google כחלק מהגדרת הסשן. מידע נוסף זמין במדריך בנושא יצירת קשר עם האדמה.

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

שילוב של כמה כלים

אתם יכולים לשלב כמה כלים ב-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}

טיפול בהפרעות

המשתמשים יכולים להפסיק את הפלט של המודל בכל שלב. כשזיהוי פעילות קול (VAD) מזהה הפרעה, היצירה המתמשכת מבוטלת ונמחקת. רק המידע שכבר נשלח ללקוח נשמר בהיסטוריית הסשנים. לאחר מכן השרת שולח הודעה מסוג BidiGenerateContentServerContent כדי לדווח על ההפרעה.

בנוסף, שרת Gemini משמיד את כל הקריאות לפונקציות בהמתנה ושולח הודעת BidiGenerateContentServerContent עם המזהים של הקריאות שבוטלו.

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

זיהוי פעילות קול (VAD)

אתם יכולים להגדיר או להשבית את זיהוי הפעילות הקולית (VAD).

שימוש ב-VAD אוטומטי

כברירת מחדל, המודל מבצע VAD באופן אוטומטי על מקור קלט אודיו רציף. אפשר להגדיר את VAD באמצעות השדה realtimeInputConfig.automaticActivityDetection בהגדרת ההגדרה.

כשזרם האודיו מושהה למשך יותר משנייה (לדוגמה, כי המשתמש השבית את המיקרופון), צריך לשלוח אירוע audioStreamEnd כדי לנקות את האודיו שנשמר במטמון. הלקוח יכול להמשיך לשלוח את נתוני האודיו בכל שלב.

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

כשמשתמשים ב-send_realtime_input, ה-API מגיב לאודיו באופן אוטומטי על סמך VAD. בעוד ש-send_client_content מוסיף הודעות להקשר של המודל לפי סדר, send_realtime_input עבר אופטימיזציה לשיפור התגובה במחיר של סדר דטרמיניסטי.

הגדרת VAD אוטומטי

כדי לשלוט טוב יותר בפעילות של VAD, אפשר להגדיר את הפרמטרים הבאים. מידע נוסף זמין במאמר הפניית 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,
        }
    }
}

השבתת VAD אוטומטי

לחלופין, אפשר להשבית את ה-VAD האוטומטי על ידי הגדרת realtimeInputConfig.automaticActivityDetection.disabled ל-true בהודעת ההגדרה. בהגדרה הזו, הלקוח אחראי לזיהוי הדיבור של המשתמש ולשליחה של ההודעות activityStart ו-activityEnd בזמנים המתאימים. לא נשלח audioStreamEnd בהגדרה הזו. במקום זאת, כל הפסקה בשידור מסומנת בהודעה 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())
    # ...

מספר הטוקנים

המספר הכולל של האסימונים שנצרכו מופיע בשדה usageMetadata בהודעת השרת שהוחזרה.

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

הארכת משך הסשן

אפשר להאריך את משך הסשן המקסימלי ללא הגבלה באמצעות שני מנגנונים:

בנוסף, תקבלו הודעת GoAway לפני סיום הסשן, שתאפשר לכם לבצע פעולות נוספות.

דחיסת חלון ההקשר

כדי לאפשר סשנים ארוכים יותר ולהימנע מסיום פתאומית של החיבור, אפשר להפעיל דחיסת חלון הקשר על ידי הגדרת השדה contextWindowCompression כחלק מהגדרת הסשן.

בקובץ ContextWindowCompressionConfig אפשר להגדיר מנגנון של חלון הזזה ומספר האסימונים שמפעילים את הדחיסה.

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

המשך הסשן

כדי למנוע סיום סשן כשהשרת מאפס מדי פעם את החיבור ל-WebSocket, מגדירים את השדה sessionResumption בהגדרת ההגדרה.

העברת ההגדרה הזו גורמת לשרת לשלוח הודעות SessionResumptionUpdate, שאפשר להשתמש בהן כדי להמשיך את הסשן על ידי העברת אסימון ההמשך האחרון בתור SessionResumptionConfig.handle של החיבור הבא.

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

קבלת הודעה לפני שהסשן מתנתק

השרת שולח הודעה מסוג GoAway שמסמנת שהחיבור הנוכחי יסתיים בקרוב. ההודעה הזו כוללת את timeLeft, שמציינת את הזמן שנותר ומאפשרת לכם לבצע פעולות נוספות לפני שהחיבור יסתיים כ-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)

קבלת הודעה כשהיצירה הושלמה

השרת שולח הודעה מסוג generationComplete שמציינת שהמודל סיים ליצור את התגובה.

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

רזולוציית המדיה

כדי לציין את רזולוציית המדיה של מדיית הקלט, מגדירים את השדה mediaResolution כחלק מהגדרת הסשן:

from google.genai import types

config = types.LiveConnectConfig(
    response_modalities=["AUDIO"],
    media_resolution=types.MediaResolution.MEDIA_RESOLUTION_LOW,
)

מגבלות

כדאי להביא בחשבון את המגבלות הבאות של Live API כשמתכננים את הפרויקט.

שיטות תגובה

אפשר להגדיר רק אופן תגובה אחד (TEXT או AUDIO) לכל סשן בהגדרת הסשן. הגדרת שתי ההגדרות האלה תגרום להצגת הודעת שגיאה בתצורה. כלומר, אפשר להגדיר את המודל להשיב בטקסט או באודיו, אבל לא בשניהם באותו סשן.

אימות לקוח

‏Live API מספק אימות רק בין שרתים, ולא מומלץ לשימוש ישיר בלקוח. יש לנתב את הקלט של הלקוח דרך שרת אפליקציה ביניים כדי לבצע אימות מאובטח באמצעות Live API.

משך הביקור

כדי להאריך את משך הסשן ללא הגבלה, מפעילים דחיסת סשנים. בלי דחיסת הנתונים, סשנים של אודיו בלבד מוגבלים ל-15 דקות, וסשנים של אודיו וווידאו מוגבלים ל-2 דקות. חריגה מהמגבלות האלה ללא דחיסת הנתונים תגרום לניתוק החיבור.

בנוסף, אפשר להגדיר המשך סשן כדי לאפשר ללקוח להמשיך סשן שהסתיים.

חלון ההקשר

לסשן יש מגבלה של חלון הקשר של:

שפות נתמכות

ב-Live API יש תמיכה בשפות הבאות.

שפה קוד BCP-47
גרמנית (גרמניה) de-DE
אנגלית (אוסטרליה) en-AU
אנגלית (בריטניה) en-GB
אנגלית (הודו) en-IN
אנגלית (ארה"ב) en-US
ספרדית (ארצות הברית) es-US
צרפתית (צרפת) fr-FR
הינדית (הודו) hi-IN
פורטוגזית (ברזיל) pt-BR
ערבית (גנרי) ar-XA
ספרדית (ספרד) es-ES
צרפתית (קנדה) fr-CA
אינדונזית (אינדונזיה) id-ID
איטלקית (איטליה) it-IT
יפנית (יפן) ja-JP
טורקית (טורקיה) tr-TR
וייטנאמית (וייטנאם) vi-VN
בנגלית (הודו) bn-IN
גוג'ראטית (הודו) gu-IN
קאנדה (הודו) kn-IN
מליאלאם (הודו) ml-IN
מראטהית (הודו) mr-IN
טמילית (הודו) ta-IN
טלוגו (הודו) te-IN
הולנדית (הולנד) nl-NL
קוריאנית (דרום קוריאה) ko-KR
סינית מנדרינית (סין) cmn-CN
פולנית (פולין) pl-PL
רוסית (רוסיה) ru-RU
תאילנדית (תאילנד) th-TH

שילובים עם צדדים שלישיים

לפריסות של אפליקציות לאינטרנט ולנייד, אפשר לבחור מבין האפשרויות הבאות:

המאמרים הבאים