¿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 montar una cadena de texto a registros

Después de esta lección: Puedo montar una pequeña cadena que lleve de texto desordenado a registros comprobados.

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

Un montón de mensajes

Una cadena de texto a registros convierte mensajes desordenados en registros comprobados que un programa puede guardar. Importa porque cada paso que has visto es pequeño y un trabajo real los necesita todos juntos.

La oficina de un instituto recibe un montón de peticiones de material en texto libre. Alguien las quiere como filas: el artículo, cuántos y si es urgente. Nadie quiere teclear trescientas.

Al final de esta lección

Nota

Puedo montar una pequeña cadena que lleve de texto desordenado a registros comprobados.

Palabras clave

PalabraQué significa
Cadenapasos que se pasan cada uno su resultado
Loteun grupo de textos tratados juntos
Rechazardejar un texto fuera, con una razón
Tasa de rechazola parte de textos que se rechazaron
Guardarescribir los registros comprobados en algún sitio
Datos personalesdatos que identifican a una persona

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

Cuatro pasos, uno tras otro

Cada mensaje pasa por los mismos pasos. Extraer: pedir los campos al modelo. Validar: comprobar el registro con el esquema. Reparar: si falla, preguntar una vez más con el fallo. Guardar: escribir el buen registro.

Un mensaje que sigue fallando se rechaza. No se guarda y tampoco se pierde: conservas el texto y la razón.

Cuenta los rechazos y di por qué

Un rechazo es información. Conserva el texto y la razón, y calcula la tasa de rechazo. Si es alta, la instrucción o el esquema necesitan trabajo.

Ten cuidado con los datos personales. Envía al modelo solo el texto que necesita. Escribe en el registro la razón, no el texto de un mensaje sobre una persona.

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 la cadena, parte 1

Comando
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const fs = require(\"fs\");' 'const { ask } = require(\"./model\");' '' 'const texts = [' '  \"Por favor, enviad 12 lápices al aula de plástica, no es urgente.\",' '  \"Necesitamos 3 cajas de tizas hoy, cuanto antes.\",' '  \"¿Alguien me puede decir dónde está la sala de profesores?\",' '];' '// Muestras grabadas, usadas solo si ningún modelo responde: una respuesta limpia, una que pide una' '// reparación y un mensaje sin pedido, que se rechaza.' 'const samples = [' '  JSON.stringify({ item: \"lápices\", quantity: 12, urgent: false }),' '  [\"Aquí tienes: \" + JSON.stringify({ item: \"tizas\", quantity: \"tres\", urgent: true }), JSON.stringify({ item: \"tizas\", quantity: 3, urgent: true })],' '  [JSON.stringify({ item: null, quantity: null, urgent: false }), \"No encuentro ningún pedido en este mensaje.\"],' '];' > pipeline6.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 cadena, parte 2

Comando
docker exec -w /home/node/project agent sh -c "printf '%s\n' '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; }' '}' '' '// El primer problema, o un texto vacío cuando el registro es bueno.' 'function problemOf(record) {' '  if (record === null) return \"no es JSON\";' '  if ((typeof record.item === \"string\") === false || record.item === \"\") return \"item no valido\";' '  if (Number.isInteger(record.quantity) === false || record.quantity < 1 || record.quantity > 20) return \"quantity no valida\";' '  if ((typeof record.urgent === \"boolean\") === false) return \"urgent no valido\";' '  return \"\";' '}' >> pipeline6.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 cadena, parte 3

Comando
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const PROMPT = \"Extrae item, quantity (de 1 a 20) y urgent (true o false) de este mensaje. Responde solo con el JSON.\n\nMensaje: \";' '' 'async function handle(text, sample) {' '  const messages = [{ role: \"user\", content: PROMPT + text }];' '  let reply = await ask(messages, sample, 80);' '  let problem = problemOf(pullJson(reply));' '  if (problem.length > 0) {' '    // Una reparación: devolver la mala respuesta y el problema, y preguntar una vez más.' '    messages.push({ role: \"assistant\", content: reply });' '    messages.push({ role: \"user\", content: \"Corrige este problema y responde solo con el JSON: \" + problem });' '    reply = await ask(messages, sample, 80);' '    problem = problemOf(pullJson(reply));' '  }' '  return { record: pullJson(reply), problem: problem };' '}' >> pipeline6.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 cadena, parte 4

Comando
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'async function main() {' '  const saved = [];' '  const rejected = [];' '  for (let at = 0; at < texts.length; at = at + 1) {' '    const result = await handle(texts[at], samples[at]);' '    if (result.problem.length > 0) rejected.push({ text: texts[at], why: result.problem });' '    else saved.push({ item: result.record.item, quantity: result.record.quantity, urgent: result.record.urgent });' '  }' '  fs.writeFileSync(\"records.json\", JSON.stringify(saved, null, 2));' '  console.log(\"Guardados \" + saved.length + \" registros en records.json\");' '  for (const one of rejected) console.log(\"Rechazado: \" + one.text + \" (\" + one.why + \")\");' '  console.log(\"Tasa de rechazo: \" + Math.floor(rejected.length * 100 / texts.length) + \" por ciento\");' '}' 'main();' >> pipeline6.js"

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

Ejecutarla con tres mensajes

Comando
docker exec -w /home/node/project agent node pipeline6.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
GuardadosGuardados 2 registros en records.json, por ejemplo
RechazadoEl mensaje sobre la sala de profesores, con una razón como item no valido
Tasa de rechazoTasa de rechazo: 33 por ciento si se rechaza uno de los tres

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

Un error frecuente

Advertencia

Mucha gente cree que un mensaje rechazado significa que la cadena falló. Rechazar es correcto cuando un mensaje no trae ningún pedido. Lo que falla es rechazar sin contar ni decir por qué.

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.