RAG (Retrieval-Augmented Generation, ou geração aumentada por recuperação) é a técnica de buscar os trechos relevantes dos seus documentos no momento da pergunta e entregá-los ao modelo junto com a instrução de responder só com base neles, citando a fonte. É a forma mais prática de fazer um modelo de IA responder sobre contratos, manuais, políticas internas ou base de conhecimento sem treinar nada e com respostas verificáveis.
RAG não elimina alucinação por mágica. Ele reduz o problema quando a recuperação traz os trechos certos e quando o prompt obriga o modelo a se apoiar neles e a admitir quando a resposta não está lá. A maior parte do trabalho, portanto, está na qualidade da busca, não na escolha do modelo. Este guia cobre o pipeline completo, as opções de banco vetorial, como avaliar e um código mínimo em Python.
Resumo rápido
- Use RAG quando o conhecimento muda com frequência, é grande demais para caber no prompt ou precisa de citação de fonte.
- O pipeline tem seis etapas: ingestão, chunking, embeddings, indexação, busca (de preferência híbrida, com reranking) e geração com citação.
- pgvector, Qdrant, Chroma, Pinecone e Weaviate resolvem o armazenamento; a escolha depende mais da sua infraestrutura do que de desempenho.
- Avalie recuperação e geração separadamente: primeiro “achou o trecho certo?”, depois “a resposta é fiel ao trecho?”.
- Os erros mais comuns são chunks mal cortados, ausência de metadados e respostas sem citação.
RAG, fine-tuning ou contexto longo: quando usar cada um
Antes de montar um pipeline, confirme se você precisa dele. Há três formas de levar conhecimento próprio a um modelo, e elas resolvem problemas diferentes.
| Abordagem | Como funciona | Bom para | Limitações |
|---|---|---|---|
| Contexto longo | Colar os documentos inteiros no prompt | Poucos documentos, análise pontual, protótipos | Custo por chamada cresce com o volume; não escala para milhares de arquivos; sem controle fino do que o modelo usou |
| RAG | Buscar só os trechos relevantes a cada pergunta | Bases grandes, conteúdo que muda, necessidade de citar fonte e de controlar acesso | Exige pipeline e manutenção; a resposta só é boa se a busca for boa |
| Fine-tuning | Treinar o modelo com exemplos seus | Estilo, formato, tarefas repetitivas e específicas | Ruim para ensinar fatos que mudam; atualizar exige novo treino; não cita fonte |
Regra prática: se cabe no prompt e é consulta esporádica, use contexto longo. Se é uma base viva consultada por muita gente, RAG. Fine-tuning entra quando o problema é comportamento (tom, formato), não conhecimento. As abordagens também se combinam: um modelo ajustado para o seu formato pode consumir trechos recuperados por RAG.
O pipeline passo a passo
1. Ingestão
Extraia o texto dos documentos (PDF, Word, páginas web, planilhas, tickets) e limpe o ruído: cabeçalhos repetidos, rodapés, números de página. PDFs escaneados precisam de OCR. Tabelas merecem atenção: convertidas para texto corrido, elas costumam perder o sentido, então vale transformá-las em markdown ou em frases (“Quarto Standard: R$ X na baixa temporada”).
2. Chunking
Chunking é dividir o texto em pedaços (chunks) que serão indexados. Chunks pequenos demais perdem contexto; grandes demais misturam assuntos e diluem a relevância. Prefira cortar pela estrutura do documento (seções, artigos, perguntas de um FAQ) a cortar por número fixo de caracteres. Uma sobreposição pequena entre chunks vizinhos ajuda a não partir uma ideia ao meio. Não existe tamanho ideal universal: teste com seus documentos.
3. Embeddings
Um embedding é um vetor de números que representa o significado de um texto; textos parecidos geram vetores próximos. Você gera um embedding para cada chunk na indexação e outro para a pergunta na hora da busca, sempre com o mesmo modelo. Opções incluem as APIs da OpenAI, Google, Cohere e Voyage, além de modelos abertos que rodam localmente. Para documentos em português, teste se o modelo escolhido lida bem com o idioma.
4. Banco vetorial e metadados
Os vetores vão para um banco que faz busca por similaridade, junto com o texto original e metadados: nome do arquivo, página, seção, data, departamento, nível de acesso. Metadados permitem filtrar (“só políticas vigentes”, “só documentos do setor jurídico”) e são o que torna possível citar a fonte.
5. Busca híbrida e reranking
A busca vetorial entende sinônimos e paráfrases, mas falha em termos exatos: códigos de produto, números de cláusula, siglas. A busca lexical tradicional (BM25, a mesma família de algoritmo de mecanismos de busca clássicos) faz o contrário. A busca híbrida roda as duas e combina os resultados, frequentemente com Reciprocal Rank Fusion (RRF), que soma pontuações baseadas na posição de cada trecho em cada lista.
Depois, um reranker (geralmente um modelo cross-encoder, que lê pergunta e trecho juntos) reordena os candidatos com mais precisão. O fluxo comum é buscar algumas dezenas de candidatos e enviar ao modelo só os melhores após o reranking.
6. Geração com citação
Monte o prompt com os trechos delimitados e identificados, instrua o modelo a responder apenas com base neles, citar o identificador de cada trecho usado e dizer explicitamente quando a informação não estiver disponível. Algumas APIs oferecem recursos nativos de citação; confira a documentação do seu fornecedor. A estrutura do prompt segue as mesmas técnicas do nosso guia de engenharia de prompts.
Exemplo prático: o assistente de políticas de um hotel
Imagine um hotel no Rio que quer responder hóspedes no site e no WhatsApp sobre check-in, cancelamento, pets e estacionamento. As informações estão espalhadas em um manual operacional em PDF, na política de reservas e num FAQ desatualizado. Contexto longo funcionaria no começo, mas o manual muda a cada temporada e a recepção precisa saber de onde veio cada resposta.
O código abaixo mostra um RAG mínimo com busca híbrida (vetorial + BM25 combinados por RRF) e geração com citação. Ele usa o SDK oficial da OpenAI (pip install openai numpy rank-bm25); defina MODELO_CHAT com um modelo atual da lista do fornecedor.
import numpy as np
from openai import OpenAI
from rank_bm25 import BM25Okapi
client = OpenAI() # lê OPENAI_API_KEY do ambiente
MODELO_EMB = "text-embedding-3-small"
MODELO_CHAT = "defina-aqui" # confira a lista de modelos do fornecedor
trechos = [
{"id": "manual-p3", "texto": "Check-in a partir das 14h e check-out até as 12h."},
{"id": "reservas-p1", "texto": "Cancelamento gratuito até 48 horas antes da chegada."},
{"id": "faq-p7", "texto": "Aceitamos pets de pequeno porte mediante taxa diária."},
]
def embed(textos):
r = client.embeddings.create(model=MODELO_EMB, input=textos)
v = np.array([d.embedding for d in r.data])
return v / np.linalg.norm(v, axis=1, keepdims=True)
vetores = embed([t["texto"] for t in trechos])
bm25 = BM25Okapi([t["texto"].lower().split() for t in trechos])
def buscar(pergunta, k=2, c=60):
sim = vetores @ embed([pergunta])[0] # similaridade de cosseno
lex = bm25.get_scores(pergunta.lower().split())
rrf = np.zeros(len(trechos))
for notas in (sim, lex): # Reciprocal Rank Fusion
for pos, i in enumerate(np.argsort(-notas)):
rrf[i] += 1 / (c + pos + 1)
return [trechos[i] for i in np.argsort(-rrf)[:k]]
def responder(pergunta):
ctx = "\n".join(f'<trecho id="{t["id"]}">{t["texto"]}</trecho>'
for t in buscar(pergunta))
r = client.chat.completions.create(model=MODELO_CHAT, messages=[
{"role": "system", "content": "Responda só com base nos trechos. "
"Cite o id usado entre colchetes. Se não houver resposta nos trechos, "
"diga que não encontrou a informação."},
{"role": "user", "content": f"<trechos>\n{ctx}\n</trechos>\n\nPergunta: {pergunta}"},
])
return r.choices[0].message.content
print(responder("Posso levar meu cachorro?"))
Repare que “cachorro” não aparece em nenhum trecho: quem encontra o FAQ de pets é a busca vetorial. Já uma pergunta com “48 horas” seria bem servida pelo BM25. Em produção, troque a lista em memória por um banco vetorial, acrescente reranking e guarde página e data nos metadados. O mesmo código roda com modelos locais apontando o cliente para a API compatível com OpenAI do Ollama; veja como rodar IA local com Ollama.
Qual banco vetorial escolher
Todos os bancos abaixo fazem busca por similaridade com filtros de metadados. As diferenças estão em operação, hospedagem e recursos extras. Preços mudam e dependem de volume; consulte a página oficial de cada um.
| Opção | Tipo | Quando faz sentido |
|---|---|---|
| pgvector | Extensão open source do PostgreSQL | Você já usa Postgres e quer vetores junto dos dados da aplicação, com SQL, transações e controle de acesso que já conhece. Combina com a busca textual nativa do Postgres para busca híbrida. |
| Qdrant | Banco vetorial open source, com versão gerenciada | Quer um banco dedicado, com filtros ricos de metadados, rodando no seu servidor ou na nuvem do fornecedor. |
| Chroma | Banco open source, leve, com opção em nuvem | Protótipos e projetos pequenos em Python; começa a funcionar com poucas linhas. |
| Pinecone | Serviço gerenciado | Não quer operar infraestrutura e aceita um serviço pago fora do seu ambiente. |
| Weaviate | Banco open source, com versão gerenciada | Quer busca híbrida e integrações com provedores de embeddings já embutidas. |
No pgvector, o básico é CREATE EXTENSION vector;, uma coluna do tipo vector(n), o operador <=> para distância de cosseno e um índice HNSW para acelerar a busca. Para a maioria das pequenas e médias empresas, começar pelo banco que a equipe já opera é a decisão mais barata.
Como avaliar um sistema RAG
Avalie as duas metades separadamente; senão você não sabe se o erro foi da busca ou do modelo.
- Recuperação: monte de 30 a 100 perguntas reais com o trecho que contém a resposta. Meça se esse trecho aparece entre os primeiros resultados (precisão e recall de contexto). Se não aparece, nenhum modelo vai acertar.
- Fidelidade (faithfulness): verifique se cada afirmação da resposta está sustentada pelos trechos entregues. Resposta correta mas sem apoio no contexto também é um problema, porque veio da memória do modelo.
- Relevância da resposta: a resposta trata da pergunta feita?
- Recusa correta: inclua perguntas cuja resposta não está na base e confira se o sistema admite que não sabe.
Bibliotecas como Ragas automatizam essas métricas usando um modelo como avaliador; ainda assim, revise uma amostra manualmente, porque avaliadores automáticos também erram.
Erros comuns
- Chunks ruins. Cortar no meio de uma tabela ou cláusula gera trechos sem sentido. Revise visualmente uma amostra dos chunks antes de indexar.
- Sem metadados. Sem data e origem, o sistema mistura a política de 2023 com a vigente e não consegue citar a fonte.
- Sem citação. Resposta sem fonte não pode ser conferida pela equipe nem pelo cliente. Exija o identificador do trecho e mostre o link do documento.
- Só busca vetorial. Perguntas com códigos, nomes próprios e números falham. Acrescente BM25.
- Ignorar permissões. Se o RH e a recepção usam o mesmo assistente, filtre por nível de acesso na busca, não no prompt.
- Base desatualizada. Defina um processo de reindexação quando documentos mudam e remova versões antigas.
- Dados pessoais indexados sem critério. Documentos com CPF ou dados de saúde exigem base legal e controles; veja nosso guia de segurança e LGPD.
Perguntas frequentes
Com modelos de contexto enorme, RAG ainda faz sentido?
Sim, em bases grandes ou que mudam com frequência. Enviar tudo a cada pergunta custa mais, demora mais e não mostra de onde veio a resposta. Para poucos documentos e uso esporádico, contexto longo é mais simples e pode bastar.
Preciso de um banco vetorial dedicado?
Não necessariamente. Para poucos milhares de chunks, até uma lista em memória funciona em protótipos, e o pgvector atende muitos casos de produção. Banco dedicado passa a valer quando volume, filtros ou operação justificam.
RAG funciona com planilhas e bancos de dados?
Para dados estruturados, costuma ser melhor deixar o modelo consultar o banco via SQL ou ferramentas (function calling) do que transformar linhas em texto. RAG brilha em texto não estruturado: manuais, contratos, e-mails, atas.
Posso rodar RAG sem enviar documentos para a nuvem?
Sim. Modelos de embeddings e de geração abertos rodam localmente com ferramentas como o Ollama, e bancos como pgvector, Qdrant e Chroma podem ficar no seu servidor. A qualidade depende do modelo local escolhido; teste com suas perguntas.
Quantos trechos devo enviar ao modelo?
Não há número fixo. Poucos trechos podem deixar a resposta de fora; muitos acrescentam ruído e custo. Comece com poucos trechos após reranking e ajuste com base na avaliação de recuperação.