Inicio / LLMOps / LLMOps: De Prototipo a Producción / Vector Databases

Vector Databases

ChromaDB, pgvector, Pinecone, índices, namespaces e integración RAG.

Intermedio Bases de datos
🔒 Solo lectura
📖

Estás en modo lectura

Puedes leer toda la lección, pero para marcar progreso, hacer ejercicios y ganar XP necesitas una cuenta Pro.

Desbloquear por $9/mes

Vector Databases

¿Qué es una Vector Database?

Una vector database almacena y permite buscar eficientemente embeddings (vectores de alta dimensionalidad). Son el componente central de cualquier pipeline RAG, permitiendo búsquedas semánticas a escala.


¿Por Qué No un DB Tradicional?

SQL:    SELECT * FROM docs WHERE content LIKE '%machine learning%'
        → Solo encuentra coincidencias exactas de texto

Vector: Buscar documentos semánticamente similares a "IA y aprendizaje"
        → Encuentra docs sobre ML, deep learning, redes neuronales, etc.
        → Entiende SIGNIFICADO, no solo palabras

Principales Vector Databases

Database Tipo Fortalezas Ideal para
Pinecone Managed SaaS Fácil, escalable, serverless Producción rápida
Weaviate Open-source Hybrid search, modules Flexibilidad
ChromaDB Open-source Simple, Python-first Prototipos, dev local
pgvector Extensión PostgreSQL Usa tu DB existente Si ya tienes Postgres
Qdrant Open-source Rust-based, rápido Alto rendimiento
Milvus Open-source Escala masiva Billones de vectores

ChromaDB (Desarrollo Local)

import chromadb
from chromadb.utils import embedding_functions

# Crear cliente
client = chromadb.PersistentClient(path="./chroma_data")

# Configurar embedding function
openai_ef = embedding_functions.OpenAIEmbeddingFunction(
    api_key="sk-...",
    model_name="text-embedding-3-small"
)

# Crear colección
collection = client.get_or_create_collection(
    name="knowledge_base",
    embedding_function=openai_ef,
    metadata={"hnsw:space": "cosine"}  # Métrica de distancia
)

# Indexar documentos
collection.add(
    documents=[
        "Python es un lenguaje de programación interpretado",
        "JavaScript se ejecuta en el navegador",
        "Rust es conocido por su seguridad de memoria",
    ],
    metadatas=[
        {"source": "python.md", "category": "backend"},
        {"source": "js.md", "category": "frontend"},
        {"source": "rust.md", "category": "systems"},
    ],
    ids=["doc1", "doc2", "doc3"],
)

# Buscar
results = collection.query(
    query_texts=["lenguaje para desarrollo web del lado del cliente"],
    n_results=2,
    where={"category": "frontend"},  # Filtro por metadatos
)

print(results["documents"])       # Documentos más relevantes
print(results["distances"])       # Scores de distancia
print(results["metadatas"])       # Metadatos asociados

pgvector (PostgreSQL)

-- Instalar extensión
CREATE EXTENSION vector;

-- Crear tabla con columna de vector
CREATE TABLE documents (
    id SERIAL PRIMARY KEY,
    content TEXT NOT NULL,
    metadata JSONB DEFAULT '{}',
    embedding vector(1536),  -- dimensión del modelo
    created_at TIMESTAMP DEFAULT NOW()
);

-- Crear índice para búsqueda eficiente
CREATE INDEX ON documents 
USING ivfflat (embedding vector_cosine_ops)
WITH (lists = 100);

-- Insertar documento con embedding
INSERT INTO documents (content, embedding) 
VALUES ('Python es genial', '[0.023, -0.041, ...]');

-- Búsqueda por similitud coseno (top 5)
SELECT content, 
       1 - (embedding <=> '[0.018, ...]') AS similarity
FROM documents
ORDER BY embedding <=> '[0.018, ...]'
LIMIT 5;
# Python con psycopg2
import psycopg2
import json

def search_similar(query_embedding, top_k=5):
    conn = psycopg2.connect("postgresql://...")
    cur = conn.cursor()
    
    cur.execute("""
        SELECT content, metadata,
               1 - (embedding <=> %s::vector) AS similarity
        FROM documents
        ORDER BY embedding <=> %s::vector
        LIMIT %s
    """, (str(query_embedding), str(query_embedding), top_k))
    
    return cur.fetchall()

Pinecone (Producción)

from pinecone import Pinecone

pc = Pinecone(api_key="...")

# Crear índice
pc.create_index(
    name="knowledge-base",
    dimension=1536,
    metric="cosine",
    spec={"serverless": {"cloud": "aws", "region": "us-east-1"}}
)

index = pc.Index("knowledge-base")

# Upsert (insertar/actualizar)
index.upsert(
    vectors=[
        {
            "id": "doc-001",
            "values": [0.023, -0.041, ...],  # embedding
            "metadata": {
                "source": "manual.pdf",
                "page": 5,
                "category": "soporte",
            }
        },
    ],
    namespace="production",
)

# Buscar con filtros
results = index.query(
    vector=[0.018, ...],
    top_k=5,
    namespace="production",
    filter={"category": {"$eq": "soporte"}},
    include_metadata=True,
)

for match in results.matches:
    print(f"Score: {match.score:.4f} | {match.metadata}")

Optimización de Vector DBs

Índices

Tipo Velocidad Precisión Memoria
Flat (Brute Force) Lento Exacto Baja
IVF Rápido ~95% Media
HNSW Muy rápido ~99% Alta
PQ (Product Quantization) Rápido ~90% Muy baja

Estrategias de Namespaces

knowledge-base/
├── production/       # Datos en producción
├── staging/          # Datos de prueba
├── v2-migration/     # Nueva versión de embeddings
└── experiment-42/    # A/B test

Patrón Completo: RAG con Vector DB

class RAGPipeline:
    def __init__(self, collection, llm_client):
        self.collection = collection
        self.llm = llm_client
    
    def ingest(self, documents: list[dict]):
        self.collection.add(
            documents=[d["content"] for d in documents],
            metadatas=[d.get("metadata", {}) for d in documents],
            ids=[d["id"] for d in documents],
        )
    
    def query(self, question: str, top_k: int = 5) -> str:
        results = self.collection.query(
            query_texts=[question],
            n_results=top_k,
        )
        
        context = "\n\n".join(results["documents"][0])
        
        response = self.llm.chat.completions.create(
            model="gpt-4o",
            messages=[
                {"role": "system", "content": f"Responde basándote en:\n{context}"},
                {"role": "user", "content": question},
            ],
        )
        
        return response.choices[0].message.content

Resumen

Las vector databases son la infraestructura clave para RAG y búsqueda semántica. ChromaDB para desarrollo, pgvector si ya tienes Postgres, y Pinecone/Qdrant para producción a escala. Elegir el índice correcto y la estrategia de namespacing es crucial para rendimiento.

🔒

Ejercicio práctico disponible

Operaciones de vector store

Desbloquear ejercicios
// Operaciones de vector store
// Desbloquea Pro para acceder a este ejercicio
// y ganar +50 XP al completarlo

function ejemplo() {
    // Tu código aquí...
}

¿Te gustó esta lección?

Con Pro puedes marcar progreso, hacer ejercicios, tomar quizzes, ganar XP y obtener tu constancia.

Ver planes desde $9/mes