JSON Schema

Avanzado
OpenAI
OpenAI
Actualizado: 03/07/2025

¡Desbloquea el curso completo!

IA
Ejercicios
Certificado
Entrar

Definición de JSON Schema para respuestas

JSON Schema es un estándar que permite definir la estructura, tipos de datos y restricciones de documentos JSON de forma declarativa. En el contexto de OpenAI, JSON Schema nos proporciona un control preciso sobre el formato de las respuestas generadas por los modelos, garantizando que la salida cumpla exactamente con nuestras especificaciones.

A diferencia del modo JSON básico que simplemente asegura una respuesta válida en formato JSON, JSON Schema define reglas específicas sobre qué propiedades debe contener el objeto, qué tipos de datos son válidos para cada campo, y qué campos son obligatorios u opcionales.

Estructura básica de un JSON Schema

Un JSON Schema se define como un objeto JSON que describe la estructura esperada. Los elementos fundamentales incluyen:

  • **type**: Especifica el tipo de dato (object, array, string, number, boolean)
  • **properties**: Define las propiedades del objeto y sus características
  • **required**: Lista los campos obligatorios
  • **additionalProperties**: Controla si se permiten propiedades adicionales
{
  "type": "object",
  "properties": {
    "nombre": {"type": "string"},
    "edad": {"type": "number"},
    "activo": {"type": "boolean"}
  },
  "required": ["nombre", "edad"],
  "additionalProperties": false
}

La principal utilidad es que te permite validar si un objeto cumple con el esquema:

from jsonschema import validate, ValidationError

json_obj = {
    "nombre": "María",
    "edad": 30,
    "correo": "maria@example.com",
    "aficiones": ["lectura", "senderismo", "pintura"]
}

json_schema = {
    "$schema": "http://json-schema.org/draft-07/schema#",
    "title": "PerfilUsuario",
    "type": "object",
    "properties": {
        "nombre": {
            "type": "string"
        },
        "edad": {
            "type": "integer",
            "minimum": 0
        },
        "correo": {
            "type": "string",
            "format": "email"
        },
        "aficiones": {
            "type": "array",
            "items": {
                "type": "string"
            }
        }
    },
    "required": ["nombre", "correo"],
    "additionalProperties": False
}

try:
    validate(instance=json_obj, schema=json_schema)
    print("El JSON Object es válido según el JSON Schema.")
except ValidationError as e:
    print("Error de validación:", e.message)

Implementación con la API Chat Completions

Ejemplo completo de cómo usar JSON Schema para pedir a un LLM de openai que nos genere una salida en JSON:

from openai import OpenAI
client = OpenAI()

response = client.chat.completions.create(
  model="gpt-4o-mini",
  messages=[
      {"role": "system", "content": "You are a helpful math tutor. Guide the user through the solution step by step."},
      {"role": "user", "content": "how can I solve 8x + 7 = -23"}
  ],
  response_format={
      "type": "json_schema",
      "json_schema": {
          "name": "math_response",
          "schema": {
              "type": "object",
              "properties": {
                  "steps": {
                      "type": "array",
                      "items": {
                          "type": "object",
                          "properties": {
                              "explanation": {"type": "string"},
                              "output": {"type": "string"}
                          },
                          "required": ["explanation", "output"],
                          "additionalProperties": False
                      }
                  },
                  "final_answer": {"type": "string"}
              },
              "required": ["steps", "final_answer"],
              "additionalProperties": False
          },
          "strict": True
      }
  }
)

content_string_json = response.choices[0].message.content
print(content_string_json)

El resultado será un json bien formado:

Implementación con la API Responses

Para utilizar JSON Schema con la API Responses moderna, configuramos el formato de respuesta especificando el schema deseado:

response = client.responses.create(
    model="gpt-4o-2024-08-06",
    input=[
        {"role": "system", "content": "You are a helpful math tutor. Guide the user through the solution step by step."},
        {"role": "user", "content": "how can I solve 8x + 7 = -23"}
    ],
    text={
        "format": {
            "type": "json_schema",
            "name": "math_response",
            "schema": {
                "type": "object",
                "properties": {
                    "steps": {
                        "type": "array",
                        "items": {
                            "type": "object",
                            "properties": {
                                "explanation": {"type": "string"},
                                "output": {"type": "string"}
                            },
                            "required": ["explanation", "output"],
                            "additionalProperties": False
                        }
                    },
                    "final_answer": {"type": "string"}
                },
                "required": ["steps", "final_answer"],
                "additionalProperties": False
            },
            "strict": True
        }
    }
)

print(response.output_text)

Como se puede apreciar, el uso de JSON Schema puede ser algo verboso o largo, es por eso que la alternativa moderna es usar librerías como Pydantic, que veremos en la siguiente lección.

Tipos de datos y validaciones avanzadas

JSON Schema soporta validaciones específicas para cada tipo de dato que permiten un control granular:

Para strings:

"descripcion": {
    "type": "string",
    "minLength": 10,
    "maxLength": 500,
    "pattern": "^[A-Za-z0-9\\s]+$"
}

Para números:

"precio": {
    "type": "number",
    "minimum": 0,
    "maximum": 10000,
    "multipleOf": 0.01
}

Para arrays:

"etiquetas": {
    "type": "array",
    "items": {"type": "string"},
    "minItems": 1,
    "maxItems": 5,
    "uniqueItems": true
}

Schemas anidados y objetos complejos

Los schemas anidados permiten definir estructuras complejas con múltiples niveles de profundidad:

# Schema para un informe de ventas complejo
sales_schema = {
    "type": "object",
    "properties": {
        "resumen": {
            "type": "object",
            "properties": {
                "total_ventas": {"type": "number"},
                "num_transacciones": {"type": "integer"},
                "fecha_reporte": {"type": "string"}
            },
            "required": ["total_ventas", "num_transacciones"],
            "additionalProperties": false
        },
        "productos": {
            "type": "array",
            "items": {
                "type": "object",
                "properties": {
                    "nombre": {"type": "string"},
                    "unidades_vendidas": {"type": "integer"},
                    "ingresos": {"type": "number"}
                },
                "required": ["nombre", "unidades_vendidas", "ingresos"],
                "additionalProperties": false
            }
        }
    },
    "required": ["resumen", "productos"],
    "additionalProperties": false
}

Compatibilidad con modelos

Es importante destacar que JSON Schema con adherencia estricta solo está disponible en modelos específicos. Los modelos compatibles incluyen:

  • gpt-4.1 y versiones posteriores
  • gpt-4.1-mini para aplicaciones que requieren menor costo
  • o4-mini y o3 para casos de uso especializados

Los modelos anteriores no soportan la funcionalidad strict: True, que es fundamental para garantizar el cumplimiento exacto del schema definido.

Ventajas del JSON Schema estructurado

El uso de JSON Schema proporciona beneficios significativos en aplicaciones de producción:

  • Predictibilidad: Las respuestas siguen siempre la misma estructura
  • Validación automática: El modelo garantiza el cumplimiento del schema
  • Integración simplificada: Facilita el procesamiento posterior de los datos
  • Reducción de errores: Elimina la necesidad de validación manual del formato

Esta aproximación resulta especialmente valiosa en sistemas automatizados donde la consistencia de los datos es crítica para el funcionamiento correcto de la aplicación.

Structured outputs con adherencia estricta

Guarda tu progreso

Inicia sesión para no perder tu progreso y accede a miles de tutoriales, ejercicios prácticos y nuestro asistente de IA.

Progreso guardado
Asistente IA
Ejercicios
Iniciar sesión gratis

Más de 25.000 desarrolladores ya confían en CertiDevs

Los structured outputs con adherencia estricta representan la evolución más avanzada del control de formato en las respuestas de OpenAI. Esta funcionalidad garantiza que el modelo genere respuestas que cumplan exactamente con el JSON Schema definido, sin desviaciones ni aproximaciones.

Activación de la adherencia estricta

La adherencia estricta se habilita mediante el parámetro strict: True en la configuración del formato de respuesta. Esta configuración instruye al modelo para que respete de forma absoluta las restricciones definidas en el schema:

from openai import OpenAI

client = OpenAI()

# Schema con adherencia estricta activada
response = client.responses.create(
    model="gpt-4.1",
    input="Genera un reporte de estado del servidor",
    format={
        "type": "json_schema",
        "strict": True,  # Adherencia estricta activada
        "schema": {
            "type": "object",
            "properties": {
                "estado": {
                    "type": "string",
                    "enum": ["activo", "inactivo", "mantenimiento"]
                },
                "cpu_uso": {"type": "number"},
                "memoria_libre": {"type": "integer"},
                "servicios": {
                    "type": "array",
                    "items": {"type": "string"}
                }
            },
            "required": ["estado", "cpu_uso", "memoria_libre"],
            "additionalProperties": False
        }
    }
)

Diferencias con el modo no estricto

Sin adherencia estricta, el modelo puede interpretar flexiblemente el schema, potencialmente generando respuestas que se aproximen pero no cumplan exactamente las especificaciones. Con strict: True, el comportamiento cambia radicalmente:

Modo no estricto:

  • Permite variaciones menores en la estructura
  • Puede incluir propiedades adicionales no especificadas
  • Los tipos de datos pueden ser aproximados

Modo estricto:

  • Cumplimiento exacto del schema definido
  • Respeto absoluto a las restricciones de tipo
  • Eliminación completa de propiedades no autorizadas

Restricciones y limitaciones del modo estricto

El modo estricto introduce limitaciones específicas en el diseño del schema que deben considerarse:

# Schema válido para modo estricto
strict_schema = {
    "type": "object",
    "properties": {
        "resultado": {"type": "string"},
        "confianza": {
            "type": "number",
            "minimum": 0.0,
            "maximum": 1.0
        },
        "categorias": {
            "type": "array",
            "items": {
                "type": "string",
                "enum": ["positivo", "negativo", "neutro"]
            }
        }
    },
    "required": ["resultado", "confianza"],
    "additionalProperties": False  # Obligatorio en modo estricto
}

Manejo de errores en adherencia estricta

Cuando el modelo no puede generar una respuesta que cumpla el schema estricto, el comportamiento es determinista y predecible:

try:
    response = client.responses.create(
        model="gpt-4.1",
        input="Analiza este texto imposible de categorizar",
        format={
            "type": "json_schema",
            "strict": True,
            "schema": {
                "type": "object",
                "properties": {
                    "categoria": {
                        "type": "string",
                        "enum": ["tecnologia", "deportes", "politica"]
                    },
                    "certeza": {"type": "boolean"}
                },
                "required": ["categoria", "certeza"],
                "additionalProperties": False
            }
        }
    )
except Exception as e:
    print(f"Error en adherencia estricta: {e}")

Optimización para structured outputs

Para maximizar la efectividad de los structured outputs estrictos, es recomendable seguir patrones específicos de diseño:

1. Definir enums explícitos para valores categóricos:

"prioridad": {
    "type": "string",
    "enum": ["baja", "media", "alta", "critica"]
}

2. Establecer rangos numéricos apropiados:

"puntuacion": {
    "type": "integer",
    "minimum": 1,
    "maximum": 100
}

3. Usar patrones de validación para strings estructurados:

"codigo_producto": {
    "type": "string",
    "pattern": "^PRD-[0-9]{4}$"
}

Casos de uso avanzados

Los structured outputs estrictos resultan especialmente valiosos en escenarios empresariales donde la consistencia es crítica:

# Schema para procesamiento de facturas
invoice_schema = {
    "type": "object",
    "properties": {
        "numero_factura": {"type": "string"},
        "fecha": {
            "type": "string",
            "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
        },
        "total": {
            "type": "number",
            "minimum": 0
        },
        "items": {
            "type": "array",
            "items": {
                "type": "object",
                "properties": {
                    "descripcion": {"type": "string"},
                    "cantidad": {"type": "integer", "minimum": 1},
                    "precio_unitario": {"type": "number", "minimum": 0}
                },
                "required": ["descripcion", "cantidad", "precio_unitario"],
                "additionalProperties": False
            }
        }
    },
    "required": ["numero_factura", "fecha", "total", "items"],
    "additionalProperties": False
}

Consideraciones de rendimiento

La adherencia estricta puede impactar el tiempo de respuesta debido al procesamiento adicional requerido para validar el cumplimiento del schema. Sin embargo, este overhead se compensa con la eliminación de la necesidad de validación posterior en el código de aplicación.

El modo estricto también reduce la variabilidad en los tokens generados, lo que puede resultar en costos más predecibles y respuestas más rápidas en casos donde el modelo tiene una estructura clara que seguir.

Aprendizajes de esta lección

  • Comprender qué es JSON Schema y su utilidad para definir estructuras JSON.
  • Aprender a crear y utilizar JSON Schema para controlar respuestas de modelos OpenAI.
  • Conocer cómo activar y aplicar la adherencia estricta para garantizar el cumplimiento exacto del schema.
  • Identificar las ventajas y limitaciones del modo estricto en la generación de respuestas.
  • Explorar casos prácticos y patrones avanzados para diseñar schemas complejos y anidados.

Completa OpenAI y certifícate

Únete a nuestra plataforma y accede a miles de tutoriales, ejercicios prácticos, proyectos reales y nuestro asistente de IA personalizado para acelerar tu aprendizaje.

Asistente IA

Resuelve dudas al instante

Ejercicios

Practica con proyectos reales

Certificados

Valida tus conocimientos

Más de 25.000 desarrolladores ya se han certificado con CertiDevs

⭐⭐⭐⭐⭐
4.9/5 valoración