Strukturierte Ausgabe

Standardmäßig generiert Gemini unstrukturierten Text. Sie können das Modell jedoch so einschränken, dass es stattdessen mit strukturierter Ausgabe antwortet – entweder JSON oder ein Wert aus einem Enum. Diese Funktion für strukturierte Ausgabe ist besonders nützlich, wenn Sie Informationen aus unstrukturierten Daten extrahieren und dann für die Verwendung in einer Anwendung verarbeiten möchten. Sie können die Funktion beispielsweise verwenden, um standardisierte Informationen aus Lebensläufen zu extrahieren und dann eine Datenbank mit den Informationen zu erstellen. Oder Sie können Zutaten aus Rezepten extrahieren und für jede Zutat einen Link zu einer Lebensmittelwebsite anzeigen.

In dieser Anleitung erfahren Sie, wie Sie mit der Gemini API strukturierte Ausgabe generieren.

JSON generieren

Es gibt zwei Möglichkeiten, JSON mit der Gemini API zu generieren:

  • Schema für das Modell konfigurieren
  • Schema in einem Text-Prompt angeben

Die empfohlene Methode zum Generieren von JSON ist die Konfiguration eines Schemas für das Modell, da das Modell so dazu gezwungen wird, JSON auszugeben.

Schema konfigurieren

Wenn Sie das Modell dazu zwingen möchten, JSON zu generieren, konfigurieren Sie eine responseSchema. Das Modell antwortet dann auf jeden Prompt mit einer JSON-formatierten Ausgabe.

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
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();
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())
}
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

Die Ausgabe könnte in etwa so aussehen:

[
  {
    "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"
    ]
  },
  ...
]

Schema in einem Text-Prompt angeben

Anstatt ein Schema zu konfigurieren, können Sie es in einem Textprompt als natürliche Sprache oder Pseudocode angeben. Diese Methode ist nicht empfehlenswert, da sie zu einer geringeren Ausgabequalität führen kann und das Modell nicht verpflichtet ist, dem Schema zu folgen.

Hier ein allgemeines Beispiel für ein Schema in einem Textprompt:

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>

Da das Modell das Schema aus dem Text im Prompt erhält, haben Sie bei der Darstellung des Schemas etwas Flexibilität. Wenn Sie jedoch ein Schema so inline angeben, ist das Modell nicht darauf beschränkt, JSON zurückzugeben. Wenn Sie eine deterministischere Antwort mit höherer Qualität erhalten möchten, konfigurieren Sie ein Schema für das Modell und duplizieren Sie das Schema nicht im Textprompt.

JSON-Schemas

Wenn Sie das Modell so konfigurieren, dass eine JSON-Antwort zurückgegeben wird, definieren Sie mit einem Schema-Objekt die Form der JSON-Daten. Schema stellt eine ausgewählte Teilmenge des OpenAPI 3.0-Schemaobjekts dar und fügt ein Feld propertyOrdering hinzu.

Hier ist eine Pseudo-JSON-Darstellung aller Schema-Felder:

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

Der Type des Schemas muss einer der OpenAPI-Datentypen oder eine Union dieser Typen (mit anyOf) sein. Für jeden Type ist nur eine Teilmenge der Felder zulässig. In der folgenden Liste wird jeder Type einem Teil der Felder zugeordnet, die für diesen Typ gültig sind:

  • 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

Hier sind einige Beispielschemata mit gültigen Kombinationen von Typ und Feld:

{ "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"]
}

Eine vollständige Dokumentation der Schemafelder, wie sie in der Gemini API verwendet werden, finden Sie in der Schemareferenz.

Property-Anordnung

Wenn Sie mit JSON-Schemas in der Gemini API arbeiten, ist die Reihenfolge der Properties wichtig. Standardmäßig werden die Properties in der API alphabetisch sortiert und die Reihenfolge, in der sie definiert sind, wird nicht beibehalten. Die Google Gen AI SDKs können diese Reihenfolge jedoch beibehalten. Wenn Sie dem Modell Beispiele mit einem konfigurierten Schema zur Verfügung stellen und die Property-Sortierung der Beispiele nicht mit der Property-Sortierung des Schemas übereinstimmt, kann die Ausgabe unzusammenhängend oder unerwartet sein.

Für eine einheitliche, vorhersehbare Sortierung von Unterkünften können Sie das optionale Feld propertyOrdering[] verwenden.

"propertyOrdering": ["recipeName", "ingredients"]

propertyOrdering[] ist kein Standardfeld in der OpenAPI-Spezifikation. Es ist ein Array von Strings, mit dem die Reihenfolge der Eigenschaften in der Antwort bestimmt wird. Wenn Sie die Reihenfolge der Properties angeben und dann Beispiele mit Properties in derselben Reihenfolge angeben, können Sie die Qualität der Ergebnisse möglicherweise verbessern. propertyOrdering wird nur unterstützt, wenn Sie types.Schema manuell erstellen.

Schemas in Python

In diesem Abschnitt finden Sie weitere Informationen zum Arbeiten mit JSON-Schemas mithilfe der Python-Bibliothek.

Wenn Sie die Python-Bibliothek verwenden, muss der Wert von response_schema einer der folgenden Werte sein:

  • Ein Typ, wie er in einer Typanmerkung verwendet wird (siehe Python-Modul typing)
  • Eine Instanz von genai.types.Schema
  • genai.types.Schema in dict

Am einfachsten lässt sich ein Schema mit einem Pydantic-Typ definieren (wie im vorherigen Beispiel gezeigt):

Python
config={'response_mime_type': 'application/json',
        'response_schema': list[Recipe]}

Wenn Sie einen Pydantic-Typ verwenden, erstellt die Python-Bibliothek ein JSON-Schema für Sie und sendet es an die API. Weitere Beispiele finden Sie in der Python-Bibliothek.

Die Python-Bibliothek unterstützt Schemas, die mit den folgenden Typen definiert sind (AllowedType ist dabei ein beliebiger zulässiger Typ):

  • int
  • float
  • bool
  • str
  • list[AllowedType]
  • AllowedType|AllowedType|...
  • Für strukturierte Typen:
    • dict[str, AllowedType]. Mit dieser Anmerkung werden alle Dictionary-Werte als vom selben Typ deklariert, aber es wird nicht angegeben, welche Schlüssel enthalten sein sollen.
    • Benutzerdefinierte Pydantic-Modelle Mit diesem Ansatz können Sie die Schlüsselnamen angeben und verschiedene Typen für die mit den einzelnen Schlüsseln verknüpften Werte definieren, einschließlich verschachtelter Strukturen.

Enum-Werte generieren

In einigen Fällen möchten Sie möglicherweise, dass das Modell eine einzelne Option aus einer Liste von Optionen auswählt. Um dieses Verhalten zu implementieren, können Sie in Ihrem Schema ein enum übergeben. Sie können eine enum-Option überall dort verwenden, wo Sie in der responseSchema eine string verwenden könnten, da ein enum ein Array von Strings ist. Ähnlich wie bei einem JSON-Schema können Sie mit einem Enum die Modellausgabe so einschränken, dass sie den Anforderungen Ihrer Anwendung entspricht.

Angenommen, Sie entwickeln eine Anwendung, mit der Musikinstrumente in eine von fünf Kategorien eingeteilt werden: "Percussion", "String", "Woodwind", "Brass" oder "Keyboard". Sie könnten ein Enum erstellen, um diese Aufgabe zu unterstützen.

Im folgenden Beispiel übergeben Sie ein Enum als responseSchema und zwingen das Modell so, die am besten geeignete Option auszuwählen.

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

Die Python-Bibliothek übersetzt die Typdeklarationen für die API. Die API akzeptiert jedoch eine Teilmenge des OpenAPI 3.0-Schemas (Schema).

Es gibt noch zwei weitere Möglichkeiten, eine Aufzählung anzugeben. Sie können einen Literal verwenden:

Python
Literal["Percussion", "String", "Woodwind", "Brass", "Keyboard"]

Sie können das Schema auch als JSON übergeben:

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

Neben einfachen Multiple-Choice-Fragen können Sie ein Enum überall in einem JSON-Schema verwenden. Sie können beispielsweise das Modell um eine Liste mit Rezepttiteln bitten und jedem Titel mithilfe eines Grade-Eintrags eine Beliebtheitsstufe zuweisen:

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)

Die Antwort könnte so aussehen:

[
  {
    "recipe_name": "Chocolate Chip Cookies",
    "rating": "a+"
  },
  {
    "recipe_name": "Peanut Butter Cookies",
    "rating": "a"
  },
  {
    "recipe_name": "Oatmeal Raisin Cookies",
    "rating": "b"
  },
  ...
]

Hinweise

Beachten Sie bei der Verwendung eines Antwortschemas die folgenden Überlegungen und Best Practices:

  • Die Größe des Antwortschemas wird auf das Eingabetokenlimit angerechnet.
  • Felder sind standardmäßig optional. Das Modell kann sie also ausfüllen oder überspringen. Sie können Felder als Pflichtfelder festlegen, um das Modell zu zwingen, einen Wert anzugeben. Wenn der zugehörige Eingabeprompt nicht genügend Kontext enthält, generiert das Modell Antworten hauptsächlich auf der Grundlage der Daten, mit denen es trainiert wurde.
  • Ein komplexes Schema kann zu einem InvalidArgument: 400-Fehler führen. Die Komplexität kann sich aus langen Attributnamen, langen Arraylängen, Enumerationen mit vielen Werten, Objekten mit vielen optionalen Eigenschaften oder einer Kombination dieser Faktoren ergeben.

    Wenn dieser Fehler bei einem gültigen Schema auftritt, nehmen Sie eine oder mehrere der folgenden Änderungen vor, um ihn zu beheben:

    • Kürzen Sie Property- oder Enum-Namen.
    • Verschachtelte Arrays vereinfachen.
    • Reduzieren Sie die Anzahl der Properties mit Einschränkungen, z. B. Zahlen mit Mindest- und Höchstwerten.
    • Reduzieren Sie die Anzahl der Properties mit komplexen Einschränkungen, z. B. Properties mit komplexen Formaten wie date-time.
    • Reduzieren Sie die Anzahl der optionalen Unterkünfte.
    • Reduzieren Sie die Anzahl der gültigen Werte für Enumerationen.
  • Wenn Sie nicht die erwarteten Ergebnisse erzielen, fügen Sie Ihren Eingabeprompts mehr Kontext hinzu oder überarbeiten Sie Ihr Antwortschema. Sehen Sie sich beispielsweise die Antwort des Modells ohne strukturierte Ausgabe an, um zu sehen, wie das Modell antwortet. Sie können dann Ihr Antwortschema aktualisieren, damit es besser zur Ausgabe des Modells passt.

Nächste Schritte

Nachdem Sie gelernt haben, wie Sie strukturierte Ausgabe generieren, können Sie die Gemini API-Tools ausprobieren: