İşlev çağrısını kullan

ML Kit'in doğrudan model erişimi sayesinde, Gemini Nano modellerinin düz metin yanıtlar yerine yapılandırılmış işlev yürütme istekleri (araç çağrıları) oluşturmasını sağlamak için işlev çağrısı özelliğini kullanabilirsiniz. İşlev çağrısı, cihaz üzerinde üretken yapay zeka modellerini harici araçlara, API'lere ve yerel uygulama özelliklerine bağlamanıza olanak tanır.

Temel özellikler

İşlev çağrısı aşağıdaki temel özellikleri sunar:

  • Tek turlu işlev çağrısı: Gemini Nano, bir veya daha fazla araç çağrısı (FunctionCall) tahmin eder, uygulamanız işlevleri yerel olarak yürütür ve akış, ek bir model yanıtına gerek kalmadan tamamlanır.
  • Çok turlu işlev çağrısı: Gemini Nano, bir veya daha fazla araç çağrısı (FunctionCall) tahmin eder, uygulamanız işlevleri yerel olarak yürütür ve daha fazla araç çağrısı veya nihai sentezlenmiş metin yanıtı almak için sonuçları geri iletir (FunctionResponsePart).

İşlev çağrısını uygularken aşağıdakilerden yararlanabilirsiniz:

  • Programatik araç tanımları: ML Kit GenAI Schema API'yi (com.google.mlkit:genai-schema) kullanarak çalışma zamanında dinamik FunctionDeclaration ve FunctionSchema araç tanımları oluşturun.
  • Yapılandırılmış bağımsız değişken ayrıştırma: Yerel uygulama mantığınızı yürütmek için doğrudan model yanıtı adayından kesin olarak yazılmış bağımsız değişken değerleri alın.

Örnek sonuçlar

İşlev çağrısı, hem tek adımlı hem de çok adımlı akışları destekler. Her iki durumda da model, işlev adı ve bağımsız değişkenlerden oluşan bir veya daha fazla araç çağrısı tahmin eder. Çok adımlı akışlarda, uygulamanın yürütme sonuçlarını aldıktan sonra uygulama, daha fazla araç çağrısı veya kullanıcı için nihai bir metin yanıtı almak üzere tüm görüşme geçmişini içeren başka bir istek gönderebilir.

Yürütme akışı Kullanıcı istemi Model çıktısı
Tek turlu "Oturma odasının ışıklarını% 80 parlaklığa ayarla." Araç çağrısı:
turn_on_light(room="living room", brightness=80)
Tek turlu "Kamera uygulamasını aç." Araç çağrısı:
open_app(appName="Camera")
Çok aşamalı etkileşim "San Francisco'da hava kaç derece?" Araç çağrısı:
get_current_weather(location="San Francisco, CA", unit="celsius")

Kullanıcıya gösterilen nihai model çıktısı:
In SF it's currently 25 degrees Celsius.

Ön koşullar

İşlev çağrısı özelliğini kullanmak için aşağıdaki cihaz ve hesap koşullarını karşılamanız gerekir:

Bu koşulları karşıladığınızdan emin olmak için AICore uygulamasında Gemini Nano 4 Fast modelinin mevcut olup olmadığını kontrol edin: AICore uygulamasını açın, Select a model (Model seçin) açılır listesini tıklayın ve Gemini Nano 4 Fast'in listede yer aldığından emin olun. Model orada yoksa cihaz desteği veya hesap kaydıyla ilgili bir sorun vardır ve işlev çağrısı çalışmaz.

Ayrıca projeniz aşağıdaki koşulları karşılamalıdır:

  • Kotlin 2.3.0 veya sonraki sürümler
  • Minimum SDK (minSdk) sürümü 26 veya daha yeni olmalıdır.

Başlayın

İşlev çağrısını kullanmaya başlamak için aşağıdaki adımları uygulayın.

  1. Proje düzeyindeki settings.gradle.kts (veya settings.gradle) dosyanızda repositories {} bloğuna mavenCentral() ekleyin.

    dependencyResolutionManagement {
        repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
        repositories {
            google()
            mavenCentral()
        }
    }
    
  2. Modül düzeyindeki build.gradle.kts (veya build.gradle) dosyanıza ML Kit Prompt API ve şema bağımlılıklarını ekleyin:

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

    Modern

    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. Modül düzeyindeki build.gradle (veya build.gradle.kts dosyanızda) minSdk sürümünü 26 veya daha yeni bir sürüme ayarlayın.

    Kotlin

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

    Modern

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

İşlev Çağrısı API'sini kullanma

İşlev çağrısını uygulamak için aşağıdaki adımları uygulayın:

  1. Araçlarınızı tanımlayın.
  2. Modeli seçin.
  3. İsteğinize araç ekleyin.
  4. Araç çağrılarını (tek turlu veya çok turlu) işleme

Sonraki bölümlerde bu adımları gösteren bir örnek ele alınmaktadır.

Araçlarınızı tanımlama

com.google.mlkit.genai.schema.tools paketindeki FunctionDeclaration, FunctionSchema ve FunctionType öğelerini kullanarak araç şemalarını programatik olarak oluşturun. (Araçları, Android'in otomatik yürütme özelliğine sahip @AppFunction ek açıklamasını kullanarak derleme zamanında tanımlamak için Araçları tanımlama bölümüne bakın.)

Örneğin, eyleme dayalı bir araç (ör. tek seferlik yürütme için akıllı ışığı açma) tanımlayabilirsiniz:

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

Alternatif olarak, bir veri alma aracı tanımlayabilirsiniz (ör. çok adımlı sentez için mevcut hava durumunu alma):

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

Modeli seçin

İşlev çağrısı için Gemini Nano 4 gerekir. Gemini Nano 4'e erişmek için model seçimi API'sini kullanarak GenerativeModel örneğinizi ModelReleaseStage.PREVIEW VE ModelPreference.FAST'yi hedefleyecek şekilde yapılandırın.

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)

İsteğinize araç ekleme

GenerateContentRequest nesnesi oluştururken FunctionDeclaration listenizi istek oluşturucudaki setTools() öğesine iletin.

Örneğin, sistem talimatı içeren tek adımlı bir işlem isteğine araç eklemek için:

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)

Çok turlu bir sorgu için FunctionDeclaration listenizi eklemek isterseniz:

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)

Araç çağrılarını işleme

Gemini Nano bir araç çağırmaya karar verdiğinde modelin yanıt adayı, candidate.functionCalls içinde bir veya daha fazla FunctionCall nesnesi içerir. Uygulamanızın araç çağrılarını işleyebilmesi için önce yanıt adayını inceleyerek araç çağrısı tahmin edilip edilmediğini doğrulaması gerekir:

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
}

Tek adımlı işlev çağrısı

Uygulamanın isteği doğrudan yerine getirdiği, eyleme dayalı görevler için tek adımlı işlev çağrısını kullanın (ör. "Kamera uygulamasını aç" veya "Living Room ışıklarını aç"). Uygulamanız işlevi yerel olarak yürüttükten sonra akış tamamlanır. Modelden başka bir yanıt alınması gerekmez.

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

Çok adımlı işlev çağrısı

Kullanıcı, araç tarafından alınan verilere dayalı olarak doğal dilde bir yanıt beklediğinde (ör. "San Francisco'da hava nasıl?") çok turlu işlev çağrısını kullanın.

Çok adımlı akışta uygulamanız şunları yapar:

  1. İstenen işlevi yerel olarak yürütür.
  2. Sonucu bir FunctionResponsePart nesnesinde paketler.
  3. Hem modelin çağrısını (MODEL rolü) hem de yürütme sonucunuzu (USER rolü) görüşme geçmişine ekler.
  4. Nihai doğal dil yanıtını sentezlemek için Gemini Nano'ya bir ek istek gönderir.
// 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")

Örnek kod

Android uygulamasında işlev çağrısının eksiksiz bir çalışma örneği için bu ML Kiti örnek uygulamasına bakın.

Bilinen sorunlar

  • Doğrudan model erişiminde AndroidX AppFunctions (@AppFunction) (genai-prompt): Derleme zamanı @AppFunction araçlarını doğrudan Prompt API (com.google.mlkit:genai-prompt:1.0.0-beta5) üzerinden keşfetme ve yürütme henüz kullanılamıyor. genai-prompt kitaplığındaki araçlar, FunctionDeclaration sınıfı kullanılarak programatik olarak tanımlanmalıdır. @AppFunction araçlarını hemen kullanmak için temsilci iş akışlarından (com.google.mlkit:genai-agent) yararlanın.
  • Akış istekleri (generateContentStream) kullanılırken araç çağrıları parça parça akış olarak aktarılmaz. Bunun yerine, model araç çağrısını oluşturmayı tamamladığında FunctionCall nesnelerinin tamamı (StreamingCallback.onNewFunctionCall aracılığıyla veya son akışlı GenerateContentResponse.candidates[0].functionCalls içinde) yayınlanır.