Resultados estructurados

Puedes configurar Gemini para que genere resultados estructurados en lugar de texto no estructurado, lo que permite extraer y estandarizar información con precisión para su posterior procesamiento. Por ejemplo, puedes usar la salida estructurada para extraer información de los currículums vitae y estandarizarlos para crear una base de datos estructurada.

Gemini puede generar JSON o valores de enumeración como resultado estructurado.

Cómo generar JSON

Para restringir el modelo a generar JSON, configura un responseSchema. Luego, el modelo responderá a cualquier instrucción con un resultado en formato 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(); 

Go

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 

El resultado podría verse de la siguiente manera:

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

Cómo generar valores de enumeración

En algunos casos, es posible que desees que el modelo elija una sola opción de una lista. Para implementar este comportamiento, puedes pasar un enum en tu esquema. Puedes usar una opción de enumeración en cualquier lugar en el que puedas usar un string en el responseSchema, ya que una enumeración es un array de cadenas. Al igual que un esquema JSON, un enum te permite restringir el resultado del modelo para que cumpla con los requisitos de tu aplicación.

Por ejemplo, supongamos que estás desarrollando una aplicación para clasificar instrumentos musicales en una de cinco categorías: "Percussion", "String", "Woodwind", "Brass" o ""Keyboard"". Podrías crear un enum para ayudarte con esta tarea.

En el siguiente ejemplo, pasas un enum como responseSchema, lo que restringe el modelo para que elija la opción más adecuada.

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 biblioteca de Python traducirá las declaraciones de tipo para la API. Sin embargo, la API acepta un subconjunto del esquema de OpenAPI 3.0 (Schema).

Existen otras dos formas de especificar una enumeración. Puedes usar un Literal: ```

Python

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

También puedes pasar el esquema como 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 

Además de los problemas básicos de opción múltiple, puedes usar una enumeración en cualquier parte de un esquema JSON. Por ejemplo, podrías pedirle al modelo una lista de títulos de recetas y usar un enum Grade para asignarle a cada título una calificación de popularidad:

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 respuesta podría verse de la siguiente manera:

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

Acerca de los esquemas JSON

La configuración del modelo para la salida JSON con el parámetro responseSchema se basa en el objeto Schema para definir su estructura. Este objeto representa un subconjunto selecto del objeto de esquema de OpenAPI 3.0 y también agrega un campo propertyOrdering.

Esta es una representación pseudo-JSON de todos los campos de 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)   } } 

El Type del esquema debe ser uno de los tipos de datos de OpenAPI o una unión de esos tipos (con anyOf). Solo un subconjunto de campos es válido para cada Type. En la siguiente lista, se asigna cada Type a un subconjunto de los campos que son válidos para ese 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

A continuación, se muestran algunos esquemas de ejemplo que muestran combinaciones válidas de tipos y campos:

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

Para obtener la documentación completa de los campos de esquema tal como se usan en la API de Gemini, consulta la referencia del esquema.

Ordenamiento de propiedades

Cuando trabajas con esquemas de JSON en la API de Gemini, el orden de las propiedades es importante. De forma predeterminada, la API ordena las propiedades alfabéticamente y no conserva el orden en el que se definen (aunque los SDKs de IA generativa de Google pueden conservar este orden). Si proporcionas ejemplos al modelo con un esquema configurado y el orden de las propiedades de los ejemplos no coincide con el orden de las propiedades del esquema, el resultado podría ser divagante o inesperado.

Para garantizar un orden coherente y predecible de las propiedades, puedes usar el campo opcional propertyOrdering[].

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

propertyOrdering[], que no es un campo estándar en la especificación de OpenAPI, es un array de cadenas que se usa para determinar el orden de las propiedades en la respuesta. Si especificas el orden de las propiedades y, luego, proporcionas ejemplos con propiedades en ese mismo orden, es posible que mejores la calidad de los resultados. propertyOrdering solo se admite cuando creas types.Schema de forma manual.

Esquemas en Python

Cuando usas la biblioteca de Python, el valor de response_schema debe ser uno de los siguientes:

  • Un tipo, como lo usarías en una anotación de tipo (consulta el módulo typing de Python)
  • Instancia de genai.types.Schema
  • El equivalente de dict de genai.types.Schema

La forma más sencilla de definir un esquema es con un tipo de Pydantic (como se muestra en el ejemplo anterior):

Python

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

Cuando usas un tipo de Pydantic, la biblioteca de Python crea un esquema JSON para ti y lo envía a la API. Para ver ejemplos adicionales, consulta la documentación de la biblioteca de Python.

La biblioteca de Python admite esquemas definidos con los siguientes tipos (en los que AllowedType es cualquier tipo permitido):

  • int
  • float
  • bool
  • str
  • list[AllowedType]
  • AllowedType|AllowedType|...
  • Para los tipos estructurados:
    • dict[str, AllowedType]. Esta anotación declara que todos los valores del diccionario son del mismo tipo, pero no especifica qué claves se deben incluir.
    • Modelos Pydantic definidos por el usuario. Este enfoque te permite especificar los nombres de las claves y definir diferentes tipos para los valores asociados con cada una de las claves, incluidas las estructuras anidadas.

Compatibilidad con el esquema JSON

JSON Schema es una especificación más reciente que OpenAPI 3.0, en la que se basa el objeto Schema. La compatibilidad con JSON Schema está disponible como versión preliminar a través del campo responseJsonSchema, que acepta cualquier esquema JSON con las siguientes limitaciones:

  • Solo funciona con Gemini 2.5.
  • Si bien se pueden pasar todas las propiedades del esquema JSON, no todas son compatibles. Consulta la documentación del campo para obtener más detalles.
  • Las referencias recursivas solo se pueden usar como el valor de una propiedad de objeto no obligatoria.
  • Las referencias recursivas se expanden hasta un grado finito, según el tamaño del esquema.
  • Los esquemas que contienen $ref no pueden contener ninguna propiedad que no comience con un $.

Este es un ejemplo de cómo generar un esquema JSON con Pydantic y enviarlo al modelo:

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 

Aún no se admite pasar el esquema JSON directamente cuando se usa el SDK.

Prácticas recomendadas

Ten en cuenta las siguientes consideraciones y prácticas recomendadas cuando uses un esquema de respuesta:

  • El tamaño del esquema de respuesta se considera para el límite de tokens de entrada.
  • De forma predeterminada, los campos son opcionales, lo que significa que el modelo puede propagar los campos o omitirlos. Puedes configurar los campos según sea necesario para forzar al modelo a proporcionar un valor. Si no hay suficiente contexto en la instrucción de entrada asociada, el modelo genera respuestas principalmente en función de los datos con los que se entrenó.
  • Un esquema complejo puede generar un error InvalidArgument: 400. La complejidad puede deberse a nombres de propiedades largos, límites de longitud de arrays largos, enumeraciones con muchos valores, objetos con muchas propiedades opcionales o una combinación de estos factores.

    Si recibes este error con un esquema válido, realiza uno o más de los siguientes cambios para resolverlo:

    • Acorta los nombres de las propiedades o los nombres de las enumeraciones.
    • Compacta los arrays anidados.
    • Reduce la cantidad de propiedades con restricciones, como los números con límites mínimos y máximos.
    • Reduce la cantidad de propiedades con restricciones complejas, como las que tienen formatos complejos, como date-time.
    • Reduce la cantidad de propiedades opcionales.
    • Reduce la cantidad de valores válidos para las enumeraciones.
  • Si no ves los resultados que esperas, agrega más contexto a tus instrucciones de entrada o revisa tu esquema de respuesta. Por ejemplo, revisa la respuesta del modelo sin un resultado estructurado para ver cómo responde. Luego, puedes actualizar el esquema de respuesta para que se adapte mejor al resultado del modelo. Si deseas obtener más sugerencias para solucionar problemas relacionados con el resultado estructurado, consulta la guía de solución de problemas.

¿Qué sigue?

Ahora que aprendiste a generar resultados estructurados, puedes intentar usar las herramientas de la API de Gemini: