En Parte 1 vimos cómo una preparación limpia de documentos y un chunking bien pensado son decisivos para la calidad de Retrieval Augmented Generation. Estas bases forman el punto de partida para toda una serie de optimizaciones adicionales que moldean el proceso completo. En la Parte 2 continuamos la serie y nos dedicamos a los siguientes bloques, que se construyen sobre esta base y desarrollan aún más el uso de RAG en la empresa.

Embedding

Embeddings específicos de dominio

Embeddings específicos de dominio significan que las representaciones vectoriales de textos no se generan con modelos de embedding entrenados de forma general, sino con modelos adaptados al lenguaje técnico y los contenidos de un sector concreto o de una empresa. Los modelos generales se entrenan con cantidades muy grandes y no específicas de textos, entre ellos libros, sitios web, Wikipedia y otras fuentes. Comprenden el lenguaje cotidiano y muchos conceptos estándar, pero a menudo no captan los matices en, por ejemplo, contratos jurídicos, manuales técnicos o informes médicos. Los embeddings específicos de dominio se crean mediante el ajuste fino de un modelo existente con datos de la respectiva área técnica o mediante el entrenamiento de un modelo propio en un corpus de documentos internos, directrices, actas y manuales.

Un ejemplo es el ámbito médico. Cuando un modelo general procesa la palabra “hemorragia”, solo reconoce el significado general. En documentos médicos, sin embargo, es crucial distinguir si se trata de una hemorragia interna o de una hemorragia postoperatoria. Un modelo de embedding ajustado con precisión a textos médicos refleja estas diferencias de forma exacta en el espacio vectorial.

Sin embeddings específicos de dominio, los términos técnicos quedan difusos, las abreviaturas se interpretan mal y no se captan relaciones importantes. El sistema de recuperación encontrará formalmente pasajes similares, pero a menudo pasará por alto los fragmentos relevantes en contenido. La generación de respuestas pierde precisión porque el espacio semántico no refleja correctamente el lenguaje técnico. Con embeddings específicos de dominio, en cambio, el sistema es más robusto, la calidad de los resultados aumenta y las respuestas pueden ajustarse con mayor exactitud al contexto real de la empresa.

Embeddings multilingües

Embeddings multilingües significan que los textos en distintos idiomas se representan en un espacio vectorial común. Un modelo así entiende que una frase en alemán, inglés o francés con el mismo contenido tiene el mismo significado semántico, aunque las palabras y la gramática sean totalmente diferentes. La ventaja es que los usuarios pueden buscar sin importar su idioma y el sistema aún así encontrará los documentos adecuados. Al mismo tiempo, se pueden procesar documentos en varios idiomas sin tener que mantener un modelo distinto para cada uno.

Un ejemplo es una empresa internacional que almacena manuales en inglés, actas en alemán y contratos en francés. Cuando un empleado busca en alemán “Lieferverzug” (retraso de entrega), el sistema debe reconocer correctamente también el inglés “delivery delay” y el francés “retard de livraison”. Los embeddings multilingües garantizan que las tres variantes queden cercanas en el espacio vectorial y por tanto se traten como semánticamente equivalentes.

Sin esta medida surgen islas de idioma. Una búsqueda solo abarca documentos en el mismo idioma, aunque otros idiomas contengan la misma información. El sistema de recuperación pierde resultados relevantes, la generación de respuestas parece incompleta y los usuarios pierden confianza en la exhaustividad del sistema. Con embeddings multilingües, en cambio, el conocimiento se vincula a través de los idiomas y queda accesible para todos los usuarios, independientemente del idioma en que se formule la pregunta o se archive el documento.

Reducción de dimensionalidad

La reducción de dimensionalidad consiste en disminuir el número de dimensiones en los embeddings sin perder el núcleo semántico de la información. Los modelos de embedding generan para cada vector de texto normalmente varios cientos o miles de dimensiones. Esta alta dimensionalidad mejora la expresividad, pero encarece la búsqueda y el almacenamiento. La reducción disminuye el tamaño de los vectores, de modo que se comparan más rápido en bases de datos vectoriales y se almacenan con menos demanda de espacio.

Un ejemplo es un modelo de embedding con 1024 dimensiones que representa todos los documentos de la empresa. Si antes de almacenar esos vectores los reducimos a 256 dimensiones, el requerimiento de almacenamiento cae a una cuarta parte y la búsqueda por similitud es sustancialmente más rápida. Procedimientos como el Análisis de Componentes Principales (PCA) aseguran que los ejes informativos más importantes se conserven, mientras que el ruido o las dimensiones poco relevantes se eliminan.

Sin esta medida aumentan la latencia y los costes con el tamaño del índice. Las consultas tardan más porque cada comparación requiere más operaciones y la base de datos escala peor al almacenar demasiadas dimensiones. Con la reducción de dimensionalidad, los embeddings siguen siendo manejables, el retrieval y el ranking son más eficientes y los resultados permanecen igualmente precisos.

Normalización de embeddings

La normalización de embeddings implica que los vectores generados se ajustan a una longitud uniforme antes de almacenarlos en la base de datos vectorial o usarlos para el retrieval. Los modelos de lenguaje producen vectores con valores numéricos en muchas dimensiones. Estos vectores pueden tener longitudes diferentes, incluso si su significado es similar. La longitud es un subproducto técnico del cálculo.

La ventaja se ve en la medida de similitud utilizada. Con la similitud coseno (Cosine Similarity) solo importa el ángulo entre vectores, no su longitud. Para que esta métrica funcione correctamente, los vectores se normalizan a longitud unitaria. También en medidas de distancia como la euclidiana (L2) la normalización impide que dos textos semánticamente similares queden muy separados solo porque sus embeddings estén escalados de forma distinta.

Sin normalización, los resultados del retrieval pueden distorsionarse. Contenidos semánticamente muy parecidos aparecen más alejados de lo real. Con la normalización a vectores unitarios, la cercanía semántica se mantiene y las comparaciones son estables y fiables.

Embeddings híbridos (texto + metadatos)

Los embeddings híbridos con texto y metadatos significan que no solo se convierte el texto del documento en un vector, sino que se incorporan también informaciones descriptivas adicionales. Los metadatos son, por ejemplo, tipo de documento, fecha de creación, autor, departamento, asignación de proyecto, idioma o nivel de seguridad. Estos datos se combinan con el texto y se embeben como un vector conjunto. El objetivo es reflejar en el espacio semántico no solo el significado del contenido, sino también sus características organizativas.

Técnicamente, esto se realiza agrupando texto y metadatos en una entrada unificada.

“[Dokumenttyp: Richtlinie] [Gültig ab: 2024] El texto real de la directriz…”

La parte de metadatos se añade como prefijo o información estructurada al texto de entrada antes de que el modelo de embedding calcule el vector. Alternativamente, pueden generarse vectores separados para texto y metadatos y luego fusionarse, por ejemplo mediante concatenación o promedio ponderado.

Sin embeddings híbridos, los metadatos quedan separados del espacio vectorial y solo pueden usarse como filtros adicionales en la base de datos. Cada consulta debe ejecutarse en paralelo, una vez por similitud semántica y otra por condiciones como tipo de documento o departamento. Con embeddings híbridos, texto y metadatos se unen en un vector común. Así surge una representación unificada que abarca significado y contexto. El retrieval se vuelve más directo y preciso, y los resultados encajan no solo semántica sino también organizativamente.

Embeddings especiales para tablas y código

Los embeddings especiales para tablas y código significan que para estos contenidos no se emplean los mismos modelos que para texto continuo, sino modelos entrenados específicamente para captar su estructura. Las tablas se componen de celdas dispuestas en filas y columnas, y su significado surge de la relación entre encabezados, valores y unidades. Un modelo de lenguaje general interpreta una tabla meramente como una secuencia de palabras y números. Un embedding específico de tablas reconoce que un número en cierta columna pertenece a un encabezado y se entiende como un indicador clave. Esto permite responder correctamente consultas como ingresos por trimestre o tiempo medio de ejecución, porque la representación vectorial refleja esas relaciones.

En el caso del código fuente, aplica un principio similar. Los modelos generales procesan el código como texto común y ven variables, paréntesis y palabras clave solo como cadenas de caracteres. Los embeddings específicos de código tienen en cuenta la sintaxis, la jerarquía de llamadas a funciones y las dependencias entre variables y módulos. Esto permite buscar definiciones de funciones, parámetros o bibliotecas utilizadas y generar respuestas que reflejen la lógica estructural del código.

Un aspecto importante es que embeddings de distintos modelos no son directamente comparables. Cada espacio vectorial tiene su propia geometría, de modo que la similitud coseno solo funciona con fiabilidad dentro de un modelo. Para salvar esta dificultad existen varios enfoques. O bien se usa un modelo unificado que procese texto, tablas y código, o bien se separan los contenidos en distintos índices y se combinan los resultados tras el retrieval. Alternativamente, los espacios de embedding pueden alinearse mediante modelos de mapeo adicionales o adaptadores, para hacerlos comparables en un espacio común. Sin una de estas medidas, los vectores de modelos diferentes serían incompatibles y el retrieval arrojaría resultados aleatorios o irrelevantes.

Sin embeddings especiales para tablas y código se pierden las estructuras subyacentes. El retrieval ofrece entonces resultados imprecisos, porque números o nombres de funciones se procesan sin su contexto. Las respuestas parecen genéricas, citan valores erróneos o devuelven fragmentos de código incompletos. Con embeddings especializados se conserva la estructura y la lógica, y con un manejo coherente de los distintos espacios vectoriales estos contenidos pueden buscarse con fiabilidad y emplearse para respuestas sólidas.

Evaluación y ajuste fino de los embeddings

La evaluación y el ajuste fino de los embeddings implican revisar regularmente la calidad de los vectores generados y adaptarlos según las necesidades de la propia área. Los embeddings son la base del retrieval y determinan qué fragmentos (chunks) se consideran similares. Si los vectores no reflejan con fiabilidad las relaciones semánticas en el contexto de la empresa, surgen resultados erróneos y respuestas imprecisas.

La evaluación se lleva a cabo con conjuntos de prueba que contienen pares conocidos de preguntas y documentos relevantes. Métricas típicas son Recall at K o MRR. Así se mide si los contenidos relevantes aparecen realmente entre los primeros resultados. Además se realizan pruebas cualitativas con usuarios expertos, que evalúan si los resultados satisfacen sus necesidades de información.

El ajuste fino sigue a la evaluación. Consiste en continuar el entrenamiento de un modelo de embedding existente con ejemplos adicionales de la propia área. De este modo aprende términos, abreviaturas o relaciones que no aparecen en los datos de entrenamiento generales. En medicina pueden ser diagnósticos específicos, y en finanzas conceptos de contratos y balances.

Sin evaluación ni ajuste fino queda incierto si los embeddings funcionan bien en el contexto especializado. Un modelo que obtiene buenos resultados en benchmarks generales puede ofrecer un rendimiento pobre en la empresa, porque no capta conceptos propios del sector. El retrieval muestra entonces resultados irrelevantes, documentos importantes caen en el ranking y la generación de respuestas se apoya en fundamentos inadecuados. Con evaluación periódica y ajuste fino dirigido se mejora sistemáticamente la precisión de los resultados y se garantiza la fiabilidad de todo el sistema RAG.

Documentar la estrategia de pooling

Documentar la estrategia de pooling implica dejar claro cómo se forma la representación de un texto a partir de los embeddings de tokens del modelo. Procedimientos comunes son usar el token CLS o el pooling por promedio (mean pooling) sobre todos los tokens. La elección de este método influye directamente en los vectores resultantes, ya que determina qué nivel de información captura más el embedding.

Si no se documentan estas diferencias, surgen inconsistencias cuando distintos equipos o canalizaciones emplean estrategias diferentes. En grandes empresas, varios departamentos suelen desarrollar sus propias cadenas RAG, a veces con frameworks o versiones de modelo distintos. Si un equipo usa pooling con CLS y otro mean pooling, aunque ambos generen embeddings válidos, ya no serán directamente comparables. Esto hace que los benchmarks pierdan relevancia, los índices compartidos contengan datos inconsistentes y los resultados de retrieval varíen según la fuente.

También al cambiar de versión de modelo puede cambiar la configuración por defecto de pooling. Sin documentación, esto pasa desapercibido y los vectores cambian sutilmente, causando rupturas en la representación.

Con una estrategia de pooling documentada y establecida, los embeddings permanecen coherentes, trazables y reproducibles. Los benchmarks son fiables, las comparaciones entre equipos posibles y el retrieval ofrece resultados estables, independientemente de la canalización usada para embedder un documento.

Detección de out of distribution para entradas fuera del ámbito de entrenamiento

La detección de out of distribution para entradas fuera del ámbito de entrenamiento significa que el sistema comprueba si un texto o chunk cae dentro del dominio cubierto por el modelo de embedding durante el entrenamiento. Los modelos de embedding siempre se entrenan con conjuntos de datos concretos, por ejemplo noticias, artículos de Wikipedia o documentación técnica. Contenidos muy distintos, como cláusulas jurídicas, diagnósticos médicos o abreviaturas internas, pueden procesarse, pero los vectores resultantes no necesariamente reflejan correctamente el significado semántico.

Técnicamente la detección se realiza con métodos como medidas de distancia en el espacio vectorial, métricas de incertidumbre o clasificadores adicionales entrenados específicamente para OOD. Si un chunk queda muy alejado de todos los vectores del entrenamiento conocido, indica que el modelo no puede generar una representación fiable.

Un ejemplo es un modelo de embedding entrenado en inglés cotidiano que de pronto debe procesar fórmulas de estructuras químicas o párrafos legales. Los vectores de estos contenidos terminan en áreas del espacio vectorial que nunca se vieron en el entrenamiento. El retrieval puede entonces seleccionar vecinos equivocados porque las distancias no reflejan verdadera cercanía semántica.

Para la detección de out of distribution en embeddings existen tres enfoques consolidados. Los procedimientos basados en distancia comprueban qué tan lejos está un nuevo vector de vectores de referencia del entrenamiento. Si la distancia al vecino más cercano o a varios vecinos supera el rango habitual, la entrada se considera sospechosa. Los métodos basados en densidad o probabilidad modelan la distribución de los vectores de entrenamiento y evalúan si una nueva entrada proviene con alta probabilidad de la misma distribución. Aquí se emplean técnicas como Gaussian Mixture Models, Kernel Density Estimation o Likelihood Scores. Una tercera opción son clasificadores entrenados para la detección OOD, que aprenden a distinguir entre in-distribution y out-of-distribution usando ejemplos negativos de dominios ajenos y midiendo incertidumbres con Softmax entropy o Monte Carlo Dropout. Estos tres enfoques pueden aplicarse por separado o combinados para reconocer de forma fiable entradas problemáticas.

Sin detección de out of distribution, esos embeddings problemáticos se incluyen en el índice. Esto conduce a un retrieval impreciso, respuestas inadecuadas y, en el peor de los casos, a desinformación. Con un control OOD riguroso, el sistema puede marcar esos chunks, procesarlos con modelos especializados o excluirlos de la inserción. Así se mantiene alta la calidad de la base vectorial y el sistema RAG ofrece resultados más fiables.

Normalización de lenguaje y formatos: números, fechas y unidades

La normalización de lenguaje y formatos de números, fechas y unidades significa que estas indicaciones se convierten antes de la inserción en embeddings a una forma coherente y comparable. El motivo es que contenidos idénticos pueden anotarse de maneras muy distintas, por ejemplo 1.000 € vs EUR 1000, 12.03.2025 vs 2025-03-12 o “5 kg” vs “5 kilogramos”. Para un modelo de lenguaje estas variantes son distintas cadenas de caracteres aunque signifiquen lo mismo. La normalización las unifica en un formato estándar para que los embeddings reflejen correctamente la igualdad semántica.

Técnicamente esto se realiza con analizadores (parsers) y reglas de conversión que reconocen formatos numéricos, monedas, unidades y fechas, y los convierten a representaciones estandarizadas. Por ejemplo se puede elegir el formato ISO para fechas o el sistema SI para unidades. La normalización se diferencia claramente del Named Entity Recognition, ya que no se trata de identificar entidades, sino de uniformar la representación de valores ya reconocidos.

Sin esta medida surgen embeddings erróneos o distorsionados. El retrieval trata valores semánticamente iguales como distintos, las consultas como “todas las facturas de marzo de 2025” fallan si no se unifican las fechas, y en la generación de respuestas pueden aparecer citas contradictorias si un documento anota “3/12/2025” y otro “12.03.2025”. Con una normalización consistente, los significados quedan claros y los resultados son precisos y fiables.

Indexación y almacenamiento vectorial

Tras el embedding, los chunks se almacenan e indexan en una base de datos vectorial. La elección del índice y sus parámetros influye en la calidad y la latencia del retrieval.

Un índice es una estructura de datos que acelera el acceso, similar al índice de un libro. Indexar significa que al insertar nuevos vectores se organizan de modo que luego puedan hallarse más rápido.

En una base de datos vectorial esto ocurre así: cada chunk de un documento se convierte en un vector. En lugar de guardarlos simplemente en una lista larga, se organizan en un índice. Un ejemplo es el índice IVF (Inverted File Index), que crea clústeres, es decir grupos de vectores similares. Al buscar, el sistema solo recorre los clústeres relevantes, no todos los datos. Otro ejemplo es HNSW (Hierarchical Navigable Small World Graph), donde los vectores son nodos en una red. La búsqueda navega por esta red como por una malla de calles, saltando de un vector al siguiente hasta hallar los más similares.

Sin indexación, el sistema debería comparar cada consulta contra todos los vectores almacenados. Con unos pocos miles de entradas aún funcionaría, pero con millones o miles de millones se vuelve imposible de forma práctica. Un sistema RAG tardaría entonces minutos en lugar de milisegundos en responder. El índice marca la diferencia entre un sistema teóricamente correcto pero inutilizable y una solución rápida y productiva.

Elegir el tipo de índice adecuado al perfil de búsqueda

Elegir el tipo de índice adecuado al perfil de búsqueda significa seleccionar el índice vectorial que mejor se ajuste a los requisitos de precisión, rapidez y volumen de datos del sistema. Distintos tipos de índice ofrecen ventajas diferentes. Un índice HNSW, por ejemplo, permite consultas muy rápidas y precisas, pero consume mucho espacio. Un índice IVF es más eficiente en memoria y adecuado para grandes volúmenes de datos, aunque emplea métodos aproximados que, mal configurados, pueden pasar por alto resultados.

El perfil de búsqueda define qué exige el sistema RAG al retrieval. Un sistema que consulta con frecuencia conjuntos de datos pequeños y requiere alta precisión se beneficia de HNSW. Uno que deba indexar miles de millones de vectores necesita en cambio métodos escalables como IVF o variantes híbridas con cuantización. También intervienen factores como frecuencia de consulta, latencia deseada y hardware disponible.

Sin elegir un tipo de índice adecuado surgen problemas sistémicos. Un índice demasiado complejo ralentiza las consultas y genera costes de memoria y operación innecesarios. Uno demasiado simplificado pierde resultados relevantes, de modo que la generación de respuestas parte de información incorrecta o incompleta. La elección del índice es, por tanto, un pilar fundamental para equilibrar eficiencia, precisión y coste en un sistema RAG.

Ajustar sistemáticamente los parámetros de HNSW

Ajustar sistemáticamente los parámetros de HNSW significa configurar con criterio las opciones del índice HNSW para lograr un buen equilibrio entre velocidad de búsqueda, precisión y consumo de memoria. HNSW, o Hierarchical Navigable Small World Graph, es uno de los algoritmos más usados para búsquedas aproximadas en espacios vectoriales. Construye una red multicapa de vectores, en la que cada vector se conecta con sus vecinos más cercanos. La búsqueda funciona como una navegación por la red: se parte de forma general y se avanza gradualmente hacia los vecinos más próximos hasta encontrar los mejores resultados.

Parámetros importantes son M, que controla el número máximo de conexiones por nodo, y efSearch, que fija cuántos candidatos se evalúan en cada búsqueda. Un M alto mejora la precisión por más conexiones, pero consume más memoria y ralentiza la construcción del índice. Un efSearch alto aumenta la probabilidad de hallar los vecinos óptimos, pero enlentece la búsqueda. efConstruction es otro parámetro que define la meticulosidad con que se eligen los vecinos durante la construcción del índice. Un valor elevado mejora la calidad del índice, pero alarga su creación.

Calibrar parámetros de IVF

Un Inverted File Index, o IVF, es un método para acelerar búsquedas en bases vectoriales muy grandes. La idea es dividir los vectores en grupos, llamados clústeres. Cada vector pertenece a un solo clúster, y estos clústeres tienen un punto central. Al realizar una consulta, primero se determina qué clústeres están más cerca del vector de la consulta y solo en ellos se continúa la búsqueda. Así se acelera mucho la operación porque no es necesario evaluar todos los vectores.

Calibrar los parámetros de IVF implica decidir cuidadosamente cuántos clústeres crear y cuán profundo buscar dentro de ellos. Si hay pocos clústeres, cada uno reúne muchos vectores y la búsqueda pierde precisión. Si hay demasiados, la consulta debe examinar muchos grupos, lo que ralentiza y aumenta el uso de memoria.

Por ejemplo, en una base con 500 millones de documentos, crear 1.000 clústeres genera de media 500.000 vectores por clúster, reduciendo precisión. Con 10 millones de clústeres, los grupos son muy pequeños, pero el sistema tarda demasiado en gestionarlos y consultar los relevantes. Un punto intermedio, como 100.000 clústeres bien configurados, logra una búsqueda rápida y precisa.

Sin esta calibración, el índice IVF trabajará o demasiado grueso o demasiado costoso, provocando resultados omitidos o tiempos de respuesta largos. Para grandes sistemas RAG, un ajuste cuidadoso es esencial para que la búsqueda vectorial sea fiable y eficiente.

Aplicar con criterio cuantización y compresión

Aplicar con criterio cuantización y compresión significa almacenar los vectores de forma más compacta sin sacrificar innecesariamente la calidad de la búsqueda. Los embeddings suelen consistir en cientos o miles de números de punto flotante con alta precisión. Para la búsqueda semántica, esa precisión muchas veces no es totalmente necesaria. En su lugar, los valores pueden reducirse o codificarse para consumir menos espacio y acelerar consultas.

Un método muy usado es la cuantización de producto (Product Quantization, PQ). El vector se divide en subvectores y cada parte se representa con un código compacto extraído de un diccionario. Así el consumo de memoria baja drásticamente y se conserva en gran medida la proximidad semántica. Una variante es la PQ optimizada (OPQ), que rota primero los vectores para distribuir mejor la información entre subvectores, mejorando la precisión.

Por ejemplo, una base con 500 millones de vectores de 768 dimensiones ocuparía varios terabytes sin comprimir. Con cuantización de producto ese volumen puede reducirse a una fracción, a menudo por encima del 90 %, sin volver inútil la calidad de los resultados. Así incluso bases de gran tamaño siguen siendo aptas para búsquedas rápidas.

Sin cuantización y compresión, los sistemas RAG pronto se topan con límites técnicos. El consumo de memoria y costes crecen mucho, las copias de seguridad resultan pesadas y las consultas tardan demasiado. Con una estrategia de compresión adecuada se gestionan eficientemente grandes volúmenes vectoriales, manteniendo un equilibrio razonable entre precisión y eficiencia.

Mantener índices de carga útil (payload) optimizados para filtros

Mantener índices de carga útil optimizados para filtros significa almacenar no solo los vectores, sino también metadatos adicionales organizados para permitir filtrados rápidos y fiables. En la práctica rara vez basta con encontrar fragments semánticamente similares; suele ser necesario acotar los resultados por atributos como departamento, tipo de documento, fecha de publicación o nivel de permiso. Para que esto sea eficiente, la base vectorial necesita estructuras específicas que soporten dichos filtros con mínimo esfuerzo computacional.

Por ejemplo, una empresa quiere respuestas solo de documentos del departamento de contabilidad. En la base vectorial los chunks de todos los departamentos conviven, pero cada chunk lleva un metadato “departamento”. Un índice de payload optimizado hace que esta información esté integrada en el índice y se aplique en cada consulta de forma eficiente. Sin estos índices, el sistema primero obtendría todos los resultados vectoriales y luego los filtraría, lo cual consume tiempo y memoria.

Sin índices de payload filter-friendly, las consultas a medida que crece la base de datos se ralentizan y devuelven resultados irrelevantes de otros departamentos, o los usuarios esperan mucho por respuestas. Con un índice de payload bien diseñado, los filtros se aplican ya durante el retrieval, reduciendo el conjunto y mejorando la calidad, para que la generación de respuestas trabaje sobre datos muy selectos.

Imponer la prefiltración antes del ANN

Imponer la prefiltración antes de la búsqueda Approximate Nearest Neighbor (ANN) significa aplicar restricciones como tipo de documento, idioma, referencia de proyecto o permisos de acceso antes de la búsqueda vectorial. Los algoritmos ANN son muy eficaces localizando vecinos cercanos en millones de vectores, pero cuanto mayor es el conjunto a explorar, más lentos e imprecisos se vuelven. Por eso es esencial limitar desde el inicio los candidatos solo a aquellos realmente relevantes.

Por ejemplo, una empresa guarda contratos, tickets de soporte y manuales en una base vectorial. Un usuario busca información de un error de producto, que solo aparece en tickets de soporte. Si la prefiltración se aplica antes, el sistema busca exclusivamente en los vectores con metadato “tipo de documento = Ticket de soporte”. Sin ello, la búsqueda ANN se ejecutaría sobre todo el corpus y luego filtraría, aumentando el coste, la latencia y pudiendo incluir contratos irrelevantes en los candidatos.

Sin prefiltración rigurosa, los costes suben, la velocidad baja y los usuarios pueden recibir información inapropiada. Con una prefiltración bien implementada, las consultas son más livianas, la calidad de resultados sube y se cumple con las condiciones de relevancia y cumplimiento desde el inicio.

Diseñar correctamente sharding y replicación

El problema inicial en bases vectoriales es que un solo servidor alcanza pronto sus límites físicos y técnicos al crecer datos y uso. Con millones o miles de millones de embeddings, la memoria no basta, los índices HNSW o IVF ocupan mucho y las peticiones simultáneas generan cuellos de botella en CPU e I/O. Además, la disponibilidad se resiente: si el único servidor falla, la búsqueda vectorial deja de estar disponible.

El sharding resuelve esto dividiendo el conjunto de datos en subconjuntos. Cada parte contiene una porción de embeddings y reside en un servidor o nodo distinto. Así ningún servidor necesita mantener el índice completo, y carga y memoria se distribuyen. Una búsqueda debe consultarlos todos, ya que los vectores más cercanos pueden estar en cualquier shard, y luego compilar los resultados parciales. Esto también implica que sin replicación, la caída de un shard empobrece la búsqueda al faltar embeddings.

La replicación complementa al sharding duplicando cada partición en varios servidores. Cada shard tiene al menos una copia. Esto aporta dos ventajas: la base completa permanece accesible aun si falla un nodo, y las consultas se reparten entre réplicas, mejorando rendimiento bajo alta carga. Así un fallo en un shard no conlleva pérdida de datos ni calidad de búsqueda.

La diferencia es clara: el sharding distribuye, la replicación duplica. Combinados, permiten un sistema escalable y tolerante a fallos.

El paralelismo con RAID en discos ilustra bien: el sharding equivale al striping de RAID 0, donde bloques de datos se reparten para aumentar velocidad; la replicación es como RAID 1, donde cada disco tiene una copia exacta, asegurando disponibilidad. En bases vectoriales suele emplearse ambas prácticas para gestionar grandes volúmenes con alta disponibilidad y fiabilidad.

Sin sharding y replicación, una base vectorial alcanza pronto límites de escalabilidad y disponibilidad en proyectos grandes. Con ambos conceptos, sigue siendo potente, tolerante a fallos y consistente, incluso con miles de millones de vectores, y las caídas puntuales no afectan la calidad de búsqueda.

Definir consistencia y aislamiento de lectura

Definir consistencia y aislamiento de lectura en un sistema distribuido de base vectorial significa establecer cómo interactúan consultas y actualizaciones y qué versión de los datos ve el usuario al buscar. Como los embeddings se distribuyen en shards y réplicas, las nuevas inserciones o cambios pueden propagarse con retraso a cada nodo. La consistencia describe si una consulta debe ver el mismo estado en todos los nodos inmediatamente tras una actualización (consistencia fuerte) o si se permiten breves diferencias (consistencia eventual).

El aislamiento de lectura se refiere a si las consultas están autorizadas a ver estados intermedios durante una operación de escritura. Con baja aislación, una búsqueda podría acceder a datos que aún se modifican y no están estables. Con alta aislación, la consulta ve o bien el estado anterior o bien el nuevo, pero nunca una mezcla.

Sin reglas claras de consistencia e aislamiento, la búsqueda vectorial ofrece resultados contradictorios. Usuarios reciben diferentes respuestas a la misma consulta, la generación de respuestas parte de datos incompletos y las auditorías pierden fiabilidad. Con definiciones explícitas, se garantiza predictibilidad, trazabilidad y confianza en el sistema.

Actualización incremental del índice

La actualización incremental del índice implica que los nuevos o modificados embeddings no requieren reconstruir todo el índice, sino que se insertan o reemplazan solo en las partes afectadas. Con grandes volúmenes, una reconstrucción completa es muy costosa y puede tardar horas o días. Un enfoque incremental actualiza únicamente los segmentos del índice impactados, manteniendo el resto operativo sin interrupción.

El proceso es así: cuando se procesa y embebe un nuevo documento, su vector se inserta en la ubicación adecuada del índice. Si un documento cambia o se elimina, sus vectores se marcan o se eliminan. Procesos en segundo plano o índices delta garantizan que estos cambios se incorporen de forma continua sin interrumpir la búsqueda.

Sin actualización incremental, habría que reconstruir periódicamente todo el índice, provocando largos tiempos de inactividad, resultados desactualizados y elevados costes operativos. Con actualizaciones incrementales, el índice permanece al día, la búsqueda vetorial mantiene su rendimiento y el sistema opera con estabilidad incluso con datos en crecimiento constante.

Usar caches de resultados y de centroides

Usar caches de resultados y de centroides significa almacenar en memoria cálculos que se repiten con frecuencia en la búsqueda vectorial. Esto permite acelerar consultas sin alterar la calidad de los resultados. Hay dos niveles donde el cache es útil.

En el primer nivel están consultas completas. Si muchos usuarios hacen la misma o muy similar, se generan listas de resultados idénticas o casi idénticas. Por ejemplo, en un portal de soporte interno los empleados buscan con frecuencia “instrucciones VPN”. Sin cache, cada consulta ejecuta la búsqueda de vecinos aunque siempre encuentre los mismos cinco documentos. Con un cache de resultados, esa lista se guarda al primer acceso y se reutiliza inmediatamente.

En el segundo nivel están los pasos internos dentro del índice. Con índices como IVF, primero se asignan los centros de clúster (centroides) más próximos a la consulta antes de afinar la búsqueda dentro del clúster. Estas distancias a centroides se calculan de nuevo con consultas similares. Con cache de centroides se recuperan directamente los valores o la selección de clúster sin recálculo.

Sin estos caches, el sistema vuelve a ejecutar consultas triviales y pasos internos una y otra vez. Esto genera latencia y carga innecesarias bajo alto volumen de peticiones. Con un cache bien diseñado se logran mejoras de rendimiento significativas, especialmente en escenarios con consultas recurrentes o búsquedas concentradas en un tema.

Optimizar el layout de memoria

Optimizar el layout de memoria significa organizar cómo se almacenan físicamente embeddings e índices en memoria para que las operaciones de búsqueda sean rápidas y eficientes en recursos. En bases vectoriales el rendimiento depende en gran medida de cómo se estructuran los datos en RAM o en disco.

Un concepto central es decidir si los datos se guardan por filas o por columnas. Si los embeddings se almacenan por filas, cada fila contiene el vector completo. Esto acelera el cálculo de distancias, ya que todos los valores de un vector están contiguos en memoria y se cargan en una sola operación. El almacenamiento por columnas puede ser ventajoso si solo se usan o comprimen ciertas dimensiones.

También importa la alineación en memoria (memory alignment). CPUs y GPUs cargan datos en bloques de tamaño fijo, por ejemplo 64 bits en CPUs o 256 bits en GPUs. Si un vector no empieza en el límite de un bloque, el hardware debe leer varios bloques y ensamblarlos, aunque el vector quepa en uno. Esto se soluciona alineando los vectores exactamente en esos límites, permitiendo lecturas en un solo acceso y acelerando el procesamiento. Además se utilizan técnicas como memory mapping, que mapean índices grandes directamente en memoria sin copiarlos completos.

Sin optimizar el layout de memoria surgen cuellos de botella. Las consultas tardan más por accesos fragmentados y el hardware no se aprovecha al máximo. Con un layout optimizado, la búsqueda vectorial gana velocidad notablemente y hasta grandes volúmenes pueden procesarse con eficiencia.

Gestionar el ciclo de vida de datos en el índice

Gestionar el ciclo de vida de datos en el índice significa que las entradas en la base vectorial no permanecen estáticas para siempre, sino que siguen un ciclo de vida bien definido. Los embeddings reflejan el estado del conocimiento en el momento de su creación. Si los documentos cambian, se corrigen o caducan, sus vectores deben actualizarse o eliminarse. De lo contrario, el índice retendrá información desactualizada o errónea, que luego producirá resultados inapropiados.

Técnicamente, el ciclo de vida se controla con metadatos. Cada vector recibe atributos como fecha de creación, número de versión, periodo de validez o fecha de expiración. Cuando un documento cambia, su embedding antiguo se reemplaza por el nuevo. Los fragments obsoletos pueden archivarse o eliminarse automáticamente. También se implementan así obligaciones de borrado según normativas, como la GDPR.

Sin gestionar el ciclo de vida, el índice crece sin control, la calidad del retrieval empeora por resultados contradictorios o desfasados y surgen riesgos de cumplimiento al hallar contenidos eliminados o caducados. Un manejo activo del ciclo de vida asegura que solo estén en el índice contenidos actuales, consistentes y válidos, mejorando así la precisión y la fiabilidad de todo el sistema RAG.

Enrutamiento del corpus y selección de índice por consulta

El enrutamiento del corpus y la selección de índice por consulta significa que no todas las búsquedas recorren ciegamente todo el conjunto de datos, sino que se dirigen al subcorpus o índice adecuado. En grandes empresas suelen coexistir varios mundos de datos, por ejemplo un índice para manuales técnicos, otro para contratos jurídicos, otro para tickets de soporte y otro para material de marketing. Un único índice gigantesco hace que el retrieval sea impreciso e ineficiente.

El enrutamiento decide, según la consulta, qué índice debe consultarse o si hay que utilizar varios en paralelo. Se analizan características de la consulta, como palabras clave detectadas, idioma, tipo de documento u opciones organizativas como departamento o proyecto. También entran en juego parámetros manuales o metadatos de la petición. Un módulo de enrutamiento dirige la consulta solo a los índices relevantes, ahorrando recursos y tiempo.

Por ejemplo, ante “¿Cuáles son los intervalos de mantenimiento de la máquina X?”, el sistema detecta que se trata de una consulta técnica y la dirige solo al índice de manuales y documentación de mantenimiento. No consulta marketing ni contratos. Esto reduce la latencia, evita resultados irrelevantes y mejora notablemente la calidad de los hallazgos.

Sin enrutamiento del corpus, cada consulta busca en todos los índices. Esto genera carga innecesaria, aumenta latencias y multiplica los resultados irrelevantes. Además crece el riesgo de que fragments fuera de contexto escalen en el ranking y distorsionen la respuesta. Con un enrutamiento focalizado la búsqueda es eficiente y entrega respuestas más relevantes.

Arquitectura híbrida con IDs sincronizadas

El problema en sistemas de búsqueda empresariales es que ninguna única tecnología cubre todos los requisitos al mismo tiempo. Un usuario a menudo necesita resultados de diferentes fuentes, porque una pregunta rara vez aborda un solo nivel. Al buscar “ISO 27001” no basta con hallar contenidos similares: las explicaciones técnicas de directrices vienen del vectorial, las menciones textuales exactas de la norma requieren búsqueda de texto completo, y la información organizativa como estado de aprobación o departamentos implicados procede de búsquedas de metadatos. Solo al combinar estos resultados se obtiene una visión completa. La respuesta es así tanto semánticamente precisa, textualmente avalada como contextualmente alineada.

El RAG puro emplea búsqueda vectorial y modelo de lenguaje. En la práctica se amplía con búsquedas de texto completo y de metadatos. De este modo se cubren todos los aspectos: cercanía semántica, coincidencias literales y contexto organizativo. Para que estos hallazgos no aparezcan duplicados o inconsistentes se necesita una arquitectura híbrida con IDs sincronizadas. Cada fuente referencia el mismo origen mediante un identificador común, de modo que los resultados se consoliden e integren de forma coherente en la generación de respuestas. Sin esta sincronización surgirán datos duplicados, inconsistentes o incompletos.

Definir y documentar la función de distancia: coseno, L2, producto interno

Definir la función de distancia significa establecer la regla matemática para medir la similitud entre dos embeddings. Tres métodos consolidados son la distancia coseno, la distancia L2 y el producto interno. La distancia coseno mide el ángulo entre dos vectores y es ideal cuando importa la dirección y no la longitud. La distancia L2, o euclidiana, mide la distancia geométrica y considera tanto dirección como magnitud. El producto interno evalúa cuánto coinciden en dirección y longitud los vectores.

La elección depende del caso de uso y del modelo de embedding: unos están entrenados específicamente para similitud coseno, otros para distancias euclidianas o producto interno. Si se aplica una función inadecuada, se pueden pasar por alto vecinos relevantes o priorizar irrelevantes. Por ello es fundamental documentar claramente la función de distancia y usarla de forma consistente en todos los componentes del sistema.

Sin una definición y documentación claras de la función de distancia surgen inconsistencias. Dos equipos podrían consultar el mismo índice con métodos distintos y obtener resultados diferentes. Los benchmarks perderían validez y la calidad de las respuestas dejaría de ser reproducible. Con una función de distancia bien seleccionada y documentada la búsqueda es fiable y los resultados trazables.

Conclusión

En la Parte 2 ha quedado claro que la calidad de un sistema RAG no depende solo del modelo de lenguaje, sino en gran medida de los embeddings y de cómo se almacenan. Ajustes específicos de dominio, mapeo multilingüe, normalización, detección OOD y la elección de estructuras de índice adecuadas determinan la fiabilidad y eficiencia de la búsqueda semántica y la solidez de la generación de respuestas. Sin embeddings bien definidos y una indexación robusta, incluso el modelo más potente produce resultados imprecisos.

En las próximas entregas nos centraremos en el proceso de retrieval. Abordaremos cómo mejorar la selección y ponderación de los chunks relevantes, cuáles son las estrategias para re-ranking y métodos híbridos, y cómo integrar metadatos y contexto de forma sistemática en la búsqueda. Paso a paso, construiremos una visión completa de cómo optimizar un sistema RAG desde la base de datos hasta la respuesta final.