Bancos vetoriais em produção para sistemas RAG
1. Fundamentos e Arquitetura de Bancos Vetoriais para RAG
1.1. Conceitos básicos: embeddings, similaridade vetorial e indexação
Sistemas RAG (Retrieval-Augmented Generation) dependem de bancos vetoriais para recuperar informações relevantes antes de alimentar modelos de linguagem. O coração dessa arquitetura são os embeddings — representações numéricas densas de texto, imagens ou áudio em um espaço vetorial de alta dimensionalidade (tipicamente 768 a 1536 dimensões). A similaridade entre embeddings é calculada por métricas como cosseno, produto escalar ou distância euclidiana.
Para viabilizar buscas em milhões de vetores com latência de milissegundos, bancos vetoriais utilizam algoritmos de indexação aproximada:
- HNSW (Hierarchical Navigable Small World): Cria grafos em múltiplas camadas, onde nós de nível superior permitem saltos rápidos para regiões promissoras. Oferece excelente recall (>99%) com latência de 1-10ms para 1M vetores.
- IVF (Inverted File Index): Particiona o espaço vetorial em clusters (usando k-means) e busca apenas nos clusters mais próximos ao query vector. Mais eficiente em memória, mas com recall ligeiramente inferior.
# Exemplo: Configuração de índice HNSW no Qdrant
{
"vectors": {
"size": 768,
"distance": "Cosine"
},
"optimizers_config": {
"indexing_threshold": 10000
},
"hnsw_config": {
"m": 16, # Conexões por nó (mais = recall maior)
"ef_construct": 200, # Tamanho da lista dinâmica durante construção
"full_scan_threshold": 10000
}
}
1.2. Integração com pipelines RAG
Um pipeline RAG típico envolve:
- Ingestão: Documentos são processados em chunks de 256-1024 tokens
- Embedding: Cada chunk é convertido em vetor via modelos como
text-embedding-3-smallouall-MiniLM-L6-v2 - Armazenamento: Vetores + metadados (fonte, timestamp, chunk_id) são inseridos no banco vetorial
- Recuperação: Query do usuário é embedada e busca-se os top-k chunks mais similares
- Geração: Chunks recuperados são inseridos no contexto do LLM
# Pipeline de ingestão com pgvector (PostgreSQL)
CREATE EXTENSION vector;
CREATE TABLE documents (
id SERIAL PRIMARY KEY,
content TEXT NOT NULL,
metadata JSONB,
embedding vector(768),
created_at TIMESTAMP DEFAULT NOW()
);
CREATE INDEX idx_documents_embedding
ON documents
USING ivfflat (embedding vector_cosine_ops)
WITH (lists = 100);
1.3. Diferenças entre bancos vetoriais especializados e extensões relacionais
| Característica | Pinecone/Weaviate/Qdrant | pgvector (PostgreSQL) |
|---|---|---|
| Latência pura | 2-5ms para 1M vetores | 10-50ms para 1M vetores |
| Escalabilidade | Sharding automático, multi-região | Requer extensões como Citus |
| Filtros híbridos | Suporte nativo a metadados | SQL completo, joins complexos |
| Manutenção | Gerenciado (SaaS) | Auto-gerenciado ou RDS |
| Custo | $70-500/mês para 1M vetores | Incluso no custo do RDS |
2. Estratégias de Indexação e Performance em Escala
2.1. Parâmetros críticos de indexação
A escolha de parâmetros impacta diretamente o trade-off precisão vs. latência:
# Configuração para alta precisão (recall > 99%)
{
"hnsw_config": {
"m": 32,
"ef_construct": 400,
"ef_search": 200 # Aumentar para consulta mais precisa
}
}
# Configuração para baixa latência (recall ~95%)
{
"hnsw_config": {
"m": 8,
"ef_construct": 100,
"ef_search": 50
}
}
2.2. Particionamento e sharding
Para datasets com mais de 10M vetores, o sharding por critérios como tenant, região geográfica ou hash do ID do documento é essencial:
# Sharding por tenant no Weaviate
{
"class": "Document",
"shardingConfig": {
"desiredCount": 16,
"virtualPerPhysical": 128,
"replicationFactor": 2
}
}
2.3. Cache de embeddings e consultas híbridas
Consultas que combinam similaridade vetorial com filtros escalares (ex: "documentos de 2024 sobre machine learning") podem ser otimizadas com:
- Pré-filtragem: Aplicar filtros SQL antes da busca vetorial (reduz o espaço de busca)
- Pós-filtragem: Buscar top-k vetores e depois filtrar (útil quando filtros são seletivos)
- Índices compostos: No pgvector, criar índices parciais por categoria
# Consulta híbrida otimizada no pgvector
SELECT content, metadata,
1 - (embedding <=> '[0.1, 0.2, ...]') AS similarity
FROM documents
WHERE metadata->>'year' = '2024'
AND metadata->>'category' = 'machine-learning'
ORDER BY embedding <=> '[0.1, 0.2, ...]'
LIMIT 10;
3. Garantia de Consistência e Atualizações em Tempo Real
3.1. Sincronização entre fontes de dados e banco vetorial
Para manter consistência entre a fonte primária (ex: banco relacional, S3) e o banco vetorial:
- CDC (Change Data Capture): Use Debezium + Kafka para capturar mudanças em tempo real
- Batch processing: Para dados que mudam com menos frequência, jobs Airflow diários
- Streaming: Para aplicações de busca em tempo real (ex: documentos colaborativos)
# Exemplo: Pipeline CDC com Debezium para Qdrant
{
"name": "postgres-connector",
"config": {
"connector.class": "io.debezium.connector.postgresql.PostgresConnector",
"database.hostname": "postgres-primary",
"database.dbname": "documents",
"table.include.list": "public.documents",
"transforms": "unwrap,vectorize",
"transforms.vectorize.type": "org.apache.kafka.connect.transforms.VectorizeEmbedding",
"transforms.vectorize.model": "text-embedding-3-small"
}
}
3.2. Versionamento de embeddings e rollback
Modelos de embedding evoluem (ex: de ada-002 para text-embedding-3-small). Estratégias de versionamento:
- Coleções separadas por versão:
documents_v1,documents_v2 - Metadata version: Adicionar campo
embedding_versione filtrar nas consultas - Rollback: Manter snapshot do índice anterior por 7 dias
3.3. Tratamento de dados obsoletos
Políticas de TTL e garbage collection são críticas para evitar degradação:
# Política de TTL no Qdrant (expira após 30 dias)
{
"collection_name": "documents",
"optimizers_config": {
"default_segment_number": 2,
"memmap_threshold_kb": 200000,
"indexing_threshold": 10000
},
"hnsw_config": {
"payload_m": 16,
"payload_ef_construct": 100
},
"wal_config": {
"wal_capacity_mb": 1024
}
}
# Garbage collection manual via API
POST /collections/documents/points/delete
{
"filter": {
"must": [
{"key": "created_at", "range": {"lt": 1700000000}}
]
}
}
4. Observabilidade e Monitoramento de Sistemas RAG
4.1. Métricas essenciais
- Latência de busca: p50 < 20ms, p99 < 100ms
- Recall: Proporção de chunks relevantes recuperados entre top-k
- Taxa de acerto: Percentual de consultas onde o chunk recuperado foi usado na resposta final
- Drift de embeddings: Monitorar distribuição das similaridades ao longo do tempo
# Métricas exportadas via Prometheus (exemplo com Qdrant)
# HELP qdrant_vectors_count_total Total number of vectors
# TYPE qdrant_vectors_count_total gauge
# HELP qdrant_search_latency_seconds Latency of search operations
# TYPE qdrant_search_latency_seconds histogram
# HELP qdrant_ef_search_avg Average ef_search parameter used
# TYPE qdrant_ef_search_avg gauge
4.2. Logging e tracing distribuído
Para depurar cadeias RAG complexas, use OpenTelemetry para rastrear:
- Query do usuário → embedding → busca vetorial → chunks recuperados → prompt do LLM → resposta
- Cada etapa deve registrar: timestamp, latência, modelo usado, tokens consumidos
4.3. Alertas para degradação de qualidade
Configure alertas baseados em:
- Queda de similaridade média: Se a similaridade média dos top-5 resultados cai > 10% em 1 hora
- Aumento de falsos positivos: Quando chunks irrelevantes aparecem consistentemente no top-k
- Timeout de busca: Mais de 1% das consultas excedem 500ms
5. Segurança e Controle de Acesso em Produção
5.1. Isolamento de tenants
Para aplicações multi-tenant, cada consulta deve ser filtrada por tenant_id:
# Filtro obrigatório por tenant no Qdrant
{
"filter": {
"must": [
{"key": "tenant_id", "match": {"value": "acme_corp"}}
]
},
"limit": 10,
"with_payload": true
}
5.2. Proteção contra injeção via embeddings
Embora raro, ataques podem tentar manipular embeddings para recuperar chunks de outros tenants. Mitigações:
- Validar que o embedding da query está dentro do range esperado (ex: norma L2 entre 0.8 e 1.2)
- Usar embeddings assinados criptograficamente para verificar origem
5.3. Criptografia
- Em repouso: Ativar criptografia AES-256 no disco do banco vetorial
- Em trânsito: TLS 1.3 obrigatório para todas as conexões
- Chaves: Gerenciar via AWS KMS ou HashiCorp Vault
6. Custos e Otimização de Recursos em Nuvem
6.1. Dimensionamento de recursos
Para 10M vetores de 768 dimensões:
- Memória: ~30 GB para índice HNSW (sem quantização)
- CPU: 8-16 cores para operações simultâneas
- Armazenamento: ~15 GB para vetores + metadados
6.2. Compressão de embeddings
Reduza custos em 60-80% com quantização:
# Quantização escalar (float32 → int8)
{
"quantization_config": {
"scalar": {
"type": "int8",
"always_ram": true
}
}
}
# Redução de dimensionalidade via PCA (1536 → 256)
from sklearn.decomposition import PCA
pca = PCA(n_components=256)
embeddings_reduced = pca.fit_transform(embeddings_original)
6.3. Modelos de precificação
| Provedor | Modelo | Custo mensal (1M vetores) |
|---|---|---|
| Pinecone | Pod-based (p1) | $70-150 |
| Weaviate | Serverless (per request) | $50-200 |
| Qdrant | Dedicated cluster | $100-300 |
| pgvector | RDS (incluso) | $30-100 (adicional ao RDS) |
7. Casos de Uso Avançados e Padrões de Arquitetura
7.1. RAG multimodal
Armazene embeddings de texto, imagem e áudio na mesma coleção, diferenciando por metadados:
{
"vectors": {
"text": [0.1, 0.2, ...], # 768 dims
"image": [0.3, 0.4, ...], # 512 dims
"audio": [0.5, 0.6, ...] # 384 dims
},
"payload": {
"modality": "image",
"source": "product_catalog_2024"
}
}
7.2. Híbrido vetorial + lexical (BM25)
Para melhor recall em consultas com termos raros, combine busca vetorial com BM25:
# Weaviate: busca híbrida nativa
{
"query": "machine learning transformers",
"alpha": 0.5, # 0 = only BM25, 1 = only vector
"limit": 10
}
7.3. Failover e replicação geográfica
Para alta disponibilidade, configure replicação cross-region:
# Replicação no Qdrant (3 nós, 2 regiões)
{
"cluster": {
"nodes": [
{"host": "qdrant-us-east-1", "port": 6333},
{"host": "qdrant-us-west-2", "port": 6333},
{"host": "qdrant-eu-west-1", "port": 6333}
],
"replication_factor": 2,
"write_consistency": "majority"
}
}
Referências
- Qdrant Documentation: HNSW Index Configuration — Guia completo sobre parâmetros HNSW para otimização de recall e latência
- Pinecone: Understanding Vector Indexes — Artigo técnico comparando algoritmos de indexação (IVF, HNSW, PQ)
- Weaviate: Hybrid Search Tutorial — Tutorial prático de busca híbrida vetorial + BM25 com exemplos de código
- pgvector GitHub Repository — Repositório oficial com documentação de instalação, índices e consultas
- OpenAI: Text Embedding Models Guide — Guia oficial sobre modelos de embedding, dimensionalidade e boas práticas de chunking