En pocas palabras
Generar respuestas de un modelo de lenguaje (LLM) conforme a un esquema como JSON Schema o una clase tipada.
Qué problema resuelve
Formatos variables, campos ausentes y tipos incompatibles al integrar IA con software.
Cuándo utilizarlo
Extracción, clasificación e integración con APIs. Ejemplo: convertir un correo en categoria, prioridad y resumen para crear un ticket.
De la idea a la práctica
Funcionamiento, ejemplos y decisiones para pasar al siguiente nivel.
Cómo funciona
El consumidor define campos, tipos y restricciones. Una API con generación restringida utiliza ese esquema durante la respuesta; después, la aplicación valida el resultado y decide si puede procesarlo. El esquema puede derivarse de un modelo Pydantic.
Ejemplo: clasificar una solicitud
Un contrato mínimo podría ser:
{
"type": "object",
"properties": {
"categoria": { "type": "string", "enum": ["soporte", "ventas"] },
"resumen": { "type": "string" }
},
"required": ["categoria", "resumen"],
"additionalProperties": false
}
Envía el esquema mediante la función de salidas estructuradas del proveedor. Este JSON describe la respuesta esperada; no es el contenido de un ticket.
Tres niveles de garantía
| Nivel | Cómo | Garantía |
|---|---|---|
| Instrucciones en el prompt | «Responde solo con JSON con estos campos» | Ninguna; a veces falla el formato |
| Modo JSON | El proveedor garantiza JSON válido | Sintaxis, no esquema |
| Generación restringida por esquema | El decodificador solo produce tokens compatibles con el JSON Schema | Esquema (dentro de las capacidades soportadas) |
La mayoría de los proveedores principales ofrecen ya el tercer nivel; en modelos propios, motores como vLLM lo implementan con gramáticas.
Diseño de esquemas
from typing import Literal
from pydantic import BaseModel, Field
class Clasificacion(BaseModel):
razonamiento: str = Field(description="Por qué se elige la categoría, en una o dos frases")
categoria: Literal["pago", "solicitud", "reclamo", "fraude", "otro"]
urgente: bool = Field(description="True si hay riesgo de pérdida económica para el cliente")
credito_id: str | None = Field(None, description="Solo si aparece explícitamente en el mensaje")
confianza: Literal["alta", "media", "baja"]
| Práctica | Motivo |
|---|---|
enum / Literal para categorías |
Evita variantes («Pago», «pagos», «PAGO») |
| Campo de razonamiento antes de la decisión | El modelo genera en orden; razonar primero mejora la decisión |
null explícito para datos ausentes |
Evita que el modelo invente un valor para cumplir el esquema |
| Descripciones en cada campo | Son parte del prompt |
| Poca profundidad y pocos campos | Menos errores y menos tokens |
En modo estricto, algunos proveedores exigen que todos los campos sean requeridos (usa tipos con null para los opcionales) y additionalProperties: false.
Validación y reintento independientes del proveedor
from pydantic import ValidationError
def clasificar(mensaje: str, intentos: int = 2) -> Clasificacion:
error = None
for _ in range(intentos + 1):
texto = llamar_modelo(mensaje, esquema=Clasificacion.model_json_schema(), error_previo=error)
try:
resultado = Clasificacion.model_validate_json(texto)
if resultado.credito_id and not existe_credito(resultado.credito_id):
raise ValueError(f"El crédito {resultado.credito_id} no existe")
return resultado
except (ValidationError, ValueError) as e:
error = str(e) # se envía al modelo en el siguiente intento
raise RuntimeError("No se obtuvo una clasificación válida")
Librerías como Instructor o Pydantic AI implementan este patrón, y Pydantic genera el JSON Schema.
Casos que hay que manejar
- Rechazos: el modelo puede negarse por políticas de seguridad; el SDK suele indicarlo en un campo aparte.
- Truncamiento: si se alcanza
max_tokens, el JSON queda incompleto. - Valores válidos pero falsos: un identificador bien formado que no existe; valida contra el sistema.
- Evolución del esquema: versiónalo como cualquier contrato y evalúa de nuevo al cambiarlo.
Criterios de implementación
Usa esquemas pequeños y versionados. Maneja rechazos, límites de tokens y valores desconocidos. Verifica identificadores y reglas del negocio fuera del modelo antes de ejecutar acciones.
Continúa en las fuentes
Documentación oficial para verificar detalles y explorar más.