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


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

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

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

إعداد مشروعك

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

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

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

المَعلمة النوع مطلوبة الوصف
currencyDate سلسلة نعم تاريخ استرجاع سعر الصرف لـ
(والذي يجب أن يكون دائمًا بالتنسيق YYYY-MM-DD أو القيمة latest في حال عدم تحديد فترة زمنية)
currencyFrom سلسلة نعم العملة المطلوب التحويل منها
currencyTo سلسلة لا العملة المطلوب التحويل إليها

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

{
  "currencyDate": "2024-04-17",
  "currencyFrom": "USD",
  "currencyTo": "SEK"
}

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

{
  "base": "USD",
  "date": "2024-04-17",
  "rates": {"SEK": 0.091}
}

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

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

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

Future<Map<String, Object?>> findExchangeRate(
  Map<String, Object?> arguments,
) async =>
    // This hypothetical API returns a JSON such as:
    // {"base":"USD","date":"2024-04-17","rates":{"SEK": 0.091}}
    {
      'date': arguments['currencyDate'],
      'base': arguments['currencyFrom'],
      'rates': <String, Object?>{arguments['currencyTo'] as String: 0.091}
    };

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

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

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

final exchangeRateTool = FunctionDeclaration(
    'findExchangeRate',
    'Returns the exchange rate between currencies on given date.',
    Schema(SchemaType.object, properties: {
      'currencyDate': Schema(SchemaType.string,
          description: 'A date in YYYY-MM-DD format or '
              'the exact value "latest" if a time period is not specified.'),
      'currencyFrom': Schema(SchemaType.string,
          description: 'The currency code of the currency to convert from, '
              'such as "USD".'),
      'currencyTo': Schema(SchemaType.string,
          description: 'The currency code of the currency to convert to, '
              'such as "USD".')
    }, requiredProperties: [
      'currencyDate',
      'currencyFrom'
    ]));

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

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

final model = GenerativeModel(
  // Use a model that supports function calling, like Gemini 1.0 Pro
  // See "Supported models" in the "Introduction to function calling" page.
  model: 'gemini-1.0-pro',
  apiKey: apiKey,

  // Specify the function declaration.
  tools: [
    Tool(functionDeclarations: [exchangeRateTool])
  ],
);

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

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

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

final chat = model.startChat();
final prompt = 'How much is 50 US dollars worth in Swedish krona?';

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

final functionCalls = response.functionCalls.toList();
// When the model response with a function call, invoke the function.
if (functionCalls.isNotEmpty) {
  final functionCall = functionCalls.first;
  final result = switch (functionCall.name) {
    // Forward arguments to the hypothetical API.
    'findExchangeRate' => await findExchangeRate(functionCall.args),
    // Throw an exception if the model attempted to call a function that was
    // not declared.
    _ => throw UnimplementedError(
        'Function not implemented: ${functionCall.name}')
  };
  // Send the response to the model so that it can use the result to generate
  // text for the user.
  response = await chat
      .sendMessage(Content.functionResponse(functionCall.name, result));
}
// When the model responds with non-null text content, print it.
if (response.text case final text?) {
  print(text);
}