Разработка бэкенда для чат-ботов столкнулась с проблемой смены парадигмы: от синхронных диалогов перешли к фоновым агентам, работающим параллельно с пользователем. При таких переходам старые протоколы не справляются, и многие советуют использовать Server-Sent Events (SSE) с заголовком Last-Event-ID для создания устойчивого потока. Да, это реально сделать, но автор статьи считает, что это отнюдь не просто.
Давайте разберем три главных требования: возобновляемые потоки, отмены и работу на множестве устройств. Возобновляемость решается через уникальные идентификаторы событий. Если клиент сбросит страницу, он сможет запросить последнее полученное событие и продолжить. Однако при архитектуре с бессостоятельными серверными репликами, где данные лежат в базе, приходится сохранять каждое отдельное событие токена. Это создает огромную нагрузку на базу данных: пишутся тысячи лишних записей с метаданными для каждого токен-дельты, хотя пользователь увидит только финальный текст. Как только поток закончится, эти промежуточные данные станут мусором, и их придется удалять, чтобы заменить полной реакцией.
Отмена запроса также усложняется. Раньше потеря соединения означала, что сервер мог смело прервать вычисления. Теперь, ожидая возможного возобновления, сервер не может просто так закрыть процесс. Нужно вводить отдельный эндпоинт для записи маркера отмены в общую базу данных, чтобы любой сервер мог его проверить и остановить LLM. Это ещё больше замедляет систему и повышает затраты.
Работа на нескольких устройствах вызывает ещё большие трудности. Хотя токены можно доставлять из БД на разные клиенты, как понять, что появилось новое сообщение, если не обновлять страницу вручную? Использование долгого опроса (long-polling) увеличивает задержки или перегружает сервер. Оставаться на протоколе HTTP — значит жертвовать производительностью ради костылей.
В заключение автор, работающий в компании Ably, предлагает свой подход. Он строит специализированный транспорт на основе паттерна pub/sub. Канал существует независимо от подключения клиента, поэтому поток не прерывается при разрыве связи. Серверы автоматически доставляют пропущенные токены, объединяют дельты в полные сообщения для оптимизации и маршрутизируют запросы на отмену без обращения к базе данных. SSE по HTTP — это не просто «легко», это дорого и неудобно для асинхронных агентов. Лучше использовать транспорт, который решает эти проблемы сразу.