Суть
Счёт за модели растёт тремя разными способами, и путать их нельзя: у каждого своя причина и своя реакция.
| Форма | Как выглядит | Что за ней стоит |
|---|---|---|
| Spike — скачок | Резкий пик за минуты | Рекурсивный баг ретраев, prompt injection с выводом бесконечного текста, DoS |
| Slow Drift — дрейф | Плавный подъём за недели | Накопление истории в RAG-контексте, незаметно растущий системный промпт, сезонный рост длины диалогов |
| Seasonality — цикл | Регулярная волна | Всплеск в будни днём, падение ночью и в выходные — норма, а не авария |
Порог в долларах видит только первое, ругается на третье и пропускает второе.
Алерт на скорость изменения
Правильная формулировка сравнивает не с константой, а с собой же неделю назад в тот же час — так сезонность вычитается автоматически:
# расход токенов за час превысил аналогичный час прошлой недели в 2 раза
(sum(rate(ai_tokens_total[1h])) by (feature_id))
> 2.0 * (sum(rate(ai_tokens_total[1h] offset 7d)) by (feature_id))
Разрез by (feature_id) обязателен: без него подорожавшая фича растворяется в общем объёме (см. атрибуцию в Agent CostControl).
Маршрут доставки: Prometheus → Alertmanager → PagerDuty для высокой severity и Slack #ai-finops для warning.
Множитель подбирается, а не берётся. Значение 2.0 — стартовая точка, а не константа: приемлемый уровень ложных срабатываний зависит от того, сколько стоит поднять человека по алерту. Калибруется задним числом на собственной истории — прогнать множитель по данным за прошедший месяц и посмотреть, сколько срабатываний было бы и сколько из них оказались бы реальными. Это дешевле, чем узнавать то же самое в проде, и делается один раз.
Про медленный дрейф. Сравнение с прошлой неделей по построению слепо к изменению, которое укладывается в недельный шум: каждый день отличается от предыдущего незначительно, а за квартал накапливается кратный рост. Ловится это не порогом, а вторым окном большего масштаба — сравнением месяца к месяцу поверх недельного алерта. Признак, который стоит выводить на дашборд отдельно: не значение метрики, а её тренд за квартал; медленный дрейф видно на нём и не видно нигде больше (Agent Observability).
Runbook: что делать при срабатывании
Три шага в фиксированном порядке — дежурный исполняет, а не изобретает:
- Проверить последний релиз. Новый промпт дорожает молча: ошибок нет, метрики зелёные, счёт растёт.
- Проверить cache hit rate. Провал кэша выглядит как рост расходов, хотя трафик не менялся.
- Активировать kill switch фичи — если причина не найдена за отведённое время, дешевле выключить.
Подробнее о формате таких инструкций — Incident Management AI.
Превентивные лимиты вместо реакции
Алерт сообщает о случившемся. Чтобы деньги не утекали в промежуток до реакции человека, лимиты ставятся на пути запроса:
User Request → Redis (sliding window / leaky bucket) → Under limit?
├── ДА → основная модель
└── НЕТ → graceful degradation
Три уровня ограничений: User Daily Cap, Team Monthly Budget, Feature Hard Kill-Switch.
Деградация при исчерпании лимита — не отказ в обслуживании, а понижение класса:
- автоматическое переключение на дешёвую модель (Cascade Routing);
- ответ из кэша или честный шаблон «лимит исчерпан, повторите через час»;
- постановка задачи в фоновую очередь с низким приоритетом.
Что должно быть на дашборде
Панель имеет право на существование, только если ведёт к конкретному инженерному действию. Рабочий набор: динамика расходов за 30 дней с разбивкой по провайдерам; heatmap перцентилей длины токенов (p50/p90/p99) по типам запросов; топ-5 самых дорогих фич за неделю с дельтой к прошлой; cache hit rate и сэкономленная сумма.
Перцентили важнее среднего: средняя длина ответа скрывает хвост, который и создаёт счёт.
Связано с
- Agent CostControl — сбор и атрибуция данных, без которых эти алерты не на чем строить
- Unit Economics AI — экономическая рамка, относительно которой аномалия считается аномалией
- Incident Management AI — процесс, в который передаётся сработавший алерт
- Cascade Routing — механизм деградации при исчерпании бюджета
- Agent Observability — общая телеметрия агента