Capítulo 5: Structured Output — Respuestas que Tu Código Puede Consumir
Hasta ahora el modelo genera texto. Útil para chat, pero ¿qué pasa cuando necesitas datos estructurados?
Imagina: quieres que el modelo extraiga información de una descripción y la guarde en tu base de datos. O clasificar tickets de soporte. O generar un catálogo de productos.
Texto plano no sirve. Necesitas objetos tipados.
Código Primero
Eso es todo. El modelo retorna un objeto tipado, no texto.
¿Qué Acaba de Pasar?
- Output.object() le dice al SDK: "quiero un objeto, no texto"
- schema define la estructura con Zod
- El SDK internamente construye el prompt correcto para el modelo
- El modelo genera JSON válido
- El SDK lo valida contra el schema
- TypeScript infiere los tipos automáticamente
output.año es number, no string. output.generos es string[]. Sin parsing manual.
Introducción a Zod
Si no has usado Zod, es una librería de validación:
Combina dos cosas:
- Validación en runtime — verifica que los datos son correctos
- Tipos en compilación — TypeScript infiere tipos del schema
Patrones útiles para AI SDK:
| Método | Uso |
|---|---|
z.string() | Texto |
z.number() | Números |
z.boolean() | true/false |
z.array(z.string()) | Lista de strings |
z.object({...}) | Objetos anidados |
z.enum(['a', 'b']) | Opciones fijas |
.optional() | Campo opcional |
.describe('...') | Ayuda al modelo a entender |
Los 5 Tipos de Output
AI SDK v6 ofrece 5 formas de estructurar la salida:
| Tipo | Uso | Cuándo usarlo |
|---|---|---|
Output.text() | Texto plano | Default, conversaciones |
Output.object() | Objeto estructurado | Datos con schema fijo |
Output.array() | Lista de objetos | Catálogos, resultados múltiples |
Output.choice() | Selección entre opciones | Clasificación, categorías |
Output.json() | JSON sin validación | Datos flexibles |
Output.object() en Profundidad
El más usado. Puedes añadir metadatos para mejorar la precisión:
El .describe() en Zod es clave. Le dice al modelo qué esperas:
Output.choice() para Clasificación
Cuando necesitas clasificar en categorías fijas:
El tipo de output es "urgente" | "normal" | "bajo". TypeScript lo sabe.
Casos de uso
- Análisis de sentimiento:
['positivo', 'negativo', 'neutral'] - Categorización de productos:
['electrónica', 'ropa', 'hogar'] - Priorización:
['crítico', 'alto', 'medio', 'bajo'] - Routing:
['ventas', 'soporte', 'facturación']
Output.array() para Listas
Cuando necesitas múltiples resultados:
Streaming de Objetos Parciales
Con streamText, puedes ver el objeto construyéndose:
Verás algo como:
Nota importante: Los objetos parciales NO se pueden validar contra el schema durante streaming. El schema solo se valida cuando el objeto está completo.
Caso Práctico: Catálogo de Productos
Una tienda online necesita generar fichas de productos desde descripciones:
Cambio de v5 a v6: generateObject → generateText
En versiones anteriores existía generateObject. Ahora está unificado:
| v5 | v6 |
|---|---|
generateObject({ schema }) | generateText({ output: Output.object({ schema }) }) |
streamObject({ schema }) | streamText({ output: Output.object({ schema }) }) |
¿Por qué el cambio? Flexibilidad. Ahora puedes combinar structured output con tools, callbacks, y otras opciones de generateText.
Errores Comunes
| Problema | Causa | Solución |
|---|---|---|
| Output vacío o incompleto | Schema muy complejo | Simplificar, añadir .describe() |
| Tipos incorrectos | Modelo "inventa" | Usar z.coerce.number() para parsing |
| Campos faltantes | Ambigüedad | Marcar explícitamente con .optional() |
| JSON inválido | Modelo confundido | Mejorar el prompt, ser más específico |
Manejo de errores
Resumen
| Concepto | Qué aprendiste |
|---|---|
Output.object() | Genera objetos tipados con schema Zod |
Output.choice() | Clasificación entre opciones fijas |
Output.array() | Listas de objetos estructurados |
partialOutputStream | Streaming de objetos parciales |
.describe() | Mejora precisión del modelo |
| Zod schemas | Validación + tipos en una sola definición |
En una frase
Structured Output: Convierte respuestas del modelo en objetos TypeScript que tu código puede consumir directamente.
Ahora sabemos cómo obtener datos estructurados del modelo. Pero hay un límite: solo puede generar información que ya "conoce". ¿Qué pasa si necesita consultar tu base de datos, llamar una API, o ejecutar código? Eso es exactamente lo que veremos en el siguiente capítulo: Tools.
¿Ya compraste el libro?
Si compraste el libro y no encuentras tu email de descarga, ingresa tu email y te enviamos un nuevo enlace.
