Кратко
- Шлюз: LiteLLM служит единой точкой доступа ИИ-агентов, помощников разработчика и конвейеров обработки данных к моделям нескольких облачных провайдеров и к локальной модели на GPU-сервере. Сервис, который обращается к шлюзу, называет модель именем группы, а роутер шлюза выбирает развёртывание, повторяет запрос при ошибке, учитывает квоты и расходы.
- Отказы роутера: за сутки отказ получили 39 % запросов, а сквозная проба оставалась зелёной: она ходила в другую модель. Причин оказалось две, и обе давали один и тот же ответ «No deployments available»: часовое остывание группы из одного развёртывания после ошибок 500 у провайдера (этот случай команда LiteLLM исправила 27.10.2026) и суточный потолок токенов, заданный в самом шлюзе. Правило на долю неудачных запросов, заведённое по ходу разбора, поймало этот отказ сразу: по журналу шлюза за те полчаса отказом заканчивались 92 % запросов. После правки настроек роутера часового остывания больше не было: за 30 суток (05.10–04.11.2026) ошибок 5xx и тайм-аутов у провайдера набралось 3,9 % от числа запросов, а отказов до потребителей дошло 0,34 %.
- Смена модели под прежним именем: провайдер отдал имя модели её новой версии. Ошибок не было, а доля материалов, которые модель-оценщик пропускала к человеку, в одной из лент упала с 10–11 % до 5,9 % в день смены и дальше примерно до 3 %. Парная переоценка 668 материалов показала: порядок оценок близок к прежнему (ранговая корреляция 0,81–0,96), а шкала опустилась на 0,8–1,6 балла. Пороги пересчитаны, сторожится доля прошедших порог.
- Расходы: шлюз считал стоимость по ценам, которые провайдер уже поменял, и учитывал 61 % стоимости вызовов по официальной таблице. Цена теперь задана смесью по доле пикового трафика шлюза: в сумме за 28 дней она совпадает со стоимостью по официальной таблице, а тест держит её в официальных границах.
- Метод: тревога ставится на исход запросов, а не на запас ресурса; правка проверяется на следующих сбоях провайдера, а не по зелёному ответу после перезапуска; настройки роутера, цены и маршруты групп
private/*записаны тестами конфигурации. - Те же отказы в отрасли: команда LiteLLM 27.10.2026 влила правку ровно этого случая (на 04.11.2026 она есть только в предварительных выпусках 1.109): если в роутере задан allowed_fails, группа из одного развёртывания без запасного маршрута всё время остывания отвечает «No deployments available». Anthropic в разборе от 17.09.2025 написала, что ухудшение ответов, на которое жаловались пользователи, её проверки пропустили. Yandex и DeepSeek записывают в журналах изменений, как за веткой latest или прежним именем оказывается новая модель. Ссылки даны в разделах «Риски и требования» и «Сверка с эталонами».
Риски и требования
Кейс адресован CTO, руководителям платформ и ИИ-направлений в организациях, где ИИ-агенты и конвейеры ходят к нескольким моделям через один шлюз. Так устроен, например, шлюз Альфа-Банка: по словам докладчиков на конференции Selectel «МЛечный путь 2026», модели, развёрнутые в кластере банка, подключены к единому шлюзу на LiteLLM, и через него ходят разные команды и сервисы.
Шлюз становится общей точкой отказа для всех агентов, поэтому его поведение при сбое задают заранее: для каждой проверки и каждого маршрута решают, пропустить запрос при сбое (fail-open) или отклонить его (fail-closed).
Труднее всего то, что шлюз почти никогда не падает целиком. Илья Захаров, директор департамента мониторинга «Группы Астра», в подкасте TAdviser сказал о мониторинге ИИ-сервисов в целом: раньше ответ 200 означал, что сервис работает, а теперь модель может ответить быстро и при этом ошибиться. Исследователи Stanford и UC Berkeley ещё в 2023 году показали, что поведение модели под прежним именем за три месяца меняется заметно: GPT-4 в марте 2023 года верно отличала простые числа от составных в 84 % случаев, а в июне в 51 % (Chen, Zaharia, Zou). Anthropic в разборе «A postmortem of three recent issues» от 17.09.2025 написала, что её проверки не уловили ухудшения ответов, о котором сообщали пользователи, хотя в худший час ошибка маршрутизации затронула 16 % запросов к Sonnet 4; причиной были ошибки инфраструктуры, а имя модели не менялось. Некоторые провайдеры сами записывают такие переключения в журналах изменений: в журнале Yandex AI Studio за веткой latest в разное время стояли разные поколения YandexGPT, с 24.06.2024 YandexGPT Lite на базе YandexGPT 3, с 02.12.2024 модель 4-го поколения; в журнале DeepSeek имя deepseek-v4-flash после выхода V4.1 Flash временно направлено на новую модель.
С 01.03.2026 действует приказ ФСТЭК России от 11.04.2025 № 117. Им утверждены Требования о защите информации, содержащейся в государственных информационных системах, иных информационных системах государственных органов, государственных унитарных предприятий, государственных учреждений. Пункт 60 Требований: «Не допускается передача лицу, разработавшему модель искусственного интеллекта, информации ограниченного доступа, содержащейся в информационных системах, в том числе для улучшения функционирования модели искусственного интеллекта». Для коммерческих систем это ориентир, а не обязательная норма. В шлюзе это вопрос маршрута: если у группы есть запасной маршрут (fallback) к облачной модели, при отказе локальной текст уйдёт провайдеру. Поэтому группы private/* устроены по принципу fail-closed: запасных маршрутов и псевдонимов у них нет, развёртывания заданы частными адресами или именами в домене организации, и это проверяет тест конфигурации; при отказе локальной модели запрос отклоняется, а не уходит наружу. В шлюзе граница контура задаётся именем группы, а не моделью: обращения по общим именам, даже к той же локальной модели, к контуру не относятся и при отказе могут уйти по запасному маршруту в облако.
Задача
LLM-шлюз, или AI-шлюз (AI gateway), стоит между приложениями и провайдерами моделей: один API перед многими моделями, маршрутизация, повторы и запасные маршруты, ключи, квоты и учёт расходов. Открытый проект LiteLLM состоит из библиотеки на Python и прокси-сервера LiteLLM Proxy, который принимает запросы в формате OpenAI API и передаёт их моделям разных провайдеров. В роли AI-шлюза (AI gateway) он маршрутизирует запросы, выдаёт API-ключи с лимитами и бюджетами и считает расходы. Через такой шлюз здесь работают ИИ-агенты и помощники разработчика, конвейеры разбора документов и оценки входящих материалов. За ним облачные модели нескольких провайдеров, у части из них суточные квоты, и локальная модель на GPU-сервере. Сервис, который обращается к шлюзу, называет модель именем группы. Роутер шлюза распределяет нагрузку между развёртываниями группы, повторяет запрос при ошибке и временно исключает из выбора развёртывание, которое ошибается слишком часто (остывание); лимитер считает квоты, а шлюз пишет стоимость каждого вызова.
Такой шлюз почти никогда не падает целиком. Отказ приходит иначе: роутер отклоняет запросы при доступном провайдере; провайдер отдаёт имя модели её новой версии; шлюз считает расходы по цене, которую провайдер уже поменял. Во всех трёх случаях проверка живости и сквозная проба через одну модель остаются зелёными. Задача: найти такие отказы и сделать так, чтобы следующий такой же был виден по числам, а не по случайному наблюдению.
Как устроен шлюз
Агенты и конвейеры обращаются к шлюзу по OpenAI-совместимому API и называют модель именем группы. В группе может быть одно развёртывание или несколько, у разных провайдеров. Роутер выбирает развёртывание, при ошибке повторяет запрос и, если развёртывание ошибается чаще допустимого, выводит его из выбора на время остывания. Суточные квоты считает лимитер в Redis, стоимость каждого вызова шлюз пишет в PostgreSQL по ценам из конфига шлюза. Группы private/* заданы только частными адресами и именами в домене организации и запасных маршрутов не имеют.
Отказы шлюза видны по двум сигналам, которые мерят исход, а не живость, и по проверке цен:
- Доля отказанных запросов. Шлюз отдаёт метрики LiteLLM в Prometheus, среди них счётчики всех запросов и неудачных ответов (в них входят и отказы роутера, и ошибки самих вызывающих); правило в Grafana поднимает тревогу, если за час неудачной была больше чем десятая часть запросов и так держится 15 минут. Доля считается по шлюзу в целом, поэтому полный отказ группы с малой долей трафика это правило не поднимет; кто именно упирается, видно по меткам модели и класса ошибки.
- Доля прошедших порог у оценщика. Конвейер оценки материалов каждое утро сравнивает долю материалов, прошедших порог, с медианой за 14 суток. Если порог не менялся, а доля упала вдвое против медианы, это повод для парной переоценки: так сдвигает долю и смена шкалы модели, и смена входного потока.
- Цены против таблицы провайдера. Тест конфигурации сверяет цену каждого имени модели с официальной таблицей провайдера на 23.10.2026: цена должна лежать между ценой вне пика и пиковой. Новую смену тарифа тест сам не заметит: таблицу в тесте и смесь цен обновляют по журналу изменений провайдера.
- uid: llm-gateway-failure-share
condition: C
data:
- refId: A
model:
# доля неудачных запросов за час; пока неудачных меньше
# 0,003 в секунду (около одного за 5 минут), числитель пуст
expr: >
(sum(rate(litellm_proxy_failed_requests_metric_total[1h])) > 0.003)
/ clamp_min(sum(rate(litellm_proxy_total_requests_metric_total[1h])), 0.001)
- refId: C
model:
type: threshold
expression: B # B: последнее значение A
conditions:
- evaluator: { type: gt, params: [0.1] }
for: 15m
noDataState: OK # пустой числитель значит «отказов почти нет»
labels:
severity: warningСверка с эталонами
Каждый класс отказа сверили с тем, что о нём публично пишут разработчики LiteLLM, провайдеры моделей и практики эксплуатации: глава о мониторинге книги Google SRE, документация LiteLLM о проверках здоровья и об остывании модели после ошибки одного пользователя, PR #48644, PR #41960, PR #40954 и issue #49089 в репозитории LiteLLM, разбор Андрея Крисанова о цене проверок здоровья, таблица цен DeepSeek, issue #47788 в репозитории OpenCode, руководство FinOps Foundation о расходах на токены, работа Chen, Zaharia, Zou, разбор Anthropic «A postmortem of three recent issues» и журналы изменений Yandex AI Studio и DeepSeek. Страницы открыты 04.11.2026, цитаты и числа сверены по самим страницам; где поведение зависит от версии или настроек, это сказано в таблице.
| Звено | Что известно в отрасли | Решение | Чем подтверждено |
|---|---|---|---|
| Сигнал тревоги | Google SRE: тревогу ставят на симптомы, а ответ 200 с неверным содержимым тоже считают ошибкой; у LiteLLM общий /health отвечает 200, даже когда нездоровы все развёртывания | доля отказанных запросов по метрикам шлюза, а не живость шлюза и не запас квоты | правило, заведённое по ходу разбора, поймало тот же отказ сразу, ещё до правки; по журналу шлюза за те полчаса отказом заканчивались 92 % запросов при зелёной сквозной пробе |
| Остывание и повторы | PR LiteLLM #48644 (27.10.2026): при заданном allowed_fails группа из одного развёртывания без запасного маршрута всё остывание отвечает «No deployments available»; правка пока в предварительных выпусках 1.109. LiteLLM: остывание после ошибки одного пользователя закрывает модель для всех | разовая ошибка провайдера не выводит развёртывание из выбора: пороги ошибок подняты, остывание короткое, ответ 429 повторяется с паузой; значения записаны тестом конфигурации | до правки 99,6 % отказов за 15 минут, хотя прямые запросы к провайдеру проходили; после правки 0 отказов на 3 494 запроса за 83 минуты; за 30 суток 05.10–04.11 при 3,9 % ошибок провайдера до потребителей дошло 0,34 % запросов |
| Пробы как расход | Крисанов: проверка здоровья модели в LiteLLM делает настоящий запрос к модели, фоновые проверки стоит оставлять локальным моделям; issue LiteLLM #49089: после обновления до 1.106.3 фоновые проверки отправляли платные запросы к моделям генерации изображений | развёртывания с суточной квотой вне общих групп, фоновые самопроверки тарифицируемых развёртываний отключены | тест конфигурации |
| Смена модели у провайдера | Chen, Zaharia, Zou: GPT-4 под тем же именем на одной задаче 84 % в марте и 51 % в июне 2023 года; Anthropic: проверки провайдера не уловили ухудшения ответов; Yandex и DeepSeek записывают переключения имён в журналах изменений | парная переоценка при смене модели и доля прошедших порог против медианы 14 суток вместо одного контрольного эталона | 668 материалов: порядок оценок сохранился, ρ 0,81–0,96, шкала ниже на 0,8–1,6 балла; пороги пересчитаны по точности и полноте решения «отправить» и по совпадению долей прошедших |
| Учёт расходов | DeepSeek с 16.08.2026 вне пика вдвое дешевле; встроенная таблица LiteLLM до PR #41960 (19.09.2026) на вызовах вне пика считала вдвое больше счёта; в issue #47788 к OpenCode пользователь показал занижение около 40 %, часть разницы дали неучтённые вызовы; FinOps Foundation называет прямые API провайдеров самым трудным каналом ИИ-расходов | цена задана смесью по доле пикового трафика шлюза; тест держит её между ценой вне пика и пиковой | в сумме за 28 дней смесь совпадает со стоимостью по официальной таблице; на живых вызовах после перезапуска учёт совпал с расчётом по новой смеси цен до восьмого знака; со счётом провайдера построчно не сверяли |
| Параметры модели | PR LiteLLM #40954: у моделей Z.AI флаг выключения рассуждения не доходил до модели, и каждый запрос оплачивал токены рассуждения | выключение рассуждения проверяется по reasoning_tokens живого ответа, а не по наличию параметра в коде | 146 токенов рассуждения с параметром шаблона чата, 0 с родным параметром DeepSeek; у потребителей, которые выключают рассуждение, 0–0,3 % по журналу шлюза |
| Граница контура | п. 60 Требований, утверждённых приказом ФСТЭК № 117: «Не допускается передача лицу, разработавшему модель искусственного интеллекта, информации ограниченного доступа, содержащейся в информационных системах…» | fail-closed: у групп private/* нет запасных маршрутов и псевдонимов, развёртывания заданы частными адресами или именами в домене организации | тест конфигурации; соответствие требованиям в целом в кейсе не оценивается |
Методика
Отказы шлюза не оставляют ошибок там, где их обычно ищут, поэтому каждый класс разбирали замером, а не по сообщениям об ошибках и не по зелёным проверкам. На том же принципе построен аудит алертинга: правило, которое не может сработать, тоже выглядит здоровым.
- Исход, а не запас. Сначала считали, сколько запросов к шлюзу закончилось отказом: по журналу шлюза за сутки 39 % ответов на запросы генерации были отказами 429. Тревога «пул заполнен на 90 %» в это время указывала на суточный пул другой модели и об отказах ничего не говорила: она мерит запас ресурса, а не исход запросов.
- Правка проверяется на следующих сбоях. В этой установке список остывания хранится в памяти процесса, и перезапуск контейнера его очищает; с Redis у роутера, по документации LiteLLM, перезапуск может, наоборот, вернуть старую запись. В обоих случаях успешный ответ сразу после перезапуска ничего не доказывает. Окно проверки считается от времени старта контейнера, а подтверждением служат часы, когда провайдер снова отвечает ошибками, а потребители отказов не получают. Ошибки провайдера видны по метрике LiteLLM об ответах развёртываний, отказы потребителям по метрике неудачных ответов, без ошибок самих вызывающих (400, 403).
- Парная переоценка оценщика. 668 материалов, оценённых прежней моделью с 26.08 по 10.09, взяли равномерно по корзинам прежнего балла и переоценили новой моделью теми же промптами и с той же сборкой входа, без записи в базу. Для каждой из пяти лент считали сдвиг среднего, ранговую корреляцию Спирмена и точность и полноту решения «отправить» при новом пороге против прежнего решения. Второй способ: подобрать порог, при котором доля прошедших совпадает с прежней.
- Сверка цены. Официальная таблица провайдера, цены вне пика и в пик, и доля пиковых вызовов в стоимости трафика шлюза за 28 дней дают смесь, которую шлюз и записывает. После перезапуска учёт на живых вызовах сравнили с расчётом по новым ценам.
- Параметр проверяется вызовом. Выключено ли рассуждение модели, проверяли по полю
usage.completion_tokens_details.reasoning_tokensживого ответа, а не по наличию параметра в коде.
83 минуты после правки 13.08 составляют одно окно наблюдения; поведение на следующих сбоях провайдера измерено за 30 суток, которые хранит Prometheus (05.10–04.11.2026), и в этот период остывание уже 10 секунд. Сдвиг шкалы измерен на одном оценщике, на пяти лентах материалов, и дан диапазоном по лентам. Выборка равномерна по корзинам прежнего балла, а на таком разбросе ранговая корреляция обычно выше, чем на естественном потоке материалов. Цена сверена с официальной таблицей провайдера и пересчётом по трафику шлюза; счёт провайдера и учёт шлюза построчно не сверяли. Смесь точна в сумме по шлюзу; для отдельного ключа с другой долей пикового трафика учёт отклоняется, но цена остаётся между ценой вне пика и пиковой. Случай с параметром рассуждения стоит на одном живом вызове, доля токенов рассуждения после правки взята из журнала шлюза на 23.10.2026. Отказы за сутки 12–13.08 по причинам не разделены: в них вошли и остывание, и суточный потолок токенов.
Технические решения
Остывание не охраняет квоты. По замыслу LiteLLM не остужает группу из одного развёртывания: в коде роутера прямо сказано, что такой группе остывания по умолчанию лучше избегать. Но если в настройках роутера задан allowed_fails, это исключение не действовало до правки команды LiteLLM от 27.10.2026, и группа из одного развёртывания без запасного маршрута всё остывание отвечала «No deployments available». Здесь пару allowed_fails: 1 и cooldown_time: 3600 держали, чтобы модель с суточной квотой после исчерпания не получала отказ каждую минуту до полуночи. Но квоты стережёт лимитер, а остывание срабатывает на ошибки, и это другой механизм: разовые ошибки 500 у провайдера выключали модель на час, и подменить её в группе было некем. Ночью отказ на время сменил причину: кончился суточный потолок токенов, заданный для этой модели в самом шлюзе, и роутер перестал выбирать развёртывание уже без всякого остывания. Текст ошибки в ответе шлюза в обоих случаях один и тот же, «No deployments available», поэтому причину каждый раз определяли по списку остывания и счётчику пула, а не по ответу. Утром 13.08 потолок сняли, и вернулось остывание: провайдер под нагрузкой отдавал серии ошибок 500, прямые запросы к нему в то же время проходили, а шлюз за 15 минут отклонил 99,6 % запросов. Правка 13.08 в настройках роутера: allowed_fails 1 → 3, cooldown_time 3600 → 60 секунд. Конфиг шлюза тогда собирал генератор, который переписывал настройки роутера целиком, поэтому до 28.08 часовое остывание возвращалось с каждой пересборкой; 28.08 значение исправили в самом генераторе. Сейчас остывание 10 секунд, пороги ошибок заданы и общие, и по классам ошибок, а ответ 429 шлюз повторяет с паузой в секунду. Эти значения записаны тестом конфигурации: он падает, если остывание длиннее 15 секунд, если до остывания допускается меньше трёх ошибок или если ответ 429 не повторяется.
Когда выводить развёртывание из выбора
Высокие пороги ошибок, короткое остывание
Разовая ошибка провайдера уходит в повтор, а не в простой модели. За 30 суток после правки в 97 % часов, когда ошибок провайдера было не меньше десятой части от числа запросов, потребители не получили ни одного отказа.
Порог в одну ошибку, час остывания
Задумано как защита суточных квот, но реагирует на ошибки, а не на квоты.
Проба тоже тратит квоту. Сквозная проба и канареечная проверка ходили в группы-агрегаты, а роутер отдавал эти обращения в том числе развёртываниям с суточной квотой, и квоту выбирали сами пробы. Развёртывания с суточной квотой вывели из агрегатов, а позже группы-агрегаты убрали совсем: каждая модель вызывается по имени. Фоновые самопроверки для тарифицируемых развёртываний отключены, и это проверяет тест конфигурации. Синтетическая проба тарифицируемого ресурса сама становится статьёй расхода, и у LiteLLM это известная история. Андрей Крисанов в разборе «Hidden Costs of LiteLLM's Health Checks» напоминает, что проверка здоровья модели в LiteLLM делает настоящий запрос к модели, и советует оставлять фоновые проверки локальным моделям, а платные внешние из них исключать. В issue #49089 пользователь LiteLLM сообщил, что после обновления до 1.106.3 фоновые проверки стали отправлять платные запросы к моделям генерации изображений и провайдер в итоге приостановил его платёжный аккаунт.
Шкала оценщика сторожится долей, а не эталоном. Контрольный эталон с баллом 9 после смены модели получил 8 при пороге 7 и остался зелёным: он ловит поломку оценщика, а не сдвиг шкалы на балл. Поэтому сигналом стала доля прошедших порог при неизменном пороге, против медианы 14 суток.
Как заметить смену модели у провайдера
Доля прошедших порог против медианы 14 суток
Смена шкалы сдвигает долю прошедших при неизменном пороге. В одной из лент доля прошедших до смены модели была 10–11 %, в день смены 5,9 %, дальше около 3 %.
Контрольный эталон с фиксированным баллом
Эталон с баллом 9 получил 8 при пороге 7 и остался зелёным, пока доля прошедших в одной из лент падала с 10–11 % до 3 %.
Цена по трафику шлюза. С 16.08 провайдер берёт в будние пиковые часы вдвое больше, чем в остальное время. Цены DeepSeek в конфиге шлюза были заданы вручную ещё по прежнему тарифу, а заданная вручную цена перекрывает встроенную таблицу LiteLLM и остаётся одним числом на всё время суток; поэтому учёт не изменился ни при смене тарифа у провайдера, ни при правке встроенной таблицы самим LiteLLM. Встроенная таблица после PR #41960 различает время суток, но сама до 19.09 считала вызовы вне пика по пиковой цене: явная цена в конфиге не зависит от того, когда таблицу поправят, зато её нужно сверять с таблицей провайдера, и это делает тест. Теперь в конфиге стоит смесь по доле пикового трафика шлюза, а тест держит цену каждого имени модели между ценой вне пика и пиковой и следит, чтобы у разных имён одной модели цена была одна.
# Официальные цены за 1M токенов: (вне пика, пик)
DEEPSEEK_PRICES_PER_1M = {
"deepseek/deepseek-flash": {
"cache_read_input_token_cost": (0.003, 0.006),
"input_cost_per_token": (0.15, 0.30),
"output_cost_per_token": (0.60, 1.20),
},
}
def test_deepseek_prices_match_official_table(config=None):
cfg = config or load_config()
seen = {}
for m in cfg["model_list"]:
lp = m.get("litellm_params", {})
model = lp.get("model")
if model not in DEEPSEEK_PRICES_PER_1M:
continue
for field, (low, high) in DEEPSEEK_PRICES_PER_1M[model].items():
per_1m = float(lp[field]) * 1e6
assert low <= per_1m <= high, f"{m['model_name']}: {field} = {per_1m:.4f}"
seen.setdefault((model, field), set()).add(float(lp[field]))
# у всех имён одной модели одна цена
for (model, field), values in seen.items():
assert len(values) == 1, f"{model}: разные {field}: {sorted(values)}"Параметр проверяется ответом модели. У моделей DeepSeek V4 рассуждение включено по умолчанию. У бэкендов за OpenAI-совместимым API разные расширения: chat_template_kwargs передаёт параметры шаблона чата серверам вроде vLLM и SGLang, а у DeepSeek для выключения рассуждения свой параметр. Запрос с chat_template_kwargs: {"thinking": false} прошёл через шлюз без ошибки, но рассуждение не выключил: на живом вызове 146 токенов рассуждения. Рассуждение тратит тот же лимит max_tokens, поэтому часть ответов приходила пустой или обрезанной. С родным параметром DeepSeek thinking: {"type": "disabled"} рассуждения на том же вызове нет, а ответ в пять раз короче. На 23.10.2026 у потребителей, которые выключают рассуждение, токенов рассуждения в журнале шлюза 0–0,3 %. Тот же класс описан в PR #40954 к LiteLLM для моделей Z.AI: флаг выключения рассуждения не доходил до модели, и каждый запрос оплачивал токены рассуждения.
Результаты
| класс отказа | что показывали проверки | исход для запросов | после правки |
|---|---|---|---|
| остывание роутера и суточный потолок токенов | сквозная проба зелёная, тревога о заполненном пуле | 39 % запросов за сутки отклонены | 0 отказов на 3 494 запроса за 83 минуты 13.08.2026; за 30 суток при 3,9 % ошибок провайдера до потребителей дошло 0,34 % запросов |
| смена модели под прежним именем | ошибок нет, контрольный эталон 8 при пороге 7 | доля прошедших порог в одной из лент 10–11 % → около 3 % | пороги пересчитаны парной переоценкой 668 материалов, сторожится доля прошедших |
| устаревшие цены | ошибок нет | учтён 61 % стоимости вызовов по официальной таблице, бюджеты ключей мягче в 1,65 раза | смесь цен в сумме за 28 дней совпадает со стоимостью по официальной таблице, тест держит цену в официальных границах |
| параметр не дошёл до модели | шлюз отвечал 200 | рассуждение на каждом вызове, часть ответов пустая | рассуждения нет, ответ в пять раз короче |
До 28.08 генератор конфига возвращал часовое остывание, и тот же класс был виден со стороны сквозной пробы, которая ходила в группу-агрегат из четырёх развёртываний. Все длинные окна отказа в её замерах за 19–27.08, от 30 до 85 минут, были ответами 429 от остывания: в нём разом оказались все четыре развёртывания группы, и длину окна задавало остывание, а не продолжительность сбоя у провайдера.
После 28.08 часового остывания в журнале шлюза нет: последний отказ с «Try again in 3600 seconds» записан 25.08. Как правка держит следующие сбои провайдера, видно по метрикам LiteLLM за 30 суток (05.10–04.11.2026). Ошибок 5xx и тайм-аутов у провайдера набралось 3,9 % от числа запросов, а отказов до потребителей дошло 0,34 %. В 163 часах из 717 ошибок провайдера было не меньше десятой части от числа запросов, и в 158 из них (97 %) ни один запрос потребителей не получил отказа: повтор проходил. Выше 10 % за час доля отказов потребителям поднималась в пяти часах. Два из них пришлись на 03.11, когда провайдер подряд отвечал 503 и повторять было некуда. Три других (15.10 и 31.10) дали лимиты запросов, заданные в самом шлюзе на развёртывание и на ключ: такие отказы видно в журнале по тексту, и правило на долю неудачных запросов показывает их наравне со сбоями провайдера.
Выводы
- LLM-шлюз отказывает не падением, а ответом: отказом роутера при доступном провайдере, другой моделью под прежним именем, расходом по устаревшей цене. Проверка живости и проба через одну модель в этих случаях остаются зелёными, поэтому тревогу ставят на исход, на долю отказанных запросов и долю прошедших порог, а цены в конфиге сверяют с таблицей провайдера тестом.
- Настройка, которая выглядит как защита квот, сама может быть источником отказа: часовое остывание на группе из одного развёртывания вместе с суточным потолком токенов дало 39 % отказов за сутки, а после снятия потолка в отдельные 15 минут отклонялось 99,6 % запросов. После правки роутера часового остывания больше не было, а за 30 суток при 3,9 % ошибок провайдера до потребителей дошло 0,34 % запросов.
- Смена модели у провайдера под прежним именем не видна ни в коде, ни в ответах и журналах шлюза; узнать о ней можно из журнала изменений провайдера, если он её записывает, и по распределению оценок. Парная переоценка 668 материалов показала близкий к прежнему порядок (ранговая корреляция 0,81–0,96) и сдвинутую шкалу (0,8–1,6 балла). Поэтому после смены модели пороги нужно пересчитывать и сторожить распределение оценок, а не один эталон.
- Цену и поведение модели по умолчанию задаёт провайдер, и меняются они без участия шлюза: шлюз учитывал 61 % стоимости вызовов по официальной таблице, а рассуждение, которое у DeepSeek V4 включено по умолчанию, параметр шаблона чата не выключал. Цену держит тест конфигурации, а выключение рассуждения проверено живым вызовом и долей токенов рассуждения в журнале шлюза.
- Правку проверяют на следующих сбоях провайдера, а не первым зелёным ответом: перезапуск, если список остывания хранится в памяти, очищает его и сам по себе выглядит как починка. А закрепляют её тестом конфигурации, иначе правку в собранном генератором конфиге перепишет следующая пересборка.