# O que é RAG? Como funciona, com três projetos reais

> O que é RAG (Retrieval-Augmented Generation), como funciona o pipeline e quando usar RAG em vez de fine-tuning, com exemplos de projetos reais.

2026-10-16 · Gustavo Karsten

RAG (Retrieval-Augmented Generation, ou geração aumentada por recuperação) é uma técnica em que o sistema busca trechos relevantes nos seus documentos e entrega esses trechos ao modelo de linguagem junto com a pergunta. O modelo responde com base no que foi recuperado, não só no que aprendeu no treino. Na prática, RAG é o jeito mais comum de fazer um LLM responder sobre dados que ele nunca viu: manuais, aulas, contratos, documentos fiscais.

Eu construí RAG em alguns projetos: um sobre documentos fiscais dos EUA, um sobre aulas em vídeo e um agente de atendimento no WhatsApp. Aqui explico o que é RAG, etapa por etapa, e onde cada etapa costuma quebrar.

## O que é RAG, em uma frase técnica

O termo vem do artigo de [Lewis et al., 2020](https://arxiv.org/abs/2005.11401), que juntou um recuperador de documentos a um gerador de texto. Hoje a palavra cobre qualquer arquitetura com o mesmo formato:

1. **Indexar:** quebrar os documentos em pedaços, gerar um vetor (embedding) para cada um e guardar.
2. **Recuperar:** transformar a pergunta em vetor e buscar os pedaços mais próximos.
3. **Gerar:** montar um prompt com a pergunta e os pedaços, e pedir ao modelo uma resposta que cite as fontes.

O modelo não "aprende" nada novo. Ele lê, a cada pergunta, o contexto que a busca trouxe. Por isso a qualidade de um sistema RAG depende mais da busca do que do modelo.

## Como funciona um pipeline RAG

### Ingestão e chunking

Antes de buscar, é preciso ter texto, e isso quase nunca é trivial.

No [IRS Helper](https://gustavokarsten.com/projects/irs-helper), um sistema RAG sobre formulários e publicações do IRS, a coleta é feita com Scrapy: spiders separados para PDFs e EPUBs do irs.gov. Os EPUBs são convertidos em PDF, e a vetorização filtra versões do mesmo documento em outros idiomas, para não encher o índice de duplicatas.

No [RAG sobre aulas em vídeo](https://gustavokarsten.com/projects/rag-video), o texto nem existe no começo. O upload entra numa fila BullMQ, e um worker em container separado extrai o áudio com ffmpeg, transcreve com Deepgram e gera os embeddings. PDFs seguem o mesmo caminho.

Depois vem o chunking: cortar o texto em pedaços. No projeto de vídeo, os chunks têm cerca de 500 tokens com sobreposição de 50, e cada um guarda o tempo de início do trecho na aula. Esse metadado é o que depois permite citar o minuto exato. A regra que tiro disso: decida o formato da citação antes de decidir o chunking, porque o que você não guarda no chunk não volta depois.

### Embeddings e banco vetorial

Um embedding é um vetor de números que representa o sentido de um texto. Textos parecidos ficam próximos no espaço vetorial. Nos meus projetos com a OpenAI, os vetores têm 1536 dimensões.

Para guardar e buscar, eu uso PostgreSQL com [pgvector](https://github.com/pgvector/pgvector). A vantagem é não ter um banco a mais: o chunk, os metadados, as permissões e o vetor ficam na mesma tabela, e dá para filtrar com SQL comum. O pgvector oferece dois índices aproximados, e usei os dois: HNSW no projeto de vídeo e IVFFlat no [DockPlus Atendimento](https://gustavokarsten.com/projects/dockplus-atendimento).

Antes disso, na PowerX, implementei RAG sobre documentos internos usando LangChain e Ollama, com o modelo de embeddings nomic-embed-text e pgvector. O banco vetorial era o mesmo; o modelo de embedding é uma peça trocável.

Uma busca vetorial no pgvector é só uma consulta SQL. Exemplo genérico:

```sql
SELECT id, content, start_seconds
FROM chunks
WHERE course_id = $1
ORDER BY embedding <=> $2   -- distância de cosseno
LIMIT 20;
```

### Recuperação: vetor, texto e HyDE

Busca só por vetor erra em termos exatos. Um vetor capta bem "como declarar renda de aluguel", mas pode errar "Form 8829", porque o número é um token raro sem muito sentido semântico.

O IRS Helper trata isso antes da busca. Se a pergunta pede um formulário ("Form 1040"), um regex encontra o número e devolve o link direto, sem chamar o LLM. Só o resto vai para a busca vetorial.

No projeto de vídeo, a busca é híbrida: uma busca vetorial e uma busca full-text do Postgres (tsvector) rodam sobre os mesmos chunks, e os resultados são unidos por Reciprocal Rank Fusion (RRF). O RRF combina posições no ranking, não pontuações, então não importa que as duas buscas meçam relevância em escalas diferentes.

O mesmo projeto usa HyDE ([Gao et al., 2022](https://arxiv.org/abs/2212.10496)). A ideia: uma pergunta curta e um trecho de aula não se parecem muito. Então o modelo primeiro escreve uma resposta hipotética, e a busca usa o embedding dessa resposta, que fica mais próxima do texto que se quer achar. A resposta hipotética pode estar errada; ela só serve de isca para a busca.

### Rerank

A busca vetorial é rápida porque compara vetores calculados de antemão. Um reranker é mais lento e mais preciso: ele lê a pergunta e cada candidato juntos e dá uma nota de relevância.

O padrão é buscar muitos e reranquear poucos. No projeto de vídeo, o Cohere reranqueia os 20 melhores e ficam 5. No IRS Helper, também com Cohere, entram 10 e ficam 5. Cinco trechos bons cabem no prompt e deixam menos espaço para o modelo se distrair.

### Geração com citações

Na última etapa, os trechos vão para o prompt com uma instrução: responda só com base neste contexto e cite a fonte.

No projeto de vídeo, as citações saem no formato `[Título, MM:SS]`, e a interface transforma cada uma num botão que leva o player ao ponto exato da aula. O aluno confere a resposta em segundos. Citação boa não é enfeite: é o que permite ao usuário desconfiar do modelo.

O mesmo sistema trata a falta de contexto. Quando a melhor pontuação da busca fica abaixo de 0,65, a resposta sai com aviso de baixa confiança. E cada etapa (HyDE, busca, rerank, transcrição) é registrada como span no Langfuse, então dá para ver onde uma resposta ruim começou.

No IRS Helper, a resposta sai por uma API FastAPI compatível com `/v1/chat/completions`, inclusive com `stream: true`. O LiteLLM registra o servidor como um modelo chamado `irs-helper`, e o OpenWebUI usa como se fosse um modelo qualquer. O RAG fica escondido atrás de uma interface que qualquer cliente OpenAI já entende.

## RAG dentro de um agente

RAG não precisa ser o sistema inteiro. No DockPlus Atendimento, um agente para WhatsApp, Telegram e e-mail, um grafo LangGraph classifica a intenção da mensagem e chama o nó certo. Dúvida vai para o nó com RAG; pedido de horário vai para agendamento; o resto pode ir para feedback ou para um humano.

Isso evita um erro comum: mandar toda mensagem para a busca. "Quero remarcar para amanhã" não precisa de documento nenhum. Rotear antes de recuperar economiza chamadas e reduz respostas que citam um trecho irrelevante só porque ele foi o mais próximo.

## Quando usar RAG, fine-tuning ou contexto longo

**Use RAG quando** a resposta depende de fatos que mudam, que são seus ou que precisam de fonte. Atualizar o conhecimento é reindexar um documento, não treinar de novo. E dá para aplicar permissão por usuário na consulta SQL.

**Use fine-tuning quando** o problema é forma, não fato: um formato de saída fixo, um tom, uma classificação específica. Fine-tuning ensina comportamento. Ele é um jeito ruim de ensinar fatos, porque não cita fonte e envelhece no dia seguinte.

**Use contexto longo quando** o acervo é pequeno e cabe inteiro no prompt, como um contrato ou um manual de poucas páginas. Sem índice, sem chunking, sem nada para dar errado na busca. O custo é pagar por todos os tokens em toda pergunta.

Na prática, os três se combinam. Um acervo grande com RAG ainda pode usar uma janela de contexto generosa para mandar mais trechos.

## Onde um sistema RAG falha

- **Texto sujo na entrada.** PDF com tabela quebrada, transcrição com erro, a mesma página em três idiomas. A busca devolve lixo com confiança.
- **Chunk sem contexto.** Um pedaço que diz "o prazo é 30 dias" sem dizer de quê. Guarde título e seção junto com o chunk.
- **Termo exato perdido.** Código de formulário, número de lei, nome de produto. Use busca full-text junto, ou um atalho como o regex do IRS Helper.
- **Pergunta que não precisa de busca.** Roteie a intenção antes, como no DockPlus Atendimento.
- **Resposta sem contexto suficiente.** Defina um limiar de pontuação e diga ao usuário quando a base não cobre a pergunta, em vez de deixar o modelo improvisar.
- **Nenhuma forma de depurar.** Sem registro de cada etapa, uma resposta errada não diz se a culpa foi da busca, do rerank ou do prompt.

## Resumo

RAG é busca mais geração. O modelo é a parte fácil de trocar; ingestão, chunking e recuperação são onde está o trabalho. Comece com pgvector e busca vetorial, meça onde erra, e só então adicione busca híbrida, HyDE ou rerank.

Os projetos citados estão em [projetos](https://gustavokarsten.com/projects), e minha trajetória em [sobre](https://gustavokarsten.com/about). Se você precisa de RAG sobre os documentos da sua empresa, [fale comigo](https://gustavokarsten.com/contact).

---
Página: https://gustavokarsten.com/articles/o-que-e-rag
Contato: gustavo.karsten@outlook.com · https://www.linkedin.com/in/gustavo-karsten-88a04383/ · https://github.com/gustavo-karsten
