Un desarrollador crea un sistema RAG con modelos locales y eleva la precisión de búsqueda del 20% al 53%
Un desarrollador (conocido en GitHub como tzar26) construyó un sistema RAG totalmente autoalojado para analizar noticias, sin una sola llamada a OpenAI ni a Anthropic. Todo el stack corre sobre modelos locales, Qwen 2.5 14B y BGE-M3, servidos a través de Ollama, con una base de datos PostgreSQL. El objetivo principal: independencia de proveedores externos y control total sobre los datos. Al principio, la búsqueda en los 12.000 artículos recopilados funcionaba solo con embeddings vectoriales, y una consulta por "oro" devolvía noticias sobre un patinador artístico que ganó el oro en una competencia, en lugar de información sobre el precio del metal. El desarrollador añadió la búsqueda de texto clásica BM25 y la combinó con la vectorial mediante el algoritmo RRF; como resultado, la proporción de artículos relevantes entre los primeros 5 resultados subió del 20% al 53%. También se reescribió el prompt de clasificación de temas: antes, por miedo a equivocarse, el modelo relegaba el 74% de los artículos a la categoría de "otros"; tras el ajuste, solo el 0,03%, y una revisión manual confirmó un 85% de precisión en el etiquetado. • Un agente en LangGraph elige por sí mismo entre tres herramientas: búsqueda de texto, agregación de métricas por SQL y búsqueda por empresas mencionadas con su tono • El cambio de LangChain a un cliente directo de Ollama aceleró el pipeline 9 veces • Ajustar Ollama (dos solicitudes en paralelo en lugar de una) aceleró la clasificación de artículos 1,5 veces
Procesado por IA desde Habr AI; editado por Hamidun News
Un desarrollador crea un sistema RAG con modelos locales y eleva la
precisión de búsqueda del 20% al 53%
Un desarrollador conocido en GitHub como tzar26 publicó un análisis detallado de su sistema de análisis de noticias, completamente autónomo y sin ninguna llamada a APIs en la nube como OpenAI o Anthropic. Todos los modelos funcionan localmente a través de Ollama: Qwen 2.5 14B para el razonamiento y la clasificación, y BGE-M3 para las representaciones vectoriales del texto. El artículo expone directamente el motivo de este enfoque: resiliencia frente a sanciones e independencia de proveedores externos. El stack resultante —Python, FastAPI, PostgreSQL con la extensión pgvector, Celery para tareas en segundo plano, LangGraph para el agente y Langfuse para el monitoreo— se empaquetó en contenedores Docker y se cubrió con pruebas mediante GitHub Actions.
Por qué la búsqueda vectorial común falló con los homónimos
El sistema recopiló más de 12.000 artículos y, al principio, los buscaba únicamente mediante la distancia coseno entre los embeddings de BGE-M3. Con consultas sencillas todo funcionaba bien, pero temas más complejos, como "la tasa de interés clave del banco central", devolvían resultados sin sentido. El ejemplo más claro fue la consulta "oro": en lugar de noticias sobre el precio del metal, la búsqueda devolvía con total naturalidad artículos sobre un patinador artístico que ganó el oro en una competencia — una confusión clásica causada por las múltiples acepciones de la palabra, que un vector no distingue según el contexto.
La solución fue una búsqueda híbrida: a la comparación vectorial se le sumó una búsqueda de texto precisa con BM25 basada en PostgreSQL (mediante tsvector nativo), y los resultados de ambos métodos se combinaron con el algoritmo RRF (Reciprocal Rank Fusion), que toma la posición de cada documento en cada conjunto de resultados y calcula un ranking combinado. BM25 es excelente para capturar términos exactos como "OPEP" o "tasa", mientras que la búsqueda vectorial capta sinónimos y relaciones semánticas. En conjunto, la proporción de documentos relevantes entre los primeros cinco resultados de búsqueda (la métrica Recall@5) subió de 0,2 a 0,53, es decir, más del doble.
Cómo dejar de relegarlo todo a la categoría de "otros"
Surgió un problema aparte durante la clasificación automática de los artículos por tema. En la primera versión del prompt, el modelo enviaba el 74% de todos los artículos a la categoría "otros", es decir, casi tres cuartas partes de la base quedaban sin una etiqueta útil. La causa resultó ser sencilla: las instrucciones incluían la frase "si tienes dudas, elige otros", y el modelo, por miedo a equivocarse, recurría a ella masivamente.
El desarrollador reescribió el prompt: añadió descripciones claras para cada categoría, incluidas comercio minorista (retail), macroeconomía (macro) e incidentes (incident), y eliminó esa frase sobre la duda. Tras el cambio, la proporción de artículos sin clasificar cayó al 0,03%. Para comprobar que las cifras eran fiables, el autor revisó manualmente una muestra aleatoria de artículos etiquetados: la precisión de la clasificación resultó ser del 85%.
Un agente que calcula, no solo busca
Una búsqueda común en la base de datos puede responder a preguntas como "qué se está escribiendo sobre el petróleo", pero eso no basta para el análisis. Por eso el autor construyó, con LangGraph, un agente con tres herramientas a elegir:
- `search_articles`: búsqueda híbrida de texto estándar
- `get_metrics`: agregación mediante SQL, por ejemplo, contar artículos sobre energía en los últimos tres días
- `search_by_entity`: búsqueda por nombres de empresas extraídos, con su tono asociado (resultado de modelos independientes de NER y análisis de sentimiento)
Ante una pregunta como "¿hay noticias negativas sobre el banco central?", el agente decide por sí mismo qué herramienta invocar, sin necesidad de indicarle explícitamente que debe calcular el tono del texto en lugar de simplemente buscarlo. Para depurar esta lógica, se desplegó una instancia autoalojada de Langfuse, que muestra cada paso de la cadena —planificador → llamada a la herramienta → respuesta final—, cuántos tokens se usaron en cada paso y qué argumentos exactos pasó el modelo a las funciones.
Los dolores técnicos de correr todo en hardware local
Ejecutar los modelos localmente trajo sus propios problemas, atípicos en las APIs en la nube:
- Ollama descargaba los modelos de la memoria de video al cambiar entre ellos, y una sola solicitud podía tardar hasta 60 segundos; se solucionó con la variable `OLLAMA_MAX_LOADED_MODELS=2`
- La biblioteca LangChain usa internamente una agregación de respuestas por streaming que provocaba una ralentización de nueve veces; se eliminó del pipeline en favor del cliente directo `ollama.AsyncClient`
- SQLAlchemy vincula el pool de conexiones al bucle de eventos (event loop), y cuando Celery interrumpía una tarea, las conexiones quedaban como "zombis"; se resolvió invocando `await engine.dispose()` después de cada tarea
- Ollama procesa las solicitudes de forma secuencial por defecto; clasificar un solo artículo tardaba unos 10 segundos, y aumentar el parámetro `OLLAMA_NUM_PARALLEL` de 1 a 2 aceleró el proceso al menos 1,5 veces
El proyecto se encuentra actualmente en fase de MVP público y está disponible en GitHub. El siguiente paso, según el autor, ya está en marcha de forma privada: vincular las empresas mencionadas con los tickers de la Bolsa de Moscú (como SBER y GAZP) y construir paneles de pronóstico para acciones específicas. Para los ingenieros que estén considerando un stack local en lugar de APIs en la nube, la conclusión práctica principal es la siguiente: el ahorro en llamadas a la API es real, pero hay que pagarlo con tiempo dedicado a ajustar la infraestructura, desde configurar el paralelismo de Ollama hasta lidiar con la gestión de conexiones en código asíncrono.
- 29 oct 2026Claude en Houdini sobre Windows: dos bugs en el panel del agente y una geoda de 31 nodos
- 29 oct 2026Technokafe monta un videoensayo con código: 73 segundos por $10 en tokens de Claude Code
- 29 oct 2026Cómo OpenAI mantuvo en pie Azure Cosmos DB bajo la carga de 1.000 millones de usuarios de ChatGPT
- 29 oct 2026Modal supera los $1 mil millones de ARR y se valora en $16 mil millones gracias a la demanda de sandboxes
Preguntas frecuentes sobre la noticia
¿Qué se sabe sobre Un desarrollador crea un sistema RAG con modelos locales y eleva la precisión de búsqueda del 20% al 53%?
Un desarrollador conocido en GitHub como tzar26 publicó un análisis detallado de su sistema de análisis de noticias, completamente autónomo y sin ninguna llamada a APIs en la nube como OpenAI o Anthropic. Todos los modelos funcionan localmente a través de Ollama: Qwen 2.5 14B para el razonamiento y la clasificación, y BGE-M3 para las representaciones vectoriales del texto. El artículo expone directamente el motivo de este enfoque: resiliencia frente a sanciones e independencia de proveedores externos. El stack resultante —Python, FastAPI, PostgreSQL con la extensión pgvecto
¿Qué se sabe sobre Por qué la búsqueda vectorial común falló con los homónimos?
El sistema recopiló más de 12.000 artículos y, al principio, los buscaba únicamente mediante la distancia coseno entre los embeddings de BGE-M3. Con consultas sencillas todo funcionaba bien, pero temas más complejos, como "la tasa de interés clave del banco central", devolvían resultados sin sentido. El ejemplo más claro fue la consulta "oro": en lugar de noticias sobre el precio del metal, la búsqueda devolvía con total naturalidad artículos sobre un patinador artístico que ganó el oro en una competencia — una confusión clásica causada por las múltiples acepciones de la pa
Cómo dejar de relegarlo todo a la categoría de "otros"?
Surgió un problema aparte durante la clasificación automática de los artículos por tema. En la primera versión del prompt, el modelo enviaba el 74% de todos los artículos a la categoría "otros", es decir, casi tres cuartas partes de la base quedaban sin una etiqueta útil. La causa resultó ser sencilla: las instrucciones incluían la frase "si tienes dudas, elige otros", y el modelo, por miedo a equivocarse, recurría a ella masivamente. El desarrollador reescribió el prompt: añadió descripciones claras para cada categoría, incluidas comercio minorista (retail), macroeconomía
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.
Lo esencial de la IA — una vez por semana
Siete historias que de verdad importaron, elegidas a mano. Sin ruido ni notas de prensa.
¡Listo! Revisa tu correo para la confirmación.