Gemini Live API

بالنسبة إلى التطبيقات التي تتطلّب دعمًا صوتيًا في الوقت الفعلي وبزمن انتقال منخفض، مثل برامج المحادثة الآلية أو التفاعلات مع الوكلاء، توفّر واجهة برمجة التطبيقات Gemini Live API طريقة محسّنة لبثّ كلّ من الإدخال والإخراج لنموذج Gemini. باستخدام Firebase AI Logic، يمكنك استدعاء واجهة برمجة التطبيقات Gemini Live API مباشرةً من تطبيق Android بدون الحاجة إلى عملية دمج في الخلفية. يوضّح لك هذا الدليل كيفية استخدام واجهة برمجة التطبيقات Gemini Live API في تطبيق Android باستخدام Firebase AI Logic.

البدء

قبل البدء، تأكَّد من أنّ تطبيقك يستهدف مستوى واجهة برمجة التطبيقات 23 أو أعلى.

إذا لم يسبق لك إجراء ذلك، عليك إعداد مشروع Firebase وربط تطبيقك بـ Firebase. لمعرفة التفاصيل، يُرجى الاطّلاع على مستندات Firebase AI Logic.

إعداد مشروع Android

أضِف مكتبة Firebase AI Logic وتبعيات App Check إلى ملفك على مستوى التطبيق build.gradle.kts أو build.gradle. استخدِم قائمة مواد Firebase لنظام Android لإدارة إصدارات المكتبة.

dependencies {
  // Import the Firebase BoM
  implementation(platform("com.google.firebase:firebase-bom:34.15.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. في إصدار تصحيح الأخطاء، اضبط App Check لاستخدام أداة إنشاء موفِّر تصحيح الأخطاء:

    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"، انتقِل إلى الأمان > App Check > علامة التبويب التطبيقات.

    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 بتطبيقك

للانتقال إلى خطوة أخرى، يمكنك أيضًا تفعيل النموذج للتفاعل مباشرةً مع منطق تطبيقك باستخدام ميزة استدعاء الدوال.

استدعاء الدوال (أو استدعاء الأدوات) هي ميزة في عمليات تنفيذ الذكاء الاصطناعي التوليدي تسمح للنموذج باستدعاء الدوال من تلقاء نفسه لتنفيذ الإجراءات. إذا كانت الدالة تتضمّن ناتجًا، يضيفه النموذج إلى سياقه ويستخدمه في عمليات الإنشاء اللاحقة.

مخطّط توضيحي يبيّن كيف تتيح واجهة برمجة التطبيقات Gemini Live تفسير طلب المستخدم من خلال نموذج، ما يؤدي إلى تشغيل دالة محدّدة مسبقًا مع وسيطات ذات صلة في تطبيق Android، والذي يتلقّى بعد ذلك رد تأكيد من النموذج.
الشكل 1: رسم بياني يوضّح كيف تسمح واجهة برمجة التطبيقات Gemini Live API للنموذج بتفسير طلب المستخدِم، ما يؤدي إلى تفعيل دالة محدّدة مسبقًا تتضمّن وسيطات ذات صلة في تطبيق Android، والذي يتلقّى بعد ذلك رد تأكيد من النموذج.

لتنفيذ ميزة استدعاء الدوال في تطبيقك، ابدأ بإنشاء كائن FunctionDeclaration لكل دالة تريد عرضها للنموذج.

على سبيل المثال، لعرض دالة addList التي تُلحِق سلسلة بقائمة من السلاسل في Gemini، ابدأ بإنشاء متغيّر 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()
        .setResponseModalities(ResponseModality.AUDIO)
        .setSpeechConfig(new SpeechConfig(new Voice("FENRIR")))
        .build(),
  List.of(Tool.functionDeclarations(List.of(addListFunctionDeclaration))),
               null,
               systemInstruction
        );

أخيرًا، نفِّذ دالة معالج للتعامل مع استدعاء الأداة الذي يجريه النموذج وأرسِل الرد إليه. تتلقّى دالة المعالج هذه، التي يتم توفيرها لـ 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());

الخطوات التالية