
Salidas estructuradas (JSON) y por qué le importan al diseño
Una salida estructurada es una respuesta del modelo en JSON con un esquema fijo. Qué garantizan Anthropic, OpenAI y Google, qué no, y cómo diseñar la interfaz.
¿Qué es JSON y por qué aparece aquí?
JSON (JavaScript Object Notation) es un formato de texto para guardar y enviar datos como pares de clave y valor y como listas. Sus valores son cadenas entre comillas dobles, números, true, false, null, listas entre corchetes u objetos entre llaves. No admite comentarios ni comas finales. Aunque nació ligado a JavaScript, casi cualquier lenguaje lo lee y escribe.
Un modelo que responde en texto libre, como “Claro, aquí tienes la respuesta: …”, es difícil de procesar. Un modelo que responde con {"titulo": "...", "prioridad": "alta"} puede alimentar un formulario directamente. La diferencia no está en la inteligencia del modelo, sino en lo que la aplicación puede hacer con su salida.
¿Cómo se consigue?
Hay tres niveles, de menor a mayor garantía:
- Pedirlo en el prompt. Describir el formato y dar un ejemplo. Es la forma más sencilla y la menos segura.
- Usar la función de salida estructurada del proveedor, cuando existe, que restringe la generación a un esquema definido (decodificación restringida).
- Validar después. Revisar la respuesta contra un esquema, por ejemplo con JSON Schema, que describe campos, tipos, obligatorios y valores permitidos. Si falla, reintentar o mostrar un estado de error.
Lo recomendable es combinar niveles: pedir el formato, usar la función del proveedor si está disponible y validar siempre antes de usar los datos.
¿Qué ofrecen hoy Anthropic, OpenAI y Google?
Los tres proveedores permiten pasar un esquema JSON y obligar a que la respuesta lo cumpla. Los nombres de los parámetros cambian y la documentación se mueve, así que conviene revisarla antes de implementar.
| Proveedor | Cómo se pide | Qué garantiza | Qué no |
|---|---|---|---|
| Anthropic (Claude) | output_config.format con type: "json_schema" y un schema; para herramientas, strict: true en su definición | JSON válido que cumple el esquema, con campos obligatorios y tipos correctos | No admite restricciones numéricas ni de longitud en el esquema (minimum, maxLength) y las rechaza con un error 400; si hay rechazo (stop_reason: "refusal") o corte por max_tokens, la salida puede no cumplirlo |
| OpenAI | text.format con type: "json_schema", name, schema y strict: true (Responses API); response_format en Chat Completions | La respuesta sigue el esquema; los rechazos llegan en un campo refusal | Cada propiedad debe ir en required y cada objeto con additionalProperties: false; una respuesta cortada por max_output_tokens queda incompleta |
| Google (Gemini) | response_format con mime_type: "application/json" y schema (documentación de la Interactions API) | JSON sintácticamente válido y acorde al esquema | Ignora sin error palabras clave como minLength o maxLength; hay que validar los valores en la aplicación |
La lección común: el esquema garantiza la forma, no la verdad. Un campo severidad siempre será “baja”, “media” o “alta”, pero el modelo puede elegir la equivocada. Por eso la validación y el estado de error de la interfaz siguen siendo necesarios.
Este es un esquema mínimo para el ejemplo de más abajo, compatible con esas restricciones (todos los campos obligatorios y additionalProperties: false):
{
"type": "object",
"properties": {
"titulo": { "type": "string" },
"severidad": { "type": "string", "enum": ["baja", "media", "alta"] },
"pantalla": { "type": ["string", "null"] }
},
"required": ["titulo", "severidad", "pantalla"],
"additionalProperties": false
}
Y una respuesta válida:
{ "titulo": "El botón Guardar no responde", "severidad": "alta", "pantalla": null }
¿Por qué le importa a un diseñador?
Porque la interfaz depende de datos predecibles:
- Componentes que no se rompen. Si el modelo cambia el nombre de un campo o devuelve un número como texto, una tarjeta o un gráfico puede fallar o mostrar un dato incorrecto.
- Estados de error diseñados. Si la validación falla, el usuario necesita ver algo útil: “No pude extraer la fecha, ¿la escribes tú?” es mejor que una pantalla vacía.
- Edición humana. Un formulario prellenado con salida estructurada permite que el usuario corrija campo por campo, algo muy difícil con texto libre.
- Consistencia visual. Un formato fijo permite diseñar componentes reutilizables para los resultados de la IA.
¿Cuándo NO conviene?
Cuando la respuesta es un texto para leer, como un correo o un resumen narrativo. Forzarla a JSON empobrece el resultado y agrega complejidad. Tampoco conviene cuando el esquema cambia constantemente: cada cambio exige actualizar validaciones, componentes y pruebas.
Texto libre o estructura: una comparación
| Criterio | Texto libre | Salida estructurada |
|---|---|---|
| Lectura humana | Excelente | Regular, si no hay vista previa |
| Integración con componentes | Difícil: hay que interpretar | Directa, campo por campo |
| Manejo de errores | Vago: “no encontré nada” | Explícito: campo vacío o inválido |
| Riesgo de formato roto | No aplica | Existe; hay que validar |
| Mejor para | Resúmenes, correos, explicaciones | Formularios, tarjetas, tablas, flujos |
Un flujo práctico
- Define el esquema del resultado con campos, tipos y valores permitidos.
- Escribe el prompt con el esquema y un ejemplo válido.
- Valida cada respuesta antes de mostrarla.
- Si falla, reintenta una vez; si vuelve a fallar, muestra un estado de error con una acción clara.
- Registra los fallos para revisar qué campos son difíciles de extraer.
Ejemplo
Ejemplo ilustrativo: una app convierte capturas de tickets de soporte en tareas de diseño con el esquema de arriba. Como el esquema fija las tres severidades, la tarjeta nunca recibe un color que no existe. Aun así, el modelo etiqueta como “alta” un ticket que solo pide cambiar el tono de un gris. La interfaz muestra la severidad en un campo editable con la etiqueta “Sugerida por IA”, y la persona que revisa lo corrige con un clic. Si el equipo usara solo el prompt, sin función del proveedor, además tendría que validar que la severidad sea una de las tres y mostrar un estado de error cuando llegue “muy alta”. El diseñador gana dos cosas: un estado de error explícito y un campo que deja claro que el dato es una propuesta.
Errores comunes
- Confiar en que el modelo siempre devolverá JSON válido sin validar.
- Diseñar componentes para el caso feliz y olvidar los campos vacíos o inválidos.
- Mezclar texto libre con JSON en la misma respuesta.
- Cambiar el esquema sin versionarlo ni actualizar la interfaz.
- Usar salida estructurada para tareas que se leen mejor como texto.
Fuentes
- JSON, Wikipedia
- JSON Schema, Wikipedia
- Anthropic, “Structured outputs”: https://platform.claude.com/docs/en/build-with-claude/structured-outputs
- OpenAI, “Structured Outputs”: https://developers.openai.com/api/docs/guides/structured-outputs
- Google, “Structured output” (Gemini, Interactions API): https://aistudio.google.com/docs/structured-output