מודלים גנרטיביים יעילים בפתרון סוגים רבים של בעיות. עם זאת, הן מוגבלות על ידי מגבלות כמו:
- הם קופאים אחרי האימון, וכתוצאה מכך הידע לא מעודכן.
- הם לא יכולים לשלוח שאילתות לנתונים חיצוניים או לשנות אותם.
קריאה לפונקציות יכולה לעזור לכם להתגבר על חלק מהמגבלות האלה. לפעמים קוראים לקריאה לפונקציה שימוש בכלי כי היא מאפשרת למודל להשתמש בכלים חיצוניים כמו ממשקי API ופונקציות כדי ליצור את התגובה הסופית שלו.
במדריך הזה נסביר איך אפשר להטמיע הגדרה של קריאה לפונקציה בדומה לתרחיש שמתואר בקטע הראשי הבא בדף. באופן כללי, אלה השלבים להגדרת קריאה לפונקציות באפליקציה:
שלב 1: כותבים פונקציה שיכולה לספק למודל את המידע שנחוץ לו כדי ליצור את התגובה הסופית (לדוגמה, הפונקציה יכולה לבצע קריאה ל-API חיצוני).
שלב 2: יוצרים הצהרת פונקציה שמתארת את הפונקציה ואת הפרמטרים שלה.
שלב 3: מספקים את הצהרת הפונקציה במהלך האינטוליזציה של המודל, כדי שהמודל ידע איך להשתמש בפונקציה, במקרה הצורך.
שלב 4: מגדירים את האפליקציה כך שהמודל יוכל לשלוח את המידע הנדרש כדי שהאפליקציה תוכל להפעיל את הפונקציה.
שלב 5: מעבירים את התשובה של הפונקציה חזרה למודל כדי שהמודל יוכל ליצור את התשובה הסופית שלו.
סקירה כללית של דוגמה לקריאה לפונקציה
כששולחים בקשה למודל, אפשר גם לספק לו קבוצה של "כלים" (כמו פונקציות) שבהם הוא יכול להשתמש כדי ליצור את התשובה הסופית. כדי להשתמש בפונקציות האלה ולקרוא להן ('קריאה לפונקציה'), המודל והאפליקציה צריכים להעביר מידע זה לזה, ולכן הדרך המומלצת להשתמש בקריאה לפונקציה היא דרך ממשק הצ'אט עם מספר סבבים.
נניח שיש לכם אפליקציה שבה משתמש יכול להזין הנחיה כמו:
What was the weather in Boston on October 17, 2024?
.
יכול להיות שמידע מזג האוויר הזה לא זמין במודלים של Gemini. עם זאת, נניח שאתם יודעים על ממשק API חיצוני של שירות מזג אוויר שיכול לספק אותו. אפשר להשתמש בקריאה לפונקציה כדי לתת למודל Gemini נתיב ל-API הזה ולנתוני מזג האוויר שלו.
קודם כל, כותבים באפליקציה פונקציה fetchWeather
שמקיימת אינטראקציה עם ה-API החיצוני ההיפותטי הזה, שיש לו את הקלט והפלט הבאים:
פרמטר | סוג | חובה | תיאור |
---|---|---|---|
קלט | |||
location |
אובייקט | כן | שם העיר והמדינה שבה רוצים לקבל את תחזית מזג האוויר. התכונה נתמכת רק בערים בארה"ב. תמיד חייב להיות אובייקט בתצוגת עץ של city ו-state .
|
date |
String | כן | התאריך שבו רוצים לאחזר את מזג האוויר (תמיד צריך להשתמש בפורמט YYYY-MM-DD ).
|
פלט | |||
temperature |
מספר שלם | כן | טמפרטורה (בפרנהייט) |
chancePrecipitation |
String | כן | הסיכוי למשקעים (מיוצג באחוזים) |
cloudConditions |
String | כן | תנאים ב-Cloud (אחד מהערכים clear , partlyCloudy , mostlyCloudy , cloudy )
|
כשמפעילים את המודל, צריך להודיע לו על קיומה של הפונקציה fetchWeather
ואיך אפשר להשתמש בה כדי לעבד בקשות נכנסות, במקרה הצורך.
הפעולה הזו נקראת 'הצהרת פונקציה'. המודל לא קורא לפונקציה ישירות. במקום זאת, כשהמודל מעבד את הבקשה הנכנסת, הוא מחליט אם הפונקציה fetchWeather
יכולה לעזור לו להשיב לבקשה. אם המודל יחליט שהפונקציה יכולה להיות אכן שימושית, הוא ייצור נתונים מובְנים שיעזרו לאפליקציה להפעיל את הפונקציה.
בודקים שוב את הבקשה הנכנסת:
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
. כשהתנאים המטאורולוגיים מגיעים לאפליקציה מה-API, היא מעבירה את המידע למודל. נתוני מזג האוויר האלה מאפשרים למודל להשלים את העיבוד הסופי וליצור את התגובה לבקשה הראשונית של 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 API כדי להציג בדף הזה תוכן וקוד ספציפיים לספק. |
אם עדיין לא עשיתם זאת, כדאי לעיין במדריך למתחילים, שבו מוסבר איך מגדירים את פרויקט Firebase, מחברים את האפליקציה ל-Firebase, מוסיפים את ה-SDK, מאתחלים את שירות הקצה העורפי של ספק Gemini API שבחרתם ויוצרים מכונה של GenerativeModel
.
כדי לבדוק את ההנחיות ולבצע בהן שינויים, ואפילו לקבל קטע קוד שנוצר, מומלץ להשתמש ב-Google AI Studio.
שלב 1: כותבים את הפונקציה
נניח שיש לכם אפליקציה שבה משתמש יכול להזין הנחיה כמו:
What was the weather in Boston on October 17, 2024?
. יכול להיות שמידע מזג האוויר הזה לא זמין במודלים של Gemini, אבל נניח שאתם יודעים על ממשק API חיצוני של שירות מזג אוויר שיכול לספק אותו. התרחיש שמתואר במדריך הזה מבוסס על ה-API החיצוני ההיפותטי הזה.
כותבים באפליקציה את הפונקציה שתהיה בקשר עם ה-API החיצוני ההיפותטי ותספק למודל את המידע הדרוש כדי ליצור את הבקשה הסופית. בדוגמה הזו של מזג האוויר, זו תהיה פונקציית fetchWeather
שתפעיל את הקריאה לממשק ה-API החיצוני ההיפותטי הזה.
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
.
כברירת מחדל, ב-SDKs של Firebase AI Logic, כל השדות נחשבים חובה, אלא אם מציינים אותם כאופציונליים במערך
optionalProperties
. בשדות האופציונליים האלה, המודל יכול לאכלס את השדות או לדלג עליהם. חשוב לזכור שההתנהגות הזו שונה מברירת המחדל של שני הספקים של Gemini API אם משתמשים ב-SDK של השרת או ב-API שלהם ישירות.
לשיטות מומלצות שקשורות להצהרות על פונקציות, כולל טיפים לשמות ולתיאורים, תוכלו לעיין במאמר שיטות מומלצות במסמכי התיעוד של 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: FunctionDeclarationsTool = {
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: קוראים לפונקציה כדי להפעיל את ה-API החיצוני
אם המודל יחליט שהפונקציה fetchWeather
יכולה לעזור לו ליצור תשובה סופית, האפליקציה צריכה לבצע את הקריאה בפועל לפונקציה הזו באמצעות נתוני הקלט המובְנים שסופקו על ידי המודל.
מאחר שצריך להעביר מידע הלוך ושוב בין המודל לאפליקציה, הדרך המומלצת להשתמש בקריאה לפונקציה היא דרך ממשק הצ'אט עם מספר סבבים.
בקטע הקוד הבא מוצג איך האפליקציה מקבלת הודעה שהמודל רוצה להשתמש בפונקציה fetchWeather
. בנוסף, אפשר לראות שהמודל סיפק את ערכי הפרמטרים הנדרשים של הקלט לקריאה לפונקציה (ול-API החיצוני שמבוסס עליה).
בדוגמה הזו, הבקשה הנכנסת הכילה את ההנחיה
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 |
המודל חייב להשתמש בקריאות פונקציה ('forced function calling'). כדי להגביל את המודל לקבוצת משנה של פונקציות, מציינים את שמות הפונקציות המותרות ב-allowedFunctionNames .
|
NONE |
אסור להשתמש בקריאות פונקציה במודל. ההתנהגות הזו זהה לבקשת מודל ללא הצהרות על פונקציות משויכות. |
מה עוד אפשר לעשות?
לנסות יכולות אחרות
- ליצור שיחות עם זיכרון (צ'אט).
- ליצור טקסט מהנחיות בטקסט בלבד.
- יצירת טקסט באמצעות הצגת הנחיות לגבי סוגי קבצים שונים, כמו תמונות, קבצי PDF, סרטונים ואודיו.
איך שולטים ביצירת תוכן
- הסבר על תכנון הנחיות, כולל שיטות מומלצות, אסטרטגיות והנחיות לדוגמה.
- להגדיר את הפרמטרים של המודל, כמו טמפרטורה ואסימונים מקסימליים של פלט (עבור Gemini) או יחס גובה-רוחב ויצירת אנשים (עבור Imagen).
- שימוש בהגדרות הבטיחות כדי לשנות את הסבירות לקבלת תשובות שעשויות להיחשב כמזיקות.
מידע נוסף על המודלים הנתמכים
כאן תוכלו לקרוא מידע נוסף על המודלים הזמינים לתרחישי שימוש שונים, על המכסות ועל התמחור שלהם.שליחת משוב על חוויית השימוש ב-Firebase AI Logic