O que é RAG (Retrieval-Augmented Generation): uma técnica que combina busca em documentos com geração de texto via LLM, fazendo o modelo responder com base na sua base de conhecimento em vez de só no treinamento. Dessa forma, o RAG resolve dois problemas críticos que travam LLMs puros: hallucination (modelos inventando fatos) e desatualização (knowledge cutoff fixo).

Neste tutorial, você vai implementar RAG do zero usando Python, pgvector como vector database, embeddings da Voyage AI e Claude API como gerador. Além disso, vou mostrar quando o RAG falha na prática e como debugar. Vamos começar.

O que é RAG (Retrieval-Augmented Generation) na prática

RAG significa Retrieval-Augmented Generation, ou seja, geração aumentada por recuperação. Na prática, o que é RAG: um padrão de arquitetura onde o modelo de linguagem consulta uma base externa antes de responder. Por exemplo, se você tem 500 PDFs de manuais técnicos, o RAG indexa esse conteúdo e, quando o usuário pergunta algo, busca os trechos mais relevantes e injeta no prompt do LLM. Assim, o modelo responde baseado em fatos da sua base, não em alucinação. Modelos de topo como o Claude Fable 5 tornam essa etapa de geração ainda mais confiável.

O termo foi popularizado por um paper da Meta em 2020 (Lewis et al.) e virou padrão empresarial após o boom dos LLMs. Hoje, praticamente toda aplicação séria de IA usa RAG: chatbots de suporte, assistentes jurídicos, análise de contratos, sistemas internos de Q&A. Inclusive, Knowledge Bases em agentes de IA são, no fundo, sistemas RAG estruturados.

Em resumo, o que é RAG resolve três limitações do LLM puro:

  • Knowledge cutoff: o modelo não conhece informação posterior ao treinamento.
  • Conhecimento privado: o LLM não tem acesso aos seus documentos internos.
  • Hallucination: sem fonte externa, o modelo inventa fatos com confiança.

Como funciona o RAG: 4 etapas (indexar, chunk, retrieve, generate)

Para entender o que é RAG por dentro, é preciso conhecer as 4 etapas do pipeline. Veja a seguir uma visão geral antes de partirmos para o código real.

Diagrama detalhado do pipeline RAG em 8 estágios: PDF, split, embed, store, query, retrieve, Claude e answer
Os 8 estágios do pipeline RAG explicados: do PDF original até a resposta final passando por embeddings, vector store e Claude.

Etapa 1: Indexar (ingestão)

Primeiro, você precisa transformar documentos brutos (PDF, HTML, markdown) em texto puro. Por exemplo, um PDF de 200 páginas vira uma string única ou várias páginas separadas. Em seguida, esse texto é dividido em pedaços menores chamados chunks.

Etapa 2: Chunk (divisão)

Cada documento é dividido em blocos de 200 a 1000 tokens. Isso é necessário porque o LLM tem janela de contexto limitada e busca por similaridade funciona melhor em trechos curtos e coesos. Além disso, você gera um embedding (vetor numérico) de cada chunk usando um modelo como voyage-3.5 ou text-embedding-3-large.

Etapa 3: Retrieve (busca)

Quando o usuário faz uma pergunta, o sistema gera um embedding da pergunta e busca os chunks com vetores mais próximos no banco. Tipicamente, retorna os 3 a 10 mais relevantes via similaridade cosseno.

Etapa 4: Generate (geração)

Por fim, os chunks recuperados são injetados no prompt do LLM como contexto. Assim, o Claude (ou outro modelo) responde com base nessa informação concreta, citando trechos da sua base. Dessa forma, a resposta é factual e rastreável.

RAG na prática: tutorial Python com Claude e pgvector

Agora vamos implementar o que é RAG de verdade. O stack escolhido: PostgreSQL com extensão pgvector como vector database, Voyage AI para embeddings e Claude API para geração. Primeiro, instale as dependências:

Bash
pip install psycopg2-binary pgvector voyageai anthropic pypdf

Em seguida, prepare o banco. Execute o comando abaixo em uma instância PostgreSQL 14+:

SQL
CREATE EXTENSION IF NOT EXISTS vector;

CREATE TABLE documents (
    id SERIAL PRIMARY KEY,
    content TEXT NOT NULL,
    embedding vector(1024),
    metadata JSONB
);

CREATE INDEX ON documents USING ivfflat (embedding vector_cosine_ops);

Indexar um PDF

Agora, veja o script de ingestão. Ele lê um PDF (manual de produto, por exemplo), divide em chunks de ~500 tokens e armazena no pgvector com embeddings da Voyage:

Python
import psycopg2
from pgvector.psycopg2 import register_vector
import voyageai
from pypdf import PdfReader

vo = voyageai.Client(api_key="VOYAGE_KEY")
conn = psycopg2.connect("postgresql://user:pass@localhost/rag")
register_vector(conn)

def chunk_text(text, size=500, overlap=50):
    words = text.split()
    chunks = []
    for i in range(0, len(words), size - overlap):
        chunks.append(" ".join(words[i:i + size]))
    return chunks

def index_pdf(path):
    reader = PdfReader(path)
    full_text = "\n".join([p.extract_text() for p in reader.pages])
    chunks = chunk_text(full_text)
    result = vo.embed(chunks, model="voyage-3.5", input_type="document")

    with conn.cursor() as cur:
        for chunk, emb in zip(chunks, result.embeddings):
            cur.execute(
                "INSERT INTO documents (content, embedding) VALUES (%s, %s)",
                (chunk, emb)
            )
        conn.commit()

index_pdf("manual.pdf")

Recuperar e gerar resposta com Claude

Por fim, o pipeline de query. Veja a seguir como recuperar chunks relevantes e enviar para o Claude:

Python
import anthropic

client = anthropic.Anthropic(api_key="ANTHROPIC_KEY")

def rag_query(question, top_k=5):
    q_emb = vo.embed([question], model="voyage-3.5",
                     input_type="query").embeddings[0]

    with conn.cursor() as cur:
        cur.execute(
            "SELECT content FROM documents "
            "ORDER BY embedding <=> %s LIMIT %s",
            (q_emb, top_k)
        )
        chunks = [row[0] for row in cur.fetchall()]

    context = "\n---\n".join(chunks)
    prompt = f"Contexto:\n{context}\n\nPergunta: {question}"

    msg = client.messages.create(
        model="claude-opus-4-8",
        max_tokens=1024,
        messages=[{"role": "user", "content": prompt}]
    )
    return msg.content[0].text

print(rag_query("Como resetar o produto?"))

De fato, é isso. Você acabou de implementar um RAG funcional em ~50 linhas. Inclusive, esse mesmo padrão escala para milhões de chunks com pgvector, bastando ajustar o índice IVFFlat ou usar HNSW.

Publicidade

Como dividir o documento em chunks no RAG?

O chunking é a etapa mais subestimada do RAG. Na prática, um chunk mal feito quebra todo o pipeline. Por isso, vamos ver as 4 estratégias mais usadas em 2026.

  • Fixed-size chunking: dividir por número fixo de tokens (ex: 500). Simples e rápido, mas corta no meio de frases.
  • Recursive chunking: dividir por separadores (parágrafo, frase, palavra). Padrão da LangChain e geralmente o melhor default.
  • Semantic chunking: agrupar frases semanticamente similares. Mais preciso, porém mais caro de calcular.
  • Document-aware chunking: respeitar estrutura nativa (markdown headers, seções de PDF). Indicado para documentação técnica.

Da mesma forma, o overlap entre chunks importa. Tipicamente 10-20% (50-100 tokens em chunks de 500). Isso garante que conceitos cortados entre chunks ainda apareçam parcialmente em ambos. Por outro lado, overlap excessivo desperdiça tokens no contexto final.

Inclusive, em 2026 a Anthropic publicou uma técnica chamada Contextual Retrieval: antes de gerar o embedding, o Claude resume o chunk no contexto do documento inteiro. Por exemplo, “Este chunk é da seção 3 do manual X e explica como resetar o produto. Conteúdo: …”. Assim, melhora a recuperação em 35% em benchmarks.

O que é reranking e agentic RAG?

O reranking reordena os chunks recuperados usando um modelo cross-encoder mais preciso que a busca vetorial inicial. Na prática, o pipeline vira dois estágios: primeiro a busca vetorial recupera top-N candidatos (rápida, mas grosseira), depois um reranker como o Cohere Rerank ou o BGE-reranker reordena e devolve os top-K de fato relevantes. Isso corrige justamente a Falha 2 que você viu acima, quando chunks semanticamente parecidos mas irrelevantes vazam pro contexto. Segundo pesquisa publicada pela Ailog sobre cross-encoders, o reranking melhora a acurácia de RAG em cerca de 40% frente à busca vetorial pura em datasets do benchmark BEIR.

Já o agentic RAG trata a recuperação como uma tool que o modelo chama em loop, não como um passo único e fixo. Em vez de recuperar uma vez e responder, o agente avalia se o contexto é suficiente, refina a query e faz re-retrieve quando a resposta parece incompleta. Dessa forma, o próprio Claude decide quando buscar mais, corrige a própria rota (self-correction) e encadeia várias buscas para perguntas complexas. Como a documentação da Anthropic descreve, agentes ganham autonomia ao usar “ferramentas para buscar informação e agir no mundo real”.

Além disso, surgiram variantes que formalizam esse comportamento. Por exemplo, o Self-RAG faz o modelo criticar as próprias recuperações, o Corrective RAG (CRAG) valida os chunks antes de gerar e o GraphRAG constrói um grafo de conhecimento para consultas multi-hop. Portanto, se o seu RAG base já funciona mas erra em perguntas que exigem raciocínio em várias etapas, reranking e agentic RAG são os próximos passos naturais.

Por que o RAG falha e como debugar?

Aqui está o que ninguém te conta sobre o que é RAG: ele falha o tempo todo se você não souber debugar. Veja a seguir os 4 modos de falha mais comuns na prática.

Falha 1: relevance score baixo

Quando os chunks recuperados têm similaridade cosseno menor que 0.7, é sinal de que a pergunta não tem resposta direta na base. Por isso, sempre logue os scores. Se top-1 é < 0.7, considere retornar “não sei” em vez de gerar resposta possivelmente errada.

Falha 2: chunks errados retornados

Às vezes o RAG retorna chunks similares semanticamente mas irrelevantes. Por exemplo, “como resetar senha” recupera “como resetar produto”. A solução: hybrid search, combinando busca vetorial com BM25 (busca por palavras-chave). Frameworks como o LlamaIndex oferecem isso nativamente.

Falha 3: hallucination com contexto presente

Mesmo com contexto correto, o LLM pode inventar. Por isso, instrua explicitamente no system prompt: “Responda APENAS com base no contexto fornecido. Se a informação não estiver no contexto, diga ‘não tenho essa informação na base'”. Da mesma forma, peça citação dos trechos usados.

Falha 4: chunks fragmentados

Quando o chunk corta no meio de uma tabela, fórmula ou bloco de código, a resposta vira lixo. Portanto, sempre use chunking respeitando estrutura. Para PDFs com tabelas, considere extração estruturada antes do chunking (bibliotecas como unstructured ou pdfplumber).

RAG vs fine-tuning: qual usar?

Antes de finalizar, vale comparar o que é RAG com as alternativas. Inclusive, em 2026 surgiram opções que questionam a necessidade de pipeline completo.

TécnicaQuando usarCustoLatência
RAGBase grande (>10MB), atualização frequenteBaixo (embeddings + storage)~500ms extra
Fine-tuningMudar tom/estilo do modeloAlto (treino + GPU)Zero extra
Contexto longoDocumento único <1MBAlto (tokens por query)Lenta (50k+ tokens)
Claude Files APIPoucos PDFs estáticosMédioMédia

Em outras palavras: fine-tuning é caro e não resolve atualização de dados. Contexto longo (Claude com 200k tokens) funciona para documentos únicos, mas vira inviável para bases grandes, pois você paga tokens em toda query. Por outro lado, a nova Claude Files API simplifica casos pequenos, mas o RAG ainda é o padrão quando a base passa de algumas dezenas de documentos.

Da mesma forma, conceitos relacionados ajudam: para entender melhor, leia agentes de IA autônomos (que usam RAG internamente), MCP (Model Context Protocol) (alternativa para conectar fontes externas ao Claude), prompts eficientes (que melhoram a geração final) e o glossário de IA 2026.

Conclusão

Portanto, agora você sabe o que é RAG na prática: um pipeline de 4 etapas (indexar, chunk, retrieve, generate) que conecta sua base privada a um LLM como Claude. Além disso, viu o código real em Python com pgvector e Voyage AI, as 4 estratégias de chunking e como debugar quando algo falha.

Lembre-se: RAG não é mágica. Primeiro, valide a qualidade dos seus chunks. Em seguida, monitore os scores de similaridade. Por fim, instrua o LLM a citar fontes e admitir quando não sabe. Dessa forma, você terá um sistema confiável, factual e que escala sem fine-tuning. Agora é hora de pegar um PDF da sua empresa e implementar.

Publicidade

Qual a diferença entre RAG e fine-tuning?
RAG injeta informação no contexto a cada query, sem treinar o modelo. Já o fine-tuning altera os pesos do LLM com seus dados. Portanto, use RAG para conhecimento que muda (base de produtos, FAQ) e fine-tuning para mudar tom/estilo de resposta.
Posso usar RAG sem vector database?
Sim. Para bases pequenas (até ~100 documentos), busca por palavras-chave (BM25) ou SQL full-text funciona. Porém, acima disso, vector databases como pgvector ou Pinecone são essenciais para performance e qualidade semântica.
Como escolher o tamanho do chunk?
O padrão é 500-800 tokens com overlap de 10-20%. Para Q&A factual, chunks menores (200-400) funcionam melhor. Já para resumos ou contexto longo, chunks maiores (800-1500). Sempre teste com queries reais antes de fixar o tamanho.
RAG funciona em português?
Sim. Modelos como voyage-3.5 e text-embedding-3-large têm suporte multilíngue e funcionam bem em pt-BR. Da mesma forma, Claude responde nativamente em português. Por isso, todo o pipeline mostrado neste tutorial funciona com documentos brasileiros sem ajuste.
RAG resolve hallucinations dos LLMs?
RAG reduz drasticamente as hallucinations, mas não elimina. Por isso, sempre instrua o modelo a citar fontes e admitir quando a informação não está no contexto. Inclusive, monitore os relevance scores: se baixos, o LLM pode ainda inventar mesmo com contexto.