Generowanie danych strukturalnych na potrzeby funkcji hybrydowych w aplikacjach na Androida


Modele Gemini domyślnie zwracają odpowiedzi w postaci nieustrukturyzowanego tekstu. W niektórych przypadkach użycia wymagany jest jednak tekst strukturalny (np. JSON lub wyliczenia). Możesz na przykład używać odpowiedzi w innych zadaniach, które wymagają ustalonego schematu danych.

Aby mieć pewność, że wygenerowane dane wyjściowe modelu zawsze są zgodne z określonym schematem, możesz zdefiniować schemat, który działa jak plan odpowiedzi modelu. Możesz wtedy bezpośrednio wyodrębniać dane z wyników modelu, co wymaga mniej przetwarzania końcowego.

Oto kilka przykładowych przypadków użycia:

  • Sprawdź, czy odpowiedź modelu zawiera prawidłowy kod JSON i jest zgodna z podanym przez Ciebie schematem.
    Na przykład model może generować uporządkowane wpisy dotyczące przepisów, które zawsze zawierają nazwę przepisu, listę składników i kroki. Dzięki temu możesz łatwiej analizować i wyświetlać te informacje w interfejsie aplikacji.

  • Ograniczanie sposobu, w jaki model może odpowiadać podczas zadań klasyfikacji.
    Możesz na przykład poprosić model o oznaczanie tekstu określonym zestawem etykiet (np. określonym zestawem wyliczeń, takim jak positive i negative), a nie etykietami generowanymi przez model (które mogą mieć pewien stopień zmienności, np. good, positive, negative lub bad).

Z tego artykułu dowiesz się, jak generować dane wyjściowe w formacie strukturalnym (np. JSON i wyliczenia) w przypadku hybrydowych interfejsów aplikacji na Androida.

 Przejdź do danych wyjściowych JSON  Przejdź do danych wyjściowych wyliczenia

Konfiguracja uporządkowanych danych wyjściowych

Generowanie danych wyjściowych w formacie strukturalnym (np. JSON i wyliczenia) jest obsługiwane w przypadku wnioskowania na urządzeniu i w chmurze.

Aby wygenerować uporządkowane dane wyjściowe, przekaż schemat bezpośrednio do funkcji generateObject(). Wymagania dotyczące schematu zależą od skonfigurowanego trybu wnioskowania:

  • W przypadku wnioskowania na urządzeniu i hybrydowego (ONLY_ON_DEVICE, PREFER_ON_DEVICE i PREFER_IN_CLOUD):

    • Wymaga użycia adnotacji @Generable w przypadku funkcji Kotlin data class z procesorem KSP; schematy ręczne i bezpośrednie adnotacje enum class nie są obsługiwane.
    • Gdy wnioskowanie jest przeprowadzane na urządzeniu, pakiet SDK automatycznie tłumaczy schemat na ograniczenia dla modelu na urządzeniu (za pomocą interfejsu ML Kit Prompt API).
    • Jeśli żądanie hybrydowe zostanie przekierowane do wnioskowania w chmurze, pakiet SDK automatycznie ustawi wartość responseMimeType na application/json i przekaże schemat do modelu Gemini hostowanego w chmurze.
  • W przypadku wnioskowania tylko w chmurze (ONLY_IN_CLOUD):

    • Obsługuje zarówno adnotacje @Generable (zalecane), jak i schematy ręczne (utworzone za pomocą metod pomocniczych JsonSchema).
    • Pakiet SDK automatycznie ustawia wartość responseMimeType na application/json i przekazuje schemat do hostowanego w chmurze modelu Gemini.

Zanim zaczniesz

Kliknij Gemini API dostawcę, aby wyświetlić na tej stronie treści i kod dostawcy.

Zanim wygenerujesz dane strukturalne, wykonaj te czynności:

  1. Zapoznaj się z przewodnikiem wprowadzającym do tworzenia środowisk hybrydowych, w którym znajdziesz informacje o konfigurowaniu projektu Firebase, pobieraniu modelu na urządzenie i konfigurowaniu App Check.

  2. Skonfiguruj wtyczkę Kotlin Symbol Processing (KSP) i dodaj zależność Firebase AI KSP do aplikacji.

    W pliku Gradle modułu (na poziomie aplikacji) (np. <project>/<app-module>/build.gradle.kts) dodaj wtyczkę KSP, wtyczkę Kotlin Serialization i wymagane zależności:

    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")
    }


 Przejdź do danych wyjściowych JSON  Przejdź do danych wyjściowych wyliczenia

Dane wyjściowe JSON

W przykładach poniżej dostosowano ogólny przykład danych wyjściowych JSON do wnioskowania hybrydowego (np. PREFER_ON_DEVICE).

W scenariuszu tych przykładów model generuje listę profili postaci do opowiadania fantasy ze strukturalnymi atrybutami, takimi jak imię, wiek, gatunek i opcjonalne akcesoria.

Schematy odpowiedzi możesz zdefiniować za pomocą jednej z tych metod:

  • Adnotacje dotyczące kluczowych cech produktu (@Generable i @Guide)

    • Obsługiwane we wszystkich trybach wnioskowania i wymagane w przypadku wnioskowania na urządzeniu i hybrydowego (w szczególności ONLY_ON_DEVICE, PREFER_ON_DEVICE i PREFER_IN_CLOUD).
    • Definiuj klasy danych w języku Kotlin, aby automatycznie generować schematy w czasie kompilacji i deserializować odpowiedzi bezpośrednio do obiektów o ściśle określonym typie za pomocą getObject().
  • Ręczne JsonSchema metody pomocnicze

    • Obsługiwane tylko w przypadku wnioskowania w chmurze (w szczególności ONLY_IN_CLOUD).
    • Ręcznie utwórz JsonSchema w kodzie bez użycia procesora KSP i odczytaj surowy ciąg znaków JSON z response.response.text.

Przykład 1. Używanie adnotacji @Generable i @Guide z KSP

Zdefiniuj funkcję Kotlin data class z adnotacjami @Serializable i @Generable. Używaj adnotacji @Guide we właściwościach, aby podać modelowi opisy, zakresy wartości lub ograniczenia dotyczące elementów.

To podejście jest obsługiwane we wszystkich trybach wnioskowania i jest wymagane w przypadku korzystania z urządzenia i hybrydowych (w szczególności ONLY_ON_DEVICE, PREFER_ON_DEVICE i PREFER_IN_CLOUD).

Zanim wypróbujesz ten przykład, wykonaj czynności opisane w sekcji Zanim zaczniesz tego przewodnika, aby skonfigurować projekt i aplikację.
W tej sekcji klikniesz też przycisk wybranego dostawcyGemini API, aby na tej stronie wyświetlać treści dotyczące tego dostawcy.

W przypadku języka Kotlin metody w tym pakiecie SDK są funkcjami zawieszającymi i muszą być wywoływane z zakresu współprogramu.
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"}")
}

Przykład 2. Używanie ręcznych metod pomocniczych JsonSchema

Jeśli Twoja aplikacja wyłącznie korzysta z wnioskowania w chmurze (w szczególności ONLY_IN_CLOUD), możesz ręcznie utworzyć JsonSchema za pomocą metod pomocniczych udostępnianych przez pakiet SDK Firebase AI Logic.

Zanim wypróbujesz ten przykład, wykonaj czynności opisane w sekcji Zanim zaczniesz tego przewodnika, aby skonfigurować projekt i aplikację.
W tej sekcji klikniesz też przycisk wybranego dostawcyGemini API, aby na tej stronie wyświetlać treści dotyczące tego dostawcy.

W przypadku języka Kotlin metody w tym pakiecie SDK są funkcjami zawieszającymi i muszą być wywoływane z zakresu współprogramu.
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)

Dane wyjściowe typu wyliczeniowego

W przykładach poniżej dostosowano ogólny przykład danych wyjściowych wyliczenia do wnioskowania hybrydowego (np. PREFER_ON_DEVICE).

W scenariuszu tych przykładów model klasyfikuje opis filmu, wybierając jeden gatunek z wstępnie zdefiniowanej listy dozwolonych opcji (drama, comedy lub documentary).

Schematy odpowiedzi możesz zdefiniować za pomocą jednej z tych metod:

  • Adnotacje dotyczące kluczowych cech produktu (@Generable)

    • Obsługiwane we wszystkich trybach wnioskowania i wymagane w przypadku wnioskowania na urządzeniu i hybrydowego (w szczególności ONLY_ON_DEVICE, PREFER_ON_DEVICE i PREFER_IN_CLOUD).
    • Zdefiniuj wyliczenie w klasie Kotlin data class, aby automatycznie wygenerować schemat i deserializować odpowiedzi bezpośrednio do obiektów o ściśle określonym typie za pomocą getObject().
  • Ręczne JsonSchema metody pomocnicze

    • Obsługiwane tylko w przypadku wnioskowania w chmurze (w szczególności ONLY_IN_CLOUD).
    • Ręcznie utwórz wyliczenie JsonSchema za pomocą JsonSchema.enumeration() bez użycia procesora KSP i odczytaj wybrany ciąg znaków z response.response.text.

Przykład 1. Używanie adnotacji @Generable z KSP

Zdefiniuj typ enum class reprezentujący dozwolone wartości i umieść go jako właściwość w klasie Kotlin data class z adnotacjami @Serializable i @Generable.

To podejście jest obsługiwane we wszystkich trybach wnioskowania i jest wymagane w przypadku korzystania z urządzenia i hybrydowych (w szczególności ONLY_ON_DEVICE, PREFER_ON_DEVICE i PREFER_IN_CLOUD).

Zanim wypróbujesz ten przykład, wykonaj czynności opisane w sekcji Zanim zaczniesz tego przewodnika, aby skonfigurować projekt i aplikację.
W tej sekcji klikniesz też przycisk wybranego dostawcyGemini API, aby na tej stronie wyświetlać treści dotyczące tego dostawcy.

W przypadku języka Kotlin metody w tym pakiecie SDK są funkcjami zawieszającymi i muszą być wywoływane z zakresu współprogramu.
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")

Przykład 2. Używanie ręcznych metod pomocniczych JsonSchema

Jeśli Twoja aplikacja wyłącznie korzysta z wnioskowania w chmurze (w szczególności ONLY_IN_CLOUD), możesz ręcznie utworzyć wyliczenie JsonSchema za pomocą metod pomocniczych udostępnianych przez pakiet SDK Firebase AI Logic.

Zanim wypróbujesz ten przykład, wykonaj czynności opisane w sekcji Zanim zaczniesz tego przewodnika, aby skonfigurować projekt i aplikację.
W tej sekcji klikniesz też przycisk wybranego dostawcyGemini API, aby na tej stronie wyświetlać treści dotyczące tego dostawcy.

W przypadku języka Kotlin metody w tym pakiecie SDK są funkcjami zawieszającymi i muszą być wywoływane z zakresu współprogramu.
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)


Prześlij opinię o korzystaniu z usługi Firebase AI Logic