Gemini Live API

برای برنامه‌هایی که نیاز به پشتیبانی صوتی بلادرنگ و با تأخیر کم دارند، مانند چت‌بات‌ها یا تعاملات عامل‌محور، Gemini Live API روشی بهینه برای پخش همزمان ورودی و خروجی برای یک مدل Gemini ارائه می‌دهد. با استفاده از Firebase AI Logic، می‌توانید Gemini Live API را مستقیماً از برنامه اندروید خود و بدون نیاز به یکپارچه‌سازی backend فراخوانی کنید. این راهنما به شما نشان می‌دهد که چگونه از Gemini Live API در برنامه اندروید خود با Firebase AI Logic استفاده کنید.

شروع کنید

قبل از شروع، مطمئن شوید که برنامه شما سطح API 23 یا بالاتر را هدف قرار می‌دهد.

اگر هنوز این کار را نکرده‌اید، یک پروژه Firebase راه‌اندازی کنید و برنامه خود را به Firebase متصل کنید. برای جزئیات بیشتر، به مستندات Firebase AI Logic مراجعه کنید.

پروژه اندروید خود را تنظیم کنید

وابستگی کتابخانه Firebase AI Logic را به فایل build.gradle.kts یا build.gradle در سطح برنامه خود اضافه کنید. از Firebase Android BoM برای مدیریت نسخه‌های کتابخانه استفاده کنید.

dependencies {
  // Import the Firebase BoM
  implementation(platform("com.google.firebase:firebase-bom:34.5.0"))
  // Add the dependency for the Firebase AI Logic library
  // When using the BoM, you don't specify versions in Firebase library dependencies
  implementation("com.google.firebase:firebase-ai")
}

پس از افزودن وابستگی، پروژه اندروید خود را با Gradle همگام‌سازی کنید.

ادغام منطق هوش مصنوعی فایربیس و مقداردهی اولیه یک مدل مولد

مجوز RECORD_AUDIO را به فایل AndroidManifest.xml برنامه خود اضافه کنید:

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

سرویس Backend API توسعه‌دهنده Gemini را راه‌اندازی اولیه کنید و به LiveModel دسترسی پیدا کنید. از مدلی استفاده کنید که از Live API پشتیبانی می‌کند، مانند gemini-live-2.5-flash-preview . برای مدل‌های موجود به مستندات Firebase مراجعه کنید.

برای مشخص کردن یک صدا، نام صدا را در شیء speechConfig به عنوان بخشی از پیکربندی مدل تنظیم کنید. اگر صدایی مشخص نکنید، پیش‌فرض Puck است.

کاتلین

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

جاوا

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

شما می‌توانید به صورت اختیاری با تنظیم یک دستورالعمل سیستمی، یک شخصیت یا نقشی را که مدل ایفا می‌کند، تعریف کنید:

کاتلین

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

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

جاوا

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

LiveGenerativeModel model = FirebaseAI
       .getInstance(GenerativeBackend.googleAI())
       .liveModel(
              "gemini-live-2.5-flash-preview",
              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
);

شما می‌توانید با استفاده از دستورالعمل‌های سیستمی برای ارائه زمینه‌ای مختص به برنامه خود (مثلاً سابقه فعالیت درون برنامه‌ای کاربر)، مکالمه با مدل را تخصصی‌تر کنید.

مقداردهی اولیه یک جلسه API زنده

پس از ایجاد نمونه LiveModel ، برای ایجاد یک شیء LiveSession و برقراری ارتباط پایدار با مدل با تأخیر کم، تابع model.connect() را فراخوانی کنید. LiveSession به شما امکان می‌دهد با شروع و توقف جلسه صوتی و همچنین ارسال و دریافت متن، با مدل تعامل داشته باشید.

سپس می‌توانید تابع startAudioConversation() را برای شروع مکالمه با مدل فراخوانی کنید:

کاتلین

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

جاوا

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

همچنین، در مکالمات خود با مدل، توجه داشته باشید که او وقفه‌ها را مدیریت نمی‌کند.

همچنین می‌توانید از Gemini Live API برای تولید صدای استریم شده از متن و تولید متن از صدای استریم شده استفاده کنید. توجه داشته باشید که Live API دو طرفه است، بنابراین از یک اتصال برای ارسال و دریافت محتوا استفاده می‌کنید. در نهایت، می‌توانید تصاویر و یک جریان ویدیویی زنده را نیز به مدل ارسال کنید.

فراخوانی تابع: اتصال Gemini Live API به برنامه شما

برای اینکه یک قدم فراتر بروید، می‌توانید مدل را طوری تنظیم کنید که مستقیماً با منطق برنامه شما با استفاده از فراخوانی تابع تعامل داشته باشد.

فراخوانی تابع (یا فراخوانی ابزار) یکی از ویژگی‌های پیاده‌سازی‌های هوش مصنوعی مولد است که به مدل اجازه می‌دهد توابع را به ابتکار خود برای انجام اقدامات فراخوانی کند. اگر تابع خروجی داشته باشد، مدل آن را به متن خود اضافه می‌کند و برای نسل‌های بعدی از آن استفاده می‌کند.

نموداری که نشان می‌دهد چگونه رابط برنامه‌نویسی کاربردی Gemini Live به یک اعلان کاربر اجازه می‌دهد تا توسط یک مدل تفسیر شود و یک تابع از پیش تعریف شده با آرگومان‌های مربوطه را در یک برنامه اندروید فعال کند، که سپس یک پاسخ تأیید از مدل دریافت می‌کند.
شکل ۱: نموداری که نشان می‌دهد چگونه رابط برنامه‌نویسی نرم‌افزار Gemini Live به یک مدل اجازه می‌دهد تا درخواست کاربر را تفسیر کند و یک تابع از پیش تعریف شده با آرگومان‌های مربوطه را در یک برنامه اندروید فعال کند، که سپس یک پاسخ تأیید از مدل دریافت می‌کند.

برای پیاده‌سازی فراخوانی تابع در برنامه خود، با ایجاد یک شیء FunctionDeclaration برای هر تابعی که می‌خواهید در مدل نمایش دهید، شروع کنید.

For example, to expose an addList function that appends a string to a list of strings to Gemini, start by creating a FunctionDeclaration variable with a name and a short description in plain English of the function and its parameter:

کاتلین

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

جاوا

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"));
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 هنگام نمونه‌سازی مدل، به آن منتقل کنید:

کاتلین

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

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

جاوا

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

در نهایت، یک تابع handler پیاده‌سازی کنید تا فراخوانی ابزاری که مدل انجام می‌دهد را مدیریت کند و پاسخ را به آن برگرداند. این تابع handler هنگام فراخوانی startAudioConversation به LiveSession ارائه می‌شود، یک پارامتر FunctionCallPart می‌گیرد و FunctionResponsePart برمی‌گرداند:

کاتلین

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

جاوا

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

مراحل بعدی