¿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 responder a partir de fuentes recuperadas

Después de esta lección: Puedo construir un prompt con lo que se encontró y responder solo a partir de eso.

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

Una respuesta con sus fuentes

La generación aumentada con recuperación (en inglés RAG) primero encuentra pasajes. Después pide a un modelo de lenguaje que responda solo con ellos. Importa porque un modelo que responde de memoria puede sonar seguro y equivocarse, mientras que uno que muestra sus fuentes se puede comprobar.

Alguien pregunta a qué hora abre la biblioteca el sábado. La web encuentra dos pasajes, pregunta a un modelo y muestra la respuesta con el pasaje del que sale.

Al final de esta lección

Nota

Puedo construir un prompt con lo que se encontró y responder solo a partir de eso.

Palabras clave

PalabraQué significaEjemplo
Contextolos pasajes que pones en el prompt
Promptel texto que envías a un modelo
Citauna marca que apunta a un pasaje[1]
Fundadabasada solo en los pasajes dados
Negativauna respuesta que dice que no sabe

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

Pon los pasajes en el prompt

El modelo no ha leído tus documentos. Por eso el prompt los lleva. Numera cada pasaje para que el modelo pueda señalar uno. Luego añade la pregunta y las reglas.

Pon pocos pasajes y cortos. Cada palabra de más se paga, y un prompt largo hace la respuesta más difícil de comprobar.

Ejemplo resuelto: las partes del prompt

ParteEjemploPara qué sirve
ReglaResponde solo con los pasajes de abajoMantiene la respuesta fundada
Regla de citaCita cada pasaje que uses así: [1]Hace la respuesta comprobable
SalidaSi no, responde exactamente: No lo séEvita una respuesta inventada
Pasajes[1] El sábado la biblioteca abre a las 10:00Los únicos hechos permitidos
Pregunta¿A qué hora abre la biblioteca el sábado?Lo que hay que responder

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

Comprueba lo que vuelve

Un prompt pide. No obliga. El modelo puede citar un pasaje que no existe, añadir un hecho que no se le dio o olvidarse de citar.

Por eso el programa comprueba. Busca las marcas de cita y mira cada una. Una respuesta que no cita nada no se muestra como con fuente.

Ejemplo resuelto: qué hacer con cada respuesta

La respuestaLo que hace el programa
Cita [1] y el pasaje 1 existeMostrarla con la fuente del pasaje 1
Cita [7] y hay dos pasajesNo fiarse de ella
No cita nadaNo mostrarla como con fuente
No lo sé.Mostrar eso, sin fuentes

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

Pregunta una vez y comprueba la respuesta

Los siguientes Run escriben dos archivos y después hacen una sola llamada corta. El primero, model.js, envía el prompt al modelo del laboratorio. Si el modelo no responde, muestra Muestra grabada y usa una respuesta escrita en el script.

El segundo, answer.js, construye el prompt, pregunta, busca las citas y dice si la respuesta es una negativa. Nada personal va en un prompt.

Escribe 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.

Escribe 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.

Escribe el script de respuesta, parte 1

Comando
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const { ask } = require(\"./model\");' '// Los pasajes que encontró una recuperación, escritos aquí para que el Run cueste una llamada corta.' 'const passages = [' '  { source: \"horario-finde\", text: \"El sábado la biblioteca abre a las 10:00 y cierra a las 14:00. El domingo está cerrada.\" },' '  { source: \"horario-semana\", text: \"La biblioteca abre a las 9:00 y cierra a las 18:00 de lunes a viernes.\" },' '];' > answer.js"

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

Escribe el script de respuesta, parte 2

Comando
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const question = \"¿A qué hora abre la biblioteca el sábado?\";' 'function buildPrompt(question, passages) {' '  const lines = [\"Responde solo con los pasajes de abajo. Cita cada pasaje que uses así: [1]. Si los pasajes no contienen la respuesta, responde exactamente: No lo sé.\", \"\"];' '  passages.forEach(function (one, i) { lines.push(\"[\" + (i + 1) + \"] \" + one.text); });' '  lines.push(\"\", \"Pregunta: \" + question);' '  return lines.join(\"\n\");' '}' >> answer.js"

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

Escribe el script de respuesta, parte 3

Comando
docker exec -w /home/node/project agent sh -c "printf '%s\n' '// Muestra grabada, usada solo si ningún modelo responde.' 'const sample = \"Abre a las 10:00 el sábado [1].\";' 'function citedSources(reply) {' '  const found = [];' '  (reply.match(/\[(\d+)\]/g) || []).forEach(function (mark) {' '    const one = passages[Number(mark.slice(1, -1)) - 1];' '    if (one && found.indexOf(one.source) < 0) found.push(one.source);' '  });' '  return found;' '}' >> answer.js"

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

Escribe el script de respuesta, parte 4

Comando
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'async function main() {' '  const prompt = buildPrompt(question, passages);' '  console.log(prompt);' '  const reply = await ask([{ role: \"user\", content: prompt }], sample, 120);' '  console.log(\"Respuesta:\", reply);' '  const cited = citedSources(reply);' '  console.log(\"Fuentes:\", cited.length > 0 ? cited.join(\", \") : \"ninguna citada\");' '  console.log(\"Dice no lo sé:\", /no lo sé/i.test(reply) ? \"sí\" : \"no\");' '}' 'main();' >> answer.js"

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

Ejecútalo y lee la respuesta

Comando
docker exec -w /home/node/project agent node answer.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íneaQué puede mostrar
El promptLas reglas, dos pasajes numerados y la pregunta
RespuestaAbre a las 10:00 el sábado [1].
Fuenteshorario-finde
Dice no lo séno

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

Un error frecuente

Advertencia

Mucha gente cree que decirle a un modelo que use solo los pasajes hace que lo cumpla. La regla reduce el riesgo de una respuesta inventada. No lo elimina. Conserva la comprobación y cambia la pregunta por una que los pasajes no cubran, para ver funcionar la salida.

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.