Recall com Hybrid Search
Latência de busca com HNSW
Postgres, Qdrant, LanceDB
Citações e Grounding explícito
1. Fundamentos e Anatomia do Pipeline RAG
RAG (Retrieval-Augmented Generation) resolve o principal ponto fraco dos LLMs: o conhecimento estático e desatualizado. Em vez de re-treinar o modelo (processo caro e demorado), o RAG busca trechos de documentos relevantes e injeta diretamente no prompt em tempo de execução.
Extração de texto (PDF, Markdown, HTML, Banco SQL), limpeza de ruídos e divisão em chunks coerentes.
Transformação de texto em vetores numéricos de alta dimensão (1536d / 3072d) com índices HNSW ou IVFFlat.
Recuperação semântica dos top-k chunks, re-ordenação via Reranker e síntese fundamentada com referências.
2. Estratégias Avançadas de Chunking & Metadados
Cortar texto arbitrariamente por contagem fixa de caracteres destrói o contexto semântico. As abordagens modernas utilizam:
- Semantic Chunking: Divide o texto em quebras naturais de parágrafo, cabeçalhos Markdown (`#`, `##`) ou mudanças abruptas na similaridade de cosseno entre frases.
- Sliding Window com Overlap: Janelas de 500 tokens com overlap de 100 tokens para garantir que frases na fronteira do chunk não percam sentido.
- Metadados Enriquecidos: Armazene obrigatoriamente
document_id,section_title,author,created_ate tags de permissão de acesso.
Exemplo de Chunking Semântico com Python / LangChain:
from langchain_text_splitters import MarkdownHeaderTextSplitter, RecursiveCharacterTextSplitter
# 1. Divisão estrutural por cabeçalhos
headers_to_split_on = [
("#", "header_1"),
("##", "header_2"),
("###", "header_3"),
]
markdown_splitter = MarkdownHeaderTextSplitter(headers_to_split_on=headers_to_split_on)
header_splits = markdown_splitter.split_text(markdown_document)
# 2. Refinamento por tamanho de token
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=600,
chunk_overlap=80,
separators=["\n\n", "\n", ". ", " "]
)
final_chunks = text_splitter.split_documents(header_splits)
3. Bancos Vetoriais na Prática: pgvector vs Qdrant vs LanceDB
| Banco Vetorial | Tipo | Melhor Caso de Uso | Escalabilidade |
|---|---|---|---|
| pgvector (PostgreSQL) | Extensão SQL Nativa | Aplicações existentes que já utilizam Postgres (Supabase, RDS). ACID completo. | Excelente até dezenas de milhões de vetores com HNSW. |
| Qdrant | Vector DB Especializado (Rust) | Alta performance, filtragem avançada por metadados JSON e busca vetorial em tempo real. | Bilhão de vetores com particionamento distribuído. |
| LanceDB | Serverless / Embedded (Apache Arrow) | RAG embarcado local, edge devices e pipelines de dados analíticos de baixo custo. | Zero gerenciamento de servidor com armazenamento em S3/Local. |
Configuração de pgvector com Índice HNSW no PostgreSQL:
-- 1. Habilitar a extensão pgvector
CREATE EXTENSION IF NOT EXISTS vector;
-- 2. Criar tabela de chunks com coluna vetorial (ex: 1536 dimensões)
CREATE TABLE document_chunks (
id BIGSERIAL PRIMARY KEY,
document_id VARCHAR(100) NOT NULL,
content TEXT NOT NULL,
metadata JSONB DEFAULT '{}'::jsonb,
embedding vector(1536) NOT NULL
);
-- 3. Criar índice HNSW com distância de cosseno (vector_cosine_ops)
CREATE INDEX ON document_chunks
USING hnsw (embedding vector_cosine_ops)
WITH (m = 16, ef_construction = 64);
-- 4. Consulta de similaridade (Cosine Distance: <=>)
SELECT id, content, 1 - (embedding <=> '[0.012, -0.045, ...]'::vector) AS similarity
FROM document_chunks
WHERE metadata->>'tenant_id' = 'empresa_abc'
ORDER BY embedding <=> '[0.012, -0.045, ...]'::vector
LIMIT 5;
4. Hybrid Search (Dense + BM25) & Rerankers
A busca puramente vetorial (densa) é excelente para capturar intenção semântica genérica, mas frequentemente falha ao procurar códigos exatos, IDs de produtos, CPF ou termos técnicos específicos. A Busca Híbrida combina busca semântica vetorial com busca textual esparsa (BM25 ou Full-Text Search do PostgreSQL) usando Reciprocal Rank Fusion (RRF).
Fluxo de Re-ranking Neural
Recupere os top-25 resultados via Busca Híbrida e aplique um modelo Cross-Encoder (como cohere-rerank-v3 ou bge-reranker-large) para reordenar os chunks com precisão semântica profunda, selecionando apenas os top-5 mais relevantes.
import cohere
co = cohere.Client("SUA_CHAVE_COHERE")
# Chunks brutos recuperados da busca híbrida
documents_to_rerank = [
{"text": chunk.content, "id": chunk.id}
for chunk in candidate_chunks
]
# Reranking neural com pontuação de relevância real
response = co.rerank(
model="rerank-multilingual-v3.0",
query="Quais são as políticas de reembolso para planos anuais cancelados em 7 dias?",
documents=documents_to_rerank,
top_n=5,
return_documents=True
)
for result in response.results:
print(f"Score: {result.relevance_score:.4f} | Chunk ID: {result.document['id']}")
5. Graph RAG & Contextual Retrieval
Para bases de conhecimento corporativas complexas (como manuais técnicos, prontuários ou auditorias jurídicas), duas técnicas eliminam as limitações do RAG padrão:
Antes de gerar os embeddings, injete um prefixo sintético no topo de cada chunk explicando o contexto do documento inteiro (ex: "Este trecho pertence ao relatório financeiro Q3/2025 da Empresa X na seção de despesas operacionais.").
Extração automática de entidades e relacionamentos (ex: Neo4j / Memgraph), permitindo que o LLM responda perguntas agregadas que exigem raciocínio através de múltiplos documentos interconectados.
6. Métricas de Avaliação RAG (Framework RAGAS)
Como saber se seu pipeline RAG está melhorando a cada alteração? Nunca dependa de testes manuais subjetivos. Meça as 4 métricas essenciais do framework RAGAS:
A resposta gerada é 100% inferida a partir dos chunks recuperados (fidelidade/ausência de alucinação)?
A resposta é concisa e responde diretamente ao que o usuário perguntou sem rodeios?
Os chunks relevantes estavam no topo do ranking antes de passar para o LLM?
O pipeline recuperou todas as informações necessárias para fundamentar a resposta?