מדריך: קריאה לפונקציה באמצעות Gemini API


בזכות הקריאה של הפונקציות קל יותר לקבל פלט של נתונים מובְנים ממודלים גנרטיביים. לאחר מכן תוכלו להשתמש בפלטים האלה כדי לקרוא לממשקי API אחרים ולהחזיר למודל את נתוני התגובה הרלוונטיים. במילים אחרות, קריאה של פונקציות עוזרת לחבר מודלים גנרטיביים למערכות חיצוניות כדי שהתוכן שנוצר יכלול את המידע העדכני והמדויק ביותר.

אפשר לספק מודלים של Gemini עם תיאורים של פונקציות. אלו פונקציות שכותבים בשפה של האפליקציה (כלומר, לא Google Cloud Functions). יכול להיות שהמודל יבקש מכם לקרוא לפונקציה ולשלוח בחזרה את התוצאה כדי לעזור למודל לטפל בשאילתה.

למידע נוסף, מומלץ לקרוא את המאמר מבוא לקריאה לפונקציות.

הגדרת הפרויקט

לפני שמפעילים את Gemini API, צריך להגדיר את פרויקט Android, שכולל הגדרה של מפתח ה-API, הוספת יחסי התלות של ה-SDK לפרויקט ב-Android והפעלת המודל.

הגדרה של בקשה להפעלת פונקציה

במדריך הזה נציג למודל אינטראקציה עם ממשק API של המרת מטבעות היפותטית שתומך בפרמטרים הבאים:

פרמטר סוג נדרש תיאור
currencyFrom string כן המטבע להמרה ממנו
currencyTo string כן המטבע להמרה

דוגמה לבקשת API

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

דוגמה לתגובת API

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

שלב 1: יוצרים את הפונקציה ששולחת את בקשת ה-API

אם עדיין לא עשיתם זאת, קודם יוצרים את הפונקציה שמבצעת בקשת API.

למטרות הדגמה במדריך הזה, במקום לשלוח בקשת API בפועל, המערכת תחזיר ערכים כתובים בתוך הקוד באותו פורמט שיוחזר API בפועל.

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 a Gemini 1.5 model
  modelName = "gemini-1.5-flash",
  // 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)
}