Możesz skonfigurować Gemini tak, aby zamiast nieuporządkowanego tekstu generował on dane uporządkowane, co umożliwia precyzyjne wyodrębnianie i standardyzację informacji na potrzeby dalszego przetwarzania. Możesz na przykład użyć uporządkowanego wyjścia, aby wyodrębnić informacje z CV i ujednolicić je w celu utworzenia uporządkowanej bazy danych.
Gemini może generować dane wyjściowe w postaci JSON lub wartości typu wyliczeniowego.
Generowanie pliku JSON
Istnieją 2 sposoby generowania pliku JSON za pomocą interfejsu Gemini API:
- Konfigurowanie schematu w modelu
- Podanie schematu w promptach tekstowych
Konfigurowanie schematu w modelu to zalecany sposób generowania danych w formacie JSON, ponieważ ogranicza model do generowania danych w tym formacie.
Konfigurowanie schematu (zalecane)
Aby ograniczyć model do generowania danych w formacie JSON, skonfiguruj responseSchema
. Model będzie wtedy odpowiadać na dowolny prompt, zwracając dane wyjściowe w formacie JSON.
Python
from google import genai
from pydantic import BaseModel
class Recipe(BaseModel):
recipe_name: str
ingredients: list[str]
client = genai.Client(api_key="GOOGLE_API_KEY")
response = client.models.generate_content(
model="gemini-2.0-flash",
contents="List a few popular cookie recipes, and include the amounts of ingredients.",
config={
"response_mime_type": "application/json",
"response_schema": list[Recipe],
},
)
# Use the response as a JSON string.
print(response.text)
# Use instantiated objects.
my_recipes: list[Recipe] = response.parsed
JavaScript
import { GoogleGenAI, Type } from "@google/genai";
const ai = new GoogleGenAI({ "GOOGLE_API_KEY" });
async function main() {
const response = await ai.models.generateContent({
model: "gemini-2.0-flash",
contents:
"List a few popular cookie recipes, and include the amounts of ingredients.",
config: {
responseMimeType: "application/json",
responseSchema: {
type: Type.ARRAY,
items: {
type: Type.OBJECT,
properties: {
recipeName: {
type: Type.STRING,
},
ingredients: {
type: Type.ARRAY,
items: {
type: Type.STRING,
},
},
},
propertyOrdering: ["recipeName", "ingredients"],
},
},
},
});
console.log(response.text);
}
main();
Przeczytaj
package main
import (
"context"
"fmt"
"log"
"google.golang.org/genai"
)
func main() {
ctx := context.Background()
client, err := genai.NewClient(ctx, &genai.ClientConfig{
APIKey: "GOOGLE_API_KEY",
Backend: genai.BackendGeminiAPI,
})
if err != nil {
log.Fatal(err)
}
config := &genai.GenerateContentConfig{
ResponseMIMEType: "application/json",
ResponseSchema: &genai.Schema{
Type: genai.TypeArray,
Items: &genai.Schema{
Type: genai.TypeObject,
Properties: map[string]*genai.Schema{
"recipeName": {Type: genai.TypeString},
"ingredients": {
Type: genai.TypeArray,
Items: &genai.Schema{Type: genai.TypeString},
},
},
PropertyOrdering: []string{"recipeName", "ingredients"},
},
},
}
result, err := client.Models.GenerateContent(
ctx,
"gemini-2.0-flash",
genai.Text("List a few popular cookie recipes, and include the amounts of ingredients."),
config,
)
if err != nil {
log.Fatal(err)
}
fmt.Println(result.Text())
}
REST
curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=$GOOGLE_API_KEY" \
-H 'Content-Type: application/json' \
-d '{
"contents": [{
"parts":[
{ "text": "List a few popular cookie recipes, and include the amounts of ingredients." }
]
}],
"generationConfig": {
"responseMimeType": "application/json",
"responseSchema": {
"type": "ARRAY",
"items": {
"type": "OBJECT",
"properties": {
"recipeName": { "type": "STRING" },
"ingredients": {
"type": "ARRAY",
"items": { "type": "STRING" }
}
},
"propertyOrdering": ["recipeName", "ingredients"]
}
}
}
}' 2> /dev/null | head
Dane wyjściowe mogą wyglądać tak:
[
{
"recipeName": "Chocolate Chip Cookies",
"ingredients": [
"1 cup (2 sticks) unsalted butter, softened",
"3/4 cup granulated sugar",
"3/4 cup packed brown sugar",
"1 teaspoon vanilla extract",
"2 large eggs",
"2 1/4 cups all-purpose flour",
"1 teaspoon baking soda",
"1 teaspoon salt",
"2 cups chocolate chips"
]
},
...
]
Podanie schematu w promptach tekstowych
Zamiast konfigurować schemat, możesz podać go w języku naturalnym lub w pseudokodzie w promptach tekstowych. Nie zalecamy tej metody, ponieważ może ona generować dane wyjściowe o gorszej jakości, a model nie jest ograniczony do przestrzegania schematu.
Oto ogólny przykład schematu podanego w promptach tekstowych:
List a few popular cookie recipes, and include the amounts of ingredients.
Produce JSON matching this specification:
Recipe = { "recipeName": string, "ingredients": array<string> }
Return: array<Recipe>
Ponieważ model otrzymuje schemat z tekstu w promptach, możesz mieć pewną elastyczność w sposobie jego reprezentowania. Gdy jednak podasz schemat w postaci inline, jak w tym przykładzie, model nie będzie musiał zwracać danych w formacie JSON. Aby uzyskać bardziej deterministyczne odpowiedzi o wyższej jakości, skonfiguruj schemat na modelu i nie powielaj go w promptach tekstowych.
Generowanie wartości typu wyliczeniowego
W niektórych przypadkach możesz chcieć, aby model wybrał jedną opcję z listy opcji. Aby zaimplementować to zachowanie, możesz przekazać w schemacie typ enum. Opcji wyliczeniowej możesz używać wszędzie tam, gdzie w elementach string
możesz użyć wartości string
, ponieważ jest to tablica ciągów znaków.responseSchema
Podobnie jak schemat JSON, enumeracja umożliwia ograniczenie danych wyjściowych modelu do wymagań aplikacji.
Załóżmy na przykład, że tworzysz aplikację do klasyfikowania instrumentów muzycznych do jednej z 5 kategorii: "Percussion"
, "String"
, "Woodwind"
, "Brass"
lub „"Keyboard"
”. Aby ułatwić to zadanie, możesz utworzyć typ wyliczeniowy.
W tym przykładzie jako parametr responseSchema
przekazujesz typ enum, ograniczając model do wyboru najbardziej odpowiedniej opcji.
Python
from google import genai
import enum
class Instrument(enum.Enum):
PERCUSSION = "Percussion"
STRING = "String"
WOODWIND = "Woodwind"
BRASS = "Brass"
KEYBOARD = "Keyboard"
client = genai.Client(api_key="GEMINI_API_KEY")
response = client.models.generate_content(
model='gemini-2.0-flash',
contents='What type of instrument is an oboe?',
config={
'response_mime_type': 'text/x.enum',
'response_schema': Instrument,
},
)
print(response.text)
# Woodwind
Biblioteka Pythona przetłumaczy deklaracje typów interfejsu API. Interfejs API akceptuje jednak podzbiór schematu OpenAPI 3.0 (Schemat).
Wyliczenie można określić na 2 inne sposoby. Możesz użyć
Literal
:
Python
Literal["Percussion", "String", "Woodwind", "Brass", "Keyboard"]
Możesz też przekazać schemat w formacie JSON:
Python
from google import genai
client = genai.Client(api_key="GEMINI_API_KEY")
response = client.models.generate_content(
model='gemini-2.0-flash',
contents='What type of instrument is an oboe?',
config={
'response_mime_type': 'text/x.enum',
'response_schema': {
"type": "STRING",
"enum": ["Percussion", "String", "Woodwind", "Brass", "Keyboard"],
},
},
)
print(response.text)
# Woodwind
Oprócz podstawowych problemów z wieloma odpowiedziami możesz używać enumeracji w dowolnym miejscu w schemacie JSON. Możesz na przykład poprosić model o listę tytułów przepisów i użyć enumeracji Grade
, aby nadać każdemu tytułowi ocenę popularności:
Python
from google import genai
import enum
from pydantic import BaseModel
class Grade(enum.Enum):
A_PLUS = "a+"
A = "a"
B = "b"
C = "c"
D = "d"
F = "f"
class Recipe(BaseModel):
recipe_name: str
rating: Grade
client = genai.Client(api_key="GEMINI_API_KEY")
response = client.models.generate_content(
model='gemini-2.0-flash',
contents='List 10 home-baked cookie recipes and give them grades based on tastiness.',
config={
'response_mime_type': 'application/json',
'response_schema': list[Recipe],
},
)
print(response.text)
Odpowiedź może wyglądać tak:
[
{
"recipe_name": "Chocolate Chip Cookies",
"rating": "a+"
},
{
"recipe_name": "Peanut Butter Cookies",
"rating": "a"
},
{
"recipe_name": "Oatmeal Raisin Cookies",
"rating": "b"
},
...
]
Informacje o schematach JSON
Konfigurowanie modelu na potrzeby danych wyjściowych w formacie JSON za pomocą parametru responseSchema
polega na definiowaniu struktury za pomocą obiektu Schema
. Ten obiekt reprezentuje wybrany podzbiór obiektu Schema OpenAPI 3.0, a także dodaje pole propertyOrdering
.
Oto reprezentacja w pseudo-formacie JSON wszystkich pól Schema
:
{
"type": enum (Type),
"format": string,
"description": string,
"nullable": boolean,
"enum": [
string
],
"maxItems": integer,
"minItems": integer,
"properties": {
string: {
object (Schema)
},
...
},
"required": [
string
],
"propertyOrdering": [
string
],
"items": {
object (Schema)
}
}
Type
schematu musi być jednym z typów danych OpenAPI lub ich unionem (za pomocą anyOf
). W przypadku każdego Type
prawidłowy jest tylko podzbiór pól.
Poniższa lista mapuje każdy typ Type
na podzbiór pól, które są prawidłowe w przypadku tego typu:
string
->enum
,format
,nullable
integer
->format
,minimum
,maximum
,enum
,nullable
number
->format
,minimum
,maximum
,enum
,nullable
boolean
->nullable
array
->minItems
,maxItems
,items
,nullable
object
->properties
,required
,propertyOrdering
,nullable
Oto kilka przykładowych schematów z prawidłowymi kombinacjami typu i pola:
{ "type": "string", "enum": ["a", "b", "c"] }
{ "type": "string", "format": "date-time" }
{ "type": "integer", "format": "int64" }
{ "type": "number", "format": "double" }
{ "type": "boolean" }
{ "type": "array", "minItems": 3, "maxItems": 3, "items": { "type": ... } }
{ "type": "object",
"properties": {
"a": { "type": ... },
"b": { "type": ... },
"c": { "type": ... }
},
"nullable": true,
"required": ["c"],
"propertyOrdering": ["c", "b", "a"]
}
Pełną dokumentację pól schematu, które są używane w Gemini API, znajdziesz w dokumentacji schematu.
Sortowanie obiektów
Gdy pracujesz z schematami JSON w interfejsie Gemini API, ważna jest kolejność właściwości. Domyślnie interfejs API sortuje właściwości alfabetycznie i nie zachowuje kolejności, w jakiej są one zdefiniowane (chociaż pakiety SDK Google Gen AI mogą zachować tę kolejność). Jeśli podajesz modelowi przykłady z skonfigurowanym schematem, a kolejność właściwości przykładów nie jest zgodna z kolejnością właściwości schematu, wynik może być niespójny lub nieoczekiwany.
Aby zapewnić spójne i przewidywalne sortowanie właściwości, możesz użyć opcjonalnego pola propertyOrdering[]
.
"propertyOrdering": ["recipeName", "ingredients"]
propertyOrdering[]
– nie jest to standardowe pole w specyfikacji OpenAPI – to tablica ciągów znaków służąca do określania kolejności właściwości w odpowiedzi. Określając kolejność właściwości, a następnie podając przykłady z tymi samymi właściwościami, możesz potencjalnie poprawić jakość wyników. propertyOrdering
jest obsługiwana tylko wtedy, gdy types.Schema
jest tworzona ręcznie.
Schematy w Pythonie
Jeśli używasz biblioteki Python, wartość response_schema
musi być jedną z tych:
- typ, który używasz w adnotacji typu (patrz moduł
typing
w Pythonie); - Przykład:
genai.types.Schema
dict
równowartośćgenai.types.Schema
Najprostszym sposobem zdefiniowania schematu jest użycie typu Pydantic (jak w poprzednim przykładzie):
Python
config={'response_mime_type': 'application/json',
'response_schema': list[Recipe]}
Gdy używasz typu Pydantic, biblioteka Pythona tworzy dla Ciebie schemat JSON i wysyła go do interfejsu API. Więcej przykładów znajdziesz w dokumentacji biblioteki Pythona.
Biblioteka Pythona obsługuje schematy zdefiniowane za pomocą tych typów (gdzie AllowedType
to dowolny dozwolony typ):
int
float
bool
str
list[AllowedType]
AllowedType|AllowedType|...
- W przypadku typów uporządkowanych:
dict[str, AllowedType]
. Ta adnotacja deklaruje, że wszystkie wartości w słowniku mają ten sam typ, ale nie określa, które klucze powinny być uwzględnione.- Zdefiniowane przez użytkownika modele analityczne. Dzięki temu możesz określić nazwy kluczy i zdefiniować różne typy wartości powiązanych z poszczególnymi kluczami, w tym struktury zagnieżdżone.
Sprawdzone metody
Podczas korzystania ze schematu odpowiedzi pamiętaj o tych kwestiach i zaleceniach:
- Rozmiar schematu odpowiedzi jest wliczany do limitu tokenów wejściowych.
- Domyślnie pola są opcjonalne, co oznacza, że model może je wypełnić lub pominąć. Możesz ustawić pola jako wymagane, aby wymusić podanie wartości przez model. Jeśli w powiązanym promptzie nie ma wystarczającego kontekstu, model generuje odpowiedzi głównie na podstawie danych, na których był trenowany.
Złożony schemat może spowodować błąd
InvalidArgument: 400
. Złożoność może wynikać z długich nazw właściwości, długich limitów długości tablic, typów enumeracji z wiele wartościami, obiektów z wiele opcjonalnych właściwości lub kombinacji tych czynników.Jeśli ten błąd wystąpi w przypadku prawidłowego schematu, wprowadź co najmniej jedną z tych zmian, aby go naprawić:
- Skróć nazwy właściwości lub nazwy typów wyliczenia.
- spłaszczania zagnieżdżonych tablic.
- Zmniejsz liczbę właściwości z ograniczeniami, takimi jak minimalne i maksymalne limity liczb.
- Zmniejsz liczbę właściwości z zaawansowanymi ograniczeniami, np. właściwości z zaawansowanymi formatami, takimi jak
date-time
. - Zmniejsz liczbę właściwości opcjonalnych.
- Zmniejsz liczbę prawidłowych wartości w przypadku typów wyliczeniowych.
Jeśli nie widzisz oczekiwanych wyników, dodaj więcej kontekstu do promptów dotyczących danych wejściowych lub zmodyfikuj schemat odpowiedzi. Możesz na przykład sprawdzić odpowiedź modelu bez danych wyjściowych w formacie ustrukturyzowanym, aby zobaczyć, jak model reaguje. Następnie możesz zaktualizować schemat odpowiedzi, aby lepiej pasował do danych wyjściowych modelu.
Co dalej?
Teraz, gdy już wiesz, jak generować uporządkowane dane wyjściowe, możesz spróbować użyć narzędzi interfejsu Gemini API: