Saltar al contenido
Lección 3 de 12

Bases de Datos Vectoriales

8 min read

Que Hacen las Bases de Datos Vectoriales

Una base de datos vectorial es un almacen de datos especializado optimizado para almacenar, indexar y consultar vectores de alta dimensionalidad. En un sistema RAG, contiene los embeddings de tus fragmentos de documentos y te permite encontrar rapidamente los fragmentos mas similares a un embedding de consulta.

Las bases de datos regulares estan disenadas para coincidencias exactas: dame la fila donde id = 42 o donde nombre = 'Alice'. Las bases de datos vectoriales resuelven un problema fundamentalmente diferente: dame los 10 vectores mas cercanos a este vector de consulta en un espacio con cientos o miles de dimensiones. Esto se llama busqueda de Vecino Mas Cercano Aproximado (ANN), y requiere algoritmos de indexacion especializados para realizarla rapidamente.

Una base de datos vectorial tipica almacena tres cosas por entrada:

  • El vector -- el embedding en si (e.g., 1536 flotantes)
  • Los metadatos -- campos estructurados como fuente, fecha, autor o categoria
  • El texto del documento -- el fragmento original de texto que fue embebido

Cuando consultas, envias un vector y recibes las top-K entradas mas similares, cada una con sus metadatos y texto.

El Panorama: Eligiendo la Base de Datos Correcta

FAISS es una biblioteca, no una base de datos. Desarrollada por Meta, proporciona algoritmos de busqueda de similitud altamente optimizados que se ejecutan en memoria. Es extremadamente rapido -- a menudo la opcion mas rapida para conjuntos de datos de menos de 10 millones de vectores.

Mejor para: Desarrollo local, prototipado, aplicaciones donde todos los datos caben en memoria, pipelines de procesamiento por lotes.

Limitaciones: Sin persistencia incorporada (guardas/cargas archivos de indice manualmente), sin filtrado de metadatos, sin servidor API incorporado, sin autenticacion. Tienes que construir todo alrededor.

import faiss
import numpy as np

# Crear un indice para vectores de 1536 dimensiones
dimension = 1536
index = faiss.IndexFlatL2(dimension)  # Busqueda exacta con distancia L2

# Agregar vectores
vectors = np.random.rand(1000, dimension).astype('float32')
index.add(vectors)

# Buscar 5 vecinos mas cercanos
query = np.random.rand(1, dimension).astype('float32')
distances, indices = index.search(query, k=5)

print(f"Indices mas cercanos: {indices[0]}")
print(f"Distancias: {distances[0]}")

# Guardar y cargar el indice
faiss.write_index(index, "my_index.faiss")
loaded_index = faiss.read_index("my_index.faiss")

ChromaDB

ChromaDB es una base de datos de embeddings de codigo abierto disenada especificamente para aplicaciones de IA. Tiene una API limpia en Python, maneja la persistencia automaticamente, soporta filtrado de metadatos e incluye una funcion de embedding incorporada para que puedas pasar texto sin procesar en lugar de vectores pre-calculados.

Mejor para: Prototipado, conjuntos de datos pequenos a medianos (hasta unos pocos millones de documentos), proyectos donde la experiencia del desarrollador importa, aprendizaje de conceptos RAG.

Limitaciones: No disenado para escala masiva (miles de millones de vectores), lenguaje de consulta limitado comparado con bases de datos completas.

import chromadb

# Crear un cliente persistente
client = chromadb.PersistentClient(path="./chroma_db")

# Crear una coleccion (como una tabla)
collection = client.get_or_create_collection(
    name="documents",
    metadata={"hnsw:space": "cosine"}  # Usar similitud coseno
)

# Agregar documentos con metadatos
collection.add(
    documents=[
        "La fotosintesis convierte la energia luminosa en energia quimica.",
        "La mitocondria es la central energetica de la celula.",
        "Las redes neuronales estan inspiradas en neuronas biologicas.",
    ],
    metadatas=[
        {"source": "libro_biologia", "chapter": 5},
        {"source": "libro_biologia", "chapter": 3},
        {"source": "libro_informatica", "chapter": 12},
    ],
    ids=["doc1", "doc2", "doc3"]
)

# Consultar con lenguaje natural
results = collection.query(
    query_texts=["Como crean energia las plantas?"],
    n_results=2,
    where={"source": "libro_biologia"}  # Filtro de metadatos
)

print(results["documents"])
print(results["distances"])

Pinecone

Pinecone es un servicio de base de datos vectorial completamente gestionado. No ejecutas ninguna infraestructura -- creas un indice a traves de su API y Pinecone maneja almacenamiento, indexacion, escalado y disponibilidad.

Mejor para: Despliegues en produccion, equipos que no quieren gestionar infraestructura, aplicaciones que requieren alta disponibilidad y escalado.

Limitaciones: Dependencia de proveedor, costos recurrentes, los datos salen de tu infraestructura, la latencia depende de la red (aunque ofrecen despliegues regionales).

pgvector

pgvector es una extension de PostgreSQL que agrega busqueda de similitud vectorial a tu base de datos PostgreSQL existente. Si ya usas PostgreSQL, esta es una opcion convincente porque mantienes tus vectores junto a tus datos relacionales.

Mejor para: Equipos que ya usan PostgreSQL, aplicaciones que necesitan JOINs SQL entre resultados vectoriales y datos relacionales, requisitos de infraestructura mas simples.

Limitaciones: El rendimiento esta por debajo de las bases de datos vectoriales dedicadas a muy alta escala. Las opciones de indexacion son mas limitadas.

Weaviate

Weaviate es una base de datos vectorial de codigo abierto con una API GraphQL, modulos incorporados para generacion de embeddings y busqueda hibrida (combinando busqueda vectorial y por palabras clave en una sola consulta).

Mejor para: Equipos que quieren busqueda hibrida lista para usar, arquitecturas orientadas a GraphQL, aplicaciones que necesitan soporte multimodal incorporado.

Qdrant

Qdrant es una base de datos vectorial de codigo abierto escrita en Rust, con enfasis en rendimiento y APIs con tipado seguro. Tiene excelentes capacidades de filtrado y soporta almacenamiento tanto en memoria como en disco.

Mejor para: Aplicaciones criticas en rendimiento, equipos que necesitan filtrado avanzado, ecosistemas Rust o gRPC.

Resumen Comparativo

| Caracteristica | FAISS | ChromaDB | Pinecone | pgvector | Qdrant | |----------------|-------|----------|----------|----------|--------| | Tipo | Biblioteca | Base de datos | Gestionado | Extension | Base de datos | | Persistencia | Manual | Incorporada | Gestionada | PostgreSQL | Incorporada | | Filtrado de metadatos | No | Si | Si | SQL | Si | | Hosting gestionado | No | No | Si | Via proveedores | Opcion cloud | | Busqueda hibrida | No | No | Si | Con tsvector | Si | | Mejor escala | Millones | Millones | Miles de millones | Millones | Miles de millones | | Curva de aprendizaje | Media | Baja | Baja | Baja (si sabes SQL) | Media |

Estrategias de Indexacion

Cuando tu conjunto de datos crece mas alla de decenas de miles de vectores, la busqueda exacta de vecinos mas cercanos (comparar la consulta con cada vector almacenado) se vuelve demasiado lenta. Las bases de datos vectoriales usan algoritmos aproximados para intercambiar una pequena cantidad de precision por mejoras masivas de velocidad.

HNSW (Hierarchical Navigable Small World)

HNSW es el algoritmo de indexacion mas popular y el predeterminado en ChromaDB, Qdrant y pgvector. Construye un grafo multicapa donde cada nodo es un vector. La busqueda comienza en la capa superior (gruesa) y navega hacia capas mas finas.

  • Velocidad de busqueda: Excelente (sub-milisegundo para millones de vectores)
  • Tiempo de construccion del indice: Moderado
  • Memoria: Alta (la estructura del grafo vive en memoria)
  • Precision: Muy alta (tipicamente 95-99% de recall)

Parametros clave:

  • M -- numero de conexiones por nodo (mayor = mejor recall, mas memoria)
  • ef_construction -- amplitud del haz durante la construccion del indice (mayor = mejor recall, construccion mas lenta)
  • ef_search -- amplitud del haz durante la busqueda (mayor = mejor recall, busqueda mas lenta)

IVF (Inverted File Index)

IVF particiona el espacio vectorial en clusters usando k-means. En tiempo de consulta, solo busca los clusters mas cercanos al vector de consulta. Este es el enfoque predeterminado de FAISS para busqueda a gran escala.

  • Velocidad de busqueda: Buena (depende del parametro nprobe)
  • Tiempo de construccion del indice: Rapido
  • Memoria: Menor que HNSW
  • Precision: Buena (depende del numero de clusters y nprobe)
import faiss
import numpy as np

dimension = 1536
n_vectors = 100000

# Crear indice IVF con 100 clusters
quantizer = faiss.IndexFlatL2(dimension)
index = faiss.IndexIVFFlat(quantizer, dimension, 100)

# Entrenar el indice (IVF requiere entrenamiento con datos de muestra)
training_data = np.random.rand(n_vectors, dimension).astype('float32')
index.train(training_data)
index.add(training_data)

# Buscar -- nprobe controla el tradeoff entre precision y velocidad
index.nprobe = 10  # Buscar en los 10 clusters mas cercanos
query = np.random.rand(1, dimension).astype('float32')
distances, indices = index.search(query, k=5)

Cuando Usar Cual Base de Datos

Recien comenzando o aprendiendo: ChromaDB. La API es intuitiva, la persistencia es automatica y puedes pasar de cero a buscar en cinco minutos.

Necesitas maximo rendimiento local: FAISS. Nada lo supera en velocidad pura en una sola maquina. Combinalo con un almacen de metadatos simple si necesitas filtrado.

Yendo a produccion con un equipo: Pinecone si quieres cero gestion de infraestructura. Qdrant si quieres autoalojar con excelente rendimiento. Weaviate si necesitas busqueda hibrida y GraphQL.

Ya usas PostgreSQL: pgvector. Mantener todo en una sola base de datos simplifica tu arquitectura enormemente, y el rendimiento es suficiente para la mayoria de las cargas de trabajo hasta unos pocos millones de vectores.

Consejo: Comienza con ChromaDB para desarrollo, luego migra a tu base de datos de produccion una vez que tus requisitos esten claros. Los cambios en el codigo de recuperacion son minimos -- generalmente solo cambiar la inicializacion del cliente y ajustar la sintaxis de consulta.

En la siguiente leccion, aprenderas como meter tus documentos en estas bases de datos procesandolos y preparandolos para embedding.