Resultados estructurados

Puedes configurar los modelos de Gemini para que generen respuestas que se ajusten a un esquema JSON proporcionado. Esta capacidad garantiza resultados predecibles y analizables, asegura la seguridad de formato y tipo, permite la detección programática de rechazos y simplifica las instrucciones.

El uso de resultados estructurados es ideal para una amplia variedad de aplicaciones:

  • Extracción de datos: Extrae información específica de texto no estructurado, como nombres, fechas e importes de una factura.
  • Clasificación estructurada: Clasifica el texto en categorías predefinidas y asigna etiquetas estructuradas, como categorizar los comentarios de los clientes por opinión y tema.
  • Flujos de trabajo basados en agentes: Genera datos estructurados que se pueden usar para llamar a otras herramientas o APIs, como crear una hoja de personaje para un juego o completar un formulario.

Además de admitir el esquema JSON en la API de REST, los SDKs de GenAI de Google para Python y JavaScript también facilitan la definición de esquemas de objetos con Pydantic y Zod, respectivamente. En el siguiente ejemplo, se muestra cómo extraer información de texto no estructurado que se ajusta a un esquema definido en el código.

En este ejemplo, se muestra cómo extraer datos estructurados del texto con tipos básicos de esquemas JSON, como object, array, string y integer.

Python

from google import genai
from pydantic import BaseModel, Field
from typing import List, Optional

class Ingredient(BaseModel):
    name: str = Field(description="Name of the ingredient.")
    quantity: str = Field(description="Quantity of the ingredient, including units.")

class Recipe(BaseModel):
    recipe_name: str = Field(description="The name of the recipe.")
    prep_time_minutes: Optional[int] = Field(description="Optional time in minutes to prepare the recipe.")
    ingredients: List[Ingredient]
    instructions: List[str]

client = genai.Client()

prompt = """
Please extract the recipe from the following text.
The user wants to make delicious chocolate chip cookies.
They need 2 and 1/4 cups of all-purpose flour, 1 teaspoon of baking soda,
1 teaspoon of salt, 1 cup of unsalted butter (softened), 3/4 cup of granulated sugar,
3/4 cup of packed brown sugar, 1 teaspoon of vanilla extract, and 2 large eggs.
For the best part, they'll need 2 cups of semisweet chocolate chips.
First, preheat the oven to 375°F (190°C). Then, in a small bowl, whisk together the flour,
baking soda, and salt. In a large bowl, cream together the butter, granulated sugar, and brown sugar
until light and fluffy. Beat in the vanilla and eggs, one at a time. Gradually beat in the dry
ingredients until just combined. Finally, stir in the chocolate chips. Drop by rounded tablespoons
onto ungreased baking sheets and bake for 9 to 11 minutes.
"""

response = client.models.generate_content(
    model="gemini-2.5-flash",
    contents=prompt,
    config={
        "response_mime_type": "application/json",
        "response_json_schema": Recipe.model_json_schema(),
    },
)

recipe = Recipe.model_validate_json(response.text)
print(recipe)

JavaScript

import { GoogleGenAI } from "@google/genai";
import { z } from "zod";
import { zodToJsonSchema } from "zod-to-json-schema";

const ingredientSchema = z.object({
  name: z.string().describe("Name of the ingredient."),
  quantity: z.string().describe("Quantity of the ingredient, including units."),
});

const recipeSchema = z.object({
  recipe_name: z.string().describe("The name of the recipe."),
  prep_time_minutes: z.number().optional().describe("Optional time in minutes to prepare the recipe."),
  ingredients: z.array(ingredientSchema),
  instructions: z.array(z.string()),
});

const ai = new GoogleGenAI({});

const prompt = `
Please extract the recipe from the following text.
The user wants to make delicious chocolate chip cookies.
They need 2 and 1/4 cups of all-purpose flour, 1 teaspoon of baking soda,
1 teaspoon of salt, 1 cup of unsalted butter (softened), 3/4 cup of granulated sugar,
3/4 cup of packed brown sugar, 1 teaspoon of vanilla extract, and 2 large eggs.
For the best part, they'll need 2 cups of semisweet chocolate chips.
First, preheat the oven to 375°F (190°C). Then, in a small bowl, whisk together the flour,
baking soda, and salt. In a large bowl, cream together the butter, granulated sugar, and brown sugar
until light and fluffy. Beat in the vanilla and eggs, one at a time. Gradually beat in the dry
ingredients until just combined. Finally, stir in the chocolate chips. Drop by rounded tablespoons
onto ungreased baking sheets and bake for 9 to 11 minutes.
`;

const response = await ai.models.generateContent({
  model: "gemini-2.5-flash",
  contents: prompt,
  config: {
    responseMimeType: "application/json",
    responseJsonSchema: zodToJsonSchema(recipeSchema),
  },
});

const recipe = recipeSchema.parse(JSON.parse(response.text));
console.log(recipe);

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

    prompt := `
  Please extract the recipe from the following text.
  The user wants to make delicious chocolate chip cookies.
  They need 2 and 1/4 cups of all-purpose flour, 1 teaspoon of baking soda,
  1 teaspoon of salt, 1 cup of unsalted butter (softened), 3/4 cup of granulated sugar,
  3/4 cup of packed brown sugar, 1 teaspoon of vanilla extract, and 2 large eggs.
  For the best part, they'll need 2 cups of semisweet chocolate chips.
  First, preheat the oven to 375°F (190°C). Then, in a small bowl, whisk together the flour,
  baking soda, and salt. In a large bowl, cream together the butter, granulated sugar, and brown sugar
  until light and fluffy. Beat in the vanilla and eggs, one at a time. Gradually beat in the dry
  ingredients until just combined. Finally, stir in the chocolate chips. Drop by rounded tablespoons
  onto ungreased baking sheets and bake for 9 to 11 minutes.
  `
    config := &genai.GenerateContentConfig{
        ResponseMIMEType: "application/json",
        ResponseJsonSchema: map[string]any{
            "type": "object",
            "properties": map[string]any{
                "recipe_name": map[string]any{
                    "type":        "string",
                    "description": "The name of the recipe.",
                },
                "prep_time_minutes": map[string]any{
                    "type":        "integer",
                    "description": "Optional time in minutes to prepare the recipe.",
                },
                "ingredients": map[string]any{
                    "type": "array",
                    "items": map[string]any{
                        "type": "object",
                        "properties": map[string]any{
                            "name": map[string]any{
                                "type":        "string",
                                "description": "Name of the ingredient.",
                            },
                            "quantity": map[string]any{
                                "type":        "string",
                                "description": "Quantity of the ingredient, including units.",
                            },
                        },
                        "required": []string{"name", "quantity"},
                    },
                },
                "instructions": map[string]any{
                    "type":  "array",
                    "items": map[string]any{"type": "string"},
                },
            },
            "required": []string{"recipe_name", "ingredients", "instructions"},
        },
    }

    result, err := client.Models.GenerateContent(
        ctx,
        "gemini-2.5-flash",
        genai.Text(prompt),
        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' \
    -X POST \
    -d '{
      "contents": [{
        "parts":[
          { "text": "Please extract the recipe from the following text.\nThe user wants to make delicious chocolate chip cookies.\nThey need 2 and 1/4 cups of all-purpose flour, 1 teaspoon of baking soda,\n1 teaspoon of salt, 1 cup of unsalted butter (softened), 3/4 cup of granulated sugar,\n3/4 cup of packed brown sugar, 1 teaspoon of vanilla extract, and 2 large eggs.\nFor the best part, they will need 2 cups of semisweet chocolate chips.\nFirst, preheat the oven to 375°F (190°C). Then, in a small bowl, whisk together the flour,\nbaking soda, and salt. In a large bowl, cream together the butter, granulated sugar, and brown sugar\nuntil light and fluffy. Beat in the vanilla and eggs, one at a time. Gradually beat in the dry\ningredients until just combined. Finally, stir in the chocolate chips. Drop by rounded tablespoons\nonto ungreased baking sheets and bake for 9 to 11 minutes." }
        ]
      }],
      "generationConfig": {
        "responseMimeType": "application/json",
        "responseJsonSchema": {
          "type": "object",
          "properties": {
            "recipe_name": {
              "type": "string",
              "description": "The name of the recipe."
            },
            "prep_time_minutes": {
                "type": "integer",
                "description": "Optional time in minutes to prepare the recipe."
            },
            "ingredients": {
              "type": "array",
              "items": {
                "type": "object",
                "properties": {
                  "name": { "type": "string", "description": "Name of the ingredient."},
                  "quantity": { "type": "string", "description": "Quantity of the ingredient, including units."}
                },
                "required": ["name", "quantity"]
              }
            },
            "instructions": {
              "type": "array",
              "items": { "type": "string" }
            }
          },
          "required": ["recipe_name", "ingredients", "instructions"]
        }
      }
    }'

Ejemplo de respuesta:

{
  "recipe_name": "Delicious Chocolate Chip Cookies",
  "ingredients": [
    {
      "name": "all-purpose flour",
      "quantity": "2 and 1/4 cups"
    },
    {
      "name": "baking soda",
      "quantity": "1 teaspoon"
    },
    {
      "name": "salt",
      "quantity": "1 teaspoon"
    },
    {
      "name": "unsalted butter (softened)",
      "quantity": "1 cup"
    },
    {
      "name": "granulated sugar",
      "quantity": "3/4 cup"
    },
    {
      "name": "packed brown sugar",
      "quantity": "3/4 cup"
    },
    {
      "name": "vanilla extract",
      "quantity": "1 teaspoon"
    },
    {
      "name": "large eggs",
      "quantity": "2"
    },
    {
      "name": "semisweet chocolate chips",
      "quantity": "2 cups"
    }
  ],
  "instructions": [
    "Preheat the oven to 375°F (190°C).",
    "In a small bowl, whisk together the flour, baking soda, and salt.",
    "In a large bowl, cream together the butter, granulated sugar, and brown sugar until light and fluffy.",
    "Beat in the vanilla and eggs, one at a time.",
    "Gradually beat in the dry ingredients until just combined.",
    "Stir in the chocolate chips.",
    "Drop by rounded tablespoons onto ungreased baking sheets and bake for 9 to 11 minutes."
  ]
}

Transmisión

Puedes transmitir resultados estructurados, lo que te permite comenzar a procesar la respuesta a medida que se genera, sin tener que esperar a que se complete todo el resultado. Esto puede mejorar el rendimiento percibido de tu aplicación.

Los fragmentos transmitidos serán cadenas JSON parciales válidas que se pueden concatenar para formar el objeto JSON final y completo.

Python

from google import genai
from pydantic import BaseModel, Field
from typing import Literal

class Feedback(BaseModel):
    sentiment: Literal["positive", "neutral", "negative"]
    summary: str

client = genai.Client()
prompt = "The new UI is incredibly intuitive and visually appealing. Great job. Add a very long summary to test streaming!"

response_stream = client.models.generate_content_stream(
    model="gemini-2.5-flash",
    contents=prompt,
    config={
        "response_mime_type": "application/json",
        "response_json_schema": Feedback.model_json_schema(),
    },
)

for chunk in response_stream:
    print(chunk.candidates[0].content.parts[0].text)

JavaScript

import { GoogleGenAI } from "@google/genai";
import { z } from "zod";
import { zodToJsonSchema } from "zod-to-json-schema";

const ai = new GoogleGenAI({});
const prompt = "The new UI is incredibly intuitive and visually appealing. Great job! Add a very long summary to test streaming!";

const feedbackSchema = z.object({
  sentiment: z.enum(["positive", "neutral", "negative"]),
  summary: z.string(),
});

const stream = await ai.models.generateContentStream({
  model: "gemini-2.5-flash",
  contents: prompt,
  config: {
    responseMimeType: "application/json",
    responseJsonSchema: zodToJsonSchema(feedbackSchema),
  },
});

for await (const chunk of stream) {
  console.log(chunk.candidates[0].content.parts[0].text)
}

Compatibilidad con esquemas JSON

Para generar un objeto JSON, establece response_mime_type en la configuración de generación como application/json y proporciona un response_json_schema. El esquema debe ser un esquema JSON válido que describa el formato de salida deseado.

Luego, el modelo generará una respuesta que será una cadena JSON sintácticamente válida que coincida con el esquema proporcionado. Cuando se usan resultados estructurados, el modelo generará resultados en el mismo orden que las claves del esquema.

El modo de salida estructurada de Gemini admite un subconjunto de la especificación JSON Schema.

Se admiten los siguientes valores de type:

  • string: Para texto
  • number: Para números de punto flotante.
  • integer: Para números enteros
  • boolean: Para valores verdadero/falso.
  • object: Para datos estructurados con pares clave-valor.
  • array: Para listas de elementos.
  • null: Para permitir que una propiedad sea nula, incluye "null" en el array de tipos (p.ej., {"type": ["string", "null"]}).

Estas propiedades descriptivas ayudan a guiar el modelo:

  • title: Es una descripción breve de una propiedad.
  • description: Es una descripción más larga y detallada de una propiedad.

Propiedades específicas del tipo

Para los valores de object:

  • properties: Es un objeto en el que cada clave es un nombre de propiedad y cada valor es un esquema para esa propiedad.
  • required: Es un array de cadenas que indica qué propiedades son obligatorias.
  • additionalProperties: Controla si se permiten las propiedades que no se incluyen en properties. Puede ser un valor booleano o un esquema.

Para los valores de string:

  • enum: Enumera un conjunto específico de cadenas posibles para las tareas de clasificación.
  • format: Especifica una sintaxis para la cadena, como date-time, date, time.

Para los valores de number y integer:

  • enum: Enumera un conjunto específico de valores numéricos posibles.
  • minimum: Es el valor mínimo inclusivo.
  • maximum: Es el valor máximo inclusivo.

Para los valores de array:

  • items: Define el esquema para todos los elementos del array.
  • prefixItems: Define una lista de esquemas para los primeros N elementos, lo que permite estructuras similares a tuplas.
  • minItems: Es la cantidad mínima de elementos en el array.
  • maxItems: Es la cantidad máxima de elementos en el array.

Compatibilidad con modelos

Los siguientes modelos admiten resultados estructurados:

Modelo Resultados estructurados
Gemini 2.5 Pro ✔️
Gemini 2.5 Flash ✔️
Gemini 2.5 Flash-Lite ✔️
Gemini 2.0 Flash ✔️*
Gemini 2.0 Flash-Lite ✔️*

* Ten en cuenta que Gemini 2.0 requiere una lista propertyOrdering explícita dentro de la entrada JSON para definir la estructura preferida. Puedes encontrar un ejemplo en esta guía de soluciones.

Comparación entre los resultados estructurados y las llamadas a funciones

Tanto los resultados estructurados como la llamada a función usan esquemas JSON, pero tienen propósitos diferentes:

Función Caso de uso principal
Resultados estructurados Dar formato a la respuesta final para el usuario Usa este parámetro cuando quieras que la respuesta del modelo tenga un formato específico (p.ej., extraer datos de un documento para guardarlos en una base de datos).
Llamada a función Realizar acciones durante la conversación Usa esta opción cuando el modelo necesite pedirte que realices una tarea (p.ej., "obtén el clima actual") antes de poder proporcionar una respuesta final.

Prácticas recomendadas

  • Descripciones claras: Usa el campo description en tu esquema para proporcionar instrucciones claras al modelo sobre lo que representa cada propiedad. Esto es fundamental para guiar el resultado del modelo.
  • Tipificación sólida: Usa tipos específicos (integer, string, enum) siempre que sea posible. Si un parámetro tiene un conjunto limitado de valores válidos, usa un enum.
  • Ingeniería de instrucciones: Indica claramente en la instrucción lo que quieres que haga el modelo. Por ejemplo, "Extrae la siguiente información del texto…" o "Clasifica estos comentarios según el esquema proporcionado…".
  • Validación: Si bien el resultado estructurado garantiza que el JSON sea sintácticamente correcto, no garantiza que los valores sean semánticamente correctos. Siempre valida el resultado final en el código de tu aplicación antes de usarlo.
  • Manejo de errores: Implementa un manejo de errores sólido en tu aplicación para administrar correctamente los casos en los que el resultado del modelo, si bien cumple con el esquema, puede no satisfacer los requisitos de tu lógica empresarial.

Limitaciones

  • Subconjunto de esquema: No se admiten todas las funciones de la especificación del esquema de JSON. El modelo ignora las propiedades no admitidas.
  • Complejidad del esquema: La API puede rechazar esquemas muy grandes o anidados de forma profunda. Si encuentras errores, intenta simplificar tu esquema acortando los nombres de las propiedades, reduciendo el anidamiento o limitando la cantidad de restricciones.