Cuando solicitás JSON en un prompt normal, el LLM frecuentemente retorna respuestas que no podés usar directamente.
Situación típica 1 — JSON envuelto en texto: pedís "dame los datos en formato JSON" y recibís "Claro, aquí tienes los datos: ```json {...}``` Como puedes ver, extraje el nombre y el email correctamente." El JSON está ahí, pero envuelto en explicaciones — si intentás procesarlo automáticamente, falla el parseo.
Situación típica 2 — Estructura inconsistente: ejecución 1 devuelve {"name": "Juan", "email": "..."}, ejecución 2 devuelve {"nombre": "Juan Garcia", "correo": "..."}, ejecución 3 anida todo en un objeto "usuario". Cada ejecución produce una estructura diferente — imposible de automatizar.
Situación típica 3 — Tipos mezclados: esperabas {"precio": 99.99, "disponible": true, "cantidad": 5} y recibiste {"precio": "99.99 euros", "disponible": "sí", "cantidad": "cinco"} — strings donde esperabas números y booleanos.
Por qué es importante: sin outputs estructurados consistentes, cada respuesta requiere limpieza manual antes de usarla, no podés alimentar los datos a otros sistemas (Excel, bases de datos, APIs), no podés comparar resultados entre ejecuciones, y la automatización es imposible.
Definí exactamente qué campos esperás, sus tipos, y cuáles son obligatorios.
Elementos del schema efectivo: nombres de campos exactos (nombre o name, email o correo), tipos de datos (string, number, boolean, array, null), opcionalidad (qué campos pueden ser null), y restricciones ("No añadas campos adicionales", "Usa solo estos valores para X").
Mostrar 1-2 ejemplos del formato exacto que esperás es más efectivo que describirlo.
Por qué funciona: el LLM ve el patrón exacto (precio como número, colores como array), elimina ambigüedad sobre formato de moneda y booleanos, y el ejemplo sirve como "contrato" implícito.
Reglas para ejemplos efectivos: usá datos realistas (no placeholders genéricos), incluí todos los tipos de campo (strings, números, arrays, nulls), y si hay casos límite (campo vacío, valor especial) inclúyelos también en el ejemplo.
El LLM tiende a "ser útil" añadiendo explicaciones. Debés prohibirlo explícitamente.
// Variantes: "restricción directa" (prohibí explicaciones), "formato de respuesta explícito" (definí qué está prohibido/permitido), o "rol restrictivo" ("Eres una API que solo retorna JSON"). Combinarlas es lo más robusto.
Definí explícitamente qué hacer cuando un dato no existe en el input.
| Situación | Técnica recomendada |
|---|---|
| Primera vez que definís el formato | Schema explícito + 1 ejemplo |
| El LLM añade texto fuera del JSON | Restricciones de formato estrictas |
| Resultados inconsistentes entre ejecuciones | Few-shot con 2-3 ejemplos diversos |
| El LLM inventa datos faltantes | Reglas explícitas para null/valores vacíos |
| Schema complejo con muchos campos | Schema + ejemplo + validación verbal de campos críticos |
| Outputs para uso en automatización | Todas las técnicas combinadas |
Objetivo: crear prompts que extraigan datos estructurados de diferentes tipos de texto y verificar consistencia entre ejecuciones.
Contexto inicial: usá Claude.ai, ChatGPT, o cualquier interfaz de LLM. No necesitás código ni APIs.
Ejecutá primero el prompt básico (sin técnicas):
Anotá: ¿el JSON es válido (empieza con {, termina con })? ¿hay texto explicativo antes o después? ¿qué nombres usó para los campos? Ejecutá el mismo prompt 2 veces más y comparás: ¿son idénticos los campos?
Ahora ejecutá el prompt estructurado, con schema, ejemplo, reglas de formato y de campos faltantes combinados (usá la plantilla completa de la sección anterior, con schema para nombre, cargo_actual, años_experiencia (number), empresa_actual, empresas_anteriores (array), email, linkedin (nullable), skills (array), y el mismo texto de Ana Martínez como input). Comparás: ¿el output es JSON puro sin texto extra? ¿años_experiencia es número (7) o string ("7 años")? ¿los campos coinciden exactamente con el schema?
Creá un prompt para extraer varios items de una lista, con un array anidado en el schema:
Verificá: ¿los precios son números (19.99) o strings ("19,99€")? ¿usó punto decimal en lugar de coma? ¿"últimas unidades" se interpretó correctamente como disponible?
Probá cómo maneja el LLM información incompleta, con un schema donde casi todo puede ser null y el input solo trae el nombre:
// Resultado esperado: {"nombre": "Carlos", "email": null, "telefono": null, "cargo": null, "empresa": null}
Verificá: ¿el LLM inventó un email o teléfono, o respetó el null?
Ejecutá este prompt 5 veces (refrescando la conversación cada vez):
Registrá categoría, prioridad y resumen de cada una de las 5 ejecuciones. Analizá: ¿cuántas dieron exactamente el mismo resultado? ¿la categoría fue consistente (todas "technical")? ¿la prioridad fue consistente (todas "alta")? Si hay variación, añadí un ejemplo few-shot y repetí el test.
Escenario: extraer información de una factura. Diseñá vos el prompt completo (con las 4 técnicas) para este schema:
numero_factura: stringfecha: string (formato YYYY-MM-DD)cliente: objeto con nombre y niflineas: array de objetos con descripción, cantidad, precio_unitario, totalsubtotal, iva (porcentaje), total: number| Si ves esto... | Causa | Solución |
|---|---|---|
Usa ```json``` markdown | Tendencia a formatear código | Añadí: "NO uses bloques de código markdown" |
| Campos con nombres diferentes al schema | Schema no lo suficientemente explícito | Mostrá un ejemplo completo del output esperado |
| Números como strings ("100" vs 100) | Ambigüedad de tipos | Especificá: "precio es number, no string" |
| Inventa datos que no existen | No definiste manejo de ausencias | Añadí: "Si no está en el texto, usa null. NUNCA inventes." |
| Resultados diferentes en cada ejecución | Falta de ejemplos y schema | Añadí 2 ejemplos few-shot con casos diversos |
Concepto central: "Dame JSON" no es suficiente. Un prompt para structured output necesita: schema explícito (qué campos y tipos), ejemplo concreto (cómo se ve), restricciones de formato (solo JSON, nada más), y manejo de ausencias (qué hacer si falta un dato).
Para recordar: