Você já se perguntou o que é RAG e por que virou padrão em sistemas de IA empresarial em 2026? Em poucas palavras, o que é RAG: uma técnica que combina busca em documentos com geração de texto via LLM. Portanto, em vez de o modelo responder apenas com o que sabe do treinamento, ele primeiro recupera informação relevante da sua base e só então gera a resposta. Dessa forma, o RAG resolve dois problemas críticos: hallucination (modelos inventando fatos) e desatualização (LLMs com 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.

O termo foi popularizado por um paper da Meta em 2020 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 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, Voyage AI para embeddings e Claude API para geração. Primeiro, instale as dependências:

Code
pip install psycopg2-binary pgvector voyageai anthropic pypdf

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

Code
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:

JavaScript
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", 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:

JavaScript
import anthropic

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

def rag_query(question, top_k=5):
    q_emb = vo.embed([question], model="voyage-3",
                     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-7",
        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 — basta ajustar o índice IVFFlat ou usar HNSW.

Publicidade

Chunking strategies: como dividir o documento

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.

Quando 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 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 alternativas: fine-tuning, contexto longo, Claude Files

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 — 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 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.