РУКОВОДСТВО · ОБНОВЛЕНО 2026-10-26
Ответ LLM приходит целиком: как проверить буферизацию SSE в nginx
Пошаговая проверка транспорта, когда сервер выдаёт части ответа, а браузер показывает их одним блоком.
Если потоковый ответ нейросети появляется целиком, сравните время прихода частей на каждом участке: от модели до приложения, через reverse proxy и в браузере. Признак stream в запросе не доказывает, что все промежуточные слои передают данные сразу. В nginx на это влияет буферизация проксируемого ответа, но похожее поведение может создать и код приложения, который сначала полностью читает тело. Меняйте только подтверждённую причину на нужном маршруте и проверяйте результат повторно.
1. Сравните прямой и внешний путь
Подготовьте тестовый ответ с несколькими событиями и известными паузами. Такой стенд не требует платной генерации. Проверьте прямое подключение к приложению и тот же путь через прокси. Для каждого события фиксируйте время отправки и получения. Если напрямую события приходят порциями, а снаружи собираются вместе, исследуйте промежуточные слои. Если уже приложение отдаёт весь результат сразу, изменение nginx не исправит чтение upstream в памяти до завершения.
2. Проверьте маршрут проксирования
Найдите фактический location, который обслуживает поток, включая вложенные правила и внешние балансировщики. Документация nginx описывает proxy_buffering: при отключении полученные данные передаются клиенту по мере чтения. Возможен также заголовок X-Accel-Buffering от приложения, если обработка не запрещена настройками. Не применяйте широкую правку ко всему сайту только из-за одного SSE endpoint. Сохраните текущую конфигурацию, проверьте синтаксис и используйте штатную процедуру выпуска вашего проекта.
3. Проверьте клиент и завершение
В браузере читайте поток постепенно, а не через метод, ожидающий полное тело. Отделите накопление сетевых байтов от обновления интерфейса: слишком редкий рендер тоже выглядит как буферизация. Корректно собирайте события, которые могут разделяться между порциями транспорта. Заключительное событие и закрытие соединения обрабатывайте по протоколу конкретного API. Не считайте паузу между фрагментами ошибкой без проверки сроков ожидания и фактического состояния соединения.
4. Повторите проверку с реалистичными условиями
Сравните короткий и длинный ответ, медленного клиента и несколько одновременных соединений. Убедитесь, что ранняя ошибка сервера отображается понятно и не превращается в вечное ожидание. Проверьте закрытие вкладки и повторное подключение по правилам приложения. Фиксируйте время первого события и полного завершения отдельно. Успешный прямой запрос не доказывает исправление внешнего пути через CDN или балансировщик; тестируйте именно адрес, которым пользуется клиент.
Частые вопросы
Нужно ли просто поставить proxy_buffering off?
Только если проверка показала буферизацию на этом участке. Сначала убедитесь, что приложение и клиент действительно обрабатывают поток по частям.
Отключение буфера увеличивает лимит ожидания?
Нет. Таймауты соединения и ожидания чтения задаются отдельно. Не смешивайте задержку первой порции с завершением по сроку.
Можно ли проверить проблему без запроса к модели?
Да. Используйте локальный тестовый endpoint, который отправляет события с известными интервалами. Это проверяет транспорт, а не качество модели.
Почему текст в интерфейсе всё равно появляется редко?
Причиной может быть накопление данных в клиентском коде или обновление экрана большими порциями. Сравните сетевые отметки и время рендера.