Contenido del curso
Estructura tus datos
Construye agentes
Despliega en producción
Outputs estructurados con JSON mode
Resumen
Cuando conectas Claude con código, aparece un problema incómodo: el modelo puede responder correctamente y aun así tu programa no logra usar esa respuesta. La solución es pedirle a Claude que responda en formato JSON y validar la estructura con Pydantic en Python o Zod en TypeScript. Esto le sirve a cualquier desarrollador que integre modelos de lenguaje dentro de aplicaciones reales.
Por qué una respuesta en texto libre rompe tu código
Imagina que le pides el total de una factura y Claude responde: "El total es de 1.250 dólares". Para un humano es impecable, pero para tu programa es un dolor de cabeza [00:20].
Tu código tiene que escarbar en esa frase para extraer el número y cruzar los dedos para que la próxima respuesta venga redactada igual. Ahí está el riesgo: una respuesta en lenguaje natural es impredecible.
Lo que necesitas es lo contrario: un formato fijo y predecible que tu programa lea sin adivinar. Y aquí viene lo interesante, eso lo consigues con JSON más una capa de validación.
¿Por qué usar JSON en las respuestas de un modelo de lenguaje? Porque te da una estructura fija de claves y valores que tu programa lee directamente, sin tener que interpretar frases ni extraer números a mano de un texto libre.
Cómo se define el modelo de datos con Pydantic
En el archivo main.py de la clase siete empezamos con los imports: annotations, JSON, OS y Anthropic, que ya veníamos usando. Lo nuevo es Pydantic, de donde importamos el BaseModel [02:00].
El BaseModel permite validar el tipo de dato y definir cada elemento de la estructura. Con el modelo claude-sonnet-4.6 ya seleccionado, se crean dos clases que heredan de BaseModel:
- Invoice Item: contiene description, quantity, unit price y total.
- Invoice Data: contiene provider, date, currency, total y una lista de items.
Cada campo tiene su tipo declarado, igual que harías en TypeScript pero aquí con Pydantic. El quantity es un float, el unit price es un float y el total también es un float, que valdrá cero en caso de que no llegue el dato [02:40].
Qué tipo lleva cada campo del invoice
En el Invoice Data, provider, date y currency son strings, el total es un número y los items son una lista del tipo Invoice Item definido arriba [03:10].
Esta declaración de tipos es la que le permite a Pydantic revisar la estructura apenas llega el dato. Si algo no cuadra, te avisa en ese momento, no mucho después donde el error es difícil de rastrear.
Cómo escribir el prompt para forzar un JSON válido
El prompt es donde le explicas a Claude el formato exacto que necesitas. Le pides que extraiga la información de la factura y la devuelva como un JSON válido [03:30].
Las instrucciones clave del prompt son:
- Usar exactamente las claves en inglés: provider, date, currency, total e items.
- No traducir esas claves.
- Respetar la estructura donde items es un array de objetos con description, quantity, unit price y total.
- Responder únicamente con el JSON, sin explicaciones ni detalles fuera de él.
Esta precisión evita que el modelo improvise nombres de campos o agregue texto que después tendrías que limpiar.
¿Cómo hago que un modelo responda solo con JSON? En el prompt le indicas que devuelva únicamente el JSON, sin explicaciones, usando claves exactas, y en el código limpias el texto y remueves el prefijo json que suelen agregar los modelos.
Qué pasa dentro de la función main
La función main arranca validando la API key. Si no existe, levanta un error de inmediato [04:20].
Después simulamos recibir una factura como texto plano, tal como llegaría en un mensaje de WhatsApp: "Factura de ACME, sociedad anónima... Dos horas de consultoría, 50 dólares cada una, atendido por Juan Pérez en la sede de Chapinero. Debes pagar 100 dólares". Toda la información está ahí, pero sin estructura [04:40].
Luego se define el client de Anthropic con la API key y se llama al endpoint messages create con el modelo definido, un max tokens de 500, el system con el prompt y un mensaje de rol usuario cuyo contenido es el texto de la factura [05:00].
Cómo se limpia y valida la respuesta final
Antes de procesar, el código toma el texto raw y lo une para limpiar espacios o textos alrededor. Aplica reglas para que empiece y cierre con las comillas correctas y remueve el prefijo json que los modelos suelen anteponer al formato [05:40].
Con el texto limpio, se valida de nuevo que la data respete el modelo definido arriba y se imprime todo con model dump JSON. La respuesta llega estructurada:
- provider: ACME, sociedad anónima.
- currency: dólares americanos.
- total: 100.
- quantity: 2, porque estaba en horas.
- unit price: 50.
En la descripción, Claude incluyó "Consultoría atendida por Juan Pérez en la sede de Chapinero". No hacía falta tanto detalle, pero lo tomó como parte de la descripción [06:40].
Con esto ya tienes datos estructurados listos para consumir desde otra aplicación. Ya no buscas un número dentro de una frase ni lo sacas a pulso: el formato quedó resuelto. Lo que sigue es lograr que Claude extraiga bien la información incluso cuando el documento no coopera.
¿Has tenido que limpiar respuestas de un modelo a mano? Cuéntanos cómo lo resolviste en los comentarios.