← Blog

RAG para las preguntas vagas, una CLI determinista para las exactas

DEENESRUUK

La memoria operativa de una telecom reside en su sistema de tickets. La nuestra es IBM Maximo: cada ticket de incidencia, cada corte de fibra, cada visita al sitio. Las preguntas que la gente le hace caen en dos formas muy diferentes, y la interesante decisión de ingeniería fue responderlas con dos herramientas distintas.

Dos tipos de preguntas

  • "¿Hubo interrupciones similares en esta ruta el invierno pasado? ¿Qué suele causar fluctuaciones en ese PoP?" — preguntas vagas, semánticas, de juicio.
  • "¿Cuántos tickets de incidencia en marzo? Enumera los abiertos para Ucrania." — preguntas exactas, contables.

El error sería lanzar ambas a un modelo de lenguaje. Un LLM es excelente para el primer tipo y cuidadosamente poco fiable para el segundo: pídele que cuente y te dará con confianza un número que está casi bien. Así que el conjunto de herramientas las separa:

  • RAG (Onyx). maximo_sync.py inicia sesión en Maximo (solo lectura), pagina la estructura del objeto ticket, convierte cada ticket en un documento de texto más documentos "digest" agregados, y los carga en un índice local Onyx. Ahora las preguntas vagas se pueden hacer en lenguaje natural. La sincronización es idempotente (manifiesto hash) por lo que es segura bajo cron.
  • Una CLI determinista. maximo_stats.py responde a las preguntas contables consultando Maximo directamente: --year, --month, --type, --status, --list, --json. Sin modelo en el bucle, sin totales alucinados. Es la contraparte aburrida y correcta del RAG.

Esa separación — LLM para significado, código para aritmética — es toda la idea.

Alrededor de los bordes

  • Un panel de estado. Se construye una instantánea por hora por país y se sincroniza con un host web; un pequeño panel PHP lo renderiza, incluyendo un mapa PoP (Leaflet) y un bloque de análisis heurístico: proxies MTTR/SLA, menciones de equipos, puntos calientes de cortes de fibra. Los análisis son deliberadamente aproximados y etiquetados como tales.
  • Un observador de Telegram. Rastrea los tickets de incidencia activos para una ubicación y me notifica sobre eventos nuevos/cerrados, con un resumen consolidado horario de lo que sigue abierto.

Construido para ser seguro y portable

Todo es solo lectura contra Maximo — solo peticiones GET, una cuenta de solo lectura, nada que pueda cambiar un ticket. Las herramientas de Python usan la biblioteca estándar solamente, sin paquetes de terceros, por lo que funcionan en cualquier máquina con Python. Y no hay nada específico del despliegue incorporado: los endpoints, credenciales y alcance provienen todos de archivos env (chmod 600, fuera del repo), mientras que los datos de referencia incluidos en el repo son pequeñas muestras sintéticas — las exportaciones reales, credenciales y instantáneas se ignoran con gitignore.

Es un pequeño conjunto de herramientas, pero captura un principio al que sigo volviendo: un modelo de lenguaje es una interfaz fantástica para tus datos y una pésima fuente de verdad. Déjalo manejar las preguntas que realmente son sobre el significado, y mantén un camino determinista para todo lo que tiene que ser correcto.

Transparencia: la mayoría de las entradas se redactan con ayuda de IA, y las versiones que no están en inglés se traducen automáticamente con un LLM local y luego se revisan. ¿Has visto un error? Avísame, por favor.