برنامج تعليمي: استدعاء الوظائف باستخدام واجهة برمجة تطبيقات Gemini


يُسهّل استدعاء الدوال عليك الحصول على مخرجات البيانات المنظَّمة من النماذج التوليدية. ويمكنك بعد ذلك استخدام هذه المخرجات لطلب واجهات برمجة تطبيقات أخرى وعرض بيانات الاستجابة ذات الصلة للنموذج. بعبارة أخرى، يساعدك استدعاء الوظيفة على ربط النماذج التوليدية بالأنظمة الخارجية، بحيث يتضمن المحتوى الذي يتم إنشاؤه أحدث المعلومات ودقتها.

يمكنك تقديم نماذج Gemini مع أوصاف للدوال. هذه هي الدوال التي تكتبها بلغة تطبيقك (أي أنها ليست دوال Google Cloud). قد يطلب منك النموذج استدعاء دالة وإعادة إرسال النتيجة لمساعدة النموذج في التعامل مع استعلامك.

اطّلِع على مقدّمة حول استدعاء الدوال البرمجية لمعرفة المزيد من المعلومات إذا لم يسبق لك ذلك.

إعداد مشروعك

قبل طلب واجهة برمجة تطبيقات Gemini، عليك إعداد مشروع Android الخاص بك الذي يتضمّن إعداد مفتاح واجهة برمجة التطبيقات، وإضافة تبعيات SDK إلى مشروع Android وإعداد النموذج.

إعداد استدعاء الدالة

في هذا البرنامج التعليمي، ستجعل النموذج يتفاعل مع واجهة برمجة تطبيقات تبادل العملات الافتراضية التي تدعم المعلمات التالية:

المَعلمة النوع مطلوبة الوصف
currencyFrom سلسلة نعم العملة المطلوب التحويل منها
currencyTo سلسلة نعم العملة المطلوب التحويل إليها

مثال على طلب بيانات من واجهة برمجة التطبيقات

{
  "currencyFrom": "USD",
  "currencyTo": "SEK"
}

مثال على ردّ من واجهة برمجة التطبيقات

{
  "base": "USD",
  "rates": {"SEK": 0.091}
}

الخطوة 1: إنشاء الدالة التي تنشئ طلب البيانات من واجهة برمجة التطبيقات

إذا لم تكن قد فعلت ذلك بالفعل، فابدأ بإنشاء الدالة التي تنشئ طلب واجهة برمجة تطبيقات.

لأغراض التوضيح في هذا البرنامج التعليمي، بدلاً من إرسال طلب فعلي من واجهة برمجة التطبيقات، ستعرض قيمًا ذات ترميز ثابت بالتنسيق نفسه الذي تعرضه واجهة برمجة التطبيقات الفعلية.

suspend fun makeApiRequest(
    currencyFrom: String,
    currencyTo: String
): JSONObject {
    // This hypothetical API returns a JSON such as:
    // {"base":"USD","rates":{"SEK": 0.091}}
    return JSONObject().apply {
        put("base", currencyFrom)
        put("rates", hashMapOf(currencyTo to 0.091))
    }
}

الخطوة 2: إنشاء تعريف دالة

أنشئ تعريف الدالة الذي ستنتقل إلى النموذج التوليدي (الخطوة التالية في هذا البرنامج التعليمي).

ننصحك بتضمين أكبر قدر ممكن من التفاصيل في أوصاف الدالة والمَعلمات. ويستخدم النموذج التوليدي هذه المعلومات لتحديد الدالة التي يجب اختيارها وكيفية توفير قيم للمعلَمات في استدعاء الدالة.

val getExchangeRate = defineFunction(
  name = "getExchangeRate",
  description = "Get the exchange rate for currencies between countries",
  Schema.str("currencyFrom", "The currency to convert from."),
  Schema.str("currencyTo", "The currency to convert to.")
) { from, to ->
    // Call the function that you declared above
    makeApiRequest(from, to)
}

الخطوة 3: تحديد تعريف الدالة أثناء إعداد النموذج

حدد تعريف الدالة عند إعداد النموذج التوليدي من خلال تمريره إلى معلمة tools للنموذج:

val generativeModel = GenerativeModel(
  // Use a model that supports function calling, like Gemini 1.0 Pro
  // (see "Supported models" in the "Introduction to function calling" page)
  modelName = "gemini-1.0-pro",
  // Access your API key as a Build Configuration variable (see "Set up your API key" above)
  apiKey = BuildConfig.apiKey,
  // Specify the function declaration.
  tools = listOf(Tool(listOf(getExchangeRate)))
)

الخطوة 4: إنشاء استدعاء دالة

يمكنك الآن المطالبة بالنموذج باستخدام الدالة المحددة.

والطريقة الموصى بها لاستخدام استدعاء الدالة هي من خلال واجهة الدردشة، نظرًا لأن استدعاءات الوظائف تتناسب بشكل جيد مع بنية الدردشة المتعددة الأدوار.

val chat = generativeModel.startChat()

val prompt = "How much is 50 US dollars worth in Swedish krona?"

// Send the message to the generative model
var response = chat.sendMessage(prompt)

// Check if the model responded with a function call
response.functionCall?.let { functionCall ->
  // Try to retrieve the stored lambda from the model's tools and
  // throw an exception if the returned function was not declared
  val matchedFunction = generativeModel.tools?.flatMap { it.functionDeclarations }
      ?.first { it.name == functionCall.name }
      ?: throw InvalidStateException("Function not found: ${functionCall.name}")

  // Call the lambda retrieved above
  val apiResponse: JSONObject = matchedFunction.execute(functionCall)

  // Send the API response back to the generative model
  // so that it generates a text response that can be displayed to the user
  response = chat.sendMessage(
    content(role = "function") {
        part(FunctionResponsePart(functionCall.name, apiResponse))
    }
  )
}

// Whenever the model responds with text, show it in the UI
response.text?.let { modelResponse ->
    println(modelResponse)
}