中文翻译暂不可用,显示俄语原文。
Настроить anomaly detection по cost
ТЕХНИЧЕСКОЕ ЗАДАНИЕ: Настроить anomaly detection по cost
1. Цель задачи
Научиться проектировать и внедрять систему автоматического обнаружения аномального роста затрат (cost) в production-среде. Реализовать конвейер сбора метрик cost, расчёта baseline и отправки алерта при превышении порога. Основной фокус — детектировать внезапное увеличение cost (например, из-за ошибок, резкого роста трафика или утечки API-вызовов) и уведомлять команду в течение 5 минут.
Ключевой результат Рабочий прототип мониторинга cost с алертом в Telegram/Slack, способный обнаружить аномалию за <5 минут.
2. Исходные данные
| Что нужно | Откуда взять |
|---|---|
| Логи затрат на LLM API (стоимость каждого вызова, prompt_tokens, completion_tokens) | Реальные логи из production / тестового окружения. Если нет — сгенерировать синтетические. |
| Метрики cost в Prometheus (суммарно за минуту/час) | Prometheus + custom exporter. |
| Текущие стоимости запросов (цены за 1K токенов) | OpenAI / Anthropic / другие API pricing pages. |
| Чат-бот / webhook для уведомлений | Telegram bot token или Slack webhook URL. |
| Инфраструктура для Python скриптов | Docker / локальный Python 3.10+. |
Если нет реальных данных — симулируем:
- Написать Python-скрипт
generate_synthetic_cost.py, который создаёт CSV-файл с колонками: timestamp, cost,requests_count,avg_cost_per_request. - Нормальные данные: средний cost = 0.05 USD/мин (стационарно), шум ±10%.
- Аномалии: вставить 3–5 временных отрезков (длительностью 5–30 минут) с внезапным ростом cost в 2–5 раз.
- Сохранить CSV в data/synthetic_logs.csv и использовать как входной источник.
- Эмулировать потоковую передачу через time.sleep и чтение CSV построчно (или батчами) — для тестирования алерта.
3. Технологический стек
| Компонент | Инструменты | Назначение |
|---|---|---|
| Хранение метрик | Prometheus + VictoriaMetrics (опционально) | Сбор и хранение временных рядов cost |
| Визуализация | Grafana | Дашборд cost в реальном времени |
| Обработка данных | Python (pandas, numpy, scipy) | Расчёт скользящих средних, выбросов |
| Детекция аномалий | Python (statsmodels, scikit-learn, или просто Z-score/ IQR) | Выявление аномалий |
| Оповещения | Alertmanager + Telegram/Slack | Отправка алерта при обнаружении |
| CI / CD | Git + Docker | Воспроизводимость |
| Имитация данных | generate_synthetic_cost.py (наш скрипт) | Генерация тестовых данных |
4. Этапы выполнения
Этап 1: Сбор и подготовка данных (оценка времени: 1–2 часа)
Действия
-
Создать директорию проекта
cost-anomaly-detection:cost-anomaly-detection/ ├── data/ │ └── synthetic_logs.csv ├── scripts/ │ ├── generate_synthetic_cost.py │ ├── exporter.py │ ├── analyzer.py │ └── alert.py ├── config/ │ └── config.yaml ├── docker-compose.yml (Prometheus + Grafana + Alertmanager) └── README.md -
Написать скрипт генерации синтетических данных (
scripts/generate_synthetic_cost.py):- Параметры:
--days 7,--base_cost 0.05,--noise_std 0.005,--anomalies 3. - Создать нормальное поведение с ежесуточными паттернами (например, дневной пик в 2 раза выше ночного).
- Вставить аномалии: резкий скачок cost (x3–x5) длительностью 15–30 минут в случайные моменты.
- Формат CSV: timestamp, cost, anomaly_flag (anomaly_flag=1 для известных аномалий, 0 для нормы).
- Параметры:
-
Разработать Prometheus-экспортер (
scripts/exporter.py):- На Python с использованием prometheus_client.
- Метрика
llm_cost_total(сумма cost за интервал). - Метрика
llm_requests_total(количество запросов). - Метрика
llm_cost_per_request(средняя стоимость запроса). - Чтение CSV (или реального API) и обновление метрик каждые 10 секунд.
-
Настроить docker-compose.yml:
- Prometheus: target на exporter (localhost:8000).
- Grafana: provision dashboard с панелью Cost (USD/min).
- Alertmanager: настроить webhook для уведомлений.
Ожидаемый результат этапа Работающий экспорт метрик cost в Prometheus, данные видны в Grafana в реальном времени.
Этап 2: Реализация алгоритма anomaly detection (оценка времени: 2–3 часа)
Действия
-
Выбрать метод детекции (рекомендуется комбинация):
- Динамический скользящий порог медианное скользящее окно (10–30 минут) + множитель IQR (3x) или 4 сигмы.
- Статистический тест CUSUM или Page-Hinkley для быстрого обнаружения сдвига среднего.
- Baseline модель еженедельный профиль (почасовые медианы) + отклонение.
-
Написать модуль анализа (
scripts/analyzer.py):- Получает метрики cost из Prometheus (через HTTP API) за последние 10 минут.
- Сравнивает с рассчитанным динамическим порогом.
- Возвращает
is_anomaly,current_value, threshold.
-
Параметризовать настройки в config/config.yaml:
detection: method: dynamic_median # или dynamic_median, cusum, seasonal window_minutes: 15 multiplier: 3.0 # множитель IQR alert_cooldown_minutes: 5 # не спамить каждую секунду # Для CUSUM: cusum_delta: 0.01 cusum_threshold: 0.05 -
Настроить вызов analyzer.py раз в минуту (через cron или внутренний планировщик).
Ожидаемый результат этапа Скрипт корректно детектирует аномалии на синтетических данных (precision/recall > 0.9 на известных аномалиях).
Этап 3: Интеграция с системой алертинга (оценка времени: 1 час)
Действия
-
Создать Telegram-бота (или Slack webhook):
- Получить
TELEGRAM_BOT_TOKENиCHAT_ID. - В
scripts/alert.pyреализовать функциюsend_alert(message)через requests.post.
- Получить
-
Alertmanager конфигурация (альтернативный путь – без Alertmanager, только Python):
-
Реализовать алерт с задержкой:
- Добавить поле
last_alert_timeв память (или файл) для cooldown. - При первой аномалии задерживать отправку на 30 секунд (чтобы избежать флапа), если аномалия продолжается >30 секунд — отправлять.
- Добавить поле
-
Протестировать на синтетических аномалиях:
- Запустить скрипт эмуляции данных.
- Проверить, что алерт приходит в течение 5 минут после начала аномалии.
Ожидаемый результат этапа При внезапном росте cost Telegram-бот отправляет уведомление команде.
Этап 4: Визуализация и мониторинг производительности (оценка времени: 1 час)
Действия
-
Дашборд Grafana:
-
Метрики самого детектора:
- Метрика
cost_anomaly_detected(0/1) – выставить как алерт в Prometheus. - Метрика
cost_anomaly_processing_time_seconds– latency обработки.
- Метрика
-
Тест на устойчивость к ложным срабатываниям:
- Запустить скрипт на 1 час без аномалий – проверить, что алертов нет (допустимо ≤1).
- Затем вставить аномалию – алерт должен сработать.
Ожидаемый результат этапа Дашборд показывает состояние cost, детектор работает стабильно.
Этап 5: Документация и тестирование (оценка времени: 1–2 часа)
Действия
- Написать README с описанием архитектуры, инструкцией по запуску, интерпретацией алертов.
- Создать скрипт end-to-end теста (
tests/test_e2e.py):- Запускает exporter, analyzer, симулятор данных.
- Проверяет, что при аномалии алерт отправлен.
- Проверяет, что время обнаружения <5 минут.
- Использует подмену Telegram на mock (например, локальный сервер).
- Зафиксировать результаты в отчёте – метрики precision/recall на тестовом наборе.
Ожидаемый результат этапа Воспроизводимый код, документация, автоматизированный тест.
5. Критерии приемки (Definition of Done)
- Синтетический датасет с известными аномалиями создан и используется.
- Prometheus-экспортер отдаёт метрики cost.
- Алгоритм детекции выбран и реализован; конфигурация вынесена в YAML.
- Алерт в Telegram (или Slack) приходит в течение 5 минут с момента начала аномалии.
- Ложные срабатывания не превышают 1 за час нормальной работы.
- Дашборд Grafana отображает cost и состояние алерта.
- Код проекта закоммичен в git (README, зависимости requirements.txt, docker-compose.yml).
- End-to-end тест проходит (detect время <5 минут).
- В README описаны шаги для развёртывания на новом окружении.
- Задача сдаётся в формате Pull Request с описанием.
6. Ожидаемый результат
- Основной артефакт Папка
cost-anomaly-detectionсо всем кодом, конфигами, тестовыми данными. - Демонстрация: Запущенный docker-compose с Prometheus, Grafana, exporter, analyzer и рабочим Telegram-ботом.
- Дополнительные результаты Дашборд Grafana (экспорт JSON), скриншот алерта в Telegram, отчёт о точности детекции (precision/recall).
7. Возможные сложности и их решение
| Сложность | Решение |
|---|---|
| Шумные данные (выбросы из-за единичных дорогих запросов) | Использовать скользящее медианное окно вместо среднего; добавить сглаживание (EWMA). |
| Выбор множителя порога | Протестировать на синтетике с разными множителями (2.0–4.0), выбрать по метрике F1. |
| Дрейф среднего cost (изменение тарифов, смена модели) | Разделить на периоды (training каждый день или неделю) + использовать adaptive threshold. |
| Задержка алерта >5 минут | Оптимизировать интервал сбора (Prometheus scrape interval 10s, проверка аномалий каждые 30s). |
| Ложные срабатывания при ночных снижениях | Учесть сезонность (daily pattern) в baseline, вычитать ожидаемый профиль. |
| Отсутствие реального Telegram-бота | Использовать Slack webhook (аналог) или простой HTTP-лог. |
8. Бюджет времени (оценка)
| Этап | Время (часы) |
|---|---|
| Этап 1: Сбор и подготовка данных | 2 |
| Этап 2: Реализация anomaly detection | 3 |
| Этап 3: Интеграция с алертингом | 1 |
| Этап 4: Визуализация и мониторинг | 1 |
| Этап 5: Документация и тесты | 2 |
| Итого | 9 часов |
Примечание для первого выполнения задачи заложите +50% времени (до 14 часов). Для опытного инженера — 6–8 часов.
9. Связанные вопросы из базы знаний
| Вопрос | Тема |
|---|---|
| 42 | Настройка Prometheus exporter для кастомных метрик |
| 87 | Работа с временными рядами в pandas (скользящие окна) |
| 123 | Методы детекции аномалий: Z-score, IQR, CUSUM |
| 215 | Конфигурация Alertmanager для отправки в Telegram |
| 310 | Создание дашборда в Grafana с переменными |
| 456 | Оценка качества anomaly detection (precision/recall) |
| 502 | Обработка пропусков в данных временных рядов |
| 678 | Docker-compose для стека Prometheus + Grafana |
| 741 | Оптимизация latency обнаружения аномалий |
| 829 | Мониторинг стоимости LLM API (pricing per token) |
10. Чек-лист самопроверки
- Я создал синтетический датасет с метками аномалий и проверил алерт на нём.
- Я убедился, что алерт приходит не позднее 5 минут после начала аномалии (замерял тайминг).
- Я проверил, что при нормальных данных алерт не срабатывает чаще 1 раза в час (low false positive).
- Я задокументировал все шаги развёртывания в README, включая переменные окружения.
- Я выложил код в git (или сдал архив) с корректной структурой проекта.