¿Te resulta más fácil leer con fondo crema, un tono de color, más contraste o un texto más grande? Elige tus colores y tu texto una sola vez, para todas las páginas.

Lección gratuita

Cómo extraer datos de un texto

Después de esta lección: Puedo convertir un párrafo en un registro sin inventar ningún valor.

Lección de 60 min7 comandosLaboratorio de agente de programación con IA: usa opencode para explicar y corregir código, y comprueba su trabajo

El teléfono que nadie dio

Extraer un registro de un texto es pedir a un modelo que lea un párrafo y rellene un conjunto fijo de campos. Importa porque el modelo tapará un hueco con una suposición si no le dices que no lo haga.

La secretaría de una facultad recibe una petición de aula con un nombre, un aula y una fecha, pero sin teléfono. La herramienta muestra un teléfono igualmente. Nadie lo dio: el modelo se lo inventó.

Al final de esta lección

Nota

Puedo convertir un párrafo en un registro sin inventar ningún valor.

Palabras clave

PalabraQué significaEjemplo
Extraersacar datos con nombre de un texto
Campoun dato con nombre dentro de un registrodate
Nullel valor que dice que un campo no está
Texto fuenteel párrafo de donde deben salir los datos
Ancladohallado en el texto fuente, no adivinado
Completitudla parte de campos que tienen valor

Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.

Nombra los campos y permite null

Di exactamente qué campos quieres y el tipo de cada uno. Luego di qué hacer cuando un dato no está en el texto: usar null, sin adivinar nunca.

Sin esa regla, un modelo puede rellenar todos los campos, porque un registro lleno parece una buena respuesta. Dale permiso para dejar un hueco.

Ejemplo resuelto: un mensaje, cinco campos

Campo¿Está en el mensaje?El valor correcto
nameSí: «me llamo María García»María García
roomSí: «el aula B12»B12
dateSí: «2026-11-20»2026-11-20
studentsSí: «24 estudiantes»24
phoneNonull

Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.

Comprueba que cada valor está anclado

No confíes solo en la instrucción. Después de la respuesta, compara cada valor con el texto fuente. Si el valor no aparece en él, trátalo como inventado y ponlo en null.

Esta comprobación es sencilla y tiene un punto débil: un número 2 de más aparecería dentro de 2026-11-20 y pasaría. Una comprobación más fina compara palabras enteras. Aun así detecta el teléfono inventado.

Escribir la ayuda del modelo, parte 1

Comando
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const base = process.env.AI_URL || \"http://ai:4000\";' 'async function ask(messages, sample, max) {' '  try {' '    const res = await fetch(base + \"/v1/chat/completions\", {' '      method: \"POST\",' '      headers: { \"content-type\": \"application/json\", authorization: \"Bearer lab\" },' '      body: JSON.stringify({ model: \"lab\", messages: messages, max_tokens: max || 200 }),' '      signal: AbortSignal.timeout(30000),' '    });' '    if (res.ok === false) throw new Error(\"estado \" + res.status);' '    return (await res.json()).choices[0].message.content;' > model.js"

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Escribir la ayuda del modelo, parte 2

Comando
docker exec -w /home/node/project agent sh -c "printf '%s\n' '  } catch (error) {' '    console.log(\"Muestra grabada: ningún modelo respondió (\" + error.message + \").\");' '    const list = [].concat(sample);' '    const turn = messages.filter(function (m) { return m.role === \"assistant\"; }).length;' '    return list[Math.min(turn, list.length - 1)];' '  }' '}' 'module.exports = { ask };' >> model.js"

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Escribir el extractor, parte 1

Comando
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const { ask } = require(\"./model\");' '' 'const source = \"Hola, me llamo María García. Quisiera reservar el aula B12 el 2026-11-20. Seremos 24 estudiantes y 3 profesores. Gracias por responder por correo.\";' 'const fields = [\"name\", \"room\", \"date\", \"students\", \"phone\"];' '' 'function pullJson(text) {' '  const start = text.indexOf(\"{\");' '  const end = text.lastIndexOf(\"}\");' '  if (start === -1 || end < start) return null;' '  try { return JSON.parse(text.slice(start, end + 1)); } catch (error) { return null; }' '}' > extract4.js"

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Escribir el extractor, parte 2

Comando
docker exec -w /home/node/project agent sh -c "printf '%s\n' '// Conservar un valor solo si aparece de verdad en el texto fuente.' 'function grounded(record, source, fields) {' '  const result = {};' '  for (const name of fields) {' '    const value = record === null ? null : record[name];' '    if (value === null || value === undefined || value === \"\") {' '      result[name] = null;' '      console.log(name + \": null (falta)\");' '    } else if (source.toLowerCase().includes(String(value).toLowerCase())) {' '      result[name] = value;' '      console.log(name + \": \" + value + \" (conservado)\");' '    } else {' '      result[name] = null;' '      console.log(name + \": \" + value + \" (no está en el texto, descartado)\");' '    }' '  }' '  return result;' '}' >> extract4.js"

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Escribir el extractor, parte 3

Comando
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const prompt = \"Extrae estos campos del mensaje como un objeto JSON: name (texto), room (texto), date (texto, año-mes-día), students (un número entero), phone (texto). Si un campo no está en el mensaje, usa null. No adivines nunca. Responde solo con el JSON.\n\nMensaje: \" + source;' '// Muestra grabada, usada solo si ningún modelo responde. Inventa un teléfono a propósito.' 'const sample = JSON.stringify({ name: \"María García\", room: \"B12\", date: \"2026-11-20\", students: 24, phone: \"612 345 678\" });' >> extract4.js"

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Escribir el extractor, parte 4

Comando
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'async function main() {' '  const reply = await ask([{ role: \"user\", content: prompt }], sample, 150);' '  const record = grounded(pullJson(reply), source, fields);' '  let filled = 0;' '  for (const name of fields) {' '    if (record[name] === null) continue;' '    filled = filled + 1;' '  }' '  console.log(\"Rellenos: \" + filled + \" de \" + fields.length);' '}' 'main();' >> extract4.js"

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Ejecutar el extractor

Comando
docker exec -w /home/node/project agent node extract4.js

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Una salida posible

LíneaLo que puede mostrar
name, room, date, studentsCada uno con un valor y (conservado)
phonenull (falta), o un valor marcado (no está en el texto, descartado)
RellenosRellenos: 4 de 5 si el modelo solo halló los cuatro datos

Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.

Un error frecuente

Advertencia

Mucha gente cree que un campo lleno es mejor que uno vacío. Un valor inventado se parece a uno real, y nadie piensa en comprobarlo. Un null dice con claridad que una persona debe mirarlo.

Sobre este laboratorio y su código: Laboratorio de agente de programación con IA: usa opencode para explicar y corregir código, y comprueba su trabajo

¿Enseñas a una clase? Asigna este módulo a tus alumnos con guía del profesor, tareas con corrección automática y un laboratorio para cada alumno.