Главная

7 мин

Мониторинг LLM в продакшене: метрики и алерты без сюрпризов

Мониторинг LLM в продакшене: какие метрики собирать по очередям, токенам, ошибкам и качеству, и как настроить алерты, чтобы узнавать о сбоях раньше пользователей.

Мониторинг LLM в продакшене: метрики и алерты без сюрпризов

Какие проблемы в LLM-продакшене важно поймать раньше жалоб

LLM в продакшене похож на обычный API только снаружи. Внутри есть три особенности: стоимость зависит от токенов, ответы не всегда предсказуемы, а качество и доступность часто завязаны на внешнего провайдера и его лимиты. Поэтому мониторинг здесь отвечает не на один вопрос "жив ли сервис", а сразу на несколько: не стало ли хуже, дороже или рискованнее.

Жалобы пользователей почти всегда запаздывают. Сначала растет очередь, потом увеличивается задержка, позже появляются таймауты, и только затем человек пишет в поддержку: "бот завис". С качеством похожая история: модель чаще уходит в сторону, путает факты или отвечает слишком общо, а заметно это становится после десятков диалогов.

Полезно заранее договориться, что для вас значит "работает". Обычно это сочетание нескольких критериев: скорость (ответы приходят вовремя даже в пик), стабильность (без всплесков ошибок и обрывов), качество (ответ решает задачу, а не просто звучит правдоподобно), стоимость (токены и расходы предсказуемы) и безопасность (нет утечек данных и опасных подсказок в логах).

Еще один частый сюрприз: проблема может быть не у вас. Провайдер меняет модель, вводит новые лимиты, где-то по сети растут потери, и вы получаете деградацию без единого релиза со своей стороны.

Чтобы ловить это раньше жалоб, заранее определите роли и реакции. Продукт отвечает за качество и конверсию в решенную задачу. Поддержка видит рост повторных обращений и "непонятных" диалогов. Безопасность следит за персональными данными и промпт-инъекциями. Инфраструктура отвечает за очереди, задержки и ошибки. В крупных организациях (например, в банке или госструктуре) именно согласованность этих ролей делает алерты полезными, а не шумными.

Карта сигналов: что измерять и как связывать данные

Чтобы мониторинг не превращался в набор разрозненных графиков, разложите наблюдаемость по слоям. У каждой проблемы есть след сразу в нескольких местах: железо и сеть дают задержки, приложение - ошибки и таймауты, модель - неожиданный текст и рост токенов, а бизнес видит падение конверсии или рост обращений в поддержку.

Ключ к связи этих следов - единый request_id. Он должен появляться на входе (фронт, API-шлюз, бот-платформа) и проходить до ответа модели и обратно. Тогда по одному запросу вы быстро поймете, был ли он в очереди, сколько занял вызов провайдера, какая модель ответила и что именно вернулось.

Для каждого запроса стоит фиксировать минимум: request_id и временные метки (вход, старт/конец LLM-вызова, выход), session_id и канал (веб, мессенджер, внутренняя система), модель/версию и параметры (температура, max_tokens, инструменты), результат (успех/ошибка, причина, ретраи, обрезка ответа). Тексты промпта и ответа тоже полезны, но храните их с маскированием персональных данных.

Хранить это обычно удобнее в трех местах: метрики для чисел и алертов (задержки, ошибки, токены), логи для деталей (тексты, причины, контекст), трейсы для цепочки вызовов (фронт -> бэкенд -> LLM -> внешние сервисы). Важно, чтобы везде был один и тот же request_id.

Простой пример: пользователи жалуются "бот стал тупее". С request_id вы можете увидеть, что качество просело не у модели, а из-за таймаутов: часть ответов обрезается, потому что очередь выросла, и приложение режет max_tokens, чтобы уложиться в лимит времени.

Очереди и задержки: метрики, которые показывают перегрузку

Перегрузка почти всегда проявляется одинаково: медленные ответы, таймауты и "плавающее" время отклика. Если ждать жалоб, вы будете тушить пожар. Поэтому в первую очередь держите метрики очередей и задержек: они раньше других показывают, что система не успевает.

Начните с очереди: длина, среднее и p95 время ожидания, скорость обработки (сколько запросов в секунду реально уходит на выполнение). Смотрите не только "сколько ждут", но и "почему": очередь растет из-за всплеска трафика, падения пропускной способности модели или ограничений провайдера.

Чтобы быстрее находить узкое место, разбивайте латентность по этапам и считайте p50/p95/p99 для каждого: pre-processing (валидация, подготовка контекста, RAG), вызов модели (время до ответа и время генерации), post-processing (фильтры, форматирование, запись в БД), сетевые задержки. Таймауты и ретраи лучше учитывать как отдельные события.

Если инфраструктура своя (например, on-prem в дата-центре), добавьте concurrency и утилизацию ресурсов: CPU/GPU, память, диск, сеть. Частый сценарий: p50 остается нормальным, а p99 растет, потому что GPU упирается в память, и часть запросов попадает в "хвост".

Не забывайте про лимиты провайдера: rate limit, throttling, остаток квот. Их лучше считать отдельными ошибками, иначе они будут выглядеть как "случайные таймауты".

Для стриминга нужны отдельные сигналы: время до первого токена и скорость токенов в секунду. Пользователь часто готов ждать дольше, если первый токен приходит быстро, а поток идет ровно.

Токены и стоимость: как не пропустить рост расходов

Если сервис стабилен, но счета растут, причина почти всегда видна в токенах. Поэтому мониторинг должен показывать не только "сколько запросов", но и "сколько текста вы гоняете через модель" - по пользователям, сценариям и времени.

Какие метрики по токенам собирать

Для каждого запроса фиксируйте input tokens, output tokens и tokens per request. Дальше смотрите распределения: медиана, 90-й и 99-й перцентили. Среднее часто обманывает: рост расходов обычно дают редкие, но очень длинные запросы.

Полезные разрезы: сценарии (поддержка, поиск по базе знаний, генерация письма), типы пользователей (внутренние сотрудники, внешние клиенты), источник контекста (история чата, документы, системный промпт), модель/версия (после переключения часто меняется длина ответа).

Следующий слой - деньги. Если тарификация по токенам, считайте estimated cost на запрос и суммарную стоимость по сценарию за час/день. Так быстро видно, что, например, 10% трафика "съедает" 60% бюджета.

Что обычно раздувает токены

Чаще всего виноваты длинный контекст и разрастающаяся история чата. Отдельно измеряйте долю запросов с длинным промптом (например, выше 90-го перцентиля за неделю) и фиксируйте причины: добавили больше документов, стали прикладывать логи целиком, не обрезаете историю.

Считайте, сколько запросов упираются в max context (или близко к нему). Это и про стоимость, и про качество: модель теряет часть полезного контекста или вы вынуждены резать данные вслепую.

Если есть кеширование (ответов, эмбеддингов, извлеченных документов), держите cache hit rate и оценку "сэкономленных токенов". В чатботе поддержки повторяемые вопросы быстро превращаются в ощутимую экономию: падает tokens per request при том же числе обращений.

Ошибки и надежность: что логировать и считать

Надежность LLM-сервиса начинается не с дашбордов, а с дисциплины логов. Важно уметь ответить на простой вопрос: что именно сломалось - модель, ваш код или зависимость.

Собирайте ошибки в двух разрезах: ответы провайдера (например, 4xx и 5xx) и ошибки приложения (валидация входа, сбой парсинга, ошибка сборки промпта). Отдельно учитывайте таймауты: они часто выглядят как "непонятные" падения, но на деле это перегрузка или зависшая зависимость.

Полезный минимум для каждого запроса: request_id, user_id/tenant (если есть), сценарий (чат, поиск, суммаризация), код результата (ok, provider_4xx, provider_5xx, timeout, app_error), статус стриминга (completed/aborted/partial), число ретраев и причина повтора, какие зависимости вызывались (поиск, векторная база, хранилище документов, авторизация) и их статусы.

Ретраи считайте отдельной метрикой, а не как "повторили и все хорошо". Смотрите долю запросов с повтором, среднее число ретраев и прибавку к задержке. Рост ретраев часто появляется раньше роста явных 5xx.

Есть и тихие сбои: пустые ответы, обрыв стрима на середине, частичный ответ без финальной части. Их легко пропустить, если смотреть только на HTTP-коды. Добавьте счетчики empty_output и stream_aborted.

Если используете circuit breaker и фолбэки (например, без RAG, с упрощенным промптом или запасным провайдером), измеряйте долю запросов, ушедших в запасной режим. Так можно увидеть деградацию зависимости до того, как польются жалобы: поиск в векторной базе начал отдавать таймауты, система чаще включает фолбэк, и пользователи получают более общие ответы.

Качество ответов: метрики без сложной науки

Качество проще начинать мерить не "умностью", а понятными исходами. Добавьте счетчики по типам ответа: успешный (помог и довел до результата), отказ (модель не ответила или сослалась на политику), предупреждение (ответ с оговорками, неполный, просит уточнить). Уже это показывает, где пользователи застревают.

Дальше подключите простую автооценку по сигналам, которые легко посчитать в логах и которые часто коррелируют с проблемами: длина ответа (слишком коротко или "простыня"), повторяемость (циклы и одни и те же фразы), соблюдение формата (просили 3 шага или JSON, пришел обычный текст), язык (пользователь на русском, модель внезапно отвечает на другом), токсичность и грубость.

Смотрите и бизнес-сигналы. Для внутреннего помощника ИТ-службы тревожными будут повторный вопрос сразу после ответа, рост эскалаций в поддержку, отказ от операции (начал оформление заявки и бросил), падение доли решенных запросов за сессию.

Автоматика не заменяет людей, поэтому нужна проверка по выборке. Выберите 20-50 диалогов в неделю и оцените по 3-5 простым критериям: "ответил по сути", "не выдумал факты", "дал следующий шаг", "тон нормальный". Критерии должны быть одинаковыми у всех проверяющих.

Чтобы замечать регрессии после обновлений промптов или модели, держите небольшой тестовый набор (golden set) из типовых задач. Прогоняйте его регулярно и сравнивайте с базовой версией по тем же критериям и авто-сигналам.

Деградации и дрейф: как замечать ухудшения вовремя

Деградация в LLM редко выглядит как "все сломалось". Чаще это постепенный рост отказов, падение полезности ответов или больше галлюцинаций. При этом графики задержек и ошибок могут оставаться зелеными, а пользователи уже недовольны. Поэтому мониторинг должен включать сигналы качества и изменения входных данных.

Что считать дрейфом и как его мерить

Сравнивайте "сегодня" с базовой неделей, когда все работало хорошо. Дрейф чаще видно по тому, как меняются запросы: темы и намерения (закупки, техподдержка, безопасность), языки и доля смешанного языка, длина промпта и ответа, доля сложных случаев (файлы, таблицы, специфичная терминология), доля запросов на обход правил и чувствительные темы.

Если растет доля сложных кейсов, качество может упасть даже без изменений модели. Это нормально, но должно включать другой режим: больше контекста, другой промпт или маршрутизацию на человека.

Канареечные релизы и сравнение версий

Любое изменение (новая версия модели, правка промпта, новый источник контента, новая аудитория) выпускайте как канарейку: 1-5% трафика на новую версию, затем расширение.

Алерты удобно строить как "новая версия хуже старой" на окне 30-60 минут. Например: отказов (policy/refusal) стало больше на X%, доля низкой оценки от пользователей выросла на X пунктов, увеличилась доля ответов, где модель не нашла нужное в базе и "додумала", выросли инциденты безопасности (PII, чувствительные данные, попытки обхода).

Пример: после обновления промпта чатбота для внутренней поддержки растет доля запросов "сделай исключение из правил" и одновременно падает полезность ответов. Это сигнал не "подкрутить температуру", а проверить, не ослабили ли вы ограничения и не изменили ли тон инструкций.

Как настроить мониторинг по шагам: от нуля до контроля качества

Чтобы мониторинг реально спасал, начните не с графиков, а с простого договора с командой: что считаем нормой и когда будим дежурного.

1) Зафиксируйте SLO, а не "все подряд"

Выберите 2-3 показателя, которые отражают пользовательский опыт. Например: 95-й перцентиль времени ответа, доля ошибок (5xx, таймауты) и один показатель качества (хотя бы доля "принято без правок" или оценка оператором).

Дальше добавляйте слой за слоем:

  • Опишите путь запроса целиком и поставьте тайминги на этапах: очередь, препроцессинг, вызов модели, постобработка, запись в базу.
  • Приведите логи к одному формату: имя модели, версия промпта, параметры (температура, max_tokens), входные и выходные токены, статус, причина ошибки.
  • Соберите дашборды под реальные сценарии, а не "общий": чат поддержки, поиск по документам (RAG), генерация отчетов.
  • Добавьте регулярный прогон тестового набора и короткий отчет по качеству (хотя бы раз в день).
  • Привяжите каждую метрику к действию: что делает дежурный, если порог превышен.

2) Сделайте качество измеримым без сложной науки

Простой вариант: один и тот же набор 50-200 типовых запросов и ожидаемые признаки ответа (нашел нужный документ, не выдумал факты, соблюдает формат). Если "поплыл" только один сценарий, это часто указывает на конкретную причину: новый промпт, обновление индекса, смена модели.

Пример: пользователи начали жаловаться на "длинные ответы". Если у вас есть разметка этапов и токены в логах, вы быстро увидите, где рост: увеличилось время в очереди или модель стала генерировать на 30% больше токенов. Это разные решения: масштабирование воркеров против ограничения max_tokens и правки промпта.

Алерты, которые работают: пороги, окна и понятные действия

Хороший алерт отвечает на два вопроса: что сломалось и что делать дальше. Если после пейджера нужно полчаса разбираться, где искать проблему, алерт будут либо игнорировать, либо он начнет раздражать.

Удобно держать алерты в трех группах. Первые ловят симптомы, то есть то, что уже видно пользователю: p95 задержки, рост очереди, всплеск 5xx, увеличение ретраев. Вторые ловят причины, которые еще не обязательно проявились наружу: rate limit у провайдера, приближение к квоте по токенам или деньгам, деградация зависимостей (векторное хранилище, база, сеть). Третьи следят за качеством: просадка на golden set, рост доли отказов, рост эскалаций на оператора.

Чтобы алерты не шумели, задавайте не только пороги, но и окно. Например, "p95 > 4 сек 10 минут" почти всегда лучше, чем "p95 > 4 сек 1 минуту". Помогают и двухступенчатые правила: предупреждение при мягком пороге, критический при жестком, плюс дедупликация, чтобы один инцидент не создавал десятки уведомлений.

Пример: у чатбота поддержки растет очередь, а p95 ползет вверх. Первый алерт (симптом) говорит "перегрузка", второй (причина) показывает "уперлись в лимит запросов", третий (качество) пока молчит. Тогда действие простое: временно снизить нагрузку (ограничить параллелизм или включить деградацию ответа), а потом разбираться с лимитами и емкостью.

Для каждого алерта нужен короткий runbook, иначе команда будет действовать наугад. Достаточно 5 пунктов:

  • Где смотреть подтверждение: графики, логи, трассировки.
  • Что проверить в первую минуту: очереди, 5xx, лимиты, здоровье зависимостей.
  • Как быстро снизить ущерб: фича-флаг, понижение температуры, отключение тяжелых инструментов, возврат к кешу.
  • Как откатить или переключиться на запасной режим.
  • Когда и кому эскалировать (с четким временем и критериями).

Это особенно важно, если LLM-сервис работает 24/7 и завязан на инфраструктуру и поддержку, как в крупных интеграционных проектах и дата-центрах.

Частые ошибки в мониторинге LLM и как их избежать

Первая ловушка - смотреть на одну красивую цифру и думать, что все под контролем. Чаще всего это среднее время ответа. Среднее прячет редкие, но болезненные хвосты: пользователю важны не "в среднем 2 секунды", а "иногда 30". Поэтому рядом со средним держите p95 и p99, а еще отдельно время в очереди и время выполнения модели.

Вторая ошибка - смешивать разные сценарии в одну метрику. Поддержка, поиск по базе знаний и генерация письма живут по разным правилам: разные промпты, разные лимиты токенов, разная терпимость к задержке. Разделяйте метрики хотя бы по типу задачи, каналу (чат, API), языку и критичным клиентам. Так вы увидите локальные провалы, а не "среднюю температуру по больнице".

Третья ошибка - не фиксировать, что именно было развернуто. Без версии модели, версии промпта, параметров (temperature, max_tokens) и контекста (источник данных, включенные инструменты) вы не сможете честно сравнить до/после и быстро откатиться.

Еще один типовой провал - алерты без владельца и без понятного действия. Если уведомление не отвечает на вопрос "кто и что делает в первые 10 минут", его будут игнорировать.

Набор привычек, который обычно спасает:

  • Делайте дашборды и алерты раздельно по сценариям и сегментам.
  • Храните версионность: модель, промпт, параметры, фичи и дату релиза.
  • Настраивайте алерты с коротким описанием шага проверки и ответственного.
  • Следите не только за ошибками, но и за токенами на запрос.
  • Проверяйте p95/p99, а не только среднее.

Отдельно про стоимость: рост токенов выглядит как "мелочь", пока счет не удваивается. Держите лимиты и алерты на токены/запрос и токены/пользователя, и отдельно на "стоимость за 1k запросов" по каждому сценарию.

Быстрый чеклист и следующие шаги

Если мониторинг уже есть, раз в неделю полезно честно ответить на вопрос: вы узнаете о проблеме по алерту или по жалобе?

Минимальный набор сигналов, который стоит держать под рукой каждый день:

  • Очередь и задержки: длина очереди, p95 (и лучше p99) латентности, время ожидания до начала генерации.
  • Ошибки и ретраи: доля 5xx, таймауты, отмены, процент повторных попыток, ошибки лимитов провайдера.
  • Токены и стоимость: входные и выходные токены на запрос, стоимость на 1k запросов, топ самых дорогих промптов.
  • Качество по выборке: регулярная проверка ответов (например, 50-100 реальных диалогов в неделю) и простая оценка "ок/не ок" с причиной.

Дашборды лучше держать простыми: один для "здоровья сервиса" (трафик, p95, ошибки), второй для "денег" (токены, стоимость, самые дорогие сценарии), третий для "качества" (доля плохих ответов по выборке и основные причины).

Когда срабатывает алерт, важнее всего быстро стабилизировать сервис и не ухудшить ситуацию релизами:

  • Заморозьте релиз и откатите последние изменения, если они совпали по времени.
  • Включите фолбэк (шаблонные ответы, поиск по базе знаний, более простая модель) для критичных сценариев.
  • Ограничьте контекст: режьте историю диалога, вложения и слишком длинные промпты.
  • Снизьте нагрузку: rate limit, очереди, временное отключение второстепенных функций.

Дальше планируйте улучшения по причинам: раз в неделю разбирайте несколько самых дорогих запросов и несколько типовых провалов качества, фиксируйте действие и ожидаемый эффект.

Если вы внедряете LLM на собственной инфраструктуре (в том числе on-prem и в дата-центрах), полезно сразу закладывать наблюдаемость, SLO и процессы реакции на инциденты. В таких проектах GSE.kz (gse.kz) часто подключается как системный интегратор: от железа и серверов до инфраструктуры для AI и поддержки 24/7, чтобы эксплуатация не держалась на ручных догадках.

Частые вопросы

Какие метрики в LLM-сервисе чаще всего первыми показывают проблему?

Начните с очереди и латентности по перцентилям (p95/p99), доли таймаутов и 5xx, а также ретраев. Эти сигналы обычно растут раньше, чем пользователи успеют пожаловаться, и хорошо показывают перегрузку и проблемы с провайдером.

Зачем нужен единый request_id и что он дает на практике?

Единый `request_id` позволяет связать метрики, логи и трассировки для одного запроса: сколько он ждал в очереди, как долго вызывалась модель, какая версия промпта и модели была, где случился таймаут и был ли ответ обрезан. Без этого вы видите «среднюю температуру», но не понимаете причину конкретных сбоев.

Как выбрать SLO для LLM, чтобы не утонуть в метриках?

Зафиксируйте 2–3 SLO, которые отражают пользовательский опыт: например, p95 времени ответа, долю ошибок/таймаутов и один простой показатель качества. Остальные метрики добавляйте как диагностику, иначе дашборды будут «все обо всем» и не помогут в инциденте.

Как быстро заметить рост расходов на токены и найти причину?

Фиксируйте `input_tokens`, `output_tokens` и `tokens_per_request` для каждого запроса и смотрите распределения, а не среднее. Добавьте оценку стоимости на запрос и по сценариям, чтобы быстро увидеть, какой тип запросов «съедает» бюджет и из-за чего вырос контекст или длина ответа.

Как отличить проблемы провайдера LLM от проблем вашего приложения?

Считайте ошибки лимитов отдельно: rate limit, throttling, исчерпание квоты, а также время ожидания у провайдера. Если смешать их с обычными таймаутами, будет казаться, что «просто сеть плавает», и вы потратите время не на то место.

Какие метрики нужны, если ответы идут стримингом?

Для стриминга важны две метрики: время до первого токена и скорость токенов в секунду. Пользователь часто терпит длинный ответ, если поток начинается быстро и идет ровно, поэтому эти сигналы лучше коррелируют с ощущением «бот завис» чем общий тайминг ответа.

Как мерить качество ответов без сложных моделей-оценщиков?

Начните с простых исходов: помог/не помог, отказ, просьба уточнить, плюс технические сигналы вроде слишком короткого ответа, повторов и несоблюдения формата. Затем добавьте регулярную ручную проверку небольшой выборки диалогов по единым критериям, чтобы видеть регрессии, которые не поймаешь по задержкам и 5xx.

Что такое golden set и как он помогает ловить деградации после обновлений?

Соберите небольшой набор типовых запросов и прогоняйте его регулярно, сравнивая текущую версию с базовой. Если выпускать изменения канарейкой на 1–5% трафика и смотреть разницу в отказах, стоимости и качестве на коротком окне, регрессии видно до массовых жалоб.

Как настроить алерты, чтобы они были полезными, а не шумными?

Хороший алерт говорит, что ухудшилось, за какой период, и что проверить в первую минуту. Используйте окна (например, 10 минут), разделяйте симптомы (p95, очередь, 5xx) и причины (лимиты, квоты, деградация зависимостей), и держите короткий runbook, чтобы действия не были «наугад».

Как логировать промпты и ответы, не создавая рисков с персональными данными?

Храните тексты промптов и ответов только если они реально нужны для расследований, и сразу применяйте маскирование персональных данных. В логах достаточно оставить идентификаторы, версии промптов, параметры генерации и технические признаки качества, чтобы разбирать инциденты без риска утечек.

Запрос

Пришлите спецификацию. Остальное сделаем мы

Одна позиция или объект под ключ, любое направление. Вашу поставку от первого звонка до акта ввода ведёт один менеджер.

Расчёт бесплатноДокументы для госзакупок и тендеровОдин договор и одна гарантия