Qué es RAG y por qué: contexto en vez de reentrenamiento
Un modelo de lenguaje sabe lo que vio durante su entrenamiento y nada más: ni tus manuales internos, ni el ticket de ayer, ni el precio de esta mañana. Hay dos formas de arreglarlo. Una es meter tus datos en los pesos reentrenando el modelo, cara, lenta e imposible de deshacer. La otra es recuperar los fragmentos relevantes en el instante de la pregunta y ponérselos delante. Eso es RAG: separar lo que el modelo sabe hacer de lo que el modelo debe saber. Vemos la arquitectura recuperar-luego-generar, por qué gana al reentrenamiento y cómo se materializa entera sobre Workers AI, Vectorize y D1.
Le preguntas al mejor modelo del mundo cuál es la política de devoluciones de tu empresa y recibes una respuesta impecablemente redactada y completamente inventada. No es un defecto del modelo: es que nunca vio ese documento. Un LLM es una función congelada en el instante en que terminó su entrenamiento, y todo lo que recuerda está comprimido, con pérdida, en sus pesos. RAG nace de una idea casi banal y por eso mismo poderosa: si el conocimiento no cabe en los pesos, que entre por el prompt. Recuperar primero, generar después. Este nivel monta esa arquitectura completa sobre Cloudflare, y esta lección explica por qué es la respuesta correcta y no un parche.
- Distinguir la memoria paramétrica del modelo de la memoria externa recuperable, y sus consecuencias.
- Describir la arquitectura recuperar-luego-generar y el papel de cada pieza sobre Cloudflare.
- Argumentar cuándo RAG gana al afinado del modelo y cuándo ambos se complementan.
- Reconocer las tres propiedades que RAG regala: frescura, atribución y control de acceso.
Lo que el modelo sabe y lo que no
Conviene separar dos cosas que el uso cotidiano confunde. Una es la capacidad: razonar sobre un texto, seguir instrucciones, resumir, redactar, traducir de un registro a otro. Otra es el conocimiento: qué dice la cláusula tercera de tu contrato marco, cuánto costó el pedido 8842, qué decidió el comité el martes pasado. La capacidad vive en los pesos y es lo que de verdad compraste al elegir el modelo. El conocimiento concreto, privado y fresco casi nunca está ahí, y cuando está, lo está de forma difusa y sin garantía.
Esa memoria paramétrica tiene tres límites que ninguna versión más grande elimina. Está fechada: hay un corte de entrenamiento y después de él el mundo siguió sin el modelo. Es comprimida con pérdida: el entrenamiento no archiva documentos, ajusta parámetros, y lo raro se difumina en lo frecuente. Y es opaca: no puedes preguntarle de dónde sacó una afirmación ni borrar un dato concreto sin tocar todo lo demás.
A eso se añade un cuarto límite que suele olvidarse porque es demasiado evidente: tus documentos privados nunca estuvieron ahí. El contrato de un cliente, el hilo de soporte de anteayer o la wiki interna no formaron parte de ningún corpus de entrenamiento, y no hay versión futura del modelo que vaya a incluirlos. Esa parte del conocimiento que más te importa es, por construcción, la que el modelo jamás tendrá.
De ahí nace la alucinación, que no es un fallo moral del modelo sino su comportamiento normal llevado a un terreno donde no tiene apoyo. El modelo interpola con fluidez sobre lo que aprendió; si no hay hecho, produce la continuación más plausible, que suena idéntica a una respuesta verdadera. Un LLM es un razonador extraordinario sobre el texto que tiene delante y un archivo mediocre sobre el texto que vio hace meses. RAG toma esa asimetría en serio: usa el modelo para lo primero y le pone delante, en cada pregunta, el texto que necesita.
Hay un agravante: el modelo tampoco sabe que no sabe. No lleva dentro un medidor de confianza que distinga el hecho memorizado mil veces de la interpolación improvisada, y su prosa suena igual de segura en ambos casos. El usuario, que solo ve la superficie, no tiene ninguna pista para separarlos. Un sistema que quiera ser fiable debe suministrar esa distinción desde fuera, y la única forma conocida de hacerlo es apoyar cada afirmación en un texto que se pueda enseñar.
Fíjate en la evidencia cotidiana de esa asimetría. Pega un contrato entero en la conversación y pregunta por su cláusula tercera: el modelo la lee, la interpreta, la compara con la quinta y detecta la contradicción entre ambas. Pregúntale lo mismo sin pegar nada y te dará una respuesta genérica con aire de certeza. La competencia estaba intacta en los dos casos; lo que cambió fue si el hecho estaba delante. Todo este nivel consiste en automatizar ese “pegar el documento correcto” para un corpus que no cabe en ninguna conversación.
Recuperar y luego generar
La arquitectura tiene dos mitades y conviene no mezclarlas nunca. La primera es un problema de recuperación: dada una pregunta, encontrar en tu corpus los pocos fragmentos que la responden. La segunda es un problema de generación: dados esos fragmentos, redactar una respuesta fiel y citada. La primera es una disciplina con medio siglo de historia y métricas; la segunda es lo que el LLM ya hace bien.
flowchart LR P[pregunta del usuario] --> E[embedding de la pregunta] E --> V[Vectorize busca los vecinos] V --> D[D1 devuelve el texto de los chunks] D --> C[prompt con el contexto] C --> L[LLM en Workers AI] L --> R[respuesta con citas] style V fill:#89b4fa,color:#11111b style L fill:#a6e3a1,color:#11111b
Ese mismo esqueleto sirve para cosas que parecen muy distintas: un asistente sobre la documentación de un producto, un agente de soporte que consulta el historial de tickets, un buscador interno que responde en prosa, una herramienta que contesta preguntas sobre el código de un repositorio. Cambian el corpus, el troceo y las instrucciones finales; el bucle recuperar-luego-generar es idéntico en los cuatro.
Sobre Cloudflare cada caja tiene un dueño y ninguna exige un servidor. Workers AI calcula el embedding de la pregunta y ejecuta el modelo generador. Vectorize guarda los vectores del corpus y responde a la búsqueda por similitud. D1 o R2 custodian el texto original de cada chunk, porque el índice vectorial no es el lugar donde vivir los documentos. El Worker es el director de orquesta: recibe la petición, encadena las llamadas y devuelve la respuesta. Y AI Gateway, si lo pones delante, aporta caché, reintentos y contabilidad de coste.
Lo importante del dibujo es que se trata de un sistema, no de un modelo. Cuando falla, el fallo es descomponible: o el recuperador no trajo el fragmento correcto, o el generador lo tenía delante y lo ignoró. Esa capacidad de localizar la culpa es una virtud de ingeniería que ningún modelo monolítico ofrece.
También conviene mirar el reloj. El bucle encadena cuatro viajes, y cada uno suma: incrustar la pregunta, buscar en el índice, leer el texto y generar. Los tres primeros se miden en decenas de milisegundos; el cuarto domina el total. Que las cuatro piezas vivan en la misma plataforma y a un binding de distancia elimina lo que en una arquitectura cosida con tres proveedores era el sumando más tonto de todos: la travesía de internet entre servicios que solo se hablan entre ellos.
La traducción a wrangler es directa y no hace falta memorizarla ahora: un binding de tipo ai para Workers AI, uno de tipo vectorize apuntando a tu índice, uno de d1_databases para el texto de los fragmentos y uno de r2_buckets para los ficheros originales. Todo lo que este nivel construye cabe en un Worker con esas cuatro entradas en su manifiesto.
Memoria paramétrica
Lo aprendido en el entrenamiento: fechado, comprimido con pérdida y opaco. Da capacidad, no hechos concretos.
Memoria recuperable
Tu corpus indexado fuera del modelo. Se actualiza, se filtra y se borra sin tocar un solo peso.
Atribución
Cada afirmación puede apuntar al fragmento que la respalda. La respuesta deja de ser un oráculo y pasa a ser verificable.
Control de acceso
Filtras en el momento de recuperar según quién pregunta. Un dato que no se recupera no puede filtrarse en la respuesta.
RAG frente a afinar el modelo
La tentación inicial de todo equipo es afinar un modelo con sus documentos. Casi siempre es la herramienta equivocada para este problema, y la razón es que el afinado enseña forma, no hechos: tono, formato de salida, vocabulario de dominio, estilo de razonamiento. Meter datos factuales en los pesos funciona mal, se olvida con facilidad y no ofrece ninguna de las propiedades que un sistema de información necesita.
La forma sencilla de recordarlo: el afinado cambia cómo habla el modelo, la recuperación cambia qué sabe. Casi todos los proyectos que fracasan afinando llegaron con un problema del segundo tipo y aplicaron la herramienta del primero.
La asimetría de coste es brutal. Reindexar un documento que cambió cuesta segundos y céntimos; reentrenar cuesta horas, un canal de datos y una campaña de evaluación entera. La frescura es continua en un índice y discreta en unos pesos. La atribución existe en el índice, porque sabes exactamente qué fragmento entregaste, e ignora en los pesos, donde la fuente ya se disolvió. El borrado es una fila menos frente a un reentrenamiento completo, y esa diferencia deja de ser técnica en cuanto alguien ejerce su derecho al olvido.
Queda la objeción moderna, y es seria: si las ventanas de contexto no paran de crecer, ¿por qué no meter el corpus entero en cada petición y ahorrarse el índice? Por tres razones que ninguna ventana grande deroga. La primera es económica: pagas todos los tokens en cada consulta, mientras que un índice cobra por lo que recupera. La segunda es de atención: un modelo con doscientos mil tokens delante atiende peor a la frase relevante que otro con cinco fragmentos bien elegidos, y la calidad cae según crece el ruido. La tercera es de tamaño: los corpus reales se miden en gigabytes y no caben en ninguna ventana concebible. La ventana larga no sustituye a la recuperación; la hace más tolerante a que recuperes de más.
El control de acceso remata el argumento. Un modelo afinado con documentos confidenciales los sabe para todo el mundo: no hay forma de que recuerde el contrato de un cliente solo cuando pregunta ese cliente. Un recuperador, en cambio, filtra por identidad en el momento de la consulta, y lo que nunca se recupera nunca llega al prompt.
La pregunta correcta no es RAG o afinado, sino qué le pides a cada uno. Afina cuando quieras cambiar cómo responde el modelo —un formato rígido de salida, la jerga de tu sector, un estilo de razonamiento propio— y recupera cuando quieras cambiar qué sabe. En un sistema maduro conviven: unos pesos que hablan tu idioma y un índice que le dicta los hechos de esta mañana.
El bucle entero, en un puñado de líneas
Antes de dedicar cuatro lecciones a las partes, conviene ver el todo. Este Worker es un RAG completo: incrusta la pregunta, busca vecinos, rehidrata su texto y genera con ese contexto delante. Le faltan casi todos los cuidados que veremos después, pero la forma ya está entera.
export default {
async fetch(request: Request, env: Env): Promise<Response> {
const pregunta = new URL(request.url).searchParams.get("q") ?? "";
// 1. la pregunta se convierte en vector
const { data } = await env.AI.run("@cf/baai/bge-base-en-v1.5", { text: [pregunta] });
// 2. el indice devuelve los vecinos mas cercanos
const vecinos = await env.INDICE.query(data[0], { topK: 5 });
// 3. D1 rehidrata el texto de esos fragmentos
const ids = vecinos.matches.map((m) => m.id);
const { results } = await env.DB.prepare(
`SELECT texto FROM chunks WHERE id IN (${ids.map(() => "?").join(",")})`,
).bind(...ids).all<{ texto: string }>();
// 4. el LLM responde con ese contexto delante
const contexto = results.map((r, i) => `[${i + 1}] ${r.texto}`).join("\n\n");
const salida = await env.AI.run("@cf/meta/llama-3.3-70b-instruct", {
messages: [
{ role: "system", content: "Responde solo con las FUENTES y cita su numero." },
{ role: "user", content: `FUENTES:\n${contexto}\n\nPREGUNTA: ${pregunta}` },
],
});
return Response.json(salida);
},
} satisfies ExportedHandler<Env>;
Cuatro llamadas, tres bindings y ningún servidor. Lo que queda de nivel no añade cajas a este diagrama: añade profundidad dentro de cada una. La arquitectura se aprende en veinte líneas; la calidad se gana en los detalles de cada una de ellas.
Una nota para cuando lo pruebes: ni Workers AI ni Vectorize tienen simulación local completa, así que en desarrollo trabajarás contra los servicios reales aunque el Worker corra en tu máquina. Merece la pena tener un índice pequeño de pruebas, separado del de producción, para no ensuciar el bueno mientras experimentas con troceos.
Y son bastantes detalles. A este esbozo le falta todo lo que separa una demo de un sistema: nadie decidió cómo se cortó el documento que hay detrás del índice, no hay filtro por permisos en la búsqueda, el contexto va en el orden en que llegó, el modelo no tiene permiso para admitir que no lo sabe y no existe forma de saber si la respuesta salió de las fuentes o de su memoria. Las cuatro lecciones siguientes son exactamente esos cuatro huecos, en orden: la ingesta, la recuperación, la generación con citas y la medición de todo lo anterior.
La formulación canónica de RAG llegó en 2020, cuando un grupo de investigadores planteó combinar dos tipos de memoria en un mismo sistema: la paramétrica, guardada en los pesos de una red, y la no paramétrica, un índice de documentos consultable en el momento de responder. Visto de lejos parecía un truco de ingeniería; visto de cerca era una tesis sobre la naturaleza del conocimiento en las máquinas. Durante una década la carrera consistió en meter más mundo dentro de los pesos, bajo la fe implícita de que un modelo suficientemente grande acabaría conteniéndolo todo. RAG rompe esa fe con una observación incómoda: comprimir el mundo en parámetros destruye justo aquello que hace utilizable al conocimiento —su procedencia, su fecha, su permiso de lectura, su reversibilidad—. Un hecho dentro de unos pesos no se puede citar, ni fechar, ni restringir a quien tiene derecho a verlo, ni borrar cuando alguien lo exige. Un hecho dentro de un índice conserva las cuatro propiedades intactas. Esto es, en el fondo, la vieja distinción entre saber hacer y saber que: el modelo aporta la competencia, el corpus aporta los hechos, y la arquitectura consiste en no confundirlos jamás. De ahí se sigue una consecuencia que reordena todo el nivel: si el conocimiento vive fuera del modelo, la calidad de tu sistema deja de depender de qué LLM elegiste y pasa a depender de cómo troceas, indexas, filtras y ordenas tu corpus. Esa es una disciplina de recuperación de información, con métricas propias y décadas de literatura, no una disciplina de prompting. Y hay un giro final que es donde entra Cloudflare: durante años esta arquitectura exigía coser servicios de tres proveedores distintos —una API de embeddings aquí, una base vectorial allá, un LLM en otro sitio— y pagar en latencia cada costura. Poner el índice, la inferencia y el orquestador en el mismo runtime, junto al usuario, convierte el bucle recuperar-generar en una sola función desplegada en el borde. La memoria externa deja de ser un servicio remoto al que el modelo llama y se vuelve parte de la propia plataforma donde el modelo corre.
- Escoge un corpus real tuyo —documentación, tickets, actas— y escribe diez preguntas que un LLM genérico no podría responder. Anota, para cada una, qué documento la contesta.
- Pregunta esas diez a un modelo sin contexto y clasifica sus respuestas en correcta, evasiva o inventada con aplomo. La tercera categoría es el argumento entero de este nivel.
- Dibuja el recorrido de una de tus preguntas por las seis cajas del diagrama, nombrando qué servicio de Cloudflare ocupa cada una en tu caso.
- Argumenta por escrito, para tu corpus concreto, por qué afinar un modelo con él sería peor que indexarlo. Usa los cuatro ejes: coste, frescura, atribución y control de acceso.
- Identifica en tu dominio una pregunta que RAG no resolverá bien —una agregación, un cálculo, una comparación global— y guárdala: la usaremos en la lección de calidad.