🧠FFVAcademy
🧩

RAG: por que "só jogar tudo no LLM" não funciona

16 min de leitura·+80 XP
Pré-requisitos (0/2)0%

Recomendamos completar os pré-requisitos antes de seguir, mas nada te impede de continuar.

"Mas por que não jogo o documento todo no contexto do LLM?" é a primeira pergunta de quem começa a trabalhar com IA em produção. A resposta envolve três limites duros — cutoff de treino, janela de contexto, alucinação — que juntos formam a parede onde RAG (Retrieval-Augmented Generation) se encaixa como solução. Este é o mapa do território.

Os três limites que criam a necessidade de RAG

LimiteO que éPor que quebra na prática
Cutoff de treinoModelo só sabe o que existia até a data em que o dataset foi congeladoPergunta sobre evento de ontem? Ele inventa. Dados internos do seu sistema? Nunca viu.
Janela de contextoLimite físico de tokens por request (200k, 1M, 2M — depende do modelo)Sua base tem 10GB. Mesmo modelo de 2M tokens não encaixa. E custo cresce linear no input.
AlucinaçãoLLM gera texto plausível, não verdadeiro. Sem âncora factual, inventa.Respostas confiantes e erradas. Em suporte, compliance ou medicina, isso é inaceitável.

A arquitetura em dois estágios

RAG separa duas responsabilidades. Primeiro, recupera os trechos relevantes à pergunta a partir de uma base indexada. Depois, gera a resposta usando esses trechos como contexto. O modelo vira um raciocinador sobre evidência fornecida, não uma enciclopédia.

🗺️ Pipeline RAG básico

            ┌──────────────────────┐
            │  Pergunta do usuário │
            └─────────┬────────────┘
                      │
                      ▼
           ┌──────────────────────┐
           │  1. Retrieve         │
           │  embed → vector DB   │
           │  top-k trechos       │
           └─────────┬────────────┘
                     │
                     ▼
           ┌──────────────────────┐
           │  2. Augment Prompt   │
           │  [pergunta + trechos]│
           └─────────┬────────────┘
                     │
                     ▼
           ┌──────────────────────┐
           │  3. Generate (LLM)   │
           │  resposta + citações │
           └──────────────────────┘

Pipeline de indexação (offline)

Antes que qualquer pergunta seja feita, a base precisa ser preparada. Isso roda em batch — hora em hora, diário, ou via event-driven quando documentos mudam.

🗺️ Indexing pipeline

  Documento  →  Parser  →  Chunker  →  Embedding  →  Vector DB
   (.pdf,        (texto     (pedaços    (modelo        (pgvector,
   .md, html)    limpo)     com overlap) de embedding)  Pinecone,
                                                         Qdrant,
                                                         Weaviate)
⚠️
80% do resultado vem do pipeline de ingestão. Parser ruim (PDF mal extraído), chunks do tamanho errado (muito grande dilui sinal, muito pequeno corta contexto), embedding fraco (genérico para domínio técnico) — qualquer um dos três quebra o RAG. Na prática, a maior parte do tempo de engenharia de RAG está no ingestion, não no generate.

RAG vs Fine-tuning: quando usar cada um

📋 Time quer atualizar respostas com base em documentos que mudam toda semana

RAG

Atualizar RAG = re-indexar. Barato, rápido, sem downtime. Fine-tuning para base que muda semanalmente é retraining contínuo — caro e frágil.

Alt: Fine-tuningdesatualiza junto com o modelo; custo por release

Alt: Longo contexto diretosó funciona se a base cabe em contexto e custo por query compensa

📋 Produto precisa de tom específico ("responda como um médico sênior, formal e cauteloso")

Fine-tuning (LoRA)

Tom e formato são skill, não fato. Fine-tuning com exemplos de estilo grava o comportamento no modelo. RAG para tom é prompt-engineering frágil.

Alt: System prompt detalhadofunciona para estilo simples; degrada com complexidade

Alt: RAGerrada — tom não é conteúdo recuperável

📋 Assistente de suporte com base de conhecimento interna + tom de marca

RAG + Fine-tuning leve (ambos)

LoRA captura tom da marca e formato das respostas (skill). RAG fornece conteúdo atualizado da base (fato). Separação clara de responsabilidades.

Por que naive RAG (top-k + embedding) falha em produção

🚨
O tutorial de RAG que você leu na internet (embed + Pinecone + top-k=5 + prompt) bate em ~40-60% de precisão em bases reais. Para chegar em 85%+, precisa de pipeline sério: chunking inteligente, hybrid search (BM25+vector), reranking, query transformation, metadados estruturados.
ProblemaSintomaMitigação
Chunks do tamanho erradoResposta falta contexto (chunk pequeno) ou dilui o sinal (chunk grande)Recursive chunking + contextual retrieval (Anthropic)
Embedding ignora intenção"Cancelar conta" e "Criar conta" têm similaridade altaHybrid search (BM25 + vector) com RRF
Top-k fixoDocumento denso devolve 5 chunks quase idênticosMMR (maximal marginal relevance) para diversidade
Sem rerankingPosição 1-5 tem ruído misturado com relevanteCross-encoder rerank (Cohere, Voyage, Jina)
Query ambígua"Como isso funciona?" sem contexto volta tudo genéricoHyDE, query expansion, multi-query

Código mínimo: naive RAG em Python

Exemplo pedagógico — serve para ver o fluxo, não para produção.

python
# Pipeline mínimo: docs → embeddings → query → LLM
from anthropic import Anthropic
import numpy as np
from sentence_transformers import SentenceTransformer

client = Anthropic()
embedder = SentenceTransformer("BAAI/bge-m3")

# 1. Indexação (offline)
docs = [
    "Para cancelar conta, acesse Configurações → Conta → Encerrar.",
    "Para criar conta nova, vá em cadastrar.com/novo e preencha email.",
    "Senha esquecida? Use o link 'recuperar' na tela de login.",
]
doc_vecs = embedder.encode(docs, normalize_embeddings=True)

# 2. Retrieval (online)
def retrieve(query: str, k: int = 2) -> list[str]:
    q_vec = embedder.encode(query, normalize_embeddings=True)
    scores = doc_vecs @ q_vec  # cosine (vetores já normalizados)
    top_idx = np.argsort(-scores)[:k]
    return [docs[i] for i in top_idx]

# 3. Generate
def answer(query: str) -> str:
    context = "\n\n".join(retrieve(query))
    msg = client.messages.create(
        model="claude-sonnet-4-6",
        max_tokens=512,
        messages=[{
            "role": "user",
            "content": f"Responda a partir do contexto. Se não estiver no contexto, diga que não sabe.\n\nContexto:\n{context}\n\nPergunta: {query}"
        }],
    )
    return msg.content[0].text

print(answer("Esqueci minha senha, o que faço?"))
💡
Rode isso, veja funcionar, e entenda: é o degrau zero. Em produção você troca o embedder genérico por domain-tuned, adiciona reranker, metadata filtering, chunking com overlap contextual, citações, e um evaluation harness que mede recall@k e faithfulness a cada deploy.

Perguntas típicas

RAG funciona com modelo local (Llama, Mistral)?

Sim. O pipeline de retrieval é independente do modelo. O que muda é qualidade do generate — modelos menores (7B-13B) precisam de chunks melhores e prompts mais explícitos. Em geral, vale mais investir em retrieval bom do que em modelo maior.

Janela de contexto grande (1M+ tokens) mata RAG?

Não. Custo cresce linear no input — 1M tokens a cada query é caro e lento. Além disso, "needle in haystack" ainda tem degradação em modelos long-context. RAG continua sendo a estratégia econômica e precisa. Long-context é complementar, não substituto.

Preciso de vector DB dedicado (Pinecone, Weaviate, Qdrant) ou pgvector serve?

Para <1M de vetores, pgvector no Postgres que você já tem é quase sempre o certo. Acima disso, ou se precisar de filtragem/metadata muito complexa, vector DB dedicada ganha. Não comece com Pinecone "só porque" — custo e vendor lock-in sem justificativa.

E se a pergunta exige sintetizar 30 documentos? Top-k=5 não basta.

Dois caminhos: (1) recursive/agentic RAG — o modelo decide sub-perguntas e faz múltiplos retrievals; (2) map-reduce — resumir em paralelo os 30 docs e depois sintetizar. Para queries estruturadas (analíticas), considere SQL direto — RAG não é martelo universal.
Take-aways. RAG = separar fato (externo, atualizável) de raciocínio (modelo). Pipeline tem dois estágios (retrieve + generate) com métricas próprias. Naive RAG é degrau zero, não produção. Qualidade vem do ingestion (parser + chunker + embedder + metadata), não do generate. Os próximos módulos vão fundo em cada peça — chunking, hybrid search, reranking e evaluation.
🧩

Quiz rápido

4 perguntas · Acerte tudo e ganhe o badge 🎯 Gabarito

Continue lendo