ใช้การเรียกใช้ฟังก์ชัน

การเข้าถึงโมเดลโดยตรงของ ML Kit ช่วยให้คุณใช้การเรียกใช้ฟังก์ชันเพื่อเปิดใช้โมเดล Gemini Nano เพื่อแสดงผลคำขอการเรียกใช้ฟังก์ชันที่มีโครงสร้าง (การเรียกใช้เครื่องมือ) แทนการตอบกลับด้วยข้อความธรรมดาได้ การเรียกใช้ฟังก์ชันช่วยให้คุณเชื่อมต่อโมเดล Generative AI ในอุปกรณ์กับเครื่องมือภายนอก, API และฟีเจอร์ของแอปในเครื่องได้

ความสามารถหลัก

การเรียกใช้ฟังก์ชันมีความสามารถหลักๆ ดังนี้

  • การเรียกใช้ฟังก์ชันแบบเทิร์นเดียว: Gemini Nano จะคาดการณ์การเรียกใช้เครื่องมืออย่างน้อย 1 รายการ (FunctionCall) แอปของคุณจะเรียกใช้ฟังก์ชันในเครื่อง และโฟลว์จะเสร็จสมบูรณ์โดยไม่ต้องมีการตอบกลับของโมเดลเพื่อติดตามผล
  • การเรียกใช้ฟังก์ชันแบบหลายรอบ: Gemini Nano จะคาดการณ์การเรียกใช้เครื่องมืออย่างน้อย 1 รายการ (FunctionCall) แอปของคุณจะเรียกใช้ฟังก์ชันในเครื่องและส่งผลลัพธ์กลับ (FunctionResponsePart) เพื่อดึงข้อมูลการเรียกใช้เครื่องมือเพิ่มเติมหรือคำตอบแบบข้อความที่สังเคราะห์ขึ้นขั้นสุดท้าย

เมื่อใช้การเรียกใช้ฟังก์ชัน คุณจะใช้ประโยชน์จากสิ่งต่อไปนี้ได้

  • คำจำกัดความของเครื่องมือแบบเป็นโปรแกรม: สร้างคำจำกัดความของเครื่องมือ FunctionDeclaration และ FunctionSchema แบบไดนามิกที่รันไทม์โดยใช้ ML Kit GenAI Schema API (com.google.mlkit:genai-schema)
  • การแยกวิเคราะห์อาร์กิวเมนต์ที่มีโครงสร้าง: รับค่าอาร์กิวเมนต์ที่มีประเภทชัดเจนโดยตรงจากตัวเลือกคำตอบของโมเดลเพื่อเรียกใช้ตรรกะของแอปในเครื่อง

ตัวอย่างผลการแข่ง

การเรียกใช้ฟังก์ชันรองรับทั้งโฟลว์แบบเทิร์นเดียวและหลายเทิร์น ในทั้ง 2 กรณี โมเดลจะคาดการณ์การเรียกใช้เครื่องมืออย่างน้อย 1 รายการซึ่งประกอบด้วยชื่อฟังก์ชันและอาร์กิวเมนต์ สำหรับโฟลว์แบบหลายเทิร์น หลังจากได้รับผลการดำเนินการของแอปแล้ว แอปจะส่งคำขออีกรายการไปยังโมเดลพร้อมประวัติการสนทนาทั้งหมดเพื่อรับการเรียกใช้เครื่องมือเพิ่มเติมหรือการตอบกลับด้วยข้อความสุดท้ายสำหรับผู้ใช้

ขั้นตอนการดำเนินการ พรอมต์ของผู้ใช้ เอาต์พุตโมเดล
แบบหมุนรอบเดียว "เปิดไฟห้องนั่งเล่นที่ความสว่าง 80%" การเรียกใช้เครื่องมือ:
turn_on_light(room="living room", brightness=80)
แบบหมุนรอบเดียว "เปิดแอปกล้องถ่ายรูป" การเรียกใช้เครื่องมือ:
open_app(appName="Camera")
การสนทนาไปมา "อากาศที่ซานฟรานซิสโกเป็นอย่างไรในหน่วยเซลเซียส" การเรียกใช้เครื่องมือระดับกลาง:
get_current_weather(location="San Francisco, CA", unit="celsius")

เอาต์พุตโมเดลสุดท้ายที่แสดงต่อผู้ใช้:
In SF it's currently 25 degrees Celsius.

ข้อกำหนดเบื้องต้น

หากต้องการใช้การเรียกใช้ฟังก์ชัน อุปกรณ์และบัญชีของคุณต้องมีคุณสมบัติตรงตามข้อกำหนดต่อไปนี้

หากต้องการตรวจสอบว่าคุณมีคุณสมบัติตรงตามข้อกำหนดเหล่านี้หรือไม่ ให้ตรวจสอบว่าโมเดล Gemini Nano 4 Fast พร้อมใช้งานในแอป AICore หรือไม่ โดยเปิดแอป AICore คลิกเมนูแบบเลื่อนลงเลือกโมเดล แล้วตรวจสอบว่ามี Gemini Nano 4 Fast อยู่ในรายการหรือไม่ หากไม่มีโมเดล แสดงว่ามีปัญหาเกี่ยวกับการรองรับอุปกรณ์หรือการลงทะเบียนบัญชี และการเรียกใช้ฟังก์ชันจะใช้งานไม่ได้

นอกจากนี้ โปรเจ็กต์ต้องเป็นไปตามข้อกำหนดต่อไปนี้

  • Kotlin เวอร์ชัน 2.3.0 ขึ้นไป
  • SDK ขั้นต่ำ (minSdk) เวอร์ชัน 26 ขึ้นไป

เริ่มต้นใช้งาน

ขั้นตอนในการเริ่มใช้การเรียกใช้ฟังก์ชันมีดังนี้

  1. ในไฟล์ settings.gradle.kts (หรือ settings.gradle) ระดับโปรเจ็กต์ ให้เพิ่ม mavenCentral() ลงในบล็อก repositories {}

    dependencyResolutionManagement {
        repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
        repositories {
            google()
            mavenCentral()
        }
    }
    
  2. ใน build.gradle.kts ระดับโมดูล (หรือไฟล์ build.gradle) ให้เพิ่มทรัพยากร Dependency ของ ML Kit Prompt API และสคีมา ดังนี้

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

    ดึงดูด

    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. ใน build.gradle (หรือไฟล์ build.gradle.kts) ระดับโมดูล ให้ตั้งค่าเวอร์ชัน minSdk เป็น 26 ขึ้นไป

    Kotlin

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

    ดึงดูด

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

วิธีใช้ Function Calling API

หากต้องการใช้การเรียกใช้ฟังก์ชัน ให้ทำตามขั้นตอนต่อไปนี้

  1. กำหนดเครื่องมือ
  2. เลือกโมเดล
  3. แนบเครื่องมือไปกับคำขอ
  4. จัดการการเรียกใช้เครื่องมือ (แบบเทิร์นเดียวหรือหลายเทิร์น)

ส่วนถัดไปจะแสดงตัวอย่างที่สาธิตขั้นตอนเหล่านี้

กำหนดเครื่องมือ

สร้างสคีมาเครื่องมือแบบเป็นโปรแกรมโดยใช้ FunctionDeclaration, FunctionSchema และ FunctionType จากแพ็กเกจ com.google.mlkit.genai.schema.tools (หากต้องการกำหนดเครื่องมือแบบประกาศที่เวลาคอมไพล์โดยใช้คำอธิบายประกอบ @AppFunction ของ Android ที่มีการดำเนินการอัตโนมัติ โปรดดูกำหนดเครื่องมือ)

ตัวอย่างเช่น คุณสามารถกำหนดเครื่องมือที่เน้นการดำเนินการ (เช่น การเปิดหลอดไฟอัจฉริยะสำหรับการดำเนินการแบบครั้งเดียว) ดังนี้

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

หรือกำหนดเครื่องมือดึงข้อมูล (เช่น การดึงข้อมูลสภาพอากาศปัจจุบันสำหรับการสังเคราะห์แบบหลายรอบ)

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

เลือกโมเดล

การเรียกใช้ฟังก์ชันต้องใช้ Gemini Nano 4 หากต้องการเข้าถึง Gemini Nano 4 ให้ใช้ API การเลือกโมเดลเพื่อกำหนดค่าอินสแตนซ์ GenerativeModel ให้กำหนดเป้าหมายเป็น ModelReleaseStage.PREVIEW และ 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)

แนบเครื่องมือไปกับคำขอ

เมื่อสร้างออบเจ็กต์ GenerateContentRequest ให้ส่งรายการ FunctionDeclaration ไปยัง setTools() ในเครื่องมือสร้างคำขอ

ตัวอย่างเช่น หากต้องการแนบเครื่องมือสำหรับคำขอการดำเนินการแบบเทิร์นเดียวที่มีคำสั่งของระบบ ให้ทำดังนี้

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)

หรือหากต้องการแนบรายการ FunctionDeclaration สำหรับการค้นหาแบบหลายเทิร์น ให้ทำดังนี้

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)

จัดการการเรียกใช้เครื่องมือ

เมื่อ Gemini Nano ตัดสินใจเรียกใช้เครื่องมือ คำตอบที่เป็นไปได้ของโมเดลจะมีออบเจ็กต์ FunctionCall อย่างน้อย 1 รายการใน candidate.functionCalls หากต้องการจัดการการเรียกใช้เครื่องมือ แอปของคุณต้องตรวจสอบผู้สมัครรับคำตอบก่อนเพื่อยืนยันว่ามีการคาดการณ์การเรียกใช้เครื่องมือหรือไม่

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
}

การเรียกใช้ฟังก์ชันแบบเทิร์นเดียว

ใช้การเรียกใช้ฟังก์ชันแบบเทิร์นเดียวสำหรับงานที่เน้นการดำเนินการซึ่งแอปจะดำเนินการตามคำขอโดยตรง (เช่น "เปิดแอปกล้อง" หรือ "เปิดไฟใน Living Room") เมื่อแอปเรียกใช้ฟังก์ชันในเครื่องแล้ว โฟลว์จะเสร็จสมบูรณ์ โดยไม่จำเป็นต้องมีการตอบกลับจากโมเดลเพื่อติดตามผล

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

การเรียกใช้ฟังก์ชันแบบหลายเทิร์น

ใช้การเรียกใช้ฟังก์ชันแบบหลายรอบเมื่อผู้ใช้คาดหวังคำตอบที่เป็นภาษาธรรมชาติโดยอิงตามข้อมูลที่เครื่องมือดึงมา (เช่น "สภาพอากาศในซานฟรานซิสโกเป็นอย่างไร")

ในขั้นตอนแบบหลายเทิร์น แอปของคุณจะทำสิ่งต่อไปนี้

  1. เรียกใช้ฟังก์ชันที่ขอในเครื่อง
  2. รวมผลลัพธ์ไว้ในออบเจ็กต์ FunctionResponsePart
  3. เพิ่มทั้งการเรียกใช้โมเดล (บทบาท MODEL) และผลการดำเนินการ (บทบาท USER) ลงในประวัติการสนทนา
  4. ส่งคำขอติดตามผลกลับไปยัง Gemini Nano เพื่อสังเคราะห์คำตอบสุดท้ายที่เป็นภาษาธรรมชาติ
// 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")

โค้ดตัวอย่าง

ดูตัวอย่างการทำงานที่สมบูรณ์ของการเรียกใช้ฟังก์ชันในแอป Android ได้ที่แอปตัวอย่าง ML Kit นี้

ปัญหาที่ทราบ

  • AndroidX AppFunctions (@AppFunction) ในการเข้าถึงโมเดลโดยตรง (genai-prompt): การค้นหาและเรียกใช้เครื่องมือ @AppFunction ในเวลาคอมไพล์ผ่าน Prompt API (com.google.mlkit:genai-prompt:1.0.0-beta5) โดยตรงยังไม่พร้อมใช้งาน คุณต้องกำหนดเครื่องมือในไลบรารี genai-prompt โดยใช้โปรแกรมผ่านคลาส FunctionDeclaration หากต้องการใช้เครื่องมือ @AppFunction ในปัจจุบัน ให้ใช้เวิร์กโฟลว์แบบ Agentic (com.google.mlkit:genai-agent)
  • เมื่อใช้คำขอสตรีมมิง (generateContentStream) ระบบจะไม่สตรีมการเรียกใช้เครื่องมือแบบโทเค็นต่อโทเค็น แต่จะมีการส่งออบเจ็กต์ FunctionCall ที่สมบูรณ์ (ผ่าน StreamingCallback.onNewFunctionCall หรือใน GenerateContentResponse.candidates[0].functionCalls ที่สตรีมสุดท้าย) เมื่อโมเดลสร้างการเรียกใช้เครื่องมือเสร็จสิ้น