Desenvolvedor cria sistema RAG com modelos locais e aumenta a precisão de busca de 20% para 53%
Um desenvolvedor (conhecido no GitHub como tzar26) construiu um sistema RAG totalmente auto-hospedado para análise de notícias, sem uma única chamada à OpenAI ou à Anthropic. Todo o stack roda sobre modelos locais, Qwen 2.5 14B e BGE-M3, servidos via Ollama, com um banco de dados PostgreSQL por trás. O objetivo principal: independência de provedores externos e controle total sobre os dados. No início, a busca entre os 12.000 artigos coletados funcionava apenas com embeddings vetoriais, e uma consulta por "ouro" retornava notícias sobre um patinador artístico que ganhou ouro em uma competição, em vez de informações sobre o preço do metal. O desenvolvedor adicionou a busca textual clássica BM25 e a combinou com a busca vetorial usando o algoritmo RRF; como resultado, a proporção de artigos relevantes entre os 5 primeiros resultados subiu de 20% para 53%. O prompt de classificação de temas também foi reescrito: antes, por medo de errar, o modelo jogava 74% dos artigos na categoria "outros" (other); depois do ajuste, apenas 0,03%, e uma revisão manual confirmou 85% de precisão na rotulagem. • Um agente em LangGraph escolhe por conta própria entre três ferramentas: busca por texto, agregação de métricas via SQL e busca por empresas mencionadas com análise de sentimento • A troca do LangChain por um cliente direto do Ollama acelerou o pipeline 9 vezes • O ajuste do Ollama (duas requisições em paralelo em vez de uma) acelerou a classificação de artigos em 1,5 vez
Processado por IA de Habr AI; editado por Hamidun News
Desenvolvedor cria sistema RAG com modelos locais e aumenta a precisão
de busca de 20% para 53%
Um desenvolvedor conhecido no GitHub como tzar26 publicou uma análise detalhada do seu sistema de análise de notícias, totalmente autônomo e sem nenhuma chamada a APIs em nuvem como OpenAI ou Anthropic. Todos os modelos rodam localmente via Ollama: Qwen 2.5 14B para raciocínio e classificação, e BGE-M3 para gerar representações vetoriais do texto. O artigo deixa claro o motivo dessa escolha: resiliência contra sanções e independência de provedores externos. O stack resultante — Python, FastAPI, PostgreSQL com a extensão pgvector, Celery para tarefas em segundo plano, LangGraph para o agente e Langfuse para monitoramento — foi empacotado em contêineres Docker e coberto por testes via GitHub Actions.
Por que a busca vetorial comum falhou com homônimos
O sistema reuniu mais de 12.000 artigos e, inicialmente, buscava entre eles apenas por distância de cosseno entre os embeddings do BGE-M3. Em consultas simples tudo funcionava bem, mas temas mais complexos, como "taxa básica do banco central", retornavam resultados sem sentido. O exemplo mais claro foi a busca por "ouro": em vez de notícias sobre o preço do metal, a busca trazia tranquilamente artigos sobre um patinador artístico que ganhou ouro em uma competição — uma confusão clássica causada pelo fato de a palavra ter múltiplos significados, algo que um vetor não distingue pelo contexto.
A solução foi uma busca híbrida: à comparação vetorial se somou uma busca textual precisa com BM25, baseada no PostgreSQL (via tsvector nativo), e os resultados dos dois métodos foram combinados pelo algoritmo RRF (Reciprocal Rank Fusion), que considera a posição de cada documento em cada um dos conjuntos de resultados e calcula um ranking combinado. O BM25 é ótimo para capturar termos exatos como "OPEP" ou "taxa", enquanto a busca vetorial capta sinônimos e relações semânticas. Juntos, eles elevaram a proporção de documentos relevantes entre os cinco primeiros resultados de busca (a métrica Recall@5) de 0,2 para 0,53 — mais do que o dobro.
Como parar de jogar tudo na categoria "outros"
Um problema separado surgiu durante a classificação automática dos artigos por tema. Na primeira versão do prompt, o modelo enviava 74% de todos os artigos para a categoria "outros" (other) — ou seja, quase três quartos da base ficavam sem um rótulo útil. A causa se revelou simples: as instruções continham a frase "em caso de dúvida, escolha outros", e o modelo, com medo de errar, recorria a ela em massa.
O desenvolvedor reescreveu o prompt: adicionou descrições claras para cada categoria, incluindo varejo (retail), macroeconomia (macro) e incidentes (incident), e removeu completamente a frase sobre a dúvida. Depois disso, a proporção de artigos não classificados caiu para 0,03%. Para confirmar que os números eram confiáveis, o autor também revisou manualmente uma amostra aleatória de artigos rotulados — a precisão da classificação ficou em 85%.
Um agente que calcula, não apenas busca
Uma busca comum no banco de dados responde a perguntas como "o que estão escrevendo sobre petróleo", mas isso não basta para análises mais profundas. Por isso, o autor construiu, com LangGraph, um agente com três ferramentas à disposição:
- `search_articles` — busca híbrida de texto padrão
- `get_metrics` — agregação via SQL, por exemplo, contar artigos sobre energia nos últimos três dias
- `search_by_entity` — busca por nomes de empresas extraídos, com o sentimento associado (resultado de modelos separados de NER e análise de sentimento)
Diante de uma pergunta como "há notícias negativas sobre o banco central?", o agente decide por conta própria qual ferramenta acionar — sem que seja necessário indicar explicitamente que ele precisa calcular o sentimento em vez de apenas buscar o texto. Para depurar essa lógica, foi implantada uma instância auto-hospedada do Langfuse, que mostra cada etapa da cadeia — planejador → chamada de ferramenta → resposta final —, quantos tokens foram usados em cada etapa e quais argumentos exatos o modelo passou para as funções.
As dores técnicas de rodar tudo em hardware local
Executar os modelos localmente trouxe seus próprios problemas, atípicos em APIs de nuvem:
- O Ollama descarregava os modelos da memória de vídeo ao alternar entre eles, e uma única requisição podia levar até 60 segundos — resolvido com a variável `OLLAMA_MAX_LOADED_MODELS=2`
- A biblioteca LangChain usa internamente uma agregação de respostas em streaming que causava uma lentidão de até nove vezes — ela foi retirada do pipeline em favor do cliente direto `ollama.AsyncClient`
- O SQLAlchemy vincula o pool de conexões ao event loop, e quando o Celery interrompia uma tarefa, as conexões ficavam "zumbis" — resolvido chamando `await engine.dispose()` após cada tarefa
- Por padrão, o Ollama processa as requisições de forma sequencial; classificar um único artigo levava cerca de 10 segundos, e aumentar o parâmetro `OLLAMA_NUM_PARALLEL` de 1 para 2 acelerou o processo em pelo menos 1,5 vez
O projeto está atualmente em fase de MVP público e disponível no GitHub. O próximo passo, segundo o autor, já está em desenvolvimento de forma reservada: vincular as empresas mencionadas aos tickers da Bolsa de Moscou (como SBER e GAZP) e construir painéis de previsão para ações específicas. Para engenheiros que estão considerando um stack local em vez de APIs em nuvem, a principal conclusão prática é esta: a economia nas chamadas de API é real, mas é preciso pagar por ela com tempo dedicado ao ajuste da infraestrutura — desde configurar o paralelismo do Ollama até lidar com o gerenciamento de conexões em código assíncrono.
- 29 de out. de 2026Claude no Houdini no Windows: dois bugs no painel do agente e uma geoda de 31 nós
- 29 de out. de 2026Technokafe montou um videoensaio com código: 73 segundos por $10 em tokens do Claude Code
- 29 de out. de 2026Como a OpenAI manteve o Azure Cosmos DB em pé sob a carga de 1 bilhão de usuários do ChatGPT
- 29 de out. de 2026Modal supera $1 bilhão em ARR e é avaliada em $16 bilhões com a demanda por sandboxes
Perguntas frequentes sobre a notícia
O que se sabe sobre Desenvolvedor cria sistema RAG com modelos locais e aumenta a precisão de busca de 20% para 53%?
Um desenvolvedor conhecido no GitHub como tzar26 publicou uma análise detalhada do seu sistema de análise de notícias, totalmente autônomo e sem nenhuma chamada a APIs em nuvem como OpenAI ou Anthropic. Todos os modelos rodam localmente via Ollama: Qwen 2.5 14B para raciocínio e classificação, e BGE-M3 para gerar representações vetoriais do texto. O artigo deixa claro o motivo dessa escolha: resiliência contra sanções e independência de provedores externos. O stack resultante — Python, FastAPI, PostgreSQL com a extensão pgvector, Celery para tarefas em segundo plano, LangGr
Por que a busca vetorial comum falhou com homônimos?
O sistema reuniu mais de 12.000 artigos e, inicialmente, buscava entre eles apenas por distância de cosseno entre os embeddings do BGE-M3. Em consultas simples tudo funcionava bem, mas temas mais complexos, como "taxa básica do banco central", retornavam resultados sem sentido. O exemplo mais claro foi a busca por "ouro": em vez de notícias sobre o preço do metal, a busca trazia tranquilamente artigos sobre um patinador artístico que ganhou ouro em uma competição — uma confusão clássica causada pelo fato de a palavra ter múltiplos significados, algo que um vetor não disting
Como parar de jogar tudo na categoria "outros"?
Um problema separado surgiu durante a classificação automática dos artigos por tema. Na primeira versão do prompt, o modelo enviava 74% de todos os artigos para a categoria "outros" (other) — ou seja, quase três quartos da base ficavam sem um rótulo útil. A causa se revelou simples: as instruções continham a frase "em caso de dúvida, escolha outros", e o modelo, com medo de errar, recorria a ela em massa. O desenvolvedor reescreveu o prompt: adicionou descrições claras para cada categoria, incluindo varejo (retail), macroeconomia (macro) e incidentes (incident), e removeu c
Build & Ship Production AI Agents Without Boilerplate Code
Start your free 72-hour trial at Hamidun Academy (academy.hamidun.com) — interactive lessons on Claude Code & Cursor, live Tech Radar, and production agent templates.
O essencial da IA — uma vez por semana
Sete histórias que realmente importaram, escolhidas a dedo. Sem ruído nem releases.
Pronto! Verifique seu e-mail para a confirmação.