Resumen

Mantener una base de datos vectorial limpia, sin duplicados y sincronizada con lo que los usuarios realmente ven es uno de los retos más frecuentes en proyectos de inteligencia artificial. La indexación de vectores resuelve exactamente ese problema: evita generar embeddings repetidos, reduce costos operativos y garantiza coherencia entre los datos almacenados y los que se consultan.

¿Por qué la indexación de vectores es tan importante?

Cuando trabajas con grandes volúmenes de datos, es común que el mismo contenido se procese más de una vez. Cada vez que generas un embedding duplicado, estás pagando por una llamada innecesaria a servicios como OpenAI y ocupando espacio en tu vector store. La indexación ataca tres frentes clave [0:06]:

  • Eliminación de duplicidad: si dos documentos son idénticos, solo se indexa uno.
  • Ahorro de costos: se evita volver a generar embeddings para vectores que ya existen.
  • Sincronía de datos: lo que el usuario consulta coincide con lo que realmente está almacenado.

¿Cómo se configuran los componentes del índice?

Para construir un índice funcional se necesitan dos componentes principales [1:15].

¿Qué papel cumple la vector store?

Es el almacén donde residen los vectores. En el ejemplo se utiliza Chroma, una base de datos vectorial ligera que ya se aborda en otros módulos del curso. Se crea una instancia de tipo Chroma y se le indica dónde persistir los datos.

¿Qué es el record manager y cómo funciona?

El SQL Record Manager es el encargado de llevar el seguimiento (tracking) de qué documentos han entrado y cuándo llegaron a la vector store [1:40]. Recibe dos parámetros fundamentales:

  • Namespace: identifica la base de datos vectorial y la colección que se está rastreando. Un buen patrón es escribir el nombre de la base de datos seguido del nombre de la colección, por ejemplo chroma/langchain_docs_index.
  • DB URL: la ubicación de la base de datos de tracking. Puede ser una base SQLite en memoria, lo que significa que al cerrar la sesión los datos de seguimiento desaparecen [2:10].

Una vez creado el record manager, es necesario llamar a create_schema() para generar las tablas internas que almacenan los registros de seguimiento.

¿Cómo funciona la limpieza de tipo none?

LangChain ofrece varios métodos de limpieza al indexar. El modo none es la opción por defecto y tiene un comportamiento muy específico [3:20]:

  • No remueve documentos previamente indexados.
  • Sí elimina duplicados al momento de la ingesta: si introduces dos documentos idénticos, solo indexa uno.

Para ejecutar la indexación se llama a la función index() con cuatro parámetros principales:

  • docs_source: los documentos a indexar.
  • record_manager: el gestor de registros.
  • vector_store: la base de datos vectorial destino.
  • cleanup: el método de limpieza, en este caso "none".

Existe además un parámetro opcional llamado source_id_key [4:10]. Este valor vive en los metadatos de cada documento y permite agrupar fragmentos que provienen del mismo recurso. Por ejemplo, si una página web se divide en diez fragmentos, todos comparten el mismo source_id_key apuntando a esa URL original.

¿Qué resultados arroja la primera ejecución?

Al procesar los datos por primera vez, el índice reportó 2601 vectores añadidos cuando el conjunto original contenía aproximadamente 2680 [5:05]. Eso significa que cerca de 80 vectores estaban duplicados y fueron descartados automáticamente. El proceso tardó casi un minuto porque se generaron los embeddings desde cero.

Lo verdaderamente valioso aparece en la segunda ejecución. Al volver a correr el mismo pipeline, el índice solo tarda unos segundos porque utiliza un mecanismo de hashing: genera un hash del contenido textual de cada documento y lo compara con los registros del record manager [5:40]. Si el hash ya existe, el documento se omite por completo y no se vuelve a llamar a la API de embeddings.

En escenarios con cientos de miles o millones de vectores, este comportamiento representa un ahorro significativo en tiempo y dinero. Finalmente, tras cada ejercicio se limpia el índice con una función de utilidad llamada clear_index para reiniciar el estado y evitar interferencias entre pruebas.

¿Has implementado algún sistema de indexación en tus proyectos? Comparte tu experiencia y las estrategias que te han funcionado mejor.