Saltar al contenido
2.13Intermedio7 min

Structured output en LLM con JSON Schema: forzar respuestas fiables

Sebastian KarallActualizado el 28 de octubre de 2026
Definición

Las salidas estructuradas con JSON Schema son una técnica que obliga a un LLM a devolver su respuesta exactamente según un esquema JSON predefinido. En lugar de texto libre, el modelo entrega un objeto legible por máquina y validable. Así los pipelines de agentes se vuelven fiables, porque los pasos posteriores del programa pueden contar con una estructura de datos garantizada.

De un vistazo

  • Las salidas estructuradas imponen un esquema JSON fijo y sustituyen el parseo de texto libre, propenso a errores, por una estructura de datos garantizada y validable.
  • Hay tres niveles de garantía: solo prompt (ninguna garantía), modo JSON (JSON válido, pero no tu esquema) y constrained decoding o Structured Outputs (esquema impuesto de forma estricta).
  • El constrained decoding garantiza la sintaxis y la conformidad con el esquema, pero no la corrección del contenido. La validación del contenido y una estrategia de reintentos siguen siendo obligatorias.
  • En Anthropic Claude, las Structured Outputs imponen el esquema, ya sea como JSON Output (output_config.format) o como Strict Tool Use (strict: true). En OpenAI se hace con Structured Outputs en modo strict. El tool use normal sin strict no garantiza el esquema.
  • Para los agentes multipaso es esencial: cada paso poco fiable se multiplica a lo largo de la cadena y hunde la tasa de éxito de extremo a extremo.
  • La validación con Pydantic o Zod más reintentos acotados con feedback del error es el estándar en la práctica para pipelines robustos.

Las salidas estructuradas con JSON Schema son una técnica que obliga a un LLM a devolver su respuesta exactamente según un esquema JSON predefinido. En lugar de texto libre, el modelo entrega un objeto legible por máquina y validable. Así los pipelines de agentes se vuelven fiables, porque los pasos posteriores del programa pueden contar con una estructura de datos garantizada en lugar de parsear texto libre propenso a errores.

  • ¿Qué? El modelo devuelve JSON según un esquema fijo, no texto libre. Los campos, los tipos y los valores permitidos están definidos.
  • ¿Por qué? Los programas pueden procesar el resultado directamente, sin una frágil lógica de regex o de cadenas. Es la base de los agentes fiables.
  • ¿Cómo? Con funciones de los proveedores, como las Structured Outputs de OpenAI y Anthropic, o con constrained decoding en modelos open-weight, complementado con validación y reintentos.

Por qué falla el parseo de texto libre en los pipelines de agentes

Por defecto, un modelo de lenguaje genera texto para lectores humanos. Para un chatbot es ideal; para un pipeline automatizado, un problema. En cuanto un programa tiene que extraer un valor de la respuesta, como una categoría, una fecha, un importe o una lista, empieza el frágil negocio del parseo. Unas veces el modelo escribe "Die Kategorie ist Rechnung.", otras "Kategorie: Rechnung", y otras antepone una explicación. Cada una de estas variantes rompe una lógica de extracción ingenua.

En los agentes multipaso esto se agrava de forma drástica, porque la falta de fiabilidad se multiplica a lo largo de la cadena. Un ejemplo de cálculo: si cada paso tiene una tasa de éxito de parseo del 95 %, la tasa de éxito de extremo a extremo de una cadena de diez pasos se queda en 0,95 elevado a 10, es decir, en torno al 60 %. Si las salidas estructuradas elevan cada paso al 99,5 %, la misma cadena llega a cerca del 95 %. De este efecto multiplicador se deriva la tesis central de este artículo: las salidas estructuradas no son una función de comodidad, sino el requisito para que los pipelines de agentes lleguen a estar listos para producción.

Los tres niveles de garantía de un vistazo

No todos los métodos que prometen JSON ofrecen la misma garantía. Hay que distinguir tres niveles, y la diferencia determina la fiabilidad.

Solo prompt. Le pides educadamente al modelo que devuelva JSON. Suele funcionar, pero no siempre. El modelo puede añadir bloques de código Markdown, omitir campos o, si duda, volver al texto corrido. Ninguna garantía.

Modo JSON. El proveedor garantiza que la salida sea JSON sintácticamente válido. Eso elimina los errores de sintaxis, pero no dice nada sobre la estructura: pueden faltar campos, llegar con tipos incorrectos o aparecer campos de más. Garantía parcial.

Constrained decoding / Structured Outputs. Aquí el proceso de generación se restringe a nivel de token, de modo que solo se pueden generar tokens que se ajusten al esquema. El modelo ya no puede salirse de un resultado conforme al esquema. Los campos obligatorios, los tipos y los valores enum permitidos están garantizados. Esta técnica es la base de OpenAI Structured Outputs (modo strict) y de las Structured Outputs de Anthropic, es decir, de los JSON Outputs mediante output_config.format y del Strict Tool Use con strict: true. El tool use normal sin strict no garantiza el esquema. En los modelos open-weight, las bibliotecas y los stacks de inferencia asumen la misma tarea mediante restricciones de gramática.

Comparativa: método, garantía y contrapartidas

Método

Garantía

Contrapartida

Solo prompt ("responde en JSON")

Ninguna. El modelo puede desviarse o devolver texto corrido

Cero esfuerzo de implementación, pero poco fiable en producción

Modo JSON

JSON sintácticamente válido, pero no tu esquema

Elimina los errores de sintaxis, pero no los campos ausentes o con tipos incorrectos

Structured Outputs / strict (OpenAI)

Esquema impuesto de forma estricta (campos, tipos, enums)

La primera petición por esquema puede costar latencia por la compilación del esquema; límites del subconjunto de esquema admitido

JSON Outputs / Strict Tool Use (Anthropic Claude)

Esquema impuesto por constrained decoding (output_config.format o strict: true)

La primera petición por esquema cuesta latencia por la compilación de la gramática; límites del subconjunto de esquema admitido

Constrained decoding (open-weight, stacks locales)

La gramática impone la conformidad con el esquema a nivel de token

Requiere control sobre el stack de inferencia; la complejidad del esquema influye en la velocidad

Esquema + validación + reintentos (Pydantic/Zod)

Forma garantizada más comprobación semántica

Más código y lógica, pero la variante más robusta para pipelines críticos

La conclusión decisiva de esta tabla: el constrained decoding garantiza la forma, no el contenido. El modelo entrega con garantía un objeto válido con el campo rechnungsdatum, pero ningún método de decoding puede asegurar que el valor introducido ahí corresponda realmente a la fecha del documento. Por eso la validación del contenido y la estrategia de reintentos siguen siendo imprescindibles.

La realidad de los proveedores en 2026

Los grandes proveedores ya vinculan la respuesta a un esquema JSON, pero difieren en parámetros y límites.

  • OpenAI: Structured Outputs con strict: true, como formato de respuesta de tipo json_schema o en el function calling. El modo JSON (json_object), en cambio, solo devuelve JSON válido, sin respetar el esquema.
  • Anthropic Claude: JSON Outputs mediante output_config.format o Strict Tool Use con strict: true, ambos con muestreo restringido por gramática. Sin strict, Claude puede devolver tipos incorrectos en el tool use ("2" en lugar de 2) u omitir campos obligatorios. La API no admite esquemas recursivos ni límites como minimum o maxLength. Por eso los límites de longitud, como en el ejemplo de abajo, van en la description y en la validación.
  • Google Gemini: La API acepta un esquema JSON junto con el tipo MIME application/json como formato de respuesta. La propia Google recomienda comprobar igualmente los valores en la aplicación.
  • Modelos open-weight: Aquí es el stack de inferencia el que impone el esquema mediante gramática. vLLM acepta un esquema JSON directamente en su servidor compatible con OpenAI, y llama.cpp traduce una parte de JSON Schema a gramáticas GBNF. Si gestionas tu propio stack, configuras el constrained decoding con independencia de la API de un proveedor.

Importante en la práctica: muchos proveedores de inferencia ofrecen endpoints compatibles con OpenAI, pero implementan las salidas estructuradas de forma distinta. Antes de decidirte, comprueba si el proveedor concreto aplica realmente el modo strict o las restricciones de esquema, o si solo ofrece modo JSON.

Esquema de ejemplo y estrategia de reintentos

Un ejemplo concreto hace tangible el principio. Un agente debe clasificar las solicitudes de soporte entrantes y extraer los campos más importantes. El esquema JSON (simplificado) es este:

```json
{
"type": "object",
"properties": {
"kategorie": {
"type": "string",
"enum": ["rechnung", "technik", "vertrag", "sonstiges"],
"description": "Categoría principal de la solicitud"
},
"dringlichkeit": {
"type": "string",
"enum": ["niedrig", "mittel", "hoch"]
},
"kundennummer": {
"type": ["string", "null"],
"description": "Número de cliente si aparece en el texto; si no, null"
},
"zusammenfassung": {
"type": "string",
"description": "Una frase, máximo 200 caracteres"
}
},
"required": ["kategorie", "dringlichkeit", "kundennummer", "zusammenfassung"],
"additionalProperties": false
}
```

Aquí hay dos decisiones de diseño clave. Primero, enums en lugar de texto libre para kategorie y dringlichkeit: así se descarta que el modelo se invente "Rechnungswesen" o "sehr hoch", lo que rompería una lógica de enrutamiento posterior. Segundo, additionalProperties: false, para que no aparezcan campos adicionales no deseados. Los campos description actúan como una instrucción implícita para el modelo.

Sobre este esquema se apoya una estrategia de reintentos acotada. El pseudocódigo llama al LLM como máximo tres veces:

```
versuch = 0
while versuch < 3:
antwort = llm.call(prompt, schema=support_schema) # salida estructurada
objekt = parse_json(antwort) # la forma está garantizada
fehler = validiere(objekt) # comprobación semántica
if not fehler:
return objekt
prompt += f"\nCorrige: {fehler}" # feedback del error
versuch += 1
eskaliere_an_mensch(antwort) # fallback tras 3 intentos
```

La clave: incluso con una forma conforme al esquema garantizada, validiere() comprueba la semántica, por ejemplo, si el campo kundennummer tiene el formato esperado o si el campo zusammenfassung respeta el límite de longitud. Si falla, el error concreto vuelve al modelo como feedback. Tres intentos son un límite razonable; después se escala a una persona en lugar de entrar en un bucle infinito y quemar dinero.

Validación con Pydantic y Zod como estándar en la práctica

En la práctica nadie escribe esquemas JSON a mano. En Python se define un modelo Pydantic; en TypeScript, un esquema Zod. Ambos generan el esquema JSON para la petición al LLM y se encargan directamente de validar la respuesta. La ventaja es doble: la misma definición controla la generación y comprueba el resultado, lo que evita incoherencias. Los errores de tipo, los campos obligatorios ausentes o los rangos de valores incumplidos aparecen al instante durante el parseo como un mensaje de error claro, que se puede reutilizar como feedback para el reintento.

Frameworks como Pydantic AI ya incorporan este bucle: comprueban la respuesta frente al modelo Pydantic y piden al modelo un nuevo intento cuando se produce un error de validación, con un límite configurable. Para el enrutamiento entre varios proveedores existen herramientas como LiteLLM y OpenRouter. Con ellas, la misma petición estructurada se ejecuta contra distintos modelos. Esto reduce la dependencia de un único proveedor y permite un fallback a un segundo modelo si un proveedor no entrega la salida estructurada de forma fiable.

Errores frecuentes

  • Esquemas demasiado complejos. Las estructuras muy anidadas con muchos campos opcionales aumentan la tasa de error y la latencia. Tan estricto como sea necesario, tan sencillo como sea posible.
  • Confundir forma con contenido. Un objeto conforme al esquema no es automáticamente correcto en cuanto al contenido. Los valores alucinados pero con tipos válidos son la clase de error más peligrosa, porque pasan desapercibidos.
  • Reintentos ilimitados. Sin un límite máximo hay riesgo de bucles infinitos y de costes disparados. Usa siempre reintentos acotados con escalado como fallback.
  • Ignorar las diferencias entre proveedores. No todos los endpoints compatibles con OpenAI imponen realmente el esquema de forma estricta. Pruébalo antes de pasar a producción.

Para agencias y decisores B2B

Si estás planificando un agente en producción o una aplicación RAG en Europa, deberías anclar las salidas estructuradas desde el inicio como principio de arquitectura, no como reparación a posteriori. Justo aquí se decide si un proyecto de IA se convierte en una herramienta fiable o se queda en una demo impredecible. Como agencia en Viena, Blck Alpaca acompaña a empresas de toda Europa en la creación de pipelines de RAG y de agentes robustos, desde la definición del esquema, pasando por la validación y la lógica de reintentos, hasta la decisión sobre proveedor y soberanía. Escríbenos si tu proyecto de RAG o de agentes necesita salidas fiables y legibles por máquina en lugar de texto libre adivinado.

Resumir con IAChatGPTClaudePerplexity

Abre el chat con un prompt ya preparado.

Preguntas frecuentes

¿Cuál es la diferencia entre el modo JSON y Structured Outputs?
El modo JSON solo garantiza que la respuesta sea JSON sintácticamente válido, pero no que se ajuste a tu esquema. Pueden faltar campos, llegar con tipos incorrectos o aparecer campos de más. Structured Outputs (con constrained decoding y modo strict) impone además la estructura exacta del esquema: los campos obligatorios, los tipos y los valores enum permitidos están garantizados. Para pipelines de agentes, solo la segunda variante es realmente fiable.
¿Garantiza el constrained decoding contenidos correctos?
No. El constrained decoding garantiza únicamente la forma: la salida es JSON válido y se ajusta al esquema. El método no puede asegurar que los valores sean correctos en cuanto al contenido, por ejemplo, que una fecha de factura extraída coincida realmente con la fecha del documento. Por eso cualquier pipeline de producción necesita además una validación semántica (comprobaciones de plausibilidad, rangos de valores, verificaciones cruzadas) y una lógica de reintentos.
¿Cómo funcionan las salidas estructuradas en Anthropic Claude?
Anthropic ofrece dos vías que imponen el esquema mediante constrained decoding. Con los JSON Outputs pasas el esquema JSON en el parámetro output_config.format y Claude responde con JSON conforme a ese esquema. Con Strict Tool Use defines una herramienta con input_schema, estableces strict: true y haces que el modelo llame a esa herramienta. Los argumentos de la llamada a la herramienta son entonces tu objeto estructurado. Sin strict, Claude solo se ciñe al esquema en la medida de lo posible durante el tool use y puede devolver, por ejemplo, "2" en lugar de 2 u omitir campos obligatorios.
¿Necesito salidas estructuradas también en aplicaciones sencillas?
En cuanto la salida del LLM la procesa un programa, y no solo la lee una persona, merece la pena un esquema. En un único paso de clasificación o extracción ahorra errores de parseo. En agentes multipaso es prácticamente imprescindible, porque las tasas de error se multiplican a lo largo de la cadena. Las aplicaciones de chat o de generación de texto pensadas solo para lectores humanos no lo necesitan.
¿Qué papel desempeña el diseño del esquema en la fiabilidad?
Un papel importante. Los esquemas acotados e inequívocos, con enums en lugar de texto libre, descripciones de campo claras y campos obligatorios bien elegidos, reducen los errores de forma considerable. Los esquemas demasiado complejos, muy anidados o ambiguos aumentan la tasa de error y la latencia. Un buen esquema es tan estricto como sea necesario y tan sencillo como sea posible, y usa las descripciones como instrucción implícita para el modelo.

¿Quieres profundizar?

Recibe nuevos análisis directamente en tu bandeja de entrada o descubre cómo aplicamos este conocimiento en empresas.