Output strutturato

Puoi configurare Gemini per l'output strutturato anziché per il testo non strutturato, consentendo l'estrazione e la standardizzazione precise delle informazioni per l'ulteriore elaborazione. Ad esempio, puoi utilizzare l'output strutturato per estrarre informazioni dai curriculum vitae, standardizzarle per creare un database strutturato.

Gemini può generare JSON o valori enum come output strutturato.

Generazione di JSON

Esistono due modi per generare JSON utilizzando l'API Gemini:

  • Configura uno schema sul modello
  • Fornire uno schema in un prompt di testo

La configurazione di uno schema sul modello è il modo consigliato per generare JSON, perché vincola il modello a restituire JSON.

Configurazione di uno schema (consigliata)

Per vincolare il modello a generare JSON, configura un responseSchema. Il modello risponderà a qualsiasi prompt con un output formattato in JSON.

Python

from google import genai
from pydantic import BaseModel

class Recipe(BaseModel):
    recipe_name: str
    ingredients: list[str]

client = genai.Client()
response = client.models.generate_content(
    model="gemini-2.5-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({});

async function main() {
  const response = await ai.models.generateContent({
    model: "gemini-2.5-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();

Vai

package main

import (
    "context"
    "fmt"
    "log"

    "google.golang.org/genai"
)

func main() {
    ctx := context.Background()
    client, err := genai.NewClient(ctx, nil)
    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.5-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.5-flash:generateContent" \
-H "x-goog-api-key: $GEMINI_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

L'output potrebbe essere simile al seguente:

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

Fornire uno schema in un prompt di testo

Anziché configurare uno schema, puoi fornirlo come linguaggio naturale o pseudo-codice in un prompt di testo. Questo metodo non è consigliato perché potrebbe produrre un output di qualità inferiore e perché il modello non è vincolato a seguire lo schema.

Ecco un esempio generico di schema fornito in un prompt di testo:

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>

Poiché il modello ottiene lo schema dal testo nel prompt, potresti avere una certa flessibilità nel modo in cui lo rappresenti. Tuttavia, quando fornisci uno schema inline come questo, il modello non è effettivamente vincolato a restituire JSON. Per una risposta più deterministica e di qualità superiore, configura uno schema sul modello e non duplicarlo nel prompt di testo.

Generazione dei valori enum

In alcuni casi, potresti voler che il modello scelga una sola opzione da un elenco di opzioni. Per implementare questo comportamento, puoi trasmettere un enum nello schema. Puoi utilizzare un'opzione enum ovunque potresti utilizzare un string in responseSchema, perché un enum è un array di stringhe. Come uno schema JSON, un'enumerazione ti consente di vincolare l'output del modello per soddisfare i requisiti della tua applicazione.

Ad esempio, supponiamo che tu stia sviluppando un'applicazione per classificare gli strumenti musicali in una delle cinque categorie: "Percussion", "String", "Woodwind", "Brass" o ""Keyboard"". Puoi creare un'enumerazione per facilitare questa attività.

Nell'esempio seguente, passi un'enumerazione come responseSchema, vincolando il modello a scegliere l'opzione più appropriata.

Python

from google import genai
import enum

class Instrument(enum.Enum):
  PERCUSSION = "Percussion"
  STRING = "String"
  WOODWIND = "Woodwind"
  BRASS = "Brass"
  KEYBOARD = "Keyboard"

client = genai.Client()
response = client.models.generate_content(
    model='gemini-2.5-flash',
    contents='What type of instrument is an oboe?',
    config={
        'response_mime_type': 'text/x.enum',
        'response_schema': Instrument,
    },
)

print(response.text)
# Woodwind

JavaScript

import { GoogleGenAI, Type } from "@google/genai";

const ai = new GoogleGenAI({});

const response = await ai.models.generateContent({
    model: "gemini-2.5-flash",
    contents: "What type of instrument is an oboe?",
    config: {
      responseMimeType: "text/x.enum",
      responseSchema: {
        type: Type.STRING,
        enum: ["Percussion", "String", "Woodwind", "Brass", "Keyboard"],
      },
    },
  });

console.log(response.text);

REST

curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
    -H 'Content-Type: application/json' \
    -d '{
          "contents": [{
            "parts":[
              { "text": "What type of instrument is an oboe?" }
            ]
          }],
          "generationConfig": {
            "responseMimeType": "text/x.enum",
            "responseSchema": {
              "type": "STRING",
              "enum": ["Percussion", "String", "Woodwind", "Brass", "Keyboard"]
            }
          }
    }'

La libreria Python tradurrà le dichiarazioni di tipo per l'API. Tuttavia, l'API accetta un sottoinsieme dello schema OpenAPI 3.0 (Schema).

Esistono altri due modi per specificare un'enumerazione. Puoi utilizzare un Literal: ```

Python

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

Puoi anche passare lo schema come JSON:

Python

from google import genai

client = genai.Client()
response = client.models.generate_content(
    model='gemini-2.5-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

Oltre ai problemi di base a scelta multipla, puoi utilizzare un'enumerazione ovunque in uno schema JSON. Ad esempio, potresti chiedere al modello un elenco di titoli di ricette e utilizzare un'enumerazione Grade per assegnare a ogni titolo un grado di popolarità:

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()
response = client.models.generate_content(
    model='gemini-2.5-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)

La risposta potrebbe avere il seguente aspetto:

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

Informazioni sugli schemi JSON

La configurazione del modello per l'output JSON utilizzando il parametro responseSchema si basa sull'oggetto Schema per definirne la struttura. Questo oggetto rappresenta un sottoinsieme selezionato dell'oggetto schema OpenAPI 3.0 e aggiunge anche un campo propertyOrdering.

Ecco una rappresentazione pseudo-JSON di tutti i campi 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)
  }
}

Il Type dello schema deve essere uno dei tipi di dati OpenAPI o un'unione di questi tipi (utilizzando anyOf). Solo un sottoinsieme di campi è valido per ogni Type. Il seguente elenco mappa ogni Type a un sottoinsieme dei campi validi per quel tipo:

  • 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

Ecco alcuni schemi di esempio che mostrano combinazioni valide di tipo e campo:

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

Per la documentazione completa dei campi dello schema utilizzati nell'API Gemini, consulta il riferimento allo schema.

Ordinazione di proprietà

Quando lavori con gli schemi JSON nell'API Gemini, l'ordine delle proprietà è importante. Per impostazione predefinita, l'API ordina le proprietà in ordine alfabetico e non mantiene l'ordine in cui sono definite (anche se gli SDK Google Gen AI potrebbero mantenere questo ordine). Se fornisci esempi al modello con uno schema configurato e l'ordine delle proprietà degli esempi non è coerente con l'ordine delle proprietà dello schema, l'output potrebbe essere incoerente o imprevisto.

Per garantire un ordine coerente e prevedibile delle proprietà, puoi utilizzare il campo facoltativo propertyOrdering[].

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

propertyOrdering[], che non è un campo standard nella specifica OpenAPI, è un array di stringhe utilizzato per determinare l'ordine delle proprietà nella risposta. Se specifichi l'ordine delle proprietà e poi fornisci esempi con le proprietà nello stesso ordine, puoi potenzialmente migliorare la qualità dei risultati. propertyOrdering è supportato solo quando crei manualmente types.Schema.

Schemi in Python

Quando utilizzi la libreria Python, il valore di response_schema deve essere uno dei seguenti:

  • Un tipo, come faresti in un'annotazione di tipo (vedi il modulo Python typing)
  • Un'istanza di genai.types.Schema
  • L'equivalente di genai.types.Schema in dict

Il modo più semplice per definire uno schema è con un tipo Pydantic (come mostrato nell'esempio precedente):

Python

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

Quando utilizzi un tipo Pydantic, la libreria Python crea uno schema JSON per te e lo invia all'API. Per altri esempi, consulta la documentazione della libreria Python.

La libreria Python supporta gli schemi definiti con i seguenti tipi (dove AllowedType è un tipo consentito):

  • int
  • float
  • bool
  • str
  • list[AllowedType]
  • AllowedType|AllowedType|...
  • Per i tipi strutturati:
    • dict[str, AllowedType]. Questa annotazione dichiara che tutti i valori dict sono dello stesso tipo, ma non specifica quali chiavi devono essere incluse.
    • Definiti dall'utente Modelli Pydantic. Questo approccio ti consente di specificare i nomi delle chiavi e definire diversi tipi per i valori associati a ciascuna chiave, incluse le strutture nidificate.

Supporto dello schema JSON

JSON Schema è una specifica più recente di OpenAPI 3.0, su cui si basa l'oggetto Schema. Il supporto dello schema JSON è disponibile come anteprima utilizzando il campo responseJsonSchema che accetta qualsiasi schema JSON con le seguenti limitazioni:

  • Funziona solo con Gemini 2.5.
  • Sebbene sia possibile trasmettere tutte le proprietà dello schema JSON, non tutte sono supportate. Per ulteriori dettagli, consulta la documentazione relativa al campo.
  • I riferimenti ricorsivi possono essere utilizzati solo come valore di una proprietà dell'oggetto non obbligatoria.
  • I riferimenti ricorsivi vengono espansi in misura finita, in base alle dimensioni dello schema.
  • Gli schemi che contengono $ref non possono contenere proprietà diverse da quelle che iniziano con $.

Ecco un esempio di generazione di uno schema JSON con Pydantic e invio al modello:

curl "https://generativelanguage.googleapis.com/v1alpha/models/\
gemini-2.5-flash:generateContent" \
    -H "x-goog-api-key: $GEMINI_API_KEY"\
    -H 'Content-Type: application/json' \
    -d @- <<EOF
{
  "contents": [{
    "parts":[{
      "text": "Please give a random example following this schema"
    }]
  }],
  "generationConfig": {
    "response_mime_type": "application/json",
    "response_json_schema": $(python3 - << PYEOF
    from enum import Enum
    from typing import List, Optional, Union, Set
    from pydantic import BaseModel, Field, ConfigDict
    import json

    class UserRole(str, Enum):
        ADMIN = "admin"
        VIEWER = "viewer"

    class Address(BaseModel):
        street: str
        city: str

    class UserProfile(BaseModel):
        username: str = Field(description="User's unique name")
        age: Optional[int] = Field(ge=0, le=120)
        roles: Set[UserRole] = Field(min_items=1)
        contact: Union[Address, str]
        model_config = ConfigDict(title="User Schema")

    # Generate and print the JSON Schema
    print(json.dumps(UserProfile.model_json_schema(), indent=2))
    PYEOF
    )
  }
}
EOF

Il passaggio diretto dello schema JSON non è ancora supportato quando si utilizza l'SDK.

Best practice

Quando utilizzi uno schema di risposta, tieni presente le seguenti considerazioni e best practice:

  • Le dimensioni dello schema di risposta vengono conteggiate ai fini del limite di token di input.
  • Per impostazione predefinita, i campi sono facoltativi, il che significa che il modello può compilarli o saltarli. Puoi impostare i campi come obbligatori per forzare il modello a fornire un valore. Se il prompt di input associato non fornisce un contesto sufficiente, il modello genera risposte basate principalmente sui dati su cui è stato addestrato.
  • Uno schema complesso può generare un errore InvalidArgument: 400. La complessità potrebbe derivare da nomi di proprietà lunghi, limiti di lunghezza degli array elevati, enumerazioni con molti valori, oggetti con molte proprietà facoltative o una combinazione di questi fattori.

    Se ricevi questo errore con uno schema valido, apporta una o più delle seguenti modifiche per risolverlo:

    • Abbrevia i nomi delle proprietà o degli enum.
    • Appiattisci gli array nidificati.
    • Riduci il numero di proprietà con vincoli, ad esempio numeri con limiti minimi e massimi.
    • Riduci il numero di proprietà con vincoli complessi, ad esempio proprietà con formati complessi come date-time.
    • Riduci il numero di proprietà facoltative.
    • Riduci il numero di valori validi per le enumerazioni.
  • Se non vedi i risultati che ti aspetti, aggiungi più contesto ai prompt di input o rivedi lo schema di risposta. Ad esempio, esamina la risposta del modello senza output strutturato per vedere come risponde il modello. Puoi quindi aggiornare lo schema della risposta in modo che si adatti meglio all'output del modello. Per ulteriori suggerimenti per la risoluzione dei problemi relativi all'output strutturato, consulta la guida alla risoluzione dei problemi.

Passaggi successivi

Ora che hai imparato a generare output strutturati, potresti provare a utilizzare gli strumenti dell'API Gemini: