artículos / Embeddings y Por Qué Funciona RAG: Cómo ...

Embeddings y Por Qué Funciona RAG: Cómo un Modelo Responde Sobre lo que Nunca Vio

AWONG 12 minutos de lectura 19 vistas

Le preguntas al LLM más caro del mundo sobre tus propios documentos y te responde con seguridad... una mentira. Este es el porqué, y la solución: qué es realmente un embedding, cómo la similitud coseno mide significado, y por qué RAG —recuperar y aumentar antes de generar— hace que un modelo responda sobre datos que nunca estuvieron en su entrenamiento, sin reentrenar nada.

Embeddings y Por Qué Funciona RAG: Cómo un Modelo Responde Sobre lo que Nunca Vio

Embeddings y Por Qué Funciona RAG: Cómo un Modelo Responde Sobre lo que Nunca Vio

Haz la prueba: toma el LLM más caro y más listo del momento, y pregúntale algo muy específico sobre tus propios documentos —la cláusula de un contrato tuyo, la configuración de tu servidor, lo que decidiste en una reunión de ayer—. Te va a responder. Con seguridad, bien redactado, sonando convincente. Y va a estar inventado.

No es que el modelo sea tonto. Es que le estás preguntando por algo que nunca vio. Y aquí está la idea que lo cambia todo, y sobre la que se construye RAG: el problema casi nunca es la inteligencia del modelo; es qué información tiene enfrente en el momento de responder.

Este post explica las dos piezas que resuelven eso —los embeddings y RAG— desde cero, sin asumir que ya sabes álgebra lineal. Al final vas a entender no solo cómo funciona, sino por qué funciona.

El Problema Real: el Modelo Solo Sabe Dos Cosas

Un LLM solo tiene acceso a dos fuentes de información cuando responde:

  • Lo que aprendió en el entrenamiento, comprimido en sus pesos. Es vasto, pero está congelado en el tiempo y no incluye tus datos privados.
  • Lo que le pones en el contexto de esta conversación: el prompt, los mensajes, los documentos que le pegas.

Eso es todo. No hay una tercera. Si la respuesta no está en el entrenamiento (porque es privada, o nueva, o muy específica) y no está en el contexto, el modelo hará lo único que sabe hacer: completar texto de forma plausible. Plausible no es lo mismo que verdadero. A eso le llamamos alucinación.

La conclusión es liberadora: si quiero que responda bien sobre mis datos, no necesito un modelo más grande ni reentrenarlo. Necesito meter la información correcta en su contexto, justo antes de que responda. Todo el truco está en ese "la información correcta". ¿Cómo la encuentro?

Por Qué No Basta Buscar por Palabras

La respuesta obvia sería: busca en mis documentos las palabras de la pregunta y pégale lo que encuentres. El problema es que el lenguaje no funciona por coincidencia de palabras. Buscas "servidor de IA" y no encuentras el documento que dice "host de GPU". Preguntas por "cómo despedir a un empleado" y no encuentras la sección titulada "terminación de la relación laboral". Mismo significado, cero palabras en común.

La búsqueda por palabra clave es ciega al significado. Y el significado es justo lo que importa. Necesitamos una forma de buscar por lo que las cosas quieren decir, no por cómo están escritas. Ahí entran los embeddings.

Qué es un Embedding

Un embedding es, simplemente, un texto convertido en una lista de números —un vector— de forma que esa lista capture el significado del texto. Un modelo de embeddings (yo uso mxbai-embed-large corriendo local en Ollama) toma una frase y escupe, por ejemplo, 1024 números.

¿Qué tienen de especial esos números? Que están colocados en un espacio donde la cercanía equivale a parecido de significado. Imagina un mapa gigante —no de dos dimensiones, sino de mil— donde cada texto es un punto. "Host de GPU" y "servidor de IA" caen casi encima uno del otro, aunque no compartan palabras. "Receta de pan" cae lejísimos. El modelo aprendió, leyendo cantidades enormes de texto, a colocar las cosas que significan algo parecido en vecindarios cercanos.

Eso es todo el concepto: un embedding es una coordenada en el mapa del significado. No guardo palabras; guardo posiciones. Y buscar por significado se vuelve un problema geométrico: ¿qué puntos están cerca de este otro?

Medir Cercanía: Similitud Coseno

Para saber qué tan "cerca" están dos vectores, el truco estándar no es medir la distancia en línea recta, sino el ángulo entre ellos: la similitud coseno. Dos vectores que apuntan en la misma dirección tienen similitud cercana a 1 (mismo significado); perpendiculares, cercana a 0 (sin relación); opuestos, cercana a -1.

La intuición de por qué el ángulo y no la distancia: nos importa hacia dónde apunta el significado, no qué tan "largo" es el texto. Una frase corta y un párrafo largo sobre el mismo tema apuntan en la misma dirección aunque sus magnitudes difieran.

# similitud coseno = producto punto / (norma_a * norma_b)
def coseno(a, b):
    dot = sum(x*y for x, y in zip(a, b))
    na  = sum(x*x for x in a) ** 0.5
    nb  = sum(y*y for y in b) ** 0.5
    return dot / (na * nb)   # ~1.0 = muy parecido, ~0 = nada que ver

De Embeddings a RAG

RAG —Retrieval-Augmented Generation, generación aumentada por recuperación— es juntar todo lo anterior en un pipeline. "Aumentada por recuperación" suena complicado; es literal: antes de generar, recupera, y úsalo para aumentar el prompt. Cinco pasos:

  1. Trocear tus documentos en pedazos (chunks) de un tamaño manejable.
  2. Embeber cada chunk y guardar su vector en una base (una columna de vectores; en Postgres, con pgvector).
  3. Cuando llega una pregunta, embeber la pregunta con el mismo modelo.
  4. Recuperar los chunks cuyos vectores estén más cerca (mayor coseno) del vector de la pregunta.
  5. Aumentar el prompt con esos chunks y dejar que el modelo genere la respuesta basándose en ellos.
contexto = recuperar_top_k(embed(pregunta), k=5)   # los 5 chunks más cercanos
prompt = f"""Responde usando SOLO este contexto:
{contexto}

Pregunta: {pregunta}"""
respuesta = llm(prompt)

El modelo ya no adivina desde su memoria comprimida: responde leyendo los apuntes correctos que le pusiste enfrente.

Por Qué Funciona (de Verdad)

RAG funciona porque separa dos cosas que el LLM hace con calidad muy distinta: recordar hechos exactos (malo —los comprime y los confunde—) y razonar sobre un texto que tiene delante (excelente). RAG le quita al modelo la tarea en la que falla (recordar) y le deja la que domina (razonar sobre lo dado).

De ahí salen sus ventajas, todas consecuencia de lo mismo:

  • Menos alucinación: la respuesta sale de chunks reales, no de la niebla de los pesos.
  • Citable: sabes de qué chunk salió cada cosa.
  • Actualizable sin reentrenar: ¿cambió un dato? Reemplazas el chunk. El conocimiento vive en la base de datos, no en el modelo —que se vuelve intercambiable—.
  • Barato: embeber y buscar cuesta una fracción de lo que cuesta reentrenar o afinar un modelo.

Si has leído mis otros posts, esto te suena: es exactamente el principio detrás de la memoria de mis agentes. El modelo es el motor; el contexto recuperado es el combustible.

Lo que Nadie te Dice

RAG no es magia, y conviene saber dónde duele:

  • El troceado importa, y mucho. Chunks demasiado grandes diluyen el significado (el vector promedia temas distintos); demasiado chicos pierden contexto. El tamaño del chunk es una decisión de diseño, no un detalle.
  • El modelo de embeddings tiene límites. Cada uno consume hasta cierta cantidad de tokens (mxbai, ~512). Si le mandas un texto más largo, en el mejor caso lo ignora; en el peor, falla. Yo aprendí esto por las malas: un tercio de mi memoria quedó sin vector —invisible a la búsqueda— porque los textos largos reventaban en silencio. Recortar antes de embeber no es opcional.
  • Basura entra, basura sale. Si el chunk correcto no está indexado, RAG no lo inventa; te dará lo más cercano que tenga, que puede ser irrelevante. El recall depende por completo de la calidad de tus chunks y tus embeddings.
  • Usa el mismo modelo para embeber documentos y preguntas. Vectores de modelos distintos viven en mapas distintos; compararlos no tiene sentido.

Conclusión

Un embedding es una coordenada en el mapa del significado. La similitud coseno mide qué tan cerca apuntan dos de esas coordenadas. Y RAG usa ambas para una idea simple y poderosa: antes de que el modelo responda, ponle enfrente los apuntes correctos.

Por eso el debate eterno sobre cuál es "el mejor modelo" me parece, casi siempre, la pregunta equivocada. El modelo razona; pero solo puede razonar sobre lo que tiene en el contexto. Quien controla qué información llega a ese contexto —y los embeddings con RAG son la mejor forma que tenemos de controlarlo— es quien de verdad decide la calidad de la respuesta. El modelo es el motor. El contexto recuperado es a dónde vas.

compartir_artículo

LinkedIn Facebook X

artículos_relacionados