У типичного среднего и крупного банка 150-250 KPI под наблюдением: время отклика контакт-центра, доля fraud-уведомлений, скорость активации карт, латентность одобрения кредитов, доля ошибок мобильного приложения, заполненность ATM... По каждому из них алерт «упал», «скакнул», «дрейфует» должен прийти нужному человеку в нужное время. Лишние алерты выматывают команду; запоздалые стоят денег.
Почему два чистых подхода ломаются
Чистый threshold: алерт при KPI < X или > Y. Быстро и объяснимо, но слепо к сезонности и тренду. Предпраздничный всплеск трат каждый год шлёт «аномалию» в один и тот же час.
Чистый ML: time-series detection (Prophet, isolation forest, LSTM). Ловит сезонность, но плохо объясним, плохо стартует на новых KPI и сам требует обслуживания.
CentraQL комбинирует оба.
Гибридная модель
for kpi in active_kpis: val = current_value(kpi) if hard_threshold_violated(kpi, val): emit(severity="critical", reason="hard threshold") continue z = rolling_z_score(kpi, window=28d) if abs(z) > kpi.z_threshold: baseline_pred = seasonal_baseline(kpi) if outside_band(val, baseline_pred, kpi.band): emit(severity="warning", reason="z-score+seasonal")
Три слоя: hard threshold, z-score, seasonal baseline.
1. Hard threshold
Здесь — контрактные лимиты. Примеры: p95 одобрения кредита > 5 с; почасовая доля fraud > 0.8%. Аналитик пишет правило, владелец одобряет, привязывается SLA.
2. Z-score
Mean и std считаются по скользящему окну 28 дней. Если |z| текущего значения превышает порог (обычно 3.0) — сигнал. «3.4 σ от средней за 28 дней» — формулировка, понятная любому CFO.
3. Seasonal baseline (специфично CentraQL)
Z-score один не ловит праздники, выходные и внутридневной ритм. Seasonal baseline даёт 8-недельную полосу среднего по тому же часу-дню недели. Сигнал срабатывает только когда z-score AND seasonal оба нарушены; значения, прошедшие лишь один тест, не алертят. Это режет ложные срабатывания в 3-5 раз.
Конфигурация порогов
Пороги слоистые — KPI-, профиль-, domain-pack-специфичные override:
- System default: |z| > 3.0
- KPI
fraud_rate_hourlyoverride: |z| > 2.5 - RegulatedFinance: |z| > 2.0 + seasonal AND
Это переводит спор о порогах в плоскость политики.
Объяснение аномалии
Когда CentraQL срабатывает, Copilot формирует объяснение через narrator-LLM: «В 14:00 ATM-заполненность 38%; последние 8 недель в этот час среднее 52% ± 4. Сигнал z=-3.6, вне сезонной полосы.» Запись попадает в PromptAuditLog.
Операционный итог
Пилот на 180 KPI в течение месяца:
- Чистый threshold: 240 алертов, 72% false-positive.
- Чистый z-score: 380 алертов, 58% false-positive.
- Гибрид CentraQL: 110 алертов, 18% false-positive.
Меньше FP = меньше alert fatigue = ~4× быстрее реакция на реальные инциденты.
Заключение
Детекция аномалий KPI — задача ни чистого rule-engine, ни чистого ML. Hard threshold держит контракт, z-score ловит отклонение, seasonal baseline — ритм. CentraQL объединяет их в одной панели, поручает объяснение Copilot и пишет результат в audit. Старт со 200 KPI банка: ~1 день на domain pack, ~3 дня тюнинга с владельцами, дальше — автоматика.
