Mostrar de dónde viene una respuesta
Una cita es una marca en una respuesta que señala la fuente de la que salió. Importa porque la gente se fía más de una respuesta que puede comprobar, y tu programa puede comprobar las marcas.
El chatbot de una biblioteca dice que un libro devuelto tarde cuesta diez céntimos al día [2]. El lector mira la fuente 2 y ve la misma regla.
Al final de esta lección
Nota
Puedo mostrar qué fuente usó una respuesta.
Palabras clave
| Palabra | Qué significa | Ejemplo |
|---|---|---|
| Fuente | un pasaje de texto que la respuesta puede usar | |
| Cita | un enlace de la respuesta a su fuente | |
| Marca | el número entre corchetes que hace la cita | [2] |
| Fundada | basada en las fuentes que diste | |
| Fuente sin usar | una fuente que ninguna marca señala |
Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.
Numera las fuentes y pide marcas
Escribe cada fuente en el mensaje con un número: [1], [2], [3]. Luego pide al modelo que use solo esas fuentes y que escriba el número después de cada dato.
Las fuentes de aquí son pasajes que escribiste en el script. Buscar fuentes reales entre muchos documentos es otro tema: aquí las escribes tú. La respuesta es fundada cuando se queda en lo que le diste.
Ejemplo resuelto: fuentes y una respuesta
| Parte | Texto |
|---|---|
| Fuente [1] | Los socios pueden llevarse hasta seis libros durante tres semanas. |
| Fuente [2] | Un libro devuelto tarde cuesta diez céntimos al día. |
| Pregunta | ¿Cuántos libros puedo llevarme y cuánto es la multa por retraso? |
| Respuesta | Puedes llevarte seis libros [1]. Un libro devuelto tarde cuesta diez céntimos al día [2]. |
Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.
Comprueba que cada marca tiene fuente
Un modelo puede escribir [4] cuando solo hay tres fuentes. Tu programa puede detectarlo. Busca cada marca y compara cada número con la lista de ids de fuente.
Busca también las fuentes sin usar y las frases sin marca. Muestran lo que la respuesta dejó fuera.
Un error frecuente
Advertencia
Mucha gente cree que una marca prueba que la respuesta es cierta. Solo prueba que la fuente existe. El modelo puede citar la fuente equivocada para un dato. La comprobación es un primer filtro, y una persona sigue leyendo la fuente en lo que importa.
Escribir la ayuda del modelo, parte 1
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
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 comprobación de citas, parte 1
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const { ask } = require(\"./model\");' 'const SOURCES = [' ' { id: 1, text: \"Los socios pueden llevarse hasta seis libros durante tres semanas.\" },' ' { id: 2, text: \"Un libro devuelto tarde cuesta diez céntimos al día.\" },' ' { id: 3, text: \"La biblioteca abre a las nueve y cierra a las cinco de la tarde en días laborables.\" },' '];' > cite5.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 comprobación de citas, parte 2
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'function sourceText() {' ' return SOURCES.map(function (s) { return \"[\" + s.id + \"] \" + s.text; }).join(\"\n\");' '}' 'function markersIn(reply) {' ' const found = [];' ' const re = /\[(\d+)\]/g;' ' let match = re.exec(reply);' ' while (match) { found.push(Number(match[1])); match = re.exec(reply); }' ' return found;' '}' >> cite5.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 comprobación de citas, parte 3
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'function check(reply) {' ' const ids = SOURCES.map(function (s) { return s.id; });' ' const markers = markersIn(reply);' ' const missing = markers.filter(function (n) { return ids.includes(n) === false; });' ' return { markers: markers, missing: missing, ok: markers.length > 0 && missing.length === 0 };' '}' 'function show(label, result) {' ' console.log(label + \" marcas \" + JSON.stringify(result.markers) + \", sin fuente \" + JSON.stringify(result.missing) + \", ok: \" + result.ok);' '}' >> cite5.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 comprobación de citas, parte 4
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'async function main() {' ' const rule = \"Responde usando solo estas fuentes numeradas. Después de cada dato escribe el número de su fuente entre corchetes, como [1]. Si las fuentes no lo dicen, responde: No lo sé.\n\" + sourceText();' ' const question = \"¿Cuántos libros puedo llevarme y cuánto es la multa por retraso?\";' ' // Muestra grabada, usada solo si ningún modelo responde.' ' const sample = \"Puedes llevarte seis libros [1]. Un libro devuelto tarde cuesta diez céntimos al día [2].\";' ' const reply = await ask([{ role: \"system\", content: rule }, { role: \"user\", content: question }], sample, 80);' ' console.log(\"Respuesta:\", reply);' ' show(\"Comprobación:\", check(reply));' ' show(\"Respuesta inventada:\", check(\"Los préstamos duran tres semanas [4].\"));' '}' 'main();' >> cite5.js"Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Preguntar y comprobar las marcas
docker exec -w /home/node/project agent node cite5.jsSe 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ínea | Lo que puede mostrar |
|---|---|
| Respuesta | Dos frases cortas, cada una acabada en una marca como [1] |
| Comprobación: | marcas [1,2], sin fuente [], ok: true, si la respuesta se quedó en las fuentes |
| Respuesta inventada: | marcas [4], sin fuente [4], ok: false, siempre |
Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.