Generowanie danych strukturalnych na potrzeby funkcji hybrydowych w aplikacjach na Androida


Modele Gemini domyślnie zwracają odpowiedzi w postaci nieustrukturyzowanego tekstu. Niektóre przypadki użycia wymagają jednak tekstu strukturalnego (np. JSON lub wyliczenia). Możesz na przykład używać odpowiedzi do innych zadań, 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. Dzięki temu możesz 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 schematem.
    Model może na przykład 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 dodanie do tekstu adnotacji z określonym zestawem etykiet (np. określonym zestawem wyliczeń, takim jak positivenegative), a nie etykietami generowanymi przez model (które mogą mieć pewien stopień zmienności, np. good, positive, negative lub bad).

Na tej stronie opisujemy, jak generować uporządkowane dane wyjściowe (np. JSON i wyliczenia) w przypadku hybrydowych elementów w aplikacjach 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ć dane strukturalne, 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_DEVICEPREFER_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 (tworzone 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 do aplikacji zależność Firebase AI KSP.

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


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

Dane wyjściowe JSON

W tych przykładach 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ć na jeden z tych sposobów:

  • Adnotacje dotyczące kluczowych cech produktu (@Generable@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_DEVICEPREFER_IN_CLOUD).
    • Definiuj klasy danych Kotlin, aby automatycznie generować schematy w czasie kompilacji i deserializować odpowiedzi bezpośrednio do obiektów o silnym typowaniu 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 JSON z response.response.text.

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

Zdefiniuj funkcję Kotlin data class z adnotacjami @Serializable@Generable. Używaj adnotacji @Guide w przypadku właściwości, 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 funkcji na urządzeniu i hybrydowych (w szczególności ONLY_ON_DEVICE, PREFER_ON_DEVICEPREFER_IN_CLOUD).

Zanim wypróbujesz ten przykład, zapoznaj się z sekcją Zanim zaczniesz w tym przewodniku, 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 w zakresie 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 z 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, zapoznaj się z sekcją Zanim zaczniesz w tym przewodniku, 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 w zakresie 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ć na jeden z tych sposobów:

  • 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_DEVICEPREFER_IN_CLOUD).
    • Zdefiniuj wyliczenie opakowane w data class w Kotlinie, aby automatycznie wygenerować schemat i deserializować odpowiedzi bezpośrednio do obiektów o silnym 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żywania 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@Generable.

To podejście jest obsługiwane we wszystkich trybach wnioskowania i jest wymagane w przypadku funkcji na urządzeniu i hybrydowych (w szczególności ONLY_ON_DEVICE, PREFER_ON_DEVICEPREFER_IN_CLOUD).

Zanim wypróbujesz ten przykład, zapoznaj się z sekcją Zanim zaczniesz w tym przewodniku, aby skonfigurować projekt i aplikację.
W tej sekcji klikniesz też przycisk wybranego dostawcyGemini API, aby na tej stronie wyświetlały się 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 w zakresie 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, zapoznaj się z sekcją Zanim zaczniesz w tym przewodniku, 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 w zakresie 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