من خلال الوصول المباشر إلى النماذج في "حزمة تعلّم الآلة"، يمكنك استخدام ميزة استدعاء الدوال لتمكين نماذج Gemini Nano من إخراج طلبات تنفيذ الدوال المنظَّمة (استدعاءات الأدوات) بدلاً من الردود النصية العادية. تتيح لك ميزة "استدعاء الدوال" ربط نماذج الذكاء الاصطناعي التوليدي على الجهاز فقط بالأدوات الخارجية وواجهات برمجة التطبيقات وميزات التطبيقات المحلية.
الإمكانات الأساسية
توفّر ميزة "استدعاء الدوال" الإمكانات الأساسية التالية:
- استدعاء الدالة في جولة واحدة: يتوقّع Gemini Nano استدعاء أداة واحدة أو أكثر (
FunctionCall)، وينفّذ تطبيقك الدوال على الجهاز، ويكتمل التدفق بدون الحاجة إلى ردّ متابعة من النموذج. - استدعاء الدالة في محادثات متعددة: يتوقّع Gemini Nano استدعاء أداة واحدة أو أكثر (
FunctionCall)، وينفّذ تطبيقك الدوال على الجهاز، ثم يعيد النتائج (FunctionResponsePart) لاسترداد المزيد من استدعاءات الأدوات أو رد نصي نهائي مركّب.
عند تنفيذ ميزة "استدعاء الدوال"، يمكنك الاستفادة مما يلي:
- تعريفات الأدوات الآلية: يمكنك إنشاء تعريفات ديناميكية لأدوات
FunctionDeclarationوFunctionSchemaفي وقت التشغيل باستخدام واجهة برمجة تطبيقات مخطط الذكاء الاصطناعي التوليدي لحزمة تعلّم الآلة (com.google.mlkit:genai-schema). - تحليل الوسيطات المنظَّمة: يمكنك تلقّي قيم وسيطات ذات نوع قوي مباشرةً من ردّ النموذج المرشّح لتنفيذ منطق التطبيق المحلي.
أمثلة النتائج
تتيح ميزة "استدعاء الدوال" استخدام مسارات المحادثات ذات الجولة الواحدة والمتعددة الجولات. في كلتا الحالتَين، يتوقّع النموذج طلبًا واحدًا أو أكثر من طلبات الأدوات التي تتألف من اسم الدالة والوسيطات. بالنسبة إلى مسارات المحادثات المتعددة، بعد تلقّي نتائج تنفيذ التطبيق، يمكن للتطبيق إرسال طلب آخر إلى النموذج يتضمّن سجلّ المحادثة الكامل للحصول على المزيد من طلبات الأدوات أو ردّ نصي نهائي للمستخدم.
| سير التنفيذ | طلب المستخدم | مخرجات النموذج |
|---|---|---|
| ردّ واحد | "أريد تشغيل مصابيح غرفة المعيشة على مستوى سطوع% 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.
|
المتطلبات الأساسية
لاستخدام ميزة "استدعاء الدوال"، يجب استيفاء المتطلبات التالية المتعلقة بالجهاز والحساب:
- جهازك متوافق مع Prompt API.
- حساب Google على جهازك هو جزء من برنامج معاينة المطوّر لخدمة AICore.
للتأكّد من استيفاء هذه المتطلبات، تحقَّق من توفّر نموذج Gemini Nano 4 Fast في تطبيق AICore: افتح تطبيق AICore، وانقر على القائمة المنسدلة اختيار نموذج، وتأكَّد من أنّ Gemini Nano 4 Fast مُدرَج. إذا لم يكن النموذج موجودًا، فهذا يعني أنّ هناك مشكلة في توافق الجهاز أو تسجيل الحساب، ولن تعمل ميزة استدعاء الدوال.
بالإضافة إلى ذلك، يجب أن يستوفي مشروعك المتطلبات التالية:
- الإصدار 2.3.0 من Kotlin أو إصدار أحدث
- الحد الأدنى لإصدار حزمة تطوير البرامج (SDK) (
minSdk) هو 26 أو إصدار أحدث
البدء
في ما يلي خطوات بدء استخدام ميزة "استدعاء الدوال".
في ملف
settings.gradle.kts(أوsettings.gradle) على مستوى المشروع، أضِفmavenCentral()إلى الحزمةrepositories {}.dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { google() mavenCentral() } }في ملف
build.gradle.kts(أوbuild.gradle) على مستوى الوحدة، أضِف اعتماديات 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") }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' }في ملف
build.gradle(أوbuild.gradle.kts) على مستوى الوحدة، اضبط إصدارminSdkعلى26أو إصدار أحدث.Kotlin
android { defaultConfig { // ... minSdk = 26 // ... } }Groovy
android { defaultConfig { // ... minSdk 26 // ... } }
كيفية استخدام Function Calling API
لتنفيذ ميزة "استدعاء الدوال"، اتّبِع الخطوات التالية:
- حدِّد أدواتك.
- اختَر النموذج.
- أرفِق الأدوات بطلبك.
- التعامل مع طلبات الأدوات (في جولة واحدة أو جولات متعددة)
تتناول الأقسام التالية مثالاً يوضّح هذه الخطوات.
تحديد أدواتك
يمكنك إنشاء مخططات الأدوات آليًا باستخدام FunctionDeclaration وFunctionSchema وFunctionType من حزمة com.google.mlkit.genai.schema.tools. (لتعريف الأدوات بشكل تعريفي في
وقت التجميع باستخدام تعليق Android التوضيحي @AppFunction مع التنفيذ التلقائي،
يُرجى الاطّلاع على تعريف الأدوات).
على سبيل المثال، يمكنك تحديد أداة موجَّهة نحو الإجراءات (مثل تشغيل مصباح ذكي لتنفيذ إجراء واحد):
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، استخدِم
واجهة برمجة التطبيقات لاختيار النموذج لضبط
مثيل 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 في 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
}
استدعاء الدوال في جولة واحدة
استخدِم استدعاء الدالة في جولة واحدة للمهام التي تتطلّب اتّخاذ إجراء، حيث ينفّذ التطبيق الطلب مباشرةً (على سبيل المثال، "افتح تطبيق الكاميرا" أو "شغِّل مصابيح الشاشات الكبيرة"). بعد أن ينفّذ تطبيقك الدالة محليًا، تكتمل العملية، ولا يلزم الحصول على ردّ متابعة من النموذج.
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")
}
}
استدعاء الدوال المتعدّد الأدوار
استخدِم ميزة استدعاء الدوال المتعددة الأدوار عندما يتوقع المستخدم إجابة بلغة طبيعية استنادًا إلى البيانات التي تستردها الأداة (على سبيل المثال، "ما حالة الطقس في سان فرانسيسكو؟").
في مسار متعدد الجولات، ينفّذ تطبيقك ما يلي:
- لتنفيذ الدالة المطلوبة محليًا
- يتم تجميع النتيجة في عنصر
FunctionResponsePart. - يُلحق كلاً من طلب النموذج (دور
MODEL) ونتيجة التنفيذ (دورUSER) بسجلّ المحادثة. - يرسل طلب متابعة إلى 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، يمكنك مراجعة نموذج تطبيق حزمة تعلّم الآلة.
المشاكل المعروفة
- AndroidX AppFunctions (
@AppFunction) في الوصول المباشر إلى النموذج (genai-prompt): لا تتوفّر بعد إمكانية اكتشاف وتنفيذ أدوات@AppFunctionفي وقت التجميع مباشرةً من خلال Prompt API (com.google.mlkit:genai-prompt:1.0.0-beta5). يجب تحديد الأدوات في مكتبةgenai-promptآليًا باستخدام فئةFunctionDeclaration. لاستخدام أدوات "@AppFunction" اليوم، يمكنك استخدام مهام سير العمل المستندة إلى الذكاء الاصطناعي الوكيل (com.google.mlkit:genai-agent). - عند استخدام طلبات البث (
generateContentStream)، لا يتم بث طلبات الأدوات رمزًا تلو الآخر. بدلاً من ذلك، يتم إرسال كائناتFunctionCallكاملة (عبرStreamingCallback.onNewFunctionCallأو فيGenerateContentResponse.candidates[0].functionCallsالنهائي الذي يتم بثه) بعد أن ينتهي النموذج من إنشاء طلب الأداة.