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

تُعدّ النماذج التوليدية فعّالة في حلّ العديد من أنواع المشاكل. ومع ذلك، فإنه تفرض عليهم قيودًا، مثل:

  • ويتم تجميدها بعد التدريب، ما يؤدي إلى تقادم المعلومات.
  • ولا يمكنهم الاستعلام عن البيانات الخارجية أو تعديلها.

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


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

  • الخطوة 1: اكتب دالة يمكنها تزويد النموذج بالمعلومات التي يحتاجها لإنشاء استجابته النهائية (على سبيل المثال، يمكن للدالة استدعاء واجهة برمجة تطبيقات خارجية).

  • الخطوة 2: أنشئ بيان دالة يصف الدالة ومَعلماتها.

  • الخطوة 3: قدِّم بيان الدالة أثناء بدء تشغيل النموذج كي يعرف النموذج كيفية استخدام الدالة، إذا لزم الأمر.

  • الخطوة 4: إعداد تطبيقك لكي يتمكّن النموذج من إرسال المعلومات المطلوبة لتطبيقك من أجل استدعاء الدالة

  • الخطوة 5: نقْل ردّ الدالة إلى النموذج لكي تتمكّن من توليد ردّه النهائي

الانتقال إلى تنفيذ الرمز

نظرة عامة على مثال على استدعاء دالة

عند إرسال طلب إلى النموذج، يمكنك أيضًا تزويد النموذج بمجموعة من "الأدوات" (مثل الدوالّ) التي يمكنه استخدامها لإنشاء الردّ النهائي. لاستخدام هذه الدوال واستدعائها ("استدعاء الدالة")، يجب أن يتبادل النموذج وتطبيقك المعلومات معًا، لذا فإنّ الطريقة المُقترَحة لاستخدام استدعاء الدالة هي من خلال واجهة المحادثة المتعدّدة المراحل.

تخيل أنّ لديك تطبيقًا يمكن للمستخدم إدخال طلب فيه مثل: What was the weather in Boston on October 17, 2024?.

قد لا تتوفر معلومات الطقس هذه في نماذج Gemini، ومع ذلك، تخيّل أنّ لديك واجهة برمجة تطبيقات لخدمة طقس خارجية يمكنها تقديم هذه المعلومات. يمكنك استخدام طلب الدالة لمنح نموذج Gemini مسارًا إلى واجهة برمجة التطبيقات تلك ومعلومات الطقس.

أولاً، عليك كتابة دالة fetchWeather في تطبيقك تتفاعل مع واجهة برمجة التطبيقات الخارجية الافتراضية هذه التي تتضمّن الإدخالات والمخرجات التالية:

المعلَمة النوع مطلوبة الوصف
الإدخال
location كائن نعم اسم المدينة والولاية المطلوب الحصول على معلومات الطقس فيها
تتوفّر هذه الميزة للمدن في الولايات المتحدة فقط. يجب أن يكون دائمًا عنصرًا مُدمَجًا من city وstate.
date سلسلة نعم تاريخ جلب حالة الطقس (يجب أن يكون دائمًا بتنسيق YYYY-MM-DD).
الناتج
temperature العدد الصحيح نعم درجة الحرارة (بالفهرنهايت)
chancePrecipitation سلسلة نعم احتمالية هطول الأمطار (يتم التعبير عنها بالنسبة المئوية)
cloudConditions سلسلة نعم حالة الغيوم (أحد الخيارات clear أو partlyCloudy أو mostlyCloudy أو cloudy)

عند إعداد النموذج، تُعلمه بوجود هذه fetchWeather الدالة وكيفية استخدامها لمعالجة الطلبات الواردة، إذا لزم الأمر. ويُعرف هذا باسم "تعريف الدالة". لا يستدعي النموذج الدالة بشكل مباشر. بدلاً من ذلك، عندما يعالج النموذج الطلب الوافد، فإنه يقرّر ما إذا كانت الدالة fetchWeather يمكنها مساعدته في الاستجابة للطلب. إذا قرر النموذج أنّ الدالة يمكن أن تكون مفيدة، ينشئ النموذج data منظَّمة ستساعد تطبيقك في استدعاء الدالة.

راجِع الطلب الوافد مرة أخرى: What was the weather in Boston on October 17, 2024?. من المرجّح أن يقرّر النموذج أنّ الدالة fetchWeather يمكن أن تساعده في إنشاء ردّ. سيفحص النموذج مَعلمات الإدخال المطلوبة لدالة fetchWeather، ثم سيُنشئ بيانات إدخال منظَّمة للدالة تبدو على النحو التالي تقريبًا:

{
  functionName: fetchWeather,
  location: {
    city: Boston,
    state: Massachusetts  // the model can infer the state from the prompt
  },
  date: 2024-10-17
}

ويُرسِل النموذج بيانات الإدخال المنظَّمة هذه إلى تطبيقك كي يتمكّن من استدعاء الدالة fetchWeather. عندما يتلقّى تطبيقك معلومات أحوال الطقس مجددًا من واجهة برمجة التطبيقات، يُرسِل المعلومات إلى النموذج. تسمح معلومات الطقس هذه للنموذج بإكمال المعالجة النهائية وإنشاء ردّ على الطلب الأولي من What was the weather in Boston on October 17, 2024?.

قد يقدّم النموذج ردًا نهائيًا بلغة طبيعية، مثل: On October 17, 2024, in Boston, it was 38 degrees Fahrenheit with partly cloudy skies.

رسم بياني يوضّح كيف يرتبط استدعاء الدالة بالنموذج الذي يتفاعل مع دالة في تطبيقك 

يمكنك معرفة مزيد من المعلومات عن استدعاء الدوالّ في مستندات Gemini Developer API.

تنفيذ استدعاء الدالة

توضّح لك الخطوات التالية في هذا الدليل كيفية تنفيذ عملية إعداد دالّة استدعاء مشابهة لسير العمل الموضّح في نظرة عامة على مثال على استدعاء دالة (اطّلِع على القسم العلوي من هذه الصفحة).

قبل البدء

انقر على مزوّد Gemini API لعرض المحتوى الخاص بالمزوّد والرمز البرمجي في هذه الصفحة.

أكمِل قراءة دليل البدء، الذي يوضّح كيفية إعداد مشروعك على Firebase وربط تطبيقك بـ Firebase وإضافة حزمة تطوير البرامج (SDK) وبدء خدمة الخلفية لمزوّد Gemini API الذي اخترته، وإنشاء مثيل GenerativeModel، إذا لم يسبق لك إجراء ذلك.

لاختبار طلباتك وتكرارها وحتى الحصول على مقتطف رمز تم إنشاؤه، ننصحك باستخدام Google AI Studio.

الخطوة 1: كتابة الدالة

تخيل أنّ لديك تطبيقًا يمكن للمستخدم إدخال طلب فيه مثل: What was the weather in Boston on October 17, 2024?. قد لا تتوفر معلومات الطقس هذه في Gemini النماذج، ولكن لنفترض أنّك تعرف واجهة برمجة تطبيقات خارجية لخدمة الطقس يمكنها تقديم هذه المعلومات. يعتمد السيناريو في هذا الدليل على واجهة برمجة التطبيقات الخارجية الافتراضية هذه.

اكتب الدالة في تطبيقك التي ستتفاعل مع واجهة برمجة التطبيقات الخارجية الافتراضية ، وقدِّم للنموذج المعلومات التي يحتاجها لإنشاء طلبه النهائي. في مثال الطقس هذا، ستكون دالة fetchWeather هي التي تُجري طلب البيانات من واجهة برمجة التطبيقات الخارجية الافتراضية هذه.

Swift

// This function calls a hypothetical external API that returns
// a collection of weather information for a given location on a given date.
func fetchWeather(city: String, state: String, date: String) -> JSONObject {

  // TODO(developer): Write a standard function that would call an external weather API.

  // For demo purposes, this hypothetical response is hardcoded here in the expected format.
  return [
    "temperature": .number(38),
    "chancePrecipitation": .string("56%"),
    "cloudConditions": .string("partlyCloudy"),
  ]
}

Kotlin

// This function calls a hypothetical external API that returns
// a collection of weather information for a given location on a given date.
// `location` is an object of the form { city: string, state: string }
data class Location(val city: String, val state: String)

suspend fun fetchWeather(location: Location, date: String): JsonObject {

    // TODO(developer): Write a standard function that would call to an external weather API.

    // For demo purposes, this hypothetical response is hardcoded here in the expected format.
    return JsonObject(mapOf(
        "temperature" to JsonPrimitive(38),
        "chancePrecipitation" to JsonPrimitive("56%"),
        "cloudConditions" to JsonPrimitive("partlyCloudy")
    ))
}

Java

// This function calls a hypothetical external API that returns
// a collection of weather information for a given location on a given date.
// `location` is an object of the form { city: string, state: string }
public JsonObject fetchWeather(Location location, String date) {

  // TODO(developer): Write a standard function that would call to an external weather API.

  // For demo purposes, this hypothetical response is hardcoded here in the expected format.
  return new JsonObject(Map.of(
        "temperature", JsonPrimitive(38),
        "chancePrecipitation", JsonPrimitive("56%"),
        "cloudConditions", JsonPrimitive("partlyCloudy")));
}

Web

// This function calls a hypothetical external API that returns
// a collection of weather information for a given location on a given date.
// `location` is an object of the form { city: string, state: string }
async function fetchWeather({ location, date }) {

  // TODO(developer): Write a standard function that would call to an external weather API.

  // For demo purposes, this hypothetical response is hardcoded here in the expected format.
  return {
    temperature: 38,
    chancePrecipitation: "56%",
    cloudConditions: "partlyCloudy",
  };
}

Dart

// This function calls a hypothetical external API that returns
// a collection of weather information for a given location on a given date.
// `location` is an object of the form { city: string, state: string }
Future<Map<String, Object?>> fetchWeather(
  Location location, String date
) async {

  // TODO(developer): Write a standard function that would call to an external weather API.

  // For demo purposes, this hypothetical response is hardcoded here in the expected format.
  final apiResponse = {
    'temperature': 38,
    'chancePrecipitation': '56%',
    'cloudConditions': 'partlyCloudy',
  };
  return apiResponse;
}

Unity

// This function calls a hypothetical external API that returns
// a collection of weather information for a given location on a given date.
System.Collections.Generic.Dictionary<string, object> FetchWeather(
    string city, string state, string date) {

  // TODO(developer): Write a standard function that would call an external weather API.

  // For demo purposes, this hypothetical response is hardcoded here in the expected format.
  return new System.Collections.Generic.Dictionary<string, object>() {
    {"temperature", 38},
    {"chancePrecipitation", "56%"},
    {"cloudConditions", "partlyCloudy"},
  };
}

الخطوة 2: إنشاء بيان دالة

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

في بيانك، أدرِج أكبر قدر ممكن من التفاصيل في أوصاف الدالة ومعلّماتها.

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

يُرجى مراعاة ما يلي بشأن المخطّط الذي تقدّمه:

  • يجب تقديم تعريفات الدوالّ بتنسيق مخطّط متوافق مع مخطّط OpenAPI. يوفّر Vertex AI دعمًا محدودًا لنموذج OpenAPI.

    • السمات التالية متوافقة: type وnullable وrequired format وdescription وproperties وitems وenum.

    • لا يمكن استخدام السمات التالية: default وoptional maximum وoneOf.

  • بالنسبة إلى Firebase AI Logic حِزم تطوير البرامج (SDK)، يتم اعتبار جميع الحقول تلقائيًا مطلوبة ما لم تحدّدها كحقول اختيارية في صفيف optionalProperties. بالنسبة إلى هذه الحقول الاختيارية، يمكن للنموذج تعبئة الحقول أو تخطّيها. يُرجى العِلم أنّ هذا السلوك يختلف عن السلوك التلقائي لموفّري Gemini API هذين إذا كنت تستخدم حِزم SDK للخادم أو واجهات برمجة التطبيقات الخاصة بهما مباشرةً.

للاطّلاع على أفضل الممارسات المتعلّقة بتعريفات الدوالّ، بما في ذلك نصائح بشأن الأسماء والأوصاف، اطّلِع على أفضل الممارسات في مستندات Gemini Developer API

في ما يلي كيفية كتابة بيان دالة:

Swift

let fetchWeatherTool = FunctionDeclaration(
  name: "fetchWeather",
  description: "Get the weather conditions for a specific city on a specific date.",
  parameters: [
    "location": .object(
      properties: [
        "city": .string(description: "The city of the location."),
        "state": .string(description: "The US state of the location."),
      ],
      description: """
      The name of the city and its state for which to get the weather. Only cities in the
      USA are supported.
      """
    ),
    "date": .string(
      description: """
      The date for which to get the weather. Date must be in the format: YYYY-MM-DD.
      """
    ),
  ]
)

Kotlin

val fetchWeatherTool = FunctionDeclaration(
    "fetchWeather",
    "Get the weather conditions for a specific city on a specific date.",
    mapOf(
        "location" to Schema.obj(
            mapOf(
                "city" to Schema.string("The city of the location."),
                "state" to Schema.string("The US state of the location."),
            ),
            description = "The name of the city and its state for which " +
                "to get the weather. Only cities in the " +
                "USA are supported."
        ),
        "date" to Schema.string("The date for which to get the weather." +
                                " Date must be in the format: YYYY-MM-DD."
        ),
    ),
)

Java

FunctionDeclaration fetchWeatherTool = new FunctionDeclaration(
        "fetchWeather",
        "Get the weather conditions for a specific city on a specific date.",
        Map.of("location",
                Schema.obj(Map.of(
                        "city", Schema.str("The city of the location."),
                        "state", Schema.str("The US state of the location."))),
                "date",
                Schema.str("The date for which to get the weather. " +
                              "Date must be in the format: YYYY-MM-DD.")),
        Collections.emptyList());

Web

const fetchWeatherTool = {
  functionDeclarations: [
   {
      name: "fetchWeather",
      description:
        "Get the weather conditions for a specific city on a specific date",
      parameters: Schema.object({
        properties: {
          location: Schema.object({
            description:
              "The name of the city and its state for which to get " +
              "the weather. Only cities in the USA are supported.",
            properties: {
              city: Schema.string(
                description: "The city of the location."
              ),
              state: Schema.string(
                description: "The US state of the location."
              ),
            },
          }),
          date: Schema.string({
            description:
              "The date for which to get the weather. Date must be in the" +
              " format: YYYY-MM-DD.",
          }),
        },
      }),
    },
  ],
};

Dart

final fetchWeatherTool = FunctionDeclaration(
    'fetchWeather',
    'Get the weather conditions for a specific city on a specific date.',
    parameters: {
      'location': Schema.object(
        description:
          'The name of the city and its state for which to get'
          'the weather. Only cities in the USA are supported.',
        properties: {
          'city': Schema.string(
             description: 'The city of the location.'
           ),
          'state': Schema.string(
             description: 'The US state of the location.'
          ),
        },
      ),
      'date': Schema.string(
        description:
          'The date for which to get the weather. Date must be in the format: YYYY-MM-DD.'
      ),
    },
  );

Unity

var fetchWeatherTool = new Tool(new FunctionDeclaration(
  name: "fetchWeather",
  description: "Get the weather conditions for a specific city on a specific date.",
  parameters: new System.Collections.Generic.Dictionary<string, Schema>() {
    { "location", Schema.Object(
      properties: new System.Collections.Generic.Dictionary<string, Schema>() {
        { "city", Schema.String(description: "The city of the location.") },
        { "state", Schema.String(description: "The US state of the location.")}
      },
      description: "The name of the city and its state for which to get the weather. Only cities in the USA are supported."
    ) },
    { "date", Schema.String(
      description: "The date for which to get the weather. Date must be in the format: YYYY-MM-DD."
    )}
  }
));

الخطوة 3: تقديم بيان الدالة أثناء بدء تشغيل النموذج

الحد الأقصى لعدد بيانات الدوالّ التي يمكنك تقديمها مع الطلب هو 128. اطّلِع على السلوكيات والخيارات الإضافية في هذه الصفحة لمعرفة كيفية اختيار النموذج من بين الدوالّ، بالإضافة إلى كيفية التحكّم في هذا الاختيار (باستخدام toolConfig لضبط وضع استدعاء الدالة).

Swift


import FirebaseAI

// Initialize the Gemini Developer API backend service
// Create a `GenerativeModel` instance with a model that supports your use case
let model = FirebaseAI.firebaseAI(backend: .googleAI()).generativeModel(
  modelName: "gemini-2.0-flash",
  // Provide the function declaration to the model.
  tools: [.functionDeclarations([fetchWeatherTool])]
)

Kotlin


// Initialize the Gemini Developer API backend service
// Create a `GenerativeModel` instance with a model that supports your use case
val model = Firebase.ai(backend = GenerativeBackend.googleAI()).generativeModel(
    modelName = "gemini-2.0-flash",
    // Provide the function declaration to the model.
    tools = listOf(Tool.functionDeclarations(listOf(fetchWeatherTool)))
)

Java


// Initialize the Gemini Developer API backend service
// Create a `GenerativeModel` instance with a model that supports your use case
GenerativeModelFutures model = GenerativeModelFutures.from(
        FirebaseAI.getInstance(GenerativeBackend.googleAI())
                .generativeModel("gemini-2.0-flash",
                        null,
                        null,
                        // Provide the function declaration to the model.
                        List.of(Tool.functionDeclarations(List.of(fetchWeatherTool)))));

Web


import { initializeApp } from "firebase/app";
import { getAI, getGenerativeModel, GoogleAIBackend } from "firebase/ai";

// TODO(developer) Replace the following with your app's Firebase configuration
// See: https://firebase.google.com/docs/web/learn-more#config-object
const firebaseConfig = {
  // ...
};

// Initialize FirebaseApp
const firebaseApp = initializeApp(firebaseConfig);

// Initialize the Gemini Developer API backend service
const firebaseAI = getAI(firebaseApp, { backend: new GoogleAIBackend() });

// Create a `GenerativeModel` instance with a model that supports your use case
const model = getGenerativeModel(firebaseAI, {
  model: "gemini-2.0-flash",
  // Provide the function declaration to the model.
  tools: fetchWeatherTool
});

Dart


import 'package:firebase_ai/firebase_ai.dart';
import 'package:firebase_core/firebase_core.dart';
import 'firebase_options.dart';

// Initialize FirebaseApp
await Firebase.initializeApp(
  options: DefaultFirebaseOptions.currentPlatform,
);

// Initialize the Gemini Developer API backend service
// Create a `GenerativeModel` instance with a model that supports your use case
_functionCallModel = FirebaseAI.googleAI().generativeModel(
       model: 'gemini-2.0-flash',
       // Provide the function declaration to the model.
       tools: [
         Tool.functionDeclarations([fetchWeatherTool]),
       ],
     );

Unity


using Firebase;
using Firebase.AI;

// Initialize the Gemini Developer API backend service
// Create a `GenerativeModel` instance with a model that supports your use case
var model = FirebaseAI.DefaultInstance.GetGenerativeModel(
  modelName: "gemini-2.0-flash",
  // Provide the function declaration to the model.
  tools: new Tool[] { fetchWeatherTool }
);

تعرَّف على كيفية اختيار نموذج مناسب لحالة الاستخدام والتطبيق.

الخطوة 4: استدعاء الدالة لاستدعاء واجهة برمجة التطبيقات الخارجية

إذا قرّر النموذج أنّ دالة fetchWeather يمكنها مساعدته في توليد ردّ نهائي، على تطبيقك إجراء الطلب الفعلي لهذه الدالة باستخدام بيانات الإدخال المنظَّمة التي يقدّمها النموذج.

بما أنّه يجب نقل المعلومات ذهابًا وإيابًا بين النموذج والتطبيق، فإنّ الطريقة المقترَحة لاستخدام استدعاء الدالة هي من خلال واجهة المحادثة المتعدّدة الأدوار.

يوضّح مقتطف الرمز التالي كيفية إبلاغ تطبيقك بأنّ النموذج يريد استخدام الدالة fetchWeather. ويوضّح أيضًا أنّ النموذج قد قدّم قيم مَعلمات الإدخال اللازمة لاستدعاء الدالة (وواجهة برمجة التطبيقات الخارجية العميقة التي تستند إليها).

في هذا المثال، كان الطلب الوافد يتضمّن الطلب التالي: What was the weather in Boston on October 17, 2024?. من هذا الطلب، استنتج النموذج مَعلمات الإدخال المطلوبة من خلال دالة fetchWeather (أي city وstate وdate).

Swift

let chat = model.startChat()
let prompt = "What was the weather in Boston on October 17, 2024?"

// Send the user's question (the prompt) to the model using multi-turn chat.
let response = try await chat.sendMessage(prompt)

var functionResponses = [FunctionResponsePart]()

// When the model responds with one or more function calls, invoke the function(s).
for functionCall in response.functionCalls {
  if functionCall.name == "fetchWeather" {
    // TODO(developer): Handle invalid arguments.
    guard case let .object(location) = functionCall.args["location"] else { fatalError() }
    guard case let .string(city) = location["city"] else { fatalError() }
    guard case let .string(state) = location["state"] else { fatalError() }
    guard case let .string(date) = functionCall.args["date"] else { fatalError() }

    functionResponses.append(FunctionResponsePart(
      name: functionCall.name,
      // Forward the structured input data prepared by the model
      // to the hypothetical external API.
      response: fetchWeather(city: city, state: state, date: date)
    ))
  }
  // TODO(developer): Handle other potential function calls, if any.
}

Kotlin

val prompt = "What was the weather in Boston on October 17, 2024?"
val chat = model.startChat()
// Send the user's question (the prompt) to the model using multi-turn chat.
val result = chat.sendMessage(prompt)

val functionCalls = result.functionCalls
// When the model responds with one or more function calls, invoke the function(s).
val fetchWeatherCall = functionCalls.find { it.name == "fetchWeather" }

// Forward the structured input data prepared by the model
// to the hypothetical external API.
val functionResponse = fetchWeatherCall?.let {
    // Alternatively, if your `Location` class is marked as @Serializable, you can use
    // val location = Json.decodeFromJsonElement<Location>(it.args["location"]!!)
    val location = Location(
        it.args["location"]!!.jsonObject["city"]!!.jsonPrimitive.content,
        it.args["location"]!!.jsonObject["state"]!!.jsonPrimitive.content
    )
    val date = it.args["date"]!!.jsonPrimitive.content
    fetchWeather(location, date)
}

Java

String prompt = "What was the weather in Boston on October 17, 2024?";
ChatFutures chatFutures = model.startChat();
// Send the user's question (the prompt) to the model using multi-turn chat.
ListenableFuture<GenerateContentResponse> response =
        chatFutures.sendMessage(new Content("user", List.of(new TextPart(prompt))));

ListenableFuture<JsonObject> handleFunctionCallFuture = Futures.transform(response, result -> {
    for (FunctionCallPart functionCall : result.getFunctionCalls()) {
        if (functionCall.getName().equals("fetchWeather")) {
            Map<String, JsonElement> args = functionCall.getArgs();
            JsonObject locationJsonObject =
                    JsonElementKt.getJsonObject(args.get("location"));
            String city =
                    JsonElementKt.getContentOrNull(
                            JsonElementKt.getJsonPrimitive(
                                    locationJsonObject.get("city")));
            String state =
                    JsonElementKt.getContentOrNull(
                            JsonElementKt.getJsonPrimitive(
                                    locationJsonObject.get("state")));
            Location location = new Location(city, state);

            String date = JsonElementKt.getContentOrNull(
                    JsonElementKt.getJsonPrimitive(
                            args.get("date")));
            return fetchWeather(location, date);
        }
    }
    return null;
}, Executors.newSingleThreadExecutor());

Web

const chat = model.startChat();
const prompt = "What was the weather in Boston on October 17, 2024?";

// Send the user's question (the prompt) to the model using multi-turn chat.
let result = await chat.sendMessage(prompt);
const functionCalls = result.response.functionCalls();
let functionCall;
let functionResult;
// When the model responds with one or more function calls, invoke the function(s).
if (functionCalls.length > 0) {
  for (const call of functionCalls) {
    if (call.name === "fetchWeather") {
      // Forward the structured input data prepared by the model
      // to the hypothetical external API.
      functionResult = await fetchWeather(call.args);
      functionCall = call;
    }
  }
}

Dart

final chat = _functionCallModel.startChat();
const prompt = 'What was the weather in Boston on October 17, 2024?';

// Send the user's question (the prompt) to the model using multi-turn chat.
var response = await chat.sendMessage(Content.text(prompt));

final functionCalls = response.functionCalls.toList();
// When the model responds with one or more function calls, invoke the function(s).
if (functionCalls.isNotEmpty) {
  final functionCall = functionCalls.first;
  if (functionCall.name == 'fetchWeather') {
    // Forward the structured input data prepared by the model
    // to the hypothetical external API.
    Map<String, dynamic> location =
        functionCall.args['location']! as Map<String, dynamic>;
    var date = functionCall.args['date']! as String;
    var city = location['city']! as String;
    var state = location['state']! as String;
    final functionResult = await fetchWeather(Location(city, state), date);
    ...
} else {
  throw UnimplementedError(
    'Function not declared to the model: ${functionCall.name}',
  );
}

Unity

var chat = model.StartChat();
var prompt = "What was the weather in Boston on October 17, 2024?";

// Send the user's question (the prompt) to the model using multi-turn chat.
var response = await chat.SendMessageAsync(prompt);

var functionResponses = new List<ModelContent>();

foreach (var functionCall in response.FunctionCalls) {
  if (functionCall.Name == "fetchWeather") {
    // TODO(developer): Handle invalid arguments.
    var city = functionCall.Args["city"] as string;
    var state = functionCall.Args["state"] as string;
    var date = functionCall.Args["date"] as string;

    functionResponses.Add(ModelContent.FunctionResponse(
      name: functionCall.Name,
      // Forward the structured input data prepared by the model
      // to the hypothetical external API.
      response: FetchWeather(city: city, state: state, date: date)
    ));
  }
  // TODO(developer): Handle other potential function calls, if any.
}

الخطوة 5: تقديم ناتج الدالة إلى النموذج لإنشاء الردّ النهائي

بعد أن تعرض الدالة fetchWeather معلومات الطقس، يجب أن يعيد تطبيقك عرضها على النموذج.

بعد ذلك، يُجري النموذج المعالجة النهائية وينشئ ردًا نهائيًا باللغة الطبيعية مثل: On October 17, 2024 in Boston, it was 38 degrees Fahrenheit with partly cloudy skies.

Swift

// Send the response(s) from the function back to the model
// so that the model can use it to generate its final response.
let finalResponse = try await chat.sendMessage(
  [ModelContent(role: "function", parts: functionResponses)]
)

// Log the text response.
print(finalResponse.text ?? "No text in response.")

Kotlin

// Send the response(s) from the function back to the model
// so that the model can use it to generate its final response.
val finalResponse = chat.sendMessage(content("function") {
    part(FunctionResponsePart("fetchWeather", functionResponse!!))
})

// Log the text response.
println(finalResponse.text ?: "No text in response")

Java

ListenableFuture<GenerateContentResponse> modelResponseFuture = Futures.transformAsync(
  handleFunctionCallFuture,
  // Send the response(s) from the function back to the model
  // so that the model can use it to generate its final response.
  functionCallResult -> chatFutures.sendMessage(new Content("function",
  List.of(new FunctionResponsePart(
          "fetchWeather", functionCallResult)))),
  Executors.newSingleThreadExecutor());

Futures.addCallback(modelResponseFuture, new FutureCallback<GenerateContentResponse>() {
@Override
public void onSuccess(GenerateContentResponse result) {
  if (result.getText() != null) {
      // Log the text response.
      System.out.println(result.getText());
  }
}

@Override
public void onFailure(Throwable t) {
  // handle error
}
}, Executors.newSingleThreadExecutor());

Web

// Send the response from the function back to the model
// so that the model can use it to generate its final response.
result = await chat.sendMessage([
  {
    functionResponse: {
      name: functionCall.name, // "fetchWeather"
      response: functionResult,
    },
  },
]);
console.log(result.response.text());

Dart

// Send the response from the function back to the model
// so that the model can use it to generate its final response.
response = await chat
     .sendMessage(Content.functionResponse(functionCall.name, functionResult));

Unity

// Send the response(s) from the function back to the model
// so that the model can use it to generate its final response.
var finalResponse = await chat.SendMessageAsync(functionResponses);

// Log the text response.
UnityEngine.Debug.Log(finalResponse.Text ?? "No text in response.");

السلوكيات والخيارات الإضافية

في ما يلي بعض السلوكيات الإضافية لاستدعاء الدوالّ التي عليك مراعاتها في الرمز البرمجي والخيارات التي يمكنك التحكّم فيها.

قد يطلب النموذج استدعاء دالة مرة أخرى أو دالة أخرى.

إذا لم يكن الردّ من طلب استدعاء دالة واحد كافيًا للنموذج لإنشاء ردّه النهائي، قد يطلب النموذج طلب استدعاء دالة إضافية، أو طلب استدعاء دالة مختلفة تمامًا. لا يمكن حدوث ذلك إلا إذا قدّمت أكثر من دالة واحدة للنموذج في قائمة بيان الدالة.

يجب أن يتيح تطبيقك للنموذج طلب مزيد من طلبات معالجة الدوالّ.

قد يطلب النموذج استدعاء عدة دوال في الوقت نفسه.

يمكنك تقديم ما يصل إلى 128 دالة في قائمة تعريف الدوال لملف النموذج. بناءً على ذلك، قد يقرر النموذج أنّه يجب استخدام دوال متعددة لمساعدة النموذج في إنشاء استجابته النهائية. وقد يقرّر استدعاء بعض هذه الدوال في الوقت نفسه، ويُعرف ذلك باسم استدعاء الدوالّ بشكل موازٍ.

يجب أن يتيح تطبيقك تنفيذ وظائف متعددة في الوقت نفسه، كما يجب أن يقدّم جميع الردود من الدوال إلى النموذج.

يمكنك التحكّم في كيفية طلب النموذج لتشغيل الدوالّ وإمكانية طلب ذلك.

يمكنك فرض بعض القيود على كيفية استخدام النموذج لبيانات وظائف معيّنة أو عدم استخدامها. ويُعرف ذلك باسم ضبط وضع استدعاء الدالة. وإليك بعض الأمثلة:

  • بدلاً من السماح للنموذج باختيار ما بين ردّ فوري باللغة الطبيعية واستدعاء دالة، يمكنك إجباره على استخدام استدعاءات الدوالّ دائمًا. ويُعرف هذا الإجراء باسم استدعاء الدالة القسري.

  • في حال تقديم بيانات متعددة للدوالّ، يمكنك حصر النموذج باستخدام مجموعة فرعية فقط من الدوالّ المقدّمة.

يمكنك تنفيذ هذه القيود (أو الأوضاع) عن طريق إضافة إعدادات أداة (toolConfig) مع الطلب وإعلانات الدوالّ. في إعدادات الأدوات، يمكنك تحديد أحد الأوضاع التالية. الوضع الأكثر فائدة هو ANY.

الوضع الوصف
AUTO سلوك النموذج التلقائي يقرّر النموذج ما إذا كان سيستخدم دالة أو ردًا باللغة الطبيعية.
ANY يجب أن يستخدم النموذج طلبات دالة ("طلبات دالة إجبارية"). لتقييد النموذج بمجموعة فرعية من الدوال، حدِّد أسماء الدوال المسموح بها في allowedFunctionNames.
NONE يجب ألّا يستخدم النموذج طلبات دالة. ويعادل هذا السلوك طلب نموذج بدون أيّ تعريفات دالة مرتبطة.



ما هي الإجراءات الأخرى التي يمكنك اتّخاذها؟

تجربة إمكانات أخرى

التعرّف على كيفية التحكّم في إنشاء المحتوى

يمكنك أيضًا تجربة طلبات البحث وإعدادات النماذج، وحتى الحصول على مقتطف رمز تم إنشاؤه باستخدام Google AI Studio.

مزيد من المعلومات عن الطُرز المتوافقة

اطّلِع على مزيد من المعلومات عن النماذج المتاحة لحالات الاستخدام المختلفة واطلاعك على الحصص و الأسعار.


تقديم ملاحظات حول تجربتك مع Firebase AI Logic