在 Android 應用程式中,為混合式體驗生成結構化輸出內容


Gemini 模型預設會以非結構化文字的形式傳回回覆。 不過,部分用途需要結構化文字 (例如 JSON 或列舉)。舉例來說,您可能會將回覆用於其他需要建立資料結構定義的下游工作。

為確保模型生成的輸出內容一律符合特定結構定義,您可以定義結構定義,做為模型回覆的藍圖。然後直接從模型輸出內容擷取資料,減少後續處理作業。

以下是一些範例用途:

  • 確保模型回覆會產生有效的 JSON,並符合您提供的結構定義。
    舉例來說,模型可以生成食譜的結構化項目,其中一律包含食譜名稱、食材清單和步驟。這樣您就能更輕鬆地在應用程式的 UI 中剖析及顯示這項資訊。

  • 限制模型在分類工作中的回應方式。
    舉例來說,您可以讓模型使用一組特定標籤 (例如一組特定列舉,如 positivenegative) 註解文字,而不是模型產生的標籤 (這類標籤可能具有一定程度的變異性,例如 goodpositivenegativebad)。

本頁說明如何在 Android 應用程式的混合式體驗中,產生結構化輸出內容 (例如 JSON 和列舉)。

跳至 JSON 輸出 跳至列舉輸出

結構化輸出設定

裝置端和雲端代管推論作業都支援產生結構化輸出內容 (例如 JSON 和列舉)。

如要產生結構化輸出內容,請直接將結構定義傳遞至 generateObject()。結構定義需求取決於您設定的推論模式:

  • 適用於裝置端和混合式推論 (ONLY_ON_DEVICEPREFER_ON_DEVICEPREFER_IN_CLOUD)

    • 必須在 Kotlin data class 上使用 @Generable 註解,並搭配 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 符號處理 (KSP) 外掛程式,並將 Firebase AI KSP 依附元件新增至應用程式。

    模組 (應用程式層級) Gradle 檔案 (例如 <project>/<app-module>/build.gradle.kts) 中,新增 KSP 外掛程式、Kotlin 序列化外掛程式和必要依附元件:

    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:17.17.0")
       implementation("com.google.firebase:firebase-ai-ondevice:16.0.0-beta05")
       implementation("com.google.firebase:firebase-appcheck-debug:19.4.1")
    
       // Add the Firebase AI KSP processor for schema generation.
       ksp("com.google.firebase:firebase-ai-ksp-processor:16.0.2")
    
       // (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_DEVICEPREFER_ON_DEVICEPREFER_IN_CLOUD) 的必要項目。
    • 定義 Kotlin 資料類別,在編譯時間自動產生結構定義,並使用 getObject() 將回應直接還原序列化為強型別物件。
  • 手動 JsonSchema 輔助方法

    • 支援雲端推論 (具體來說,是 ONLY_IN_CLOUD)。
    • 在程式碼中手動建構 JsonSchema,而不使用 KSP 處理器,並從 response.response.text 讀取原始 JSON 字串。

範例 1:搭配 KSP 使用 @Generable@Guide 註解

定義以 @Serializable@Generable 註解的 Kotlin data class。在屬性上使用 @Guide 註解,為模型提供說明、值界限或項目限制。

所有推論模式都支援這種做法,且必須用於裝置端和混合式體驗 (具體來說,就是 ONLY_ON_DEVICEPREFER_ON_DEVICEPREFER_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),則可以使用 Firebase AI Logic SDK 提供的輔助方法,手動建構 JsonSchema

試用這個範例前,請先完成本指南的「事前準備」一節,設定專案和應用程式。
在該節中,您也會點選所選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)。

在這些範例的情境中,模型會從預先定義的允許選項清單 (dramacomedydocumentary) 中選取單一類型,藉此分類電影說明。

您可以透過下列任一方式定義回應結構定義:

  • 主要賣點註解 (@Generable)

    • 支援所有推論模式,且為裝置端和混合式推論 (具體來說,是 ONLY_ON_DEVICEPREFER_ON_DEVICEPREFER_IN_CLOUD) 的必要項目。
    • 定義封裝在 Kotlin data class 中的列舉,即可自動產生結構定義,並使用 getObject() 將回應直接還原序列化為強型別物件。
  • 手動 JsonSchema 輔助方法

    • 支援雲端推論 (具體來說,是 ONLY_IN_CLOUD)。
    • 使用 JsonSchema.enumeration() 手動建構列舉 JsonSchema,但不要使用 KSP 處理器,並從 response.response.text 讀取所選字串。

範例 1:搭配 KSP 使用 @Generable 註解

定義代表允許值的 enum class,並將其包裝為 Kotlin data class 內以 @Serializable@Generable 註解的屬性。

所有推論模式都支援這種做法,且必須用於裝置端和混合式體驗 (具體來說,就是 ONLY_ON_DEVICEPREFER_ON_DEVICEPREFER_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),則可以使用 Firebase AI Logic SDK 提供的輔助方法,手動建構列舉 JsonSchema

試用這個範例前,請先完成本指南的「事前準備」一節,設定專案和應用程式。
在該節中,您也會點選所選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 的使用體驗意見回饋