Gemini Live API

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

שנתחיל?

לפני שמתחילים, חשוב לוודא שהאפליקציה מטרגטת ל-API ברמה 23 ומעלה.

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

הגדרת פרויקט Android

מוסיפים את ספריית Firebase AI Logic ואת יחסי התלות של App Check לקובץ build.gradle.kts או build.gradle ברמת האפליקציה. כדי לנהל את גרסאות הספרייה, משתמשים בעץ המוצר (BoM) של Firebase ל-Android.

dependencies {
  // Import the Firebase BoM
  implementation(platform("com.google.firebase:firebase-bom:35.1.0"))

  // Add the dependencies for the Firebase AI Logic and App Check libraries
  // When using the BoM, you don't specify versions in Firebase library dependencies
  implementation("com.google.firebase:firebase-ai")
  implementation("com.google.firebase:firebase-appcheck-debug")
}

אחרי שמוסיפים את יחסי התלות, מסנכרנים את פרויקט Android עם Gradle.

הגדרת ספק אימות לצורכי ניפוי באגים של App Check לפיתוח מקומי

החל מתחילת יולי 2026, כחלק מתהליך ההגדרה המודרך של AI Logic במסוף Firebase, המערכת תאכוף באופן אוטומטי את Firebase App Check כדי להגן על Gemini API. לפיתוח מקומי, צריך להגדיר את ספק אימות לצורכי ניפוי באגים של App Check כדי לעקוף את האימות תוך שמירה על האכיפה של App Check.

  1. בגרסת ה-build לניפוי באגים, מגדירים את App Check כך שישתמש ב-factory של ספק אימות לצורכי ניפוי באגים:

    Kotlin

    Firebase.initialize(context = this)
    Firebase.appCheck.installAppCheckProviderFactory(
        DebugAppCheckProviderFactory.getInstance(),
    )
    

    Java

    FirebaseApp.initializeApp(/*context=*/ this);
    FirebaseAppCheck firebaseAppCheck = FirebaseAppCheck.getInstance();
    firebaseAppCheck.installAppCheckProviderFactory(
            DebugAppCheckProviderFactory.getInstance());
    
  2. איך מקבלים טוקן לניפוי באגים:

    1. מפעילים את האפליקציה באמולטור או במכשיר הבדיקה.

    2. מחפשים את אסימון ניפוי הבאגים של App Check ביומנים. לדוגמה:

      D DebugAppCheckProvider: Enter this debug secret into the allow list
      in the Firebase Console for your project: 123a4567-b89c-12d3-e456-789012345678
      
    3. מעתיקים את הטוקן (לדוגמה, 123a4567-b89c-12d3-e456-789012345678).

  3. רושמים את אסימון ניפוי הבאגים ב-App Check:

    1. במסוף Firebase, עוברים אל Security (אבטחה) > App Check > הכרטיסייה Apps (אפליקציות).

    2. מוצאים את האפליקציה, לוחצים על סמל האפשרויות הנוספות () ובוחרים באפשרות ניהול אסימוני ניפוי באגים.

    3. פועלים לפי ההוראות במסך כדי לרשום את אסימון ניפוי הבאגים.

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

שילוב של Firebase AI Logic והפעלת מודל גנרטיבי

מוסיפים את ההרשאה RECORD_AUDIO לקובץ AndroidManifest.xml של האפליקציה:

<uses-permission android:name="android.permission.RECORD_AUDIO" />

מפעילים את שירות הקצה העורפי של Gemini Developer API וניגשים אל LiveModel. משתמשים במודל שתומך ב-Live API, כמו gemini-2.5-flash-native-audio-preview-12-2025. במסמכי התיעוד של Firebase מפורטים המודלים הזמינים של Live API.

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

Kotlin

// Initialize the `LiveModel`
val model = Firebase.ai(backend = GenerativeBackend.googleAI()).liveModel(
    modelName = "gemini-2.5-flash-native-audio-preview-12-2025",
    generationConfig = liveGenerationConfig {
        responseModality = ResponseModality.AUDIO
        speechConfig = SpeechConfig(voice = Voice("FENRIR"))
    }
)

Java

// Initialize the `LiveModel`
LiveGenerativeModel model = FirebaseAI
       .getInstance(GenerativeBackend.googleAI())
       .liveModel(
              "gemini-2.5-flash-native-audio-preview-12-2025",
              new LiveGenerationConfig.Builder()
                     .setResponseModality(ResponseModality.AUDIO)
                     .setSpeechConfig(new SpeechConfig(new Voice("FENRIR"))
              ).build(),
        null,
        null
);

אפשר להגדיר פרסונה או תפקיד שהמודל ימלא באמצעות הגדרת הוראות מערכת:

Kotlin

val systemInstruction = content {
    text("You are a helpful assistant, you main role is [...]")
}

val model = Firebase.ai(backend = GenerativeBackend.googleAI()).liveModel(
    modelName = "gemini-2.5-flash-native-audio-preview-12-2025",
    generationConfig = liveGenerationConfig {
        responseModality = ResponseModality.AUDIO
        speechConfig = SpeechConfig(voice = Voice("FENRIR"))
    },
    systemInstruction = systemInstruction,
)

Java

Content systemInstruction = new Content.Builder()
       .addText("You are a helpful assistant, you main role is [...]")
       .build();

LiveGenerativeModel model = FirebaseAI
       .getInstance(GenerativeBackend.googleAI())
       .liveModel(
              "gemini-2.5-flash-native-audio-preview-12-2025",
              new LiveGenerationConfig.Builder()
                     .setResponseModality(ResponseModality.AUDIO)
                     .setSpeechConfig(new SpeechConfig(new Voice("FENRIR"))
              ).build(),
        tools, // null if you don't want to use function calling
        systemInstruction
);

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

התחלת סשן ב-Live API

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

אחר כך אפשר להפעיל את startAudioConversation() כדי להתחיל את השיחה עם המודל:

Kotlin

val session = model.connect()
session.startAudioConversation()

Java

LiveModelFutures model = LiveModelFutures.from(liveModel);
ListenableFuture<LiveSession> sessionFuture = model.connect();

Futures.addCallback(sessionFuture, new FutureCallback<LiveSession>() {
    @Override
    public void onSuccess(LiveSession ses) {
        LiveSessionFutures session = LiveSessionFutures.from(ses);
        session.startAudioConversation();
    }
    @Override
    public void onFailure(Throwable t) {
        // Handle exceptions
    }
}, executor);

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

אתם יכולים גם להשתמש ב-Gemini Live API כדי ליצור אודיו ממודלים שונים של קלט:

קריאה להפעלת פונקציות: קישור Gemini Live API לאפליקציה

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

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

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

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

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

Kotlin

val itemList = mutableListOf<String>()

fun addList(item: String) {
    itemList.add(item)
}

val addListFunctionDeclaration = FunctionDeclaration(
    name = "addList",
    description = "Function adding an item the list",
    parameters = mapOf(
        "item" to Schema.string("A short string describing the item to add to the list")
    )
)

Java

HashMap<String, Schema> addListParams = new HashMap<String, Schema>(1);

addListParams.put("item", Schema.str("A short string describing the item to add to the list"));

FunctionDeclaration addListFunctionDeclaration = new FunctionDeclaration(
    "addList",
    "Function adding an item the list",
    addListParams,
    Collections.emptyList()
);

אחר כך, מעבירים את ה-FunctionDeclaration הזה בתור Tool למודל כשיוצרים מופע שלו:

Kotlin

val addListTool = Tool.functionDeclarations(listOf(addListFunctionDeclaration))

val model = Firebase.ai(backend = GenerativeBackend.googleAI()).liveModel(
    modelName = "gemini-2.5-flash-native-audio-preview-12-2025",
    generationConfig = liveGenerationConfig {
        responseModality = ResponseModality.AUDIO
        speechConfig = SpeechConfig(voice = Voice("FENRIR"))
    },
    systemInstruction = systemInstruction,
    tools = listOf(addListTool)
)

Java

LiveGenerativeModel model = FirebaseAI.getInstance(
    GenerativeBackend.googleAI()).liveModel(
        "gemini-2.5-flash-native-audio-preview-12-2025",
  new LiveGenerationConfig.Builder()
        .setResponseModality(ResponseModality.AUDIO)
        .setSpeechConfig(new SpeechConfig(new Voice("FENRIR")))
        .build(),
  List.of(Tool.functionDeclarations(List.of(addListFunctionDeclaration))),
               null,
               systemInstruction
        );

בשלב האחרון, מטמיעים פונקציית handler כדי לטפל בקריאה לפונקציה שהמודל מבצע, ומעבירים לו בחזרה את התשובה. פונקציית ה-handler הזו, שסופקה ל-LiveSession כשקוראים ל-startAudioConversation, מקבלת פרמטר FunctionCallPart ומחזירה FunctionResponsePart:

Kotlin

session.startAudioConversation(::functionCallHandler)

// ...

fun functionCallHandler(functionCall: FunctionCallPart): FunctionResponsePart {
    return when (functionCall.name) {
        "addList" -> {
            // Extract function parameter from functionCallPart
            val itemName = functionCall.args["item"]!!.jsonPrimitive.content
            // Call function with parameter
            addList(itemName)
            // Confirm the function call to the model
            val response = JsonObject(
                mapOf(
                    "success" to JsonPrimitive(true),
                    "message" to JsonPrimitive("Item $itemName added to the todo list")
                )
            )
            FunctionResponsePart(functionCall.name, response)
        }
        else -> {
            val response = JsonObject(
                mapOf(
                    "error" to JsonPrimitive("Unknown function: ${functionCall.name}")
                )
            )
            FunctionResponsePart(functionCall.name, response)
        }
    }
}

Java

Futures.addCallback(sessionFuture, new FutureCallback<LiveSessionFutures>() {

    @RequiresPermission(Manifest.permission.RECORD_AUDIO)
    @Override
    @OptIn(markerClass = PublicPreviewAPI.class)
    public void onSuccess(LiveSessionFutures ses) {
        ses.startAudioConversation(::handleFunctionCallFuture);
    }

    @Override
    public void onFailure(Throwable t) {
        // Handle exceptions
    }
}, executor);

// ...

ListenableFuture<JsonObject> handleFunctionCallFuture = Futures.transform(response, result -> {
    for (FunctionCallPart functionCall : result.getFunctionCalls()) {
        if (functionCall.getName().equals("addList")) {
            Map<String, JsonElement> args = functionCall.getArgs();
            String item =
                    JsonElementKt.getContentOrNull(
                            JsonElementKt.getJsonPrimitive(
                                    locationJsonObject.get("item")));
            return addList(item);
        }
    }
    return null;
}, Executors.newSingleThreadExecutor());

השלבים הבאים