Gemini Live API

Untuk aplikasi yang memerlukan dukungan suara real-time dan latensi rendah, seperti chatbot atau interaksi berbasis agen, Gemini Live API menyediakan cara yang dioptimalkan untuk melakukan streaming input dan output untuk model Gemini. Dengan menggunakan Firebase AI Logic, Anda dapat memanggil Gemini Live API langsung dari aplikasi Android Anda tanpa memerlukan integrasi backend. Panduan ini menunjukkan cara menggunakan Gemini Live API di aplikasi Android Anda dengan Firebase AI Logic.

Memulai

Sebelum memulai, pastikan aplikasi Anda menargetkan API level 21 atau yang lebih tinggi.

Jika belum, siapkan project Firebase dan hubungkan aplikasi Anda ke Firebase. Untuk mengetahui detailnya, lihat dokumentasi Logika AI Firebase.

Menyiapkan project Android Anda

Tambahkan dependensi library Firebase AI Logic ke file build.gradle.kts atau build.gradle level aplikasi Anda. Gunakan Firebase Android BoM untuk mengelola versi library.

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

Setelah menambahkan dependensi, sinkronkan project Android Anda dengan Gradle.

Mengintegrasikan Firebase AI Logic dan melakukan inisialisasi model generatif

Tambahkan izin RECORD_AUDIO ke file AndroidManifest.xml aplikasi Anda:

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

Lakukan inisialisasi layanan backend Gemini Developer API dan akses LiveModel. Gunakan model yang mendukung Live API, seperti gemini-2.0-flash-live-preview-04-09. Lihat dokumentasi Firebase untuk model yang tersedia.

Untuk menentukan suara, tetapkan nama suara dalam objek speechConfig sebagai bagian dari konfigurasi model. Jika Anda tidak menentukan suara, defaultnya adalah Puck.

Kotlin

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

Java

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

Secara opsional, Anda dapat menentukan persona atau peran yang dimainkan model dengan menetapkan instruksi sistem:

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.0-flash-live-preview-04-09",
       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.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
);

Anda dapat lebih mengkhususkan percakapan dengan model menggunakan petunjuk sistem untuk memberikan konteks khusus untuk aplikasi Anda (misalnya, histori aktivitas dalam aplikasi pengguna).

Menginisialisasi sesi Live API

Setelah membuat instance LiveModel, panggil model.connect() untuk membuat objek LiveSession dan membuat koneksi persisten dengan model dengan streaming latensi rendah. LiveSession memungkinkan Anda berinteraksi dengan model dengan memulai dan menghentikan sesi suara, serta mengirim dan menerima teks.

Kemudian, Anda dapat memanggil startAudioConversation() untuk memulai percakapan dengan model:

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

Selain itu, dalam percakapan Anda dengan model, perhatikan bahwa model tidak menangani interupsi. Kami berencana menambahkannya pada masa mendatang.

Anda juga dapat menggunakan Gemini Live API untuk membuat audio yang di-streaming dari teks dan membuat teks dari audio yang di-streaming. Perhatikan bahwa Live API bersifat dua arah sehingga Anda menggunakan koneksi yang sama untuk mengirim dan menerima konten. Pada akhirnya, Anda juga dapat mengirim gambar dan live stream video ke model.

Panggilan fungsi: menghubungkan Gemini Live API ke aplikasi Anda

Untuk melangkah lebih jauh, Anda juga dapat mengaktifkan model agar berinteraksi langsung dengan logika aplikasi Anda menggunakan panggilan fungsi.

Panggilan fungsi (atau panggilan alat) adalah fitur penerapan AI generatif yang memungkinkan model memanggil fungsi atas inisiatifnya sendiri untuk melakukan tindakan. Jika fungsi memiliki output, model akan menambahkannya ke konteks dan menggunakannya untuk generasi berikutnya.

Diagram yang menggambarkan cara Gemini Live API memungkinkan perintah pengguna
       ditafsirkan oleh model, memicu fungsi yang telah ditentukan sebelumnya dengan
       argumen yang relevan di aplikasi Android, yang kemudian menerima respons
       konfirmasi dari model.
Gambar 1: Diagram yang menggambarkan cara Gemini Live API memungkinkan perintah pengguna ditafsirkan oleh model, yang memicu fungsi yang telah ditentukan sebelumnya dengan argumen yang relevan di aplikasi Android, yang kemudian menerima respons konfirmasi dari model.

Untuk menerapkan panggilan fungsi di aplikasi Anda, mulailah dengan membuat objek FunctionDeclaration untuk setiap fungsi yang ingin Anda ekspos ke model.

Misalnya, untuk mengekspos fungsi addList yang menambahkan string ke daftar string ke Gemini, mulailah dengan membuat variabel FunctionDeclaration dengan nama dan deskripsi singkat dalam bahasa Inggris biasa tentang fungsi dan parameternya:

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

Kemudian, teruskan FunctionDeclaration ini sebagai Tool ke model saat Anda membuat instance-nya:

Kotlin

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

Java

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

Terakhir, terapkan fungsi pengendali untuk menangani panggilan alat yang dilakukan model dan teruskan kembali responsnya. Fungsi handler ini yang disediakan untuk LiveSession saat Anda memanggil startAudioConversation, menggunakan parameter FunctionCallPart dan menampilkan 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());

Langkah berikutnya