RAG для расплывчатых вопросов, детерминированный CLI для точных
Оперативная память телекоммуникационной компании хранится в её системе тикетов. Наша — IBM Maximo: каждый инцидент, каждый обрыв оптоволокна, каждый выезд на объект. Вопросы, которые люди ей задают, делятся на две очень разные категории — и интересное инженерное решение состояло в том, чтобы отвечать на них с помощью двух разных инструментов.
Два типа вопросов
- "Были ли похожие сбои на этом маршруте прошлой зимой? Что обычно вызывает нестабильность (flapping) в этой точке присутствия (PoP)?" — расплывчатые, семантические вопросы, требующие суждения.
- "Сколько инцидентов за март? Перечисли открытые по Украине." — точные, поддающиеся подсчету вопросы.
Ошибка — попытаться подать обе категории в языковую модель. LLM отлично справляется с первым типом и крайне ненадежна со вторым — попросите её посчитать, и она уверенно выдаст число, которое почти верное. Поэтому инструментарий разделяет их:
- RAG (Onyx).
maximo_sync.pyвходит в Maximo (только чтение), парсит структуру объекта тикета, преобразует каждый тикет в текстовый документ плюс агрегированные документы-«дайджесты» и загружает их в локальный индекс Onyx. Теперь к расплывчатым вопросам можно обращаться на естественном языке. Синхронизация идемпотентна (хеш манифест), поэтому она безопасна при работе с cron. - Детерминированный CLI.
maximo_stats.pyотвечает на вопросы, поддающиеся подсчету, напрямую запрашивая Maximo —--year,--month,--type,--status,--list,--json. Никакой модели в цикле, никаких галлюцинированных итогов. Это скучная, но правильная противоположность RAG.
Это разделение — LLM для смысла, код для арифметики — и есть вся идея.
По периферии
- Панель состояния (dashboard). Ежечасный снимок создается по каждой стране и синхронизируется с веб-хостингом; небольшой PHP-дашборд отображает его, включая карту PoP (Leaflet) и блок эвристической аналитики — прокси MTTR/SLA, упоминания оборудования, горячие точки обрывов оптоволокна. Аналитика намеренно приблизительная и помечена как таковая.
- Наблюдатель Telegram. Он отслеживает активные инциденты для определенного местоположения и присылает мне уведомления о новых/закрытых событиях, а также ежечасный консолидированный дайджест по тому, что всё ещё открыто.
Создано для безопасности и переносимости
Всё работает в режиме только чтение относительно Maximo — только запросы GET, учётная запись с правами на чтение, ничего, что может изменить тикет. Python-инструменты используют только стандартную библиотеку, никаких сторонних пакетов, поэтому они работают на любой машине с установленным Python. И ничего специфичного для развёртывания не встроено: конечные точки, учётные данные и область действия берутся из env файлов (chmod 600, вне репозитория), а справочные данные, включённые в репозиторий, — это небольшие синтетические образцы — реальные экспортные файлы, учётные данные и снимки игнорируются gitignore.
Это небольшой инструментарий, но он отражает принцип, к которому я постоянно возвращаюсь: языковая модель — фантастический интерфейс к вашим данным и ужасный источник истины. Позвольте ей решать вопросы, которые действительно касаются смысла, а для всего, что должно быть правильным, оставьте детерминированный путь.
Прозрачность: большинство постов здесь написаны с помощью ИИ, а неанглийские версии переведены локальной LLM и вычитаны. Заметили ошибку? Напишите мне.