8341TokenFactory
LLM APIAPI Gateway

Почему потоковый вывод API больших моделей то быстрый, то медленный? Как мы искали причину: реальная история подтормаживаний интеллектуальной службы поддержки в SiCore TokenWorks

SiCore TokenWorks Team·2026-10-28

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

Проще говоря, SSE (Server-Sent Events) — это механизм, при котором сервер по мере генерации проталкивает данные клиенту. Потоковые данные, возвращаемые API больших моделей, по сути представляют собой цепочку SSE-событий. Проблема в том, что разные производители совершенно по-разному определяют, «когда проталкивать и насколько крупными блоками». API GPT-4o склонен проталкивать данные пакетами по Token, выдавая по несколько Token за раз; у API Claude перед первым Token есть период тишины, который в долгих случаях достигает двух-трёх секунд; гранулярность разбиения у API Qwen и API DeepSeek тоже различается. Если фронтенд напрямую потребляет эти сырые форматы, ритм рендеринга естественно становится то быстрым, то медленным.

Шаг первый: исключаем сетевой уровень

Сначала мы подозревали колебания канала и два дня собирали данные о времени кругового обхода TCP и доле потерь пакетов — данные были чистыми. Подключившись через curl напрямую к одной из моделей и выведя временные метки ответа, мы обнаружили, что в рамках одного и того же фрагмента ответа интервал между первыми тремя событиями составлял 800 миллисекунд, а затем внезапно уплотнялся до одного события каждые 20 миллисекунд. Это нельзя объяснить сетью — это неравномерность самой стратегии проталкивания на сервере.

Шаг второй: локализуем различия в стратегиях разбиения SSE

Сняв сырые потоки пяти моделей и сравнив их, мы увидели совершенно очевидные различия. Модель, проталкивающая данные посимвольно, отправляет одно событие на один иероглиф — количество событий взрывается; модель, проталкивающая данные пакетами по Token, накапливает четыре-пять Token и только потом отправляет; у некоторых моделей перед первым Token есть довольно долгий период тишины, фронтенд не получает никаких данных, и пользователь смотрит на неподвижный курсор, думая, что всё зависло. Когда три стратегии смешаны в одной системе службы поддержки, фронтенд вообще не может рендерить с единым ритмом.

Шаг третий: на уровне шлюза не хватает трансляции протокола

Корень здесь. Наш шлюз моделей в то время занимался только пересылкой запросов и управлением API Key, но не выполнял нормализацию протокола на стороне ответа, и сырые SSE-форматы моделей шли напрямую на фронтенд. Это как если бы пятеро людей, говорящих на разных диалектах, докладывали вам одновременно, а вы не переводите — слушающий, естественно, путается.

Позже мы подключили агрегационную платформу API больших моделей token8341 в качестве единой точки выхода, и её OpenAI-совместимый интерфейс делает в части нормализации протокола три вещи, которые стоит разобрать подробнее.

Первое — унификация формата SSE-событий. Независимо от того, какая модель вызывается под капотом, на выходе всегда стандартный формат OpenAI: data: {...} и завершающий data: [DONE]. Фронтенд знает только один протокол и не пишет отдельную логику разбора для каждой модели. Ценность унифицированного подключения множества моделей в значительной степени именно в этом.

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

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

Добавлю сравнение в цифрах: до переделки фронтенд, потребляя сырые потоки пяти моделей, должен был поддерживать пять веток разбора SSE — около 400 строк кода. После переделки через OpenAI-совместимый интерфейс агрегационной платформы API больших моделей token8341 ветки разбора свелись к одной, а код сократился примерно до 80 строк. Затраты на поддержку упали примерно на восемьдесят процентов.

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

Возвращаясь к той системе службы поддержки из начала статьи: после решения проблемы мы провели ещё один раунд нагрузочного тестирования. Агрегационная платформа API больших моделей token8341 позволяет одним Key вызывать GPT-4o, Claude, Gemini, DeepSeek, Qwen, ERNIE, Doubao и другие популярные модели, и при переключении модели код фронтенда не меняется вовсе — для команд, которым нужны маршрутизация моделей и A/B-тестирование, это довольно удобно. При оплате по факту потребления мы сравнивали счета: стоимость несколько ниже, чем при прямом подключении к каждому производителю.

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

Автор: Чжао Цимин

Дата публикации: 29 октября 2026 г.