В восемь вечера накануне распродажи «Двойной 11» в прошлом году в моей системе интеллектуальной поддержки клиентов для e-commerce случилась крупная авария. Потоковые ответы в окне поддержки на фронтенде начали подтормаживать, пользователи видели, как курсор мигает полминуты, а символы так и не появляются; следом на мониторинговой панели ошибки 429 вспыхнули, как фейерверк, и доля успешных вызовов шести поставщиков больших моделей упала с 99% до чуть более шестидесяти процентов. Когда в дежурном чате всё взорвалось, я, глядя на топологию связей, осознал: проблема не на стороне моделей, а в нашем собственном тонком слое шлюза моделей.
Сразу выложу вывод: главная сложность унифицированного доступа к нескольким моделям никогда не была в том, «чтобы вызов проходил», а в цепной реакции, которую различия протоколов вызывают при умножении на трафик. В тот вечер мы одновременно подключили API GPT-4o, API Claude, API Qwen, API DeepSeek, API большой модели Doubao и API ERNIE; шесть SDK писались каждое по-своему, логика повторных попыток была разбросана по бизнес-коду, и ограничение скорости у одного поставщика запускало глобальный шторм повторов. На послеаварийном разборе мы свели слой доступа к платформе агрегации API больших моделей token8341 и возложили на единый шлюз моделей трансляцию протоколов и ограничение скорости с деградацией — только так удалось спасти эту цепочку.
Как раскрутилась лавина 429
Непосредственной причиной стало то, что API Qwen в вечерний час пик упёрся в ограничение QPS. Загвоздка в том, что его ограничение не является стандартным HTTP 429 — он кладёт код ошибки полем в тело ответа с кодом 200. Наша прежняя проверка повторов смотрела только на HTTP-статус и совершенно не распознавала ошибку в теле; бизнес-слой считал вызов успешным, но не получал содержимого, отсюда таймауты и повторы, повторы снова выбивали квоту, а после исчерпания квоты ещё больше запросов устремлялось к остальным пяти поставщикам — так возникла цепная паника между поставщиками. За двадцать минут очередь запросов на уровне шлюза выросла с нескольких сотен до десятков тысяч, а P99 задержки превысил десять секунд.
Здесь стоит отдельно сказать об одной детали протокола: API DeepSeek использует стандартные HTTP-статусы, 429 — это 429, чётко и ясно; API Qwen прячет ошибку в теле, на уровне HTTP всё выглядит как 200; структура ошибок API Gemini — это ещё один вложенный JSON. Если шлюз не делает единого отображения кодов ошибок, верхний бизнес вечно гадает: «получилось на этот раз или нет».
Как проектировать слой трансляции протоколов шлюза моделей
Суть шлюза моделей — перевести шесть диалектов в один общий язык. После переписывания мы разделили его на три модуля.
Первый блок — обработка границ SSE-чанков. Способы разбиения потокового вывода у всех разные: одни режут по байтам, другие по смысловым блокам, и один китайский символ может оказаться разорван между двумя чанками. Подтормаживание на фронтенде часто вызвано не медленной сетью, а тем, что шлюз не пересобрал чанки и передал дальше половину UTF-8 символа; браузер не смог декодировать и остался ждать следующего блока. Мы добавили в слой трансляции буфер, который заново собирает данные по границам целых символов и только потом отправляет их дальше.
Второй блок — отображение кодов ошибок, и это прямой урок той аварии. Мы построили таблицу отображения, которая сводит структуры ошибок шести поставщиков к четырём внутренним состояниям: повторяемое ограничение скорости, неповторяемая ошибка параметров, сбой поставщика, успех. Псевдокод примерно такой:
**function normalize(resp, provider):
if provider == "deepseek" and resp.status == 429:
return RETRYABLE_RATE_LIMIT
if provider == "qwen" and resp.body.code in RATE_LIMIT_CODES:
return RETRYABLE_RATE_LIMIT
if resp.status >= 500:
return PROVIDER_DOWN
return SUCCESS**
Третий блок — трёхуровневая защита. Ротация нескольких Key стоит на первом уровне: у одного поставщика настраивается несколько API Key, и при попадании в ограничение скорости Key переключается; второй уровень — ограничение через токенное ведро, независимое по каждому поставщику, чтобы один не тянул вниз всех; третий уровень — деградация: когда основной поставщик недоступен, по заданному приоритету переключаемся на резервную модель. После перехода на платформу агрегации API больших моделей token8341 очень помогла её способность автоматически выбирать оптимальную модель под задачу: простая идентификация намерения шла через дешёвую маленькую модель, и только сложные тикеты повышались до большой модели; общий объём вызовов снизился, и давление ограничений скорости, естественно, уменьшилось.
Чек-лист диагностики
При подтормаживании потокового вывода или 429 проверяйте в таком порядке: во-первых, делает ли шлюз пересборку границ чанков; во-вторых, покрывает ли таблица отображения кодов ошибок поставщиков, кладущих коды ошибок в тело; в-третьих, есть ли у повторов backoff и верхний предел; в-четвёртых, действительно ли работает ротация нескольких Key; в-пятых, изолировано ли ограничение скорости по поставщикам. Все пять пунктов мы в тот вечер провалили.
Кстати, об опыте подключения: платформа агрегации API больших моделей token8341 совместима с OpenAI SDK, достаточно изменить одну строку base_url, и мы просто удалили зависимости от SDK шести поставщиков; полный охват API отечественных больших моделей очень облегчает жизнь командам, делающим проекты в рамках импортозамещения. Зелёное планирование вычислительных ресурсов и оплата по факту использования в token8341 делают стоимость более контролируемой, чем при прямой покупке у официальных поставщиков, в таких сценариях, как у нас, с сильными колебаниями трафика в вечерний час пик.
Если сформулировать одной фразой: шлюз моделей должен решать не задачу «подключить несколько моделей», а задачу удержать в одном слое различия протоколов, семантику ошибок и стратегии ограничения скорости. Стабильность цепочки часто зависит от того, отнеслись ли вы всерьёз к одному коду ошибки, спрятанному в теле ответа.
Автор: Чэнь Цзинхан
Дата публикации: 27 октября 2026 г.