Gemini Live API

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

شروع کنید

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

اگر قبلاً این کار را نکرده اید، یک پروژه 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.1.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 همگام کنید.

Firebase AI Logic را یکپارچه کنید و یک مدل تولیدی را مقداردهی اولیه کنید

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

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

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

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

کاتلین

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

جاوا

// Initialize the `LiveModel`
LiveGenerativeModel model = FirebaseAI
       .getInstance(GenerativeBackend.googleAI())
       .liveModel(
              "gemini-2.0-flash-live-preview-04-09",
              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-2.0-flash-live-preview-04-09",
       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-2.0-flash-live-preview-04-09",
              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() را فراخوانی کنید:

کاتلین

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 API به کاربر اجازه می دهد        توسط یک مدل تفسیر شود و یک تابع از پیش تعریف شده را با        آرگومان های مربوطه در یک برنامه اندروید، که سپس تأیید دریافت می کند        پاسخ از مدل
شکل 1: نمودار نشان می دهد که چگونه Gemini Live API اجازه می دهد تا یک درخواست کاربر توسط یک مدل تفسیر شود، یک تابع از پیش تعریف شده با آرگومان های مربوطه در یک برنامه Android را راه اندازی می کند، که سپس یک پاسخ تایید از مدل دریافت می کند.

برای اجرای فراخوانی تابع در برنامه خود، با ایجاد یک شی FunctionDeclaration برای هر تابعی که می خواهید در معرض مدل قرار دهید، شروع کنید.

به عنوان مثال، برای نمایش یک تابع addList که یک رشته را به لیستی از رشته‌ها به Gemini اضافه می‌کند، با ایجاد یک متغیر FunctionDeclaration با یک نام و یک توضیح کوتاه به انگلیسی ساده از تابع و پارامتر آن شروع کنید:

کاتلین

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

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-2.0-flash-live-preview-04-09",
       generationConfig = liveGenerationConfig {
          responseModality = ResponseModality.AUDIO
          speechConfig = SpeechConfig(voice= Voice("FENRIR"))
       },
       systemInstruction = systemInstruction,
       tools = listOf(addListTool)
)

جاوا

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

در نهایت، یک تابع 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());

مراحل بعدی