Nem tudo é RAG: por que grep venceu embeddings no meu auditor de código Progress
Se o seu dado tem gancho (nome de rotina, tabela, ID), busca léxica ganha de banco vetorial em custo e eficácia. Eu medi. No mundo Datasul/Progress, isso é quase sempre verdade.
"RAG = embeddings + banco vetorial." Você já leu isso mil vezes. Eu também — e cheguei a construir assim. Depois medi, e o resultado me fez arrancar a camada vetorial fora.
🎯 O problema
Auditar bases legadas em Progress 4GL/ABL contra um checklist de dezenas de verificações, comparando o código do cliente com um acervo de ~94 mil fontes-padrão do ecossistema (EMS2, Foundation, EMS5).
A pergunta óbvia: "vou indexar tudo com embeddings e fazer busca semântica, certo?"
Errado — pelo menos pro meu caso.
💸 RAG vetorial cobra um pedágio contínuo
Busca por embeddings só compensa quando você precisa de similaridade semântica: achar algo por significado difuso, sem um gancho literal pra chegar nele.
O custo, porém, não é só o embedding inicial:
- 💸 Banco vetorial pra manter no ar (Postgres + pgvector)
- 💸 Pipeline de embedding rodando
- 💸 Decisões de chunking (tamanho? overlap? por função?)
- 💸 Re-indexação a cada mudança — o índice envelhece a cada commit
Cada item desses é manutenção eterna. Custo de indexação do grep: zero.
🪝 Código tem gancho — e isso muda tudo
| Meu alvo de busca | Exemplo | Tipo |
|---|---|---|
| Nomes de rotina / programas | CD0101, bo/boad098.p | Léxico |
| Padrões de sintaxe | EXCLUSIVE-LOCK, FOR EACH | Léxico |
| Módulo, tabelas, dependências | quem chama quem | Estruturado |
| Acervo | finito e conhecido | Delimitado |
Quando o dado tem gancho léxico ou estruturado, a similaridade vetorial não adiciona recall — só adiciona custo. Um grep bem direcionado chega no trecho certo com precisão determinística, por uma fração do preço.
Rodei o A/B em projetos reais: um com RAG vetorial em Postgres, outro sem. O sem-RAG (grep + índice de metadados) saiu mais eficaz e mais barato.
🧭 A pergunta que decide
💡 Eu tenho um gancho léxico/estruturado pra chegar no dado — ou só consigo descrevê-lo por significado?
Tem gancho → busca léxica (
grep, índice de metadados). É o caso de código. Só significado difuso → aí sim, RAG vetorial paga o próprio custo.
O fluxo de decisão completo:
graph TD
A[Preciso recuperar<br>dados pro meu LLM] --> B{Tem gancho lexico<br>ou estruturado?}
B -- "Sim: codigo, IDs,<br>tabelas, metadado" --> C[grep / indice<br>de metadados]
B -- "Nao: significado<br>difuso" --> D[RAG vetorial<br>embeddings]
C --> E{Recall caiu em<br>criterios conceituais?}
E -- Nao --> F[Pronto:<br>simples e barato]
E -- Sim --> G[Hibrido: embedding so no<br>subconjunto que o<br>lexico nao cobre]
📚 Por que isso é maior que uma escolha técnica
Michael Albada (Building Applications with AI Agents) coloca RAG num degrau abaixo de agente numa escada de decisão — RAG "faz aparecer informação", não decide nem age. No meu sistema, o grep é uma ferramenta dentro do agente, não o sistema inteiro.
E Chip Huyen (AI Engineering) dá o princípio que sustenta tudo:
A solução mais simples que atinge a qualidade-alvo é a solução certa — não uma versão inferior.
RAG casado com o problema errado é pagar por capacidade que você não usa.
⚠️ O ponto cego honesto do grep
⚠️ Busca léxica acha onde a string aparece — não onde o conceito acontece sem a string. Pra critérios conceituais ("trata erro adequadamente" sem palavra óbvia), o recall cai.
A saída é híbrida: léxico como camada primária, embeddings reservados só pro subconjunto onde o léxico falha — nunca as 94 mil fontes inteiras.
🏁 O que fica
Antes de subir um banco vetorial, faça a pergunta do gancho. No mundo Progress/Datasul — onde tudo tem nome, código e estrutura — você provavelmente vai economizar bastante indo de grep.
E você — já mediu se o seu RAG vetorial está pagando o próprio custo, ou montou porque "todo mundo usa"? Conta aí nos comentários.