¿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

Reescribir consultas para buscar mejor

Después de esta lección: Puedo reescribir una pregunta para que encuentre más y comprobar con fuentes conocidas que la reescritura ayudó.

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

La pregunta no es la consulta

Reescribir una consulta es cambiar una pregunta antes de buscar con ella, para que la búsqueda encuentre más. Importa porque la gente escribe preguntas cortas, vagas o en dos partes, y un índice solo conoce las palabras que contiene.

«Cómo recupero mi dinero» no comparte ninguna palabra con la página que dice «reembolso». «¿Y cuántos?» solo comparte la «y», una palabra que no sirve de nada para buscar.

Al final de esta lección

Nota

Puedo reescribir una pregunta para que encuentre más y comprobar con fuentes conocidas que la reescritura ayudó.

Palabras clave

PalabraQué significa
Consultael texto que la búsqueda recibe de verdad
Ampliaciónañadir palabras relacionadas a una consulta
Descomposicióndividir una pregunta en preguntas más pequeñas
Pregunta de seguimientouna pregunta que solo se entiende con la conversación
Sinónimootra palabra para la misma idea
Fuente conocidala página que debe encontrar una pregunta de prueba

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

Ampliar añade las palabras que usa la página

Una página sobre reembolsos dice «reembolso». Una persona dice «recuperar mi dinero». La ampliación añade palabras relacionadas a la consulta: «mi dinero» pasa a «mi dinero reembolso devolver». Una tabla de sinónimos lo hace. Un modelo también puede sugerirlos.

Conserva las palabras originales y añade más. Una ampliación que sustituye las palabras de la persona puede perder la única palabra exacta que importaba.

Una pregunta en dos partes son dos búsquedas

Toma «Estás cerrado el domingo y puedo devolver un paquete». Una sola búsqueda devuelve la página que mejor encaja con una mitad. La otra mitad se pierde.

La descomposición divide la pregunta donde dice «y» y busca cada trozo. Después se fusionan las listas, con la fusión de la lección 1.

Un seguimiento necesita la conversación

«¿Y cuántos?» no significa nada solo. Únelo a la pregunta anterior, «puedo devolver un paquete», o haz que un modelo escriba una pregunta que se entienda sola.

No envíes nunca toda la conversación: las consultas largas se desvían. Añade solo la última pregunta, y solo cuando la nueva es corta.

Un error frecuente

Advertencia

Mucha gente cree que una reescritura siempre ayuda. Un sinónimo puede llevar a la página equivocada y un historial largo puede desviar la consulta. Guarda un conjunto de preguntas de prueba con fuentes conocidas y cuenta los aciertos antes y después de cada cambio.

Escribe el ayudante 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\";' '// Los tokens de una respuesta, o null si no trae ninguno.' 'function count(data, name) {' '  return data.usage && typeof data.usage[name] === \"number\" ? data.usage[name] : null;' '}' > 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 ayudante del modelo, parte 2

Comando
docker exec -w /home/node/project agent sh -c "printf '%s\n' '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 || 100 }),' '      signal: AbortSignal.timeout(30000),' '    });' '    if (res.ok === false) throw new Error(\"estado \" + res.status);' '    const d = await res.json();' '    return { text: d.choices[0].message.content, inTokens: count(d, \"prompt_tokens\"), outTokens: count(d, \"completion_tokens\"), recorded: false };' '  } catch (error) {' '    console.log(\"Muestra grabada: ningún modelo respondió (\" + error.message + \").\");' '    return { text: sample, inTokens: null, outTokens: null, recorded: true };' '  }' '}' '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 reescritor, parte 1

Comando
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const { ask } = require(\"./model\");' 'const docs = {' '  hours: \"la tienda abre a las nueve el sábado y cierra a la una\",' '  sunday: \"la tienda está cerrada el domingo\",' '  returns: \"puedes devolver un paquete en treinta días y recibir un reembolso\",' '  delivery: \"el envío tarda tres días y cuesta cuatro euros\",' '};' 'const synonyms = { dinero: [\"reembolso\", \"devolver\"] };' > rewrite1.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 reescritor, parte 2

Comando
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'function stem(w) { return w.length > 3 && w.endsWith(\"s\") ? w.slice(0, -1) : w; }' 'function words(t) { return t.toLowerCase().replace(/[?¿,]/g, \"\").split(\" \").map(stem); }' 'function best(q) {' '  const w = words(q);' '  let id = \"nada\", top = 0;' '  Object.keys(docs).forEach(function (k) {' '    const n = words(docs[k]).filter(function (x) { return w.includes(x); }).length;' '    if (n > top) { top = n; id = k; }' '  });' '  return id;' '}' 'function expand(q) {' '  const extra = [];' '  q.toLowerCase().split(\" \").forEach(function (w) {' '    (synonyms[w] || []).forEach(function (s) { extra.push(s); });' '  });' '  return q + \" \" + extra.join(\" \");' '}' >> rewrite1.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 reescritor, parte 3

Comando
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const cases = [' '  { q: \"a qué hora abre la tienda el sábado\", want: \"hours\" },' '  { q: \"cómo recupero mi dinero\", want: \"returns\" },' '  { q: \"cuántos días tarda el envío\", want: \"delivery\" },' '];' 'let plain = 0, wider = 0;' 'cases.forEach(function (c) {' '  const a = best(c.q), b = best(expand(c.q));' '  if (a === c.want) plain++;' '  if (b === c.want) wider++;' '  console.log(c.q + \" | simple: \" + a + \" | ampliada: \" + b);' '});' 'console.log(\"aciertos simple:\", plain, \"ampliada:\", wider, \"de\", cases.length);' >> rewrite1.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 reescritor, parte 4

Comando
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const two = \"estás cerrado el domingo y puedo devolver un paquete\";' 'console.log(\"la pregunta entera encuentra:\", best(two));' 'console.log(\"la pregunta dividida encuentra:\", two.split(\" y \").map(best).join(\" + \"));' 'async function main() {' '  const text = \"Antes: puedo devolver un paquete. Ahora: cuántos días tengo. Reescribe la última pregunta para que se entienda sola. Responde solo con la pregunta.\";' '  const reply = await ask([{ role: \"user\", content: text }], \"¿Cuántos días tengo para devolver un paquete?\", 40);' '  console.log(\"reescrita:\", reply.text.trim());' '  console.log(\"encuentra:\", best(reply.text));' '}' 'main();' >> rewrite1.js"

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

Ejecuta y cuenta los aciertos

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

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

Esto es un sustituto

El buscador cuenta las palabras compartidas en cuatro páginas. Un sistema real busca en un índice real. La única llamada al modelo reescribe un seguimiento, y el programa usa una reescritura grabada cuando ningún modelo responde.

El método no cambia con el tamaño: cambiar la consulta y contar los aciertos sobre fuentes conocidas.

Lo que imprime el Run

PreguntaSimple encuentraAmpliada encuentra
a qué hora abre la tienda el sábadohourshours
cómo recupero mi dineronadareturns
cuántos días tarda el envíodeliverydelivery

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

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.