Datos estructurados: extraer, clasificar, normalizar
Objetivos de este capítulo
- Extraer información precisa desde texto libre con un esquema estricto
- Clasificar en lote con una taxonomía cerrada y definiciones por categoría
- Normalizar los valores y enrutar los casos dudosos hacia una revisión humana
El yacimiento escondido en el texto libre
Tras la feria profesional de Lyon, Sofía trae un botín engorroso: 80 emails de prospectos, notas de conversaciones tomadas al vuelo, y el archivo de las 200 reseñas de clientes del trimestre que duerme desde el capítulo 4. Toda esa materia contiene datos valiosos — quién pide una demo, qué restaurante, qué tamaño de equipo, qué nivel de urgencia — pero encerrados en texto libre, ilegible para una hoja de cálculo. ¿Reintroducirlos a mano? Dos días. ¿Hacerlos extraer por un prompt bien diseñado? Una hora, verificación incluida.
Ese es el oficio de este capítulo: transformar texto libre en datos estructurados fiables. El capítulo 4 puso el ladrillo de base — el JSON estricto con esquema. Ahora vamos a industrializarlo: extracción multicampo, clasificación con taxonomía cerrada, normalización de valores, procesamiento en lote, y sobre todo el enrutamiento de los casos dudosos — porque la diferencia entre un juguete de demo y una herramienta de producción se juega por completo en los casos que no caben en las casillas.
La extracción: un esquema, reglas por campo
La extracción consiste en localizar en un texto información precisa y guardarla en campos definidos. La calidad depende de tres elementos que ya conoces por separado: un esquema exacto (capítulo 4), una regla de no invención (capítulo 6), y — la novedad — unas reglas por campo: para cada campo, qué se extrae, en qué forma, y qué poner cuando la información está ausente.
Extraes datos de contacto desde emails de prospectos, para el equipo comercial de un editor de software de horarios para restaurantes.
Para cada email entre delimitadores, devuelve ÚNICAMENTE un objeto JSON:
{
"nombre": "nombre y apellido, o null si ausente",
"establecimiento": "nombre del restaurante o grupo, o null",
"tamano_equipo": "número entero de empleados, o null si no se menciona",
"peticion": "demo" | "tarifas" | "pregunta" | "otro",
"urgencia": "alta" | "normal",
"cita_clave": "la frase del email que justifica el campo peticion"
}
Reglas:
- No inventes NUNCA un valor: información ausente = null.
- tamano_equipo: únicamente si hay un número escrito; «un equipo grande» = null.
- urgencia = alta únicamente si se menciona un plazo explícito.
- cita_clave: copia exacta del texto, sin reformular.
--- EMAIL ---
{{email}}
--- FIN ---El campo cita_clave es el truco más rentable de este prompt: al exigir la frase exacta que justifica la clasificación, haces cada línea auditable en dos segundos — la cita encaja o no encaja — y reduces la invención, porque el modelo debe anclar su respuesta en el texto. Es el mismo principio que el razonamiento verificable del capítulo 3, trasladado a los datos. En cuanto a las reglas por campo, zanjan de antemano las ambigüedades que de otro modo descubrirías en producción: qué hacer con «un equipo grande», qué merece urgencia «alta».
La clasificación: una taxonomía cerrada y definida
Clasificar es colocar cada elemento en una categoría de una lista cerrada. El error clásico es dar los nombres de las categorías sin definirlas: «clasifica estas reseñas en: servicio, producto, precio, otro». El modelo tiene entonces su propia idea de la frontera entre «servicio» y «producto» — y cambia de una reseña a otra. Una taxonomía profesional define cada categoría, da un ejemplo, y precisa las reglas de desempate.
Clasifica cada reseña de cliente en UNA categoría de esta lista cerrada:
- "funcionalidad": la reseña trata de lo que el software hace o no hace. Ej.: «imposible exportar el horario en PDF».
- "ergonomia": la reseña trata de la facilidad de uso. Ej.: «tardé 3 días en encontrar dónde cambiar un turno».
- "soporte": la reseña trata de la ayuda recibida del equipo. Ej.: «respuesta en 10 minutos, problema resuelto».
- "precio": la reseña trata del coste o de la relación calidad-precio.
- "otro": nada de lo anterior se aplica claramente.
Reglas de desempate:
- Si la reseña toca varias categorías, elige la de la frase más desarrollada y anota las demás en "categorias_secundarias".
- En caso de duda real, usa "otro" con "confianza": "baja" — no fuerces nunca una categoría.
Formato por reseña: { "id": N, "categoria": "...", "categorias_secundarias": [...], "confianza": "alta|baja", "cita_clave": "..." }Tres mecanismos a retener. Las definiciones con ejemplos estabilizan las fronteras — es few-shot (capítulo 2) aplicado a las categorías. La regla de desempate trata el caso multitema, inevitable en reseñas reales. Y el campo confianza da al modelo una salida honorable cuando duda: sin ella, fuerza una categoría con aplomo, y tus estadísticas mienten en silencio. Un «otro, confianza baja» es un dato honesto; un «precio» adivinado es un dato tóxico.
Normalizar: el dato limpio a la primera
Extraer no basta: hace falta que los valores sean comparables. Si una extracción devuelve «15», «quince empleados» y «~15 pers.», tu hoja de cálculo se hunde bajo las variantes y cada ordenación se vuelve falsa. La normalización se prescribe en el prompt, campo por campo: fechas en formato AAAA-MM-DD, importes en número sin símbolo, teléfonos en cifras seguidas, nombres de establecimiento en su caja original pero sin comillas. Cada formato precisado de antemano es una hora de limpieza ahorrada después.
Una trampa específica merece la advertencia: las conversiones silenciosas. Pide «el número de empleados» y el modelo podría convertir «una decena» en 10 — una invención disfrazada de normalización. La regla «únicamente si hay un número escrito» del prompt de extracción existe para eso. El principio general: la normalización cambia la forma de un valor presente, nunca crea un valor ausente. La frontera entre ambos debe estar escrita negro sobre blanco en tus reglas por campo.
Antes/después: la pasada de normalización en la práctica
La normalización puede integrarse en las reglas por campo desde la extracción — es lo ideal — pero también funciona como pasada separada, muy útil cuando heredas datos ya extraídos pero sucios: una exportación de formulario, una vieja hoja de cálculo rellenada a mano, el archivo de contactos de la feria tecleado por tres personas distintas. El prompt de normalización es entonces una etapa de cadena (capítulo 7) por derecho propio:
Normalizas fichas de prospectos introducidas manualmente, sin modificar el fondo.
Para cada línea entre delimitadores, devuelve la versión normalizada:
- fecha_contacto: formato AAAA-MM-DD. «el martes pasado» o fecha ambigua = null.
- telefono: solo cifras, sin espacios ni puntos. Número incompleto = null.
- establecimiento: caja original, sin comillas ni «Restaurante» redundante como prefijo.
- tamano_equipo: número entero únicamente si figura un número en la ficha, si no null.
- ciudad: nombre completo, primera letra en mayúscula, sin código postal.
Reglas absolutas:
- Cambias la FORMA de los valores presentes, no creas NUNCA un valor ausente.
- Añade un campo "alertas" que liste todo lo que te haya parecido ambiguo en la línea.
- Conserva el identificador de línea tal cual.
--- LÍNEAS ---
{{líneas ID ; fecha ; teléfono ; establecimiento ; tamaño ; ciudad}}
--- FIN ---El campo alertas juega aquí el papel que jugaba confianza en clasificación: una salida honorable para la duda. ¿«06.12.34» es un teléfono truncado? ¿«La Brasserie» y «Brasserie» son el mismo establecimiento? El modelo señala en lugar de decidir en silencio, y Sofía arbitra las alertas en bloque al final — unos minutos, frente a horas releyendo cada línea. Un dato normalizado sin pista de auditoría es un dato que se acaba reverificando entero el día de la primera duda.
Procesar en lote sin perder el hilo
Queda la cuestión de escala: 200 reseñas no se procesan en un solo prompt gigante. Más allá de cierto volumen, la calidad se degrada en mitad de la lista — la atención del modelo es mejor en los extremos, como se vio en el capítulo 4 — y una sola salida malformada puede arruinar el lote entero. La práctica robusta: paquetes de 10 a 20 elementos, cada uno con un identificador explícito, y una verificación por paquete antes de pasar al siguiente.
Los identificadores son el detalle que salva: numera tus entradas («RESENA-001», «RESENA-002») y exige el identificador en cada objeto de salida. Puedes entonces verificar mecánicamente que ninguna entrada ha sido saltada ni duplicada — el modelo a veces salta un elemento en pleno lote sin avisar. Cuenta las entradas, cuenta las salidas, compara los identificadores: tres verificaciones de diez segundos que atrapan las pérdidas silenciosas.
flowchart LR
T["Texto bruto: reseñas, emails, notas"] --> L["Lotes de 10 a 20 con identificadores"]
L --> X["Extracción y clasificación según esquema"]
X --> C{"¿Confianza alta y JSON válido?"}
C -->|"Sí"| D["Hoja de cálculo o panel de control"]
C -->|"No"| H["Cola de revisión humana"]
H -->|"Casos resueltos"| DLa red de seguridad: enrutar lo dudoso, verificar por muestreo
El diagrama de arriba contiene la decisión de arquitectura más importante del capítulo: los casos de confianza baja no van a la hoja de cálculo, van a una cola de revisión humana. De las 200 reseñas de Sofía, 14 salieron con confianza baja; las resolvió a mano en diez minutos. Las otras 186 eran fiables — lo verificó por muestreo: 15 reseñas sacadas al azar, cita comparada con el texto fuente, cero errores. Muestreo limpio, lote aceptado. Es el mismo espíritu que el juego de pruebas que sistematizaremos en el capítulo 9.
Si el muestreo revela errores, no corrijas las líneas una a una: busca el patrón. ¿Tres errores en reseñas irónicas? Añade una regla o un ejemplo few-shot de ironía al prompt y relanza el lote. Corregir la salida repara una vez; corregir el prompt repara todas las veces siguientes — es la lección de las plantillas del capítulo 5, aplicada a los datos. Y guarda la versión corregida del prompt en tu biblioteca, con sus casos de prueba.
Al final, el pipeline de Sofía cabe en una frase: lotes identificados, un esquema con reglas por campo, citas para auditar, un campo confianza para enrutar, un muestreo para validar. Cinco mecanismos simples — y el archivo de 200 reseñas que dormía desde hacía dos meses se convirtió, en una mañana, en un panel que la dirección consulta cada semana.
Contexto
Al volver de la feria de Lyon, el equipo comercial espera la lista cualificada de prospectos: quién quiere una demo, qué tamaño de establecimiento, qué urgencia. Sofía tiene 80 emails a granel. Quiere construir el pipeline de extracción completo — esquema, reglas por campo, lotes identificados, enrutamiento de los casos dudosos — y entregar una tabla fiable antes del viernes, con la prueba por muestreo de que los datos son correctos.
Instrucciones
- Elige un yacimiento de texto libre de tu día a día (emails, reseñas, notas, tickets) y lista los 5-6 campos que tendrían valor en una hoja de cálculo.
- Escribe el esquema JSON con una regla por campo: forma esperada, normalización, y valor en caso de ausencia (null, nunca invención).
- Añade un campo cita_clave y un campo confianza con su regla de uso: en caso de duda, confianza baja antes que categoría forzada.
- Numera 15-20 entradas reales, procésalas en un lote, y verifica mecánicamente: tantas salidas como entradas, identificadores todos presentes, JSON válido.
- Haz un muestreo de 5 líneas: compara cada cita con el texto fuente. Si hay errores, busca el patrón y corrige el prompt, no las líneas.
- Procesa a mano la cola de las confianzas bajas, entrega la tabla final — y guarda el prompt validado en tu biblioteca con sus casos de prueba.
En resumen
- La extracción fiable = esquema exacto + reglas por campo (forma, normalización, valor si ausente) + prohibición de inventar.
- El campo cita_clave ancla cada dato en el texto fuente: auditable en dos segundos, invención reducida.
- Una taxonomía profesional define cada categoría con un ejemplo y reglas de desempate — no solo nombres.
- El campo confianza da una salida honorable a la duda: «otro, confianza baja» vale más que una categoría forzada que falsea las estadísticas.
- La normalización cambia la forma de un valor presente, nunca crea un valor ausente.
- Procesa por lotes de 10-20 con identificadores, y verifica mecánicamente: recuento de salidas, identificadores, validez del JSON.
- Enruta los casos dudosos hacia una revisión humana y valida los lotes por muestreo; si hay errores, corrige el prompt (el patrón), no las líneas.
Quiz — comprueba tu comprensión
1. ¿Para qué sirve el campo cita_clave en un prompt de extracción?
2. ¿Por qué definir cada categoría de una taxonomía con un ejemplo?
3. ¿Qué hacer con un elemento que el modelo duda en clasificar?
4. ¿Cuál es el límite de la normalización?
5. ¿Por qué procesar 200 reseñas en lotes de 10-20 en lugar de un prompt gigante?
6. El muestreo revela 3 errores en reseñas irónicas. ¿Qué haces?