إنشاء نواتج منظَّمة للتجارب المختلطة في تطبيقات Android


تعرض نماذج Gemini الردود كنص غير منظَّم تلقائيًا. مع ذلك، تتطلّب بعض حالات الاستخدام نصًا منظَّمًا (مثل JSON أو التعدادات). على سبيل المثال، قد تستخدم الردّ في مهام أخرى لاحقة تتطلّب مخطط بيانات محدّدًا.

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

في ما يلي بعض الأمثلة على حالات الاستخدام:

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

  • تقييد طريقة ردّ النموذج أثناء مهام التصنيف
    على سبيل المثال، يمكنك أن تطلب من النموذج إضافة تعليقات توضيحية إلى النص باستخدام مجموعة معيّنة من التصنيفات (على سبيل المثال، مجموعة معيّنة من التعدادات مثل positive وnegative)، بدلاً من التصنيفات التي ينتجها النموذج (والتي قد تتضمّن درجة من التباين مثل good أو positive أو negative أو bad).

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

الانتقال إلى ناتج JSON الانتقال إلى ناتج التعداد

إعدادات الناتج المنظَّم

يتوفّر إنشاء ناتج منظَّم (مثل JSON والتعدادات) لكلّ من الاستدلال على الجهاز فقط والاستدلال المستضاف على السحابة الإلكترونية.

لإنشاء ناتج منظَّم، مرِّر المخطط مباشرةً إلى generateObject(). تعتمد متطلبات المخطط على وضع الاستدلال الذي تم ضبطه:

  • للاستدلال على الجهاز فقط والاستدلال المختلط (ONLY_ON_DEVICE وPREFER_ON_DEVICE وPREFER_IN_CLOUD):

    • يتطلّب استخدام التعليق التوضيحي @Generable في data class على Kotlin مع معالج KSP، ولا تتوفّر المخططات اليدوية والتعليقات التوضيحية المباشرة لـ enum class.
    • عند تشغيل الاستدلال على الجهاز، تترجم حزمة SDK تلقائيًا المخطط إلى قيود للنموذج على الجهاز (باستخدام واجهة برمجة التطبيقات ML Kit Prompt API).
    • إذا تم الرجوع إلى الاستدلال على السحابة الإلكترونية في طلب مختلط، تضبط حزمة SDK تلقائيًا responseMimeType على application/json وتمرِّر المخطط إلى نموذج Gemini المستضاف على السحابة الإلكترونية.
  • للاستدلال على السحابة الإلكترونية فقط (ONLY_IN_CLOUD):

    • يتوافق مع كلّ من التعليقات التوضيحية @Generable (ننصح بها) والمخططات اليدوية (التي تم إنشاؤها باستخدام طرق مساعدة JsonSchema).
    • تضبط حزمة SDK تلقائيًا responseMimeType على application/json و تمرِّر المخطط إلى نموذج Gemini المستضاف على السحابة الإلكترونية.

قبل البدء

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

قبل إنشاء ناتج منظَّم، تأكَّد من إكمال الإعدادات التالية:

  1. أكمِل دليل البدء لإنشاء تجارب مختلطة، الذي يغطّي إعداد مشروع Firebase وتنزيل النموذج على الجهاز فقط وضبط App Check.

  2. اضبط المكوّن الإضافي 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.0.0")
       implementation("com.google.firebase:firebase-ai-ondevice:16.0.0-beta06")
       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 الانتقال إلى ناتج التعداد

الردّ بتنسيق 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 الذي اخترته حتى يظهر لك المحتوى الخاص بالموفِّر على هذه الصفحة.

بالنسبة إلى Kotlin، فإنّ الطرق في حزمة SDK هذه هي دوالّ معلّقة ويجب استدعاؤها من نطاق coroutine.
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 يدويًا باستخدام طرق مساعدة توفّرها حزمة Firebase AI Logic SDK.

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

بالنسبة إلى Kotlin، فإنّ الطرق في حزمة SDK هذه هي دوالّ معلّقة ويجب استدعاؤها من نطاق coroutine.
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)

ناتج التعداد

تكيِّف الأمثلة التالية مثال الناتج العام للتعداد لاستيعاب الاستدلال المختلط (على سبيل المثال، PREFER_ON_DEVICE).

في سيناريو هذه الأمثلة، يصنّف النموذج وصفًا لفيلم من خلال اختيار نوع واحد من قائمة محدّدة مسبقًا بالخيارات المسموح بها (drama أو comedy أو documentary).

يمكنك تحديد مخططات الردود باستخدام أحد الأسلوبَين التاليَين:

  • التعليقات التوضيحية لـ KSP (@Generable)

    • تتوفّر لـ جميع أوضاع الاستدلال، ومطلوبة للاستدلال على الجهاز فقط والاستدلال المختلط (على وجه التحديد، ONLY_ON_DEVICE وPREFER_ON_DEVICE وPREFER_IN_CLOUD).
    • حدِّد تعدادًا مضمّنًا في data class على Kotlin لإنشاء المخطط تلقائيًا وإلغاء تسلسل الردود مباشرةً في كائنات ذات أنواع قوية باستخدام getObject().
  • طرق مساعدة JsonSchema اليدوية

    • تتوفّر فقط للاستدلال المستند إلى السحابة الإلكترونية (على وجه التحديد، ONLY_IN_CLOUD).
    • أنشِئ تعدادًا 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 الذي اخترته حتى يظهر لك المحتوى الخاص بالموفِّر على هذه الصفحة.

بالنسبة إلى Kotlin، فإنّ الطرق في حزمة SDK هذه هي دوالّ معلّقة ويجب استدعاؤها من نطاق coroutine.
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)، يمكنك إنشاء تعداد JsonSchema يدويًا باستخدام طرق مساعدة توفّرها حزمة Firebase AI Logic SDK.

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

بالنسبة إلى Kotlin، فإنّ الطرق في حزمة SDK هذه هي دوالّ معلّقة ويجب استدعاؤها من نطاق coroutine.
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