Módulo 2: Cómo funcionan Vector Databases (Conceptual)

Cápsula 02: Arquitectura de Vector Databases (3 Capas)

🎯 Objetivo de la cápsula

Entender las 3 capas arquitectónicas de una vector database (Indexing, Query Engine, Storage) y cómo interactúan para lograr búsqueda eficiente en millones de vectores.

Al finalizar esta cápsula:

  • ✅ Explicarás las 3 capas y su responsabilidad
  • ✅ Entenderás el flujo completo: Insert → Index → Query → Retrieve
  • ✅ Comprenderás por qué separación en capas es importante para performance

Tiempo estimado: 10-12 minutos


🏗️ Las 3 capas de Vector Database

Una vector database NO es solo "almacenar embeddings en disco". Es una arquitectura de 3 capas diseñada para búsqueda eficiente a escala.

Visión general

┌─────────────────────────────────────────┐
│  LAYER 1: INDEXING                      │
│  Construir estructura para búsqueda     │
│  rápida (HNSW, IVF, PQ)                 │
└─────────────────────────────────────────┘
              ↓
┌─────────────────────────────────────────┐
│  LAYER 2: QUERY ENGINE                  │
│  Ejecutar búsqueda en índice            │
│  (ANN search, filtering, ranking)       │
└─────────────────────────────────────────┘
              ↓
┌─────────────────────────────────────────┐
│  LAYER 3: STORAGE                       │
│  Persistir vectores + metadata en disco │
│  (durability, backups, replication)     │
└─────────────────────────────────────────┘

Clave: Cada capa tiene responsabilidad específica. Esto permite optimizar cada una independientemente.


Layer 1: Indexing (Construcción de índice)

¿Qué hace?

Construye estructura de datos especializada para búsqueda rápida, transformando colección desordenada de vectores en grafo/árbol navegable.

¿Por qué es importante?

Sin indexing, búsqueda es brute force O(n):

# Sin índice (brute force)
for vector in database:  # ❌ 1M iteraciones
    similarity = cosine(query, vector)

Con indexing, búsqueda es O(log n) o mejor:

# Con índice HNSW (conceptual)
path = navigate_graph(query)  # ✅ ~100 saltos (no 1M)
candidates = get_neighbors(path)

Algoritmos principales

AlgoritmoTipoComplejidadUsado por
HNSWGrafo navegable jerárquicoO(log n)ChromaDB, Weaviate, Qdrant
IVFClustering + bucketsO(sqrt(n))Faiss, Milvus
PQCompresión de vectoresO(n) compressedFaiss, Milvus (addon)
ScaNNLearned quantizationO(log n)Google Research

Profundizaremos en cada algoritmo en Cápsulas 04-06.

Trade-offs

Build time vs Query time:

  • HNSW: Build lento (1M vectores = 5-10 min), Query rápido (15ms)
  • IVF: Build rápido (1M vectores = 2-3 min), Query medio (30ms)

Memory vs Accuracy:

  • HNSW: Mayor memoria (4-8 GB para 1M vectores 1536-dim), accuracy 98%
  • IVF+PQ: Menor memoria (1-2 GB), accuracy 88-93%

Layer 2: Query Engine (Motor de búsqueda)

¿Qué hace?

Ejecuta búsqueda en índice usando algoritmo apropiado + aplica filtros + ranking.

Responsabilidades

  1. ANN Search (Approximate Nearest Neighbors)

    • Navegar índice HNSW/IVF
    • Encontrar top-k candidates
  2. Metadata filtering (crucial para RAG)

    • Filtrar por fecha, autor, categoría
    • Ejemplo RAG: Solo buscar en documentos de "customer support"
  3. Post-filtering ranking

    • Re-score resultados con metadata
    • Remover duplicados

Flujo de query

User query → Embed → ANN Search → Filter → Rank → Top-k results

Ejemplo RAG concreto:

# Query
query = "How do I reset my password?"
query_embedding = embed(query)  # [1536 dims]

# Layer 2: Query Engine ejecuta
results = db.query(
    query_embedding=query_embedding,
    k=10,  # Top 10 candidates
    where={"category": "support", "language": "en"},  # Filtro metadata
)

# Resultados: Top 10 chunks relevantes filtrados

Trade-offs

Filtering antes vs después de ANN:

Pre-filtering (filtrar antes de búsqueda):

  • ✅ Más rápido (busca en subset)
  • ❌ Puede fallar si subset vacío
  • Usado por: Pinecone, Weaviate

Post-filtering (filtrar después de búsqueda):

  • ✅ Siempre devuelve resultados
  • ❌ Más lento (busca en todo, luego filtra)
  • Usado por: ChromaDB (default)

Decisión: Depende de tu caso de uso RAG (volumen de filtros, cardinalidad de metadata).


Layer 3: Storage (Persistencia)

¿Qué hace?

Persiste vectores + metadata en disco con garantías de durabilidad, consistencia, y backups.

Responsabilidades

  1. Durability (no perder datos)

    • Write-ahead log (WAL)
    • Snapshots periódicos
  2. Replication (alta disponibilidad)

    • Master-replica setup
    • Eventual consistency
  3. Compression (reducir storage cost)

    • Comprimir vectores en disco
    • Descomprimir en memoria para query

Implementaciones comunes

Storage BackendUsado porCaracterísticas
Embedded DB (SQLite, RocksDB)ChromaDBLocal, single-node, fácil setup
Object Storage (S3, GCS)PineconeCloud-native, infinitely scalable
Columnar Storage (Parquet)WeaviateEficiente para analytics
Distributed FS (HDFS, Ceph)MilvusEnterprise, multi-node

Trade-offs

In-memory vs Disk:

In-memory:

  • ✅ Latencia ultra-baja (<5ms)
  • ❌ Costoso (RAM > disk)
  • ❌ Limite de scale (RAM finita)
  • Usado por: Redis + RediSearch

Disk-based:

  • ✅ Económico (disk es barato)
  • ✅ Infinitely scalable
  • ❌ Latencia mayor (10-50ms)
  • Usado por: ChromaDB, Pinecone, Milvus

Hybrid (mayoría de prod):

  • Hot data (reciente) → RAM
  • Cold data (viejo) → Disk
  • Best of both worlds

🔄 Flujo completo: Insert → Query

Ahora que conoces las 3 capas, veamos cómo interactúan en operaciones reales.

Operación 1: Insert (agregar vectores)

User                Layer 1         Layer 2         Layer 3
 │                  Indexing        Query Eng       Storage
 │
 ├─ insert(vec) ──→ Build index ──→ (no-op) ──────→ Persist to disk
 │                  (HNSW add)                       (append WAL)
 │                      │                                 │
 │                      └─────── Index built ────────────┘
 │                               (async)
 │
 └─ ACK inserted

Pasos:

  1. User inserta vector + metadata
  2. Layer 1 (Indexing): Agrega vector a índice HNSW (update grafo)
  3. Layer 3 (Storage): Persiste a disco (write-ahead log)
  4. ACK al user (operación completa)

Nota: Build index puede ser async (batch updates cada N inserts).

Operación 2: Query (buscar similares)

User                Layer 1         Layer 2         Layer 3
 │                  Indexing        Query Eng       Storage
 │
 ├─ query(vec) ────→ ANN search ──→ Apply filters ─→ Fetch metadata
 │                   (navigate      (where clause)   (from disk)
 │                    HNSW graph)        │                │
 │                       │               │                │
 │                       └───── Top-k candidates ────────┘
 │                                       │
 │                                 Re-rank + limit
 │                                       │
 └─ ← Results ────────────────────────────┘

Pasos:

  1. User envía query vector
  2. Layer 2 (Query Engine): Ejecuta ANN search en índice (Layer 1)
  3. Layer 1 (Indexing): Navega grafo HNSW → devuelve candidates
  4. Layer 2 (Query Engine): Aplica filtros metadata
  5. Layer 3 (Storage): Fetch full metadata de candidates
  6. Layer 2 (Query Engine): Re-rank + limit a top-k
  7. Devuelve resultados a user

Latencia típica: 15-50ms (1M vectores, 1536-dim, HNSW)


🏭 Ejemplo real: ChromaDB arquitectura

Veamos cómo ChromaDB implementa estas 3 capas.

Layer 1: Indexing

  • Algoritmo: HNSW (default)
  • Librería: hnswlib (C++ binding)
  • Build strategy: Incremental (agregar vectores uno a uno)

Layer 2: Query Engine

  • ANN search: HNSW navigation
  • Filtering: Post-filtering (busca primero, filtra después)
  • Ranking: Cosine similarity (default) o dot product

Layer 3: Storage

  • Backend: DuckDB (embedded columnar DB)
  • Durability: Write-ahead log (WAL)
  • Compression: Parquet format (vectores + metadata)

Ventaja: Toda la arquitectura en un proceso (no requiere servidor externo).

Desventaja: Single-node (no distributed). Para scale → migrar a Pinecone/Weaviate.


📊 Benchmark: Impact de cada capa

Midamos latencia de cada capa en query típico (1M vectores, 1536-dim, ChromaDB).

CapaOperaciónLatencia% del total
Layer 1ANN search (HNSW navigate)12 ms60%
Layer 2Metadata filtering3 ms15%
Layer 3Fetch full metadata from disk5 ms25%
TotalEnd-to-end query20 ms100%

Insights:

  1. Layer 1 (indexing) domina latencia → Optimizar algoritmo HNSW es crítico
  2. Layer 3 (storage) es 25% → Usar SSD (no HDD) ayuda significativamente
  3. Layer 2 (filtering) es barato → Puedes filtrar agresivamente sin penalty

Comparación con brute force:

MétodoLatenciaSpeedup
Brute force (numpy)1500 ms1x
Vector DB (HNSW)20 ms75x faster

🤔 Por qué separación en capas importa

Ventaja 1: Optimización independiente

Sin separación:

# ❌ Todo en una función (monolítico)
def search(query):
    results = brute_force_search(query)  # Slow
    filtered = apply_filters(results)
    return persist(filtered)

Con separación:

# ✅ Cada capa optimizable independientemente
def search(query):
    candidates = layer1.ann_search(query)  # Optimizado: HNSW
    filtered = layer2.filter(candidates)   # Optimizado: Bitmap index
    full = layer3.fetch(filtered)          # Optimizado: Columnar storage
    return full

Resultado: Puedes cambiar algoritmo de Layer 1 (HNSW → IVF) sin tocar Layers 2-3.

Ventaja 2: Scaling horizontal

Layer 1 (Indexing):

  • Escala con RAM (índice en memoria)
  • Requiere beefy machine (32-64 GB RAM)

Layer 3 (Storage):

  • Escala con disk (S3, GCS)
  • Puede ser separado a storage cluster

Arquitectura distributed:

┌──────────────┐    ┌──────────────┐    ┌──────────────┐
│  Query Node  │───→│  Index Node  │───→│ Storage Node │
│  (Layer 2)   │    │  (Layer 1)   │    │  (Layer 3)   │
└──────────────┘    └──────────────┘    └──────────────┘

Ejemplo: Pinecone usa arquitectura distribuida (Layers 1-3 en nodos separados).

Ventaja 3: Flexibilidad de configuración

Puedes ajustar cada capa según requisitos:

Caso A: Latencia crítica (chatbot)

  • Layer 1: HNSW (alta accuracy, 15ms)
  • Layer 2: Pre-filtering (reduce search space)
  • Layer 3: In-memory (Redis, <5ms)
  • Resultado: <20ms end-to-end

Caso B: Cost-optimized (batch processing)

  • Layer 1: IVF (menor memoria, 50ms)
  • Layer 2: Post-filtering (simple)
  • Layer 3: Disk (S3, 100ms)
  • Resultado: <200ms end-to-end (pero 10x más barato)

✅ Checklist de comprensión

Verifica que entendiste esta cápsula:

  • ¿Cuáles son las 3 capas de vector database?

    • Respuesta: Indexing (construir índice), Query Engine (ejecutar búsqueda), Storage (persistir datos)
  • ¿Qué hace Layer 1 (Indexing)?

    • Respuesta: Construye estructura de datos especializada (HNSW, IVF, PQ) para búsqueda O(log n) vs O(n)
  • ¿Qué hace Layer 2 (Query Engine)?

    • Respuesta: Ejecuta ANN search, aplica filtros metadata, re-rank resultados
  • ¿Qué hace Layer 3 (Storage)?

    • Respuesta: Persiste vectores + metadata con durabilidad, replication, compression
  • ¿Por qué separación en capas es importante?

    • Respuesta: Permite optimizar cada capa independientemente, escalar horizontalmente, ajustar trade-offs según caso de uso

Si respondiste 4-5/5 correctamente → ✅ Listo para Cápsula 03 (Indexing Algorithms Overview)


🔗 Conexión con RAG

¿Cómo esto ayuda en RAG?

Cuando construyes RAG system, necesitas entender arquitectura para:

Debuggear performance

Problema: "Mi RAG tarda 500ms en retrieval. ¿Dónde está el bottleneck?"

Solución con conocimiento de capas:

  • Profile cada capa:
    • Layer 1 (indexing): 450ms → Problema aquí (índice mal configurado)
    • Layer 2 (query): 30ms
    • Layer 3 (storage): 20ms
  • Fix: Rebuild índice HNSW con mejores parámetros (efConstruction=200)

Optimizar costos

Problema: "ChromaDB local consume 64 GB RAM. Muy caro."

Solución con conocimiento de capas:

  • Layer 1: Cambiar HNSW → IVF (menor memoria)
  • Layer 3: Usar disk storage en lugar de in-memory
  • Resultado: 16 GB RAM (4x reducción)

Tomar mejores decisiones

Problema: "¿Migrar de ChromaDB a Pinecone?"

Comparación con conocimiento de arquitectura:

LayerChromaDBPinecone
Layer 1HNSW (alta accuracy)Custom (optimizado)
Layer 2Post-filteringPre-filtering
Layer 3DuckDB (local)S3 (cloud)
ScaleSingle-nodeMulti-node
Latencia20ms (local)50ms (network)
CostFree (self-hosted)$70/month

Decisión informada: ChromaDB para MVP (<100K vectores), Pinecone para production (>1M vectores).


🚀 Siguiente paso

Ahora que entiendes arquitectura de 3 capas, profundizaremos en Layer 1 (Indexing).

Próxima cápsula: 03 - Indexing Algorithms Overview

Aprenderás:

  • Brute force O(n) vs indexing O(log n) (matemáticas simples)
  • Principales algoritmos: HNSW, IVF, PQ, ScaNN
  • Trade-offs: Accuracy vs Speed vs Memory
  • Cuándo usar cada uno

¿Por qué importante? Layer 1 domina 60-70% de latencia de query. Optimizar indexing = mayor impacto en performance.


Tiempo de lectura: 10-12 minutos
Siguiente: 03-indexing-algorithms-overview.md