Menggunakan panggilan fungsi

Dengan akses model langsung ML Kit, Anda dapat menggunakan pemanggilan fungsi untuk memungkinkan model Gemini Nano menghasilkan permintaan eksekusi fungsi terstruktur (panggilan alat), bukan respons teks biasa. Pemanggilan fungsi memungkinkan Anda menghubungkan model AI generatif di perangkat ke alat eksternal, API, dan fitur aplikasi lokal.

Kemampuan utama

Pemanggilan fungsi menyediakan kemampuan utama berikut:

  • Pemanggilan fungsi satu giliran: Gemini Nano memprediksi satu atau beberapa panggilan alat (FunctionCall), aplikasi Anda menjalankan fungsi secara lokal, dan alur selesai tanpa memerlukan respons model lanjutan.
  • Pemanggilan fungsi multi-turn: Gemini Nano memprediksi satu atau beberapa panggilan alat (FunctionCall), aplikasi Anda menjalankan fungsi secara lokal, dan meneruskan hasilnya kembali (FunctionResponsePart) untuk mengambil lebih banyak panggilan alat atau respons teks yang disintesis akhir.

Saat menerapkan panggilan fungsi, Anda dapat memanfaatkan hal berikut:

  • Definisi alat terprogram: Buat definisi alat FunctionDeclaration dan FunctionSchema dinamis saat runtime menggunakan ML Kit GenAI Schema API (com.google.mlkit:genai-schema).
  • Penguraian argumen terstruktur: Menerima nilai argumen yang diketik dengan jelas langsung dari kandidat respons model untuk menjalankan logika aplikasi lokal Anda.

Hasil contoh

Pemanggilan fungsi mendukung alur single-turn dan multi-turn. Dalam kedua kasus tersebut, model memprediksi satu atau beberapa panggilan alat yang terdiri dari nama fungsi dan argumen. Untuk alur multi-turn, setelah menerima hasil eksekusi aplikasi, aplikasi dapat mengirim permintaan lain ke model dengan histori percakapan lengkap untuk mendapatkan lebih banyak panggilan alat atau respons teks akhir bagi pengguna.

Alur eksekusi Perintah pengguna Output model
Satu giliran "Nyalakan lampu ruang keluarga dengan kecerahan 80%." Panggilan alat:
turn_on_light(room="living room", brightness=80)
Satu giliran "Buka aplikasi Kamera." Panggilan alat:
open_app(appName="Camera")
Multi-turn "Bagaimana cuaca di San Francisco dalam Celsius?" Panggilan alat perantara:
get_current_weather(location="San Francisco, CA", unit="celsius")

Output model akhir yang ditampilkan kepada pengguna:
In SF it's currently 25 degrees Celsius.

Prasyarat

Untuk menggunakan panggilan fungsi, Anda harus memenuhi persyaratan perangkat dan akun berikut:

Untuk memastikan Anda telah memenuhi persyaratan ini, pastikan model Gemini Nano 4 Fast tersedia di aplikasi AICore: buka aplikasi AICore, klik dropdown Select a model, dan pastikan Gemini Nano 4 Fast tercantum. Jika model tidak ada, berarti ada masalah dengan dukungan perangkat atau pendaftaran akun dan pemanggilan fungsi tidak akan berfungsi.

Selain itu, project Anda harus memenuhi persyaratan berikut:

  • Kotlin versi 2.3.0 atau yang lebih tinggi
  • SDK minimum (minSdk) versi 26 atau yang lebih tinggi

Mulai

Berikut adalah langkah-langkah untuk mulai menggunakan panggilan fungsi.

  1. Dalam file settings.gradle.kts (atau settings.gradle) level project, tambahkan mavenCentral() ke blok repositories {}.

    dependencyResolutionManagement {
        repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
        repositories {
            google()
            mavenCentral()
        }
    }
    
  2. Dalam file build.gradle.kts (atau build.gradle) level modul, tambahkan dependensi skema dan Prompt API ML Kit:

    Kotlin

    plugins {
        id("com.android.application")
        id("org.jetbrains.kotlin.android")
    }
    
    dependencies {
        // ML Kit GenAI Prompt and Schema SDKs
        implementation("com.google.mlkit:genai-prompt:1.0.0-beta5")
        implementation("com.google.mlkit:genai-schema:1.0.0-alpha2")
    }
    

    Groovy

    plugins {
        id 'com.android.application'
        id 'org.jetbrains.kotlin.android'
    }
    
    dependencies {
        // ML Kit GenAI Prompt and Schema SDKs
        implementation 'com.google.mlkit:genai-prompt:1.0.0-beta5'
        implementation 'com.google.mlkit:genai-schema:1.0.0-alpha2'
    }
    
  3. Dalam file build.gradle (atau build.gradle.kts) tingkat modul, tetapkan versi minSdk ke 26 atau yang lebih tinggi.

    Kotlin

    android {
        defaultConfig {
            // ...
            minSdk = 26
            // ...
        }
    }
    

    Groovy

    android {
        defaultConfig {
            // ...
            minSdk 26
            // ...
        }
    }
    

Cara menggunakan Function Calling API

Untuk menerapkan panggilan fungsi, lakukan langkah-langkah berikut:

  1. Tentukan alat Anda.
  2. Pilih model.
  3. Lampirkan alat ke permintaan Anda.
  4. Menangani panggilan alat (single-turn atau multi-turn).

Bagian berikutnya membahas contoh yang menunjukkan langkah-langkah ini.

Menentukan alat Anda

Buat skema alat secara terprogram menggunakan FunctionDeclaration, FunctionSchema, dan FunctionType dari paket com.google.mlkit.genai.schema.tools. (Untuk menentukan alat secara deklaratif pada waktu kompilasi menggunakan anotasi @AppFunction Android dengan eksekusi otomatis, lihat Menentukan alat.)

Misalnya, Anda dapat menentukan alat yang berorientasi pada tindakan (seperti menyalakan lampu smart untuk eksekusi satu giliran):

import com.google.mlkit.genai.schema.tools.FunctionDeclaration
import com.google.mlkit.genai.schema.tools.FunctionSchema
import com.google.mlkit.genai.schema.tools.FunctionType

val turnOnLightTool = FunctionDeclaration(
    name = "turn_on_light",
    description = "Turn on the lights in a room and set the brightness",
    parameters = FunctionSchema(
        type = FunctionType.OBJECT,
        properties = mapOf(
            "room" to FunctionSchema(
                type = FunctionType.STRING,
                description = "The room name"
            ),
            "brightness" to FunctionSchema(
                type = FunctionType.INTEGER,
                description = "Brightness level from 0 to 100"
            )
        ),
        required = listOf("room")
    )
)

Atau tentukan alat pengambilan data (seperti mengambil cuaca saat ini untuk sintesis multi-turn):

import com.google.mlkit.genai.schema.tools.FunctionDeclaration
import com.google.mlkit.genai.schema.tools.FunctionSchema
import com.google.mlkit.genai.schema.tools.FunctionType

val getWeatherTool = FunctionDeclaration(
    name = "get_current_weather",
    description = "Get the current weather for a location",
    parameters = FunctionSchema(
        type = FunctionType.OBJECT,
        properties = mapOf(
            "location" to FunctionSchema(
                type = FunctionType.STRING,
                description = "The city and state, e.g. San Francisco, CA"
            ),
            "unit" to FunctionSchema(
                type = FunctionType.STRING,
                description = "The temperature unit, either 'celsius' or 'fahrenheit'"
            )
        ),
        required = listOf("location")
    )
)

Pilih model

Pemanggilan fungsi memerlukan Gemini Nano 4. Untuk mengakses Gemini Nano 4, gunakan API pemilihan model untuk mengonfigurasi instance GenerativeModel Anda agar menargetkan ModelReleaseStage.PREVIEW DAN ModelPreference.FAST.

import com.google.mlkit.genai.prompt.Generation
import com.google.mlkit.genai.prompt.ModelPreference
import com.google.mlkit.genai.prompt.ModelReleaseStage
import com.google.mlkit.genai.prompt.generationConfig
import com.google.mlkit.genai.prompt.modelConfig

// Target the preview fast model (Gemini Nano 4)
val config = generationConfig {
    modelConfig = modelConfig {
        releaseStage = ModelReleaseStage.PREVIEW
        preference = ModelPreference.FAST
    }
}
val generativeModel = Generation.getClient(config)

Melampirkan alat ke permintaan Anda

Saat membuat objek GenerateContentRequest, teruskan daftar FunctionDeclaration Anda ke setTools() di builder permintaan.

Misalnya, untuk melampirkan alat untuk permintaan tindakan satu giliran dengan petunjuk sistem:

import com.google.mlkit.genai.prompt.SystemInstruction
import com.google.mlkit.genai.prompt.TextPart
import com.google.mlkit.genai.prompt.generateContentRequest

val requestText = "Turn on the living room lights and set brightness to 50"

val request = generateContentRequest(
    SystemInstruction("You are a helpful home automation assistant."),
    TextPart(requestText)
) {
    // Attach the FunctionDeclaration tool schemas
    setTools(listOf(turnOnLightTool))
    temperature = 0.2f
}

// Run non-streaming inference
val response = generativeModel.generateContent(request)

Atau untuk melampirkan daftar FunctionDeclaration Anda untuk kueri multi-giliran:

import com.google.mlkit.genai.prompt.SystemInstruction
import com.google.mlkit.genai.prompt.TextPart
import com.google.mlkit.genai.prompt.generateContentRequest

val availableTools = listOf(getWeatherTool)

// Use the generateContentRequest DSL
val request = generateContentRequest(
    TextPart("What is the weather in San Francisco, CA in celsius?")
) {
    setTools(availableTools)
}
val response = generativeModel.generateContent(request)

Menangani panggilan alat

Saat Gemini Nano memutuskan untuk memanggil alat, kandidat respons model berisi satu atau beberapa objek FunctionCall di candidate.functionCalls. Untuk menangani panggilan alat, aplikasi Anda harus memeriksa kandidat respons terlebih dahulu untuk memverifikasi apakah ada panggilan alat yang diprediksi:

import com.google.mlkit.genai.common.FunctionArgValue
import com.google.mlkit.genai.prompt.Content
import com.google.mlkit.genai.prompt.FunctionCallPart
import com.google.mlkit.genai.prompt.FunctionResponsePart
import com.google.mlkit.genai.prompt.GenerateContentRequest
import com.google.mlkit.genai.prompt.TextPart
import com.google.mlkit.genai.prompt.content

val candidate = response.candidates.firstOrNull()
val functionCalls = candidate?.functionCalls ?: emptyList()

if (functionCalls.isNotEmpty()) {
    // Process tool calls using either the single-turn or multi-turn flow
    // described in the following sections
}

Pemanggilan fungsi satu giliran

Gunakan panggilan fungsi satu giliran untuk tugas berorientasi tindakan yang langsung memenuhi permintaan (misalnya, "Buka aplikasi kamera" atau "Nyalakan lampu ruang keluarga"). Setelah aplikasi Anda menjalankan fungsi secara lokal, alur selesai; tidak diperlukan respons model lanjutan.

for (functionCall in functionCalls) {
    val name = functionCall.name
    val args = functionCall.arguments // Map<String, FunctionArgValue>

    when (name) {
        "open_app" -> {
            val appName = (args["appName"] as? FunctionArgValue.StringValue)?.value
            launchApp(appName)
        }
        "turn_on_light" -> {
            val room = (args["room"] as? FunctionArgValue.StringValue)?.value
            val brightness = (args["brightness"] as? FunctionArgValue.IntValue)?.value ?: 100
            setLightState(room, brightness)
        }
        else -> Log.w(TAG, "Unhandled tool call: $name")
    }
}

Pemanggilan fungsi multi-turn

Gunakan pemanggilan fungsi multi-turn saat pengguna mengharapkan jawaban bahasa alami berdasarkan data yang diambil oleh alat (misalnya, "Bagaimana cuaca di San Francisco?").

Dalam alur multi-turn, aplikasi Anda melakukan hal berikut:

  1. Menjalankan fungsi yang diminta secara lokal.
  2. Mengemas hasilnya dalam objek FunctionResponsePart.
  3. Menambahkan panggilan model (peran MODEL) dan hasil eksekusi Anda (peran USER) ke histori percakapan.
  4. Mengirim permintaan lanjutan kembali ke Gemini Nano untuk menyintesis jawaban bahasa alami akhir.
// 1. Execute each predicted tool call and collect results
val responseParts = mutableListOf<FunctionResponsePart>()

for (functionCall in functionCalls) {
    val responsePart: FunctionResponsePart = when {
        functionCall.name == "get_current_weather" -> {
            val location = (functionCall.arguments["location"] as? FunctionArgValue.StringValue)?.value ?: ""
            val unit = (functionCall.arguments["unit"] as? FunctionArgValue.StringValue)?.value ?: "celsius"

            val weatherData = fetchWeather(location, unit) // Local network/API call

            // Package the tool execution result as a key-value map
            FunctionResponsePart(
                id = functionCall.id,
                name = functionCall.name,
                response = mapOf("result" to weatherData)
            )
        }

        else -> throw IllegalArgumentException("Unknown tool: ${functionCall.name}")
    }
    responseParts.add(responsePart)
}

// 2. Append turns to conversation history to construct the multi-turn context
val history = request.contents.toMutableList().apply {
    // Turn 1: Model's request containing the predicted FunctionCallPart object
    add(
        content(Content.Role.MODEL) {
            for (call in functionCalls) {
                addPart(FunctionCallPart(call))
            }
        }
    )
    // Turn 2: User's response containing the executed FunctionResponsePart object
    add(
        content(Content.Role.USER) {
            for (responsePart in responseParts) {
                addPart(responsePart)
            }
        }
    )
}

// 3. Send the updated history back to Gemini Nano for final text synthesis
val followUpRequest = GenerateContentRequest.Builder(history)
    .setTools(availableTools) // Include tools in case the model requires subsequent tool calls
    .build()

val finalResponse = generativeModel.generateContent(followUpRequest)
val answer = finalResponse.candidates.firstOrNull()?.text

Log.d(TAG, "Final Model Response: $answer")

Kode contoh

Untuk contoh lengkap pemanggilan fungsi yang berfungsi di aplikasi Android, lihat aplikasi contoh ML Kit ini.

Masalah umum

  • AppFunctions AndroidX (@AppFunction) dalam akses model langsung (genai-prompt): Menemukan dan menjalankan alat @AppFunction waktu kompilasi secara langsung melalui Prompt API (com.google.mlkit:genai-prompt:1.0.0-beta5) belum tersedia; alat di library genai-prompt harus ditentukan secara terprogram menggunakan class FunctionDeclaration. Untuk menggunakan alat @AppFunction saat ini, gunakan alur kerja agentic (com.google.mlkit:genai-agent).
  • Saat menggunakan permintaan streaming (generateContentStream), panggilan alat tidak di-streaming token demi token. Sebagai gantinya, objek FunctionCall lengkap akan dimunculkan (melalui StreamingCallback.onNewFunctionCall atau dalam GenerateContentResponse.candidates[0].functionCalls yang di-streaming terakhir) setelah model selesai membuat panggilan alat.