כברירת מחדל, המודלים של Gemini מחזירים תשובות כטקסט לא מובנה. עם זאת, במקרים מסוימים נדרש טקסט מובנה (כמו JSON או טיפוסי enum). לדוגמה, יכול להיות שאתם משתמשים בתשובה למשימות אחרות בהמשך התהליך שדורשות סכימת נתונים מוגדרת.
כדי לוודא שהפלט שהמודל יוצר תמיד תואם לסכימה ספציפית, אתם יכולים להגדיר סכימה שפועלת כמו תוכנית לתשובות של המודל. לאחר מכן, אתם יכולים לחלץ נתונים ישירות מהפלט של המודל עם פחות עיבוד לאחר מכן.
הנה מספר תרחישים לדוגמה:
מוודאים שהתשובה של המודל יוצרת קובץ JSON תקין ותואמת לסכימה שסיפקתם.
לדוגמה, המודל יכול ליצור רשומות מובְנות של מתכונים שתמיד כוללות את שם המתכון, רשימת המרכיבים והשלבים. כך תוכלו לנתח את המידע הזה ולהציג אותו בקלות רבה יותר בממשק המשתמש של האפליקציה.להגביל את האופן שבו המודל יכול להגיב במהלך משימות סיווג.
לדוגמה, אתם יכולים לבקש מהמודל להוסיף הערות לטקסט עם קבוצה ספציפית של תוויות (למשל, קבוצה ספציפית של ערכי enum כמוpositiveו-negative), במקום תוויות שהמודל מייצר (שיכולות להיות במידה מסוימת של שונות כמוgood,positive,negativeאוbad).
בדף הזה מוסבר איך ליצור פלט מובנה (כמו JSON וטיפוסי enum) בחוויות ההיברידיות באפליקציות ל-Android.
מעבר לפלט מסוג JSON מעבר לפלט מסוג enum
הגדרת פלט מובנה
אפשר ליצור פלט מובנה (כמו JSON וסוגים ממוספרים) גם בהסקה במכשיר וגם בהסקה בענן.
כדי ליצור פלט מובנה, מעבירים את הסכימה ישירות אל generateObject().
דרישות הסכימה תלויות במצב ההיסק שהגדרתם:
להסקת מסקנות במכשיר ומשולבת (
ONLY_ON_DEVICE,PREFER_ON_DEVICEו-PREFER_IN_CLOUD):- צריך להשתמש בהערה
@Generableב-data classשל Kotlin עם מעבד KSP. אין תמיכה בסכימות ידניות ובהערותenum classישירות. - כשההסקה פועלת במכשיר, ה-SDK מתרגם באופן אוטומטי את הסכימה לאילוצים של המודל במכשיר (באמצעות Prompt API של ML Kit).
- אם בקשה היברידית חוזרת להסקת מסקנות בענן, ה-SDK מגדיר באופן אוטומטי את
responseMimeTypeל-application/jsonומעביר את הסכימה למודל Gemini שמתארח בענן.
- צריך להשתמש בהערה
להסקת מסקנות בענן בלבד (
ONLY_IN_CLOUD):- תמיכה גם בהערות
@Generable(מומלץ) וגם בסכימות ידניות (שנוצרו באמצעות שיטות עזר שלJsonSchema). - ערך הפרמטר
responseMimeTypeמוגדר אוטומטית על ידי ה-SDK כ-application/json, והסכימה מועברת למודל Gemini שמתארח בענן.
- תמיכה גם בהערות
לפני שמתחילים
|
כדי לראות תוכן וקוד שספציפיים לספק, לוחצים על הספק Gemini API בדף הזה. |
לפני שיוצרים פלט מובנה, צריך לבצע את ההגדרות הבאות:
משלימים את המדריך לתחילת העבודה על פיתוח חוויות היברידיות, שכולל הגדרה של פרויקט Firebase, הורדה של המודל במכשיר והגדרה של App Check.
מגדירים את הפלאגין Kotlin Symbol Processing (KSP) ומוסיפים את יחסי התלות של Firebase AI KSP לאפליקציה.
בקובץ Gradle של המודול (ברמת האפליקציה) (למשל
<project>/<app-module>/build.gradle.kts), מוסיפים את הפלאגין של KSP, את הפלאגין של Kotlin Serialization ואת יחסי התלות הנדרשים:plugins { // ... other plugins id("com.google.gms.google-services") id("com.google.devtools.ksp") version "LATEST_VERSION" id("org.jetbrains.kotlin.plugin.serialization") version "LATEST_VERSION" } dependencies { // ... other androidx dependencies // Add the dependencies for the Firebase AI Logic and App Check libraries. implementation("com.google.firebase:firebase-ai:18.1.0") implementation("com.google.firebase:firebase-ai-ondevice:16.0.0-beta07") implementation("com.google.firebase:firebase-appcheck-debug:20.0.0") // Add the Firebase AI KSP processor for schema generation. ksp("com.google.firebase:firebase-ai-ksp-processor:17.0.0") // (Optional) Add kotlinx.serialization JSON library for object decoding. implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:LATEST_VERSION") }
מעבר לפלט מסוג JSON מעבר לפלט מסוג enum
פלט מסוג JSON
בדוגמאות הבאות, הדוגמה הכללית לפלט JSON מותאמת להסקה היברידית (לדוגמה, PREFER_ON_DEVICE).
בתרחיש של הדוגמאות האלה, המודל יוצר רשימה של פרופילים של דמויות לסיפור פנטזיה, עם מאפיינים מובְנים כמו שם, גיל, מין ואביזרים אופציונליים.
אפשר להגדיר את סכמות התשובות באחת מהדרכים הבאות:
הערות KSP (
@Generableו-@Guide)- נתמך בכל מצבי ההיסק, ונדרש להיסק במכשיר ולהיסק היברידי (ספציפית,
ONLY_ON_DEVICE,PREFER_ON_DEVICEו-PREFER_IN_CLOUD). - מגדירים מחלקות נתונים של Kotlin כדי ליצור סכימות באופן אוטומטי בזמן הקימפול, ולהמיר תשובות ישירות לאובייקטים עם סוגים מוגדרים באמצעות
getObject().
- נתמך בכל מצבי ההיסק, ונדרש להיסק במכשיר ולהיסק היברידי (ספציפית,
שיטות עזר ידניות של
JsonSchema- נתמך רק להסקה מבוססת-ענן (באופן ספציפי,
ONLY_IN_CLOUD). - יוצרים באופן ידני
JsonSchemaבקוד בלי להשתמש במעבד KSP, וקוראים את מחרוזת ה-JSON הגולמית מ-response.response.text.
- נתמך רק להסקה מבוססת-ענן (באופן ספציפי,
דוגמה 1: שימוש בהערות @Generable ו-@Guide עם KSP
מגדירים data class של Kotlin עם הערות @Serializable ו-@Generable.
אפשר להשתמש בהערות @Guide במאפיינים כדי לספק למודל תיאורים, גבולות ערכים או אילוצים של פריטים.
הגישה הזו נתמכת בכל מצבי ההיסק, והיא נדרשת לחוויות במכשיר וחוויות היברידיות (ספציפית, ONLY_ON_DEVICE, PREFER_ON_DEVICE ו-PREFER_IN_CLOUD).
|
לפני שמנסים את הדוגמה הזו, צריך להשלים את השלבים בקטע לפני שמתחילים במדריך הזה כדי להגדיר את הפרויקט והאפליקציה. בקטע הזה צריך גם ללחוץ על כפתור של ספק Gemini API שבחרתם כדי לראות בדף הזה תוכן שספציפי לספק. |
import com.google.firebase.Firebase
import com.google.firebase.ai.type.GenerativeBackend
import com.google.firebase.ai.InferenceMode
import com.google.firebase.ai.OnDeviceConfig
import com.google.firebase.ai.annotations.Generable
import com.google.firebase.ai.annotations.Guide
import com.google.firebase.ai.ai
import kotlinx.serialization.Serializable
// Define data classes representing the schema, annotated with @Serializable and @Generable.
// You can provide descriptions on @Generable and @Guide to guide the model's output.
@Serializable
@Generable(description = "A character profile for a fantasy story")
data class Character(
val name: String,
val age: Int,
val species: String,
// Use @Guide to add property descriptions, value bounds (minimum/maximum), or formats.
// Properties with default values or nullable types are treated as optional in the schema.
@Guide(description = "An accessory the character wears or carries")
val accessory: String? = null
) {
// An empty companion object is required for KSP to generate the firebaseAISchema() extension.
companion object
}
@Serializable
@Generable(description = "A list of character profiles")
data class CharacterList(
// Use minItems or maxItems to specify collection size bounds for the model.
@Guide(description = "List of characters", minItems = 1)
val characters: List<Character>
) {
// An empty companion object is required for KSP to generate the firebaseAISchema() extension.
companion object
}
// Initialize the Gemini Developer API backend service.
// Create a GenerativeModel instance configured for hybrid inference (like PREFER_ON_DEVICE).
val model = Firebase.ai(backend = GenerativeBackend.googleAI())
.generativeModel(
modelName = "CLOUD_MODEL_NAME",
onDeviceConfig = OnDeviceConfig(mode = InferenceMode.INFERENCE_MODE)
)
// Obtain the schema generated by KSP via the firebaseAISchema() extension.
val schema = CharacterList.firebaseAISchema()
val prompt = "Create profiles for some characters for a fantasy story."
// Generate the structured object (the SDK applies the schema to on-device or cloud models).
val response = model.generateObject(schema, prompt)
// Access the strongly-typed deserialized object directly via getObject().
val characterList: CharacterList? = response.getObject()
characterList?.characters?.forEach { character ->
println("Name: ${character.name}, Species: ${character.species}, Age: ${character.age}")
println("Accessory: ${character.accessory ?: "None"}")
}
דוגמה 2: שימוש בשיטות עזר ידניות של JsonSchema
אם האפליקציה משתמשת רק בהסקה מבוססת-ענן (באופן ספציפי, ONLY_IN_CLOUD), אתם יכולים ליצור באופן ידני JsonSchema באמצעות שיטות עזר שסופקו על ידי ה-SDK של Firebase AI Logic.
|
לפני שמנסים את הדוגמה הזו, צריך להשלים את השלבים בקטע לפני שמתחילים במדריך הזה כדי להגדיר את הפרויקט והאפליקציה. בקטע הזה צריך גם ללחוץ על כפתור של ספק Gemini API שבחרתם כדי לראות בדף הזה תוכן שספציפי לספק. |
import com.google.firebase.Firebase
import com.google.firebase.ai.type.GenerativeBackend
import com.google.firebase.ai.InferenceMode
import com.google.firebase.ai.OnDeviceConfig
import com.google.firebase.ai.ai
import com.google.firebase.ai.type.JsonSchema
// Define the schema manually using JsonSchema helper methods.
// Properties are required by default unless specified in optionalProperties.
val jsonSchema = JsonSchema.obj(
properties = mapOf(
"characters" to JsonSchema.array(
items = JsonSchema.obj(
properties = mapOf(
"name" to JsonSchema.string(),
"accessory" to JsonSchema.string(),
"age" to JsonSchema.integer(),
"species" to JsonSchema.string()
),
optionalProperties = listOf("accessory")
)
)
)
)
// Initialize the Gemini Developer API backend service.
// Manual schemas are only supported for cloud-based inference (specifically, ONLY_IN_CLOUD).
val model = Firebase.ai(backend = GenerativeBackend.googleAI())
.generativeModel(
modelName = "CLOUD_MODEL_NAME",
onDeviceConfig = OnDeviceConfig(mode = InferenceMode.ONLY_IN_CLOUD)
)
// Call generateObject() with the manual schema and prompt.
val response = model.generateObject(
jsonSchema,
"Create profiles for some characters for a fantasy story."
)
// Access the generated JSON string conforming to the schema from response.response.text.
println(response.response.text)
פלט של טיפוס בן מנייה (enum)
בדוגמאות הבאות, הדוגמה הכללית לפלט של enum מותאמת להסקת מסקנות היברידית (לדוגמה, PREFER_ON_DEVICE).
בתרחיש של הדוגמאות האלה, המודל מסווג תיאור של סרט על ידי בחירת ז'אנר אחד מתוך רשימה מוגדרת מראש של אפשרויות מותרות (drama, comedy או documentary).
אפשר להגדיר את סכמות התשובות באחת מהדרכים הבאות:
-
- נתמך בכל מצבי ההיסק, ונדרש להיסק במכשיר ולהיסק היברידי (ספציפית,
ONLY_ON_DEVICE,PREFER_ON_DEVICEו-PREFER_IN_CLOUD). - מגדירים enum שכלול ב-
data classשל Kotlin כדי ליצור באופן אוטומטי את הסכימה ולבטל את הסריאליזציה של התשובות ישירות לאובייקטים עם סוגים מוגדרים באמצעותgetObject().
- נתמך בכל מצבי ההיסק, ונדרש להיסק במכשיר ולהיסק היברידי (ספציפית,
שיטות עזר ידניות של
JsonSchema- נתמך רק להסקה מבוססת-ענן (באופן ספציפי,
ONLY_IN_CLOUD). - יוצרים באופן ידני enum
JsonSchemaבאמצעותJsonSchema.enumeration()בלי להשתמש במעבד KSP, וקוראים את המחרוזת שנבחרה מ-response.response.text.
- נתמך רק להסקה מבוססת-ענן (באופן ספציפי,
דוגמה 1: שימוש בהערות @Generable עם KSP
מגדירים enum class שמייצג את הערכים המותרים, ועוטפים אותו כמאפיין בתוך data class של Kotlin עם הערות @Serializable ו-@Generable.
הגישה הזו נתמכת בכל מצבי ההיסק, והיא נדרשת לחוויות במכשיר וחוויות היברידיות (ספציפית, ONLY_ON_DEVICE, PREFER_ON_DEVICE ו-PREFER_IN_CLOUD).
|
לפני שמנסים את הדוגמה הזו, צריך להשלים את השלבים בקטע לפני שמתחילים במדריך הזה כדי להגדיר את הפרויקט והאפליקציה. בקטע הזה צריך גם ללחוץ על כפתור של ספק Gemini API שבחרתם כדי לראות בדף הזה תוכן שספציפי לספק. |
import com.google.firebase.Firebase
import com.google.firebase.ai.type.GenerativeBackend
import com.google.firebase.ai.InferenceMode
import com.google.firebase.ai.OnDeviceConfig
import com.google.firebase.ai.annotations.Generable
import com.google.firebase.ai.annotations.Guide
import com.google.firebase.ai.ai
import kotlinx.serialization.Serializable
// Define an enum class representing the allowed options.
@Serializable
enum class FilmGenre {
DRAMA,
COMEDY,
DOCUMENTARY
}
// Wrap the enum in a data class annotated with @Serializable and @Generable.
// On-device inference requires an @Generable data class.
// Direct enum annotations are not supported on-device.
@Serializable
@Generable(description = "The classification result for the film")
data class FilmClassification(
@Guide(description = "The genre of the film")
val genre: FilmGenre
) {
// An empty companion object is required for KSP to generate the firebaseAISchema() extension.
companion object
}
// Initialize the Gemini Developer API backend service.
// Create a GenerativeModel instance configured for hybrid inference (like PREFER_ON_DEVICE).
val model = Firebase.ai(backend = GenerativeBackend.googleAI())
.generativeModel(
modelName = "CLOUD_MODEL_NAME",
onDeviceConfig = OnDeviceConfig(mode = InferenceMode.INFERENCE_MODE)
)
// Obtain the schema generated by KSP via the firebaseAISchema() extension.
val schema = FilmClassification.firebaseAISchema()
val prompt = """
The film aims to educate and inform viewers about real-life subjects, events, or people.
It offers a factual record of a particular topic by combining interviews, historical footage,
and narration. The primary purpose of a film is to present information and provide insights
into various aspects of reality.
"""
// Generate the structured object (the SDK applies the schema to on-device or cloud models).
val response = model.generateObject(schema, prompt)
// Access the strongly-typed deserialized object and enum value directly via getObject().
val classification: FilmClassification? = response.getObject()
val genre: FilmGenre? = classification?.genre
println("Selected genre: $genre")
דוגמה 2: שימוש בשיטות עזר ידניות של JsonSchema
אם האפליקציה משתמשת רק בהסקה מבוססת-ענן (ספציפית, ONLY_IN_CLOUD), אתם יכולים ליצור באופן ידני enum JsonSchema באמצעות שיטות עזר שסופקו על ידי ה-SDK של Firebase AI Logic.
|
לפני שמנסים את הדוגמה הזו, צריך להשלים את השלבים בקטע לפני שמתחילים במדריך הזה כדי להגדיר את הפרויקט והאפליקציה. בקטע הזה צריך גם ללחוץ על כפתור של ספק Gemini API שבחרתם כדי לראות בדף הזה תוכן שספציפי לספק. |
import com.google.firebase.Firebase
import com.google.firebase.ai.type.GenerativeBackend
import com.google.firebase.ai.InferenceMode
import com.google.firebase.ai.OnDeviceConfig
import com.google.firebase.ai.ai
import com.google.firebase.ai.type.JsonSchema
// Define an enum schema with allowed string values and a description.
val enumSchema = JsonSchema.enumeration(
values = listOf("drama", "comedy", "documentary"),
description = "The genre of the film"
)
// Initialize the Gemini Developer API backend service.
// Manual schemas are only supported for cloud-based inference (specifically, ONLY_IN_CLOUD).
val model = Firebase.ai(backend = GenerativeBackend.googleAI())
.generativeModel(
modelName = "CLOUD_MODEL_NAME",
onDeviceConfig = OnDeviceConfig(mode = InferenceMode.ONLY_IN_CLOUD)
)
val prompt = """
The film aims to educate and inform viewers about real-life subjects, events, or people.
It offers a factual record of a particular topic by combining interviews, historical footage,
and narration. The primary purpose of a film is to present information and provide insights
into various aspects of reality.
"""
// Call generateObject() with the enum schema and prompt.
val response = model.generateObject(enumSchema, prompt)
// Access the selected enum value string from response.response.text.
println(response.response.text)
שליחת משוב על חוויית השימוש ב-Firebase AI Logic