Перейти к содержимому
23 мая 2025 г.·7 мин чтения

Метрики LLM-шлюза в продакшене: короткий набор на день

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

Метрики LLM-шлюза в продакшене: короткий набор на день

Почему без цифр шлюз быстро теряет контроль

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

Если смотреть только на обращения пользователей, вы почти всегда узнаете о проблеме слишком поздно. Один общий график тоже мало помогает. Через шлюз часто идут десятки моделей, несколько провайдеров и разные сценарии: чат, суммаризация, поиск по базе, поддержка. В среднем все выглядит нормально, хотя у одного провайдера уже пошли 5xx, а одна модель отвечает на 40% медленнее обычного. В едином OpenAI-совместимом endpoint это случается постоянно.

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

  • где началась проблема;
  • что первым заметит пользователь;
  • что нужно чинить сейчас;
  • когда пора переключать маршрут на другую модель или провайдера.

Без цифр команда спорит на уровне ощущений. Одним кажется, что просело качество. Другие винят сеть или провайдера. Третьи видят только растущий счет. Все могут быть правы одновременно, но без простого набора показателей это не видно.

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

Нормальный дашборд должен подсказывать действие за несколько минут. Команда открывает его утром и сразу видит, где просел провайдер, где выросла цена запроса и где пора откатить маршрут.

С чего начать набор метрик

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

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

На первый экран обычно ставят такие показатели:

  • число запросов за день и за час;
  • доля успешных ответов;
  • p95 задержки;
  • среднее время до первого токена;
  • доля таймаутов;
  • доля ошибок 4xx;
  • доля ошибок 5xx;
  • средняя стоимость одного запроса;
  • средняя стоимость 1000 токенов;
  • доля запросов с жалобой на качество, ручной или автоматической.

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

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

У каждой метрики должно быть понятное действие. Если p95 вышел за порог, команда проверяет провайдера и, если нужно, переключает часть трафика. Если растут 5xx, смотрит, это сбой маршрутизации или проблема у провайдера. Если выросла цена запроса, проверяет, не ушел ли трафик на более дорогую модель. Если падает доля успешных ответов в одном сценарии, разбирает промпт и входные данные.

Если действие заранее не определено, метрика почти бесполезна.

Что считать качеством ответа

Качество редко видно по одной оценке. Вежливый текст еще не значит, что ответ помог пользователю или вообще пригоден для продукта. Для ежедневной работы хватает четырех сигналов. Они дают больше пользы, чем длинный список редких показателей.

Минимальный набор

  • Проход ручной проверки на выборке. Раз в день или после релиза берите 30-50 ответов и отмечайте, ответил ли каждый по делу, не придумал ли факт и не нарушил ли правила. Если из 40 ответов прошли 32, это 80%.
  • Сбои формата. Считайте отдельно случаи, когда модель ломает JSON, пропускает поле или нарушает схему. Для продукта это часто больнее, чем просто слабый текст, потому что дальше падает код или зависает сценарий.
  • Доля повторных запросов после неудачи. Если приложение делает retry, переводит запрос на запасную модель или пользователь повторяет тот же вопрос, качество уже просело. Такой сигнал хорошо ловит скрытую проблему, когда явных ошибок в логах почти нет.
  • Контрольный набор задач. Держите 20-50 типовых запросов и прогоняйте их после смены модели, промпта или маршрута. Подойдут извлечение полей, суммаризация, классификация и ответы по базе знаний.

Эти показатели лучше читать вместе. Ручная проверка показывает, полезен ли ответ человеку. Формат и повторные запросы показывают, может ли система жить с этим ответом без лишних обходов.

Простой пример: бот поддержки дает понятные ответы, и ручная проверка держится на 84%. Но JSON ломается в 6% случаев, а повторные запросы выросли с 9% до 17%. Внешне модель пишет неплохо, а в работе команда уже теряет время на повторы и разбор сбоев.

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

Что смотреть по задержке

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

p50 показывает обычный день: как быстро шлюз отвечает в типичном запросе. p95 показывает хвост: сколько ждут те, кому повезло меньше. Именно p95 чаще всего бьет по продукту, саппорту и SLA.

Для чата мало знать только полное время ответа. Пользователь сначала замечает, как быстро пришел первый токен. Если ответ начал печататься за 700 мс, а закончился через 8 секунд, это один опыт. Если первый токен пришел через 4 секунды, тот же ответ уже кажется зависшим.

Поэтому лучше держать отдельно p50 и p95 по общему времени ответа, time to first token для диалоговых сценариев, полное время ответа для длинных задач и долю запросов, которые уперлись в таймаут.

Одна цифра по всей системе мало что дает. Задержку стоит резать хотя бы по модели, провайдеру и типу запроса. Короткий чат, извлечение данных из документа и длинная генерация отчета ведут себя по-разному. Если смешать их в один график, причина проблем потеряется.

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

Таймауты не стоит держать отдельно от p95. Когда p95 подползает к лимиту в 20 или 30 секунд, это уже сигнал. Если команда прогоняет один и тот же сценарий через разные модели и провайдеров в одном шлюзе, такая связка метрик быстро показывает, где можно ждать, а где лучше сразу переключать маршрут.

Какие ошибки считать отдельно

Оставьте данные в стране
Используйте локальные модели, если вам важны data residency и низкая задержка.

Один общий error rate чаще мешает, чем помогает. Если вы смешали 429, 5xx, сетевые таймауты и ошибки схемы в одну цифру, команда увидит рост сбоев, но не поймет, что чинить первым.

Разделите ошибки хотя бы на четыре группы:

  • 429 - вы уперлись в лимиты, и тут чаще помогает очередь, другой провайдер или более аккуратный retry;
  • 5xx - проблема обычно на стороне модели или провайдера, это прямой сигнал для переключения маршрута;
  • сетевые сбои и timeout - здесь ищут нестабильный канал, DNS, прокси или слишком короткие таймауты;
  • ошибки валидации и схемы - запрос дошел, но ваш код или контракт сломался.

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

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

Еще один полезный показатель - доля запросов, которые стали успешными только после ретрая. Если она растет, шлюз пока держится, но запас уже тает. Например, success rate сегодня 99.2%, и это выглядит спокойно. Но если 7% успешных ответов пришли только со второй или третьей попытки, инцидент уже близко.

Для каждого сбоя храните request_id. Без него разбор быстро превращается в гадание: трудно найти лог, сопоставить провайдера, модель, статус и время ответа. С request_id инженер за пару минут понимает, где сломалось: в клиенте, в шлюзе или у внешнего API.

Как считать расходы без путаницы

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

Первая опора - стоимость 1000 успешных запросов. Если за день прошло 12 000 вызовов, но часть упала по таймауту или ошибке, делите затраты только на успешные. Так видно, сколько стоит рабочий поток, а не весь шум вокруг него.

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

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

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

Небольшой пример: FAQ-бот обычно решает простые вопросы на недорогой модели. Если через неделю 25% таких запросов начали уходить в более дорогую модель, а доля попаданий в кэш просела, счет вырастет даже при том же трафике. Проблема тут не в объеме запросов, а в правиле маршрутизации или в изменившемся шаблоне промпта.

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

Первый дашборд за один день

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

Для старта хватит простого лога по каждому запросу. Сохраняйте модель, провайдера, выбранный маршрут, входные и выходные токены, код ошибки и время ответа. Если команда работает через единый OpenAI-совместимый шлюз, такие поля проще собирать в одном месте, а не по разным кабинетам провайдеров.

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

Не усложняйте пороги. Если p95 вырос примерно на 30% к обычной базе, дайте желтый сигнал. Если ошибки ушли выше 2-3% или цена успешного ответа резко выросла, включайте красный.

Такой дашборд уже помогает в ежедневной работе. Он быстро показывает, когда один провайдер стал медленнее, когда маршрут начал чаще падать по таймауту и когда новая модель съедает бюджет без заметной пользы.

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

Пример: бот поддержки после запуска

Разберите инцидент быстрее
Храните request_id, маршрут и статус вызова там, где команда быстро находит причину.

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

Проблема всплыла, когда команда разложила данные по длине ответа. У коротких ответов все осталось почти как раньше, а у длинных p95 заметно вырос. Пользователь, который спрашивал про возврат денег или условия договора, ждал уже не 4-5 секунд, а 11-13. Среднее почти скрывало это, потому что коротких диалогов было больше.

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

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

Короткая ручная выборка из нескольких десятков диалогов показала еще одну проблему. Формат ответа ломался чаще, чем казалось по логам. HTTP 200 приходил, токены списывались, но JSON иногда терял поле, а шаблон ответа для оператора съезжал. Для бизнеса это ошибка, хотя технический мониторинг считал такой вызов успешным.

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

Именно так полезные метрики работают в продакшене. Они не говорят абстрактно, что "что-то стало хуже". Они показывают, где именно теряются секунды, деньги и качество.

Где команды ошибаются чаще всего

Чаще всего команды портят картину сами. Они собирают много чисел, но смотрят на них так, что решение принять нельзя. Метрики должны помогать выбирать модель, маршрут и лимиты на сегодня, а не жить в красивом отчете.

Первая ошибка - жить по среднему времени ответа. Среднее почти всегда успокаивает зря. Если 80% запросов проходят за 2 секунды, а остальные висят по 15, пользователь запомнит именно подвисание.

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

Третья ошибка бьет по бюджету. Команда считает расходы только по токенам и радуется дешевой модели. Потом эта модель чаще ошибается, оператор делает больше повторов, а бот чаще переводит диалог человеку. На бумаге токены дешевле. По факту один решенный кейс стоит дороже.

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

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

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

Хороший дашборд спорит с ощущениями. В этом его смысл.

Короткая проверка на каждый день

Сравните провайдеров честно
Сравнивайте p95, таймауты и цену по каждому маршруту в одном месте.

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

Для такой проверки достаточно пяти сигналов.

  • Смотрите p95 по главным сценариям, а не среднюю задержку. Если бот поддержки обычно укладывается в 4 секунды, а сегодня p95 вырос до 7, проблема уже есть.
  • Держите рядом 429, 5xx и таймауты. Их полезнее сравнивать не с идеалом, а с вашим обычным диапазоном за последние дни.
  • Проверяйте цену одного полезного ответа после каждого изменения маршрутизации, промпта или модели. Если качество не выросло, а ответ подорожал на 20-30%, такое изменение редко стоит оставлять.
  • Открывайте небольшую выборку живых ответов. Десяти-пятнадцати штук обычно хватает, чтобы заметить поломанный JSON, лишний текст вместо нужного формата или более слабые ответы после тихой смены модели.
  • Смотрите, не сел ли весь трафик на одного провайдера или одну модель. Если один маршрут забрал почти все запросы, вы получили лишний риск по отказам, лимитам и цене.

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

Звучит скучно, но работает. Один короткий просмотр утром часто спасает день лучше, чем длинный разбор после жалоб пользователей.

Следующий шаг для команды

Набор метрик работает только тогда, когда команда встраивает его в обычный ритм работы. Запишите 8-12 показателей, дайте им простые названия и назначьте одного человека, который смотрит на них каждый день. Он не обязан чинить все сам. Его задача проще: заметить сдвиг, открыть разбор и не дать проблеме потеряться между релизами.

Лучше считать метрики на уровне одного шлюза, даже если у вас несколько моделей и провайдеров. Иначе команда видит только куски картины. У одного провайдера растет задержка, у другого чаще идут ошибки, у третьего выше цена, а влияние на продукт никто не собирает в одно место. Сначала держите общий срез по качеству, p95 задержки, доле ошибок и стоимости на 1000 запросов. Потом уже проваливайтесь в модель, маршрут или клиента.

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

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

Для команд в Казахстане и Центральной Азии это особенно удобно, когда моделей много, а учет нужен единый. В такой схеме AI Router на airouter.kz помогает собрать маршрутизацию, аудит-логи и биллинг в тенге в одном месте. Тогда проще сравнивать провайдеров, считать расходы и разбирать инциденты без переключения между разными кабинетами.

Часто задаваемые вопросы

С каких метрик собрать первый дашборд?

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

Сразу режьте данные по модели, провайдеру и сценарию. Иначе средние цифры спрячут проблему.

Почему средней задержки недостаточно?

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

Смотрите хотя бы p50 и p95. Для чата отдельно держите время до первого токена, потому что его человек замечает первым.

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

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

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

Как понять, что качество ответа реально упало?

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

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

Какие ошибки нужно считать отдельно?

Не смешивайте все в один error rate. Отдельно держите 429, 5xx, сетевые таймауты и ошибки схемы или валидации.

Так команда сразу понимает, что делать. При 429 часто помогает очередь или другой провайдер, при 5xx — переключение маршрута, при ошибке схемы — правка контракта или промпта.

Как не смешать тестовый и боевой трафик?

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

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

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

Общая сумма за день мало что объясняет. Считайте цену успешного ответа и стоимость 1000 успешных запросов, а не всех вызовов подряд.

Полезно смотреть входные и выходные токены раздельно. Тогда видно, расход растет из-за длинного промпта, слишком многословного вывода или из-за того, что маршрутизация чаще уводит трафик в дорогую модель.

Когда пора переключать трафик на другую модель или провайдера?

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

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

Что обязательно писать в лог каждого запроса?

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

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

Как часто проверять дашборд и кто должен за него отвечать?

Обычно хватает короткой проверки утром и после каждого релиза. Если дашборд собран нормально, на просмотр уходит 5–7 минут.

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