К содержанию
Выпуск №70 · 17 августа 2026 / Новости

Realtime-агентам нужен балансировщик, который считает сессии, а не запросы

Голосовой агент занимает воркер не на время одного вызова, а на всю жизнь разговора. Если маршрутизация смотрит только на QPS и CPU, сервис может выглядеть свободным ровно до момента, когда пользователи заговорят одновременно.

Редакция 17 августа 2026 г., 18:26 MSK

В Telegram
Вывеска Google у офиса компании
Иллюстрация: hegai.media

Realtime-агента нельзя масштабировать как обычный API: единицей нагрузки становится не запрос, а живая сессия со своим состоянием и уже обещанными ей ресурсами. Поэтому до выхода в продакшен команде нужно отдельно спроектировать привязку сессий к воркерам, учёт их жизненного цикла и восстановление после сбоя. Обычный балансировщик этого контекста не видит.

Почему привычные метрики начинают врать

В Google Developers Blog описали архитектуру session-aware load balancing для realtime AI. Разница с обычным API фундаментальная. Вместо короткого цикла «запрос, обработка, ответ» сервер держит постоянный двусторонний поток: аудиофрагменты, частичные транскрипты, ответы модели и синтезированную речь.

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

На таком контуре QPS перестаёт быть достаточной мерой занятости. Google приводит простой пример: один backend обрабатывает 100 запросов по 50 миллисекунд, другой принимает пять запросов, каждый из которых превращается в 20-минутную сессию. По частоте входящих запросов второй выглядит почти пустым, хотя уже взял на себя более тяжёлую и долгую работу.

CPU тоже показывает только текущий момент. Воркеры могут держать 20 молчащих голосовых сессий и выглядеть недогруженными. Но если все пользователи заговорят одновременно, нагрузка резко вырастет. Число активных сессий в этой модели показывает не текущую работу, а обязательства, которые backend уже принял.

Именно поэтому round-robin здесь опасен не сам по себе, а своей слепотой. Он способен равномерно раздать новые подключения и всё равно создать перекос: пять долгих разговоров не равны пяти коротким обращениям, а тихая сессия не равна свободной мощности.

Сессию придётся сделать частью маршрутизации

Google предлагает считать активные сессии на уровне самого приложения, в точках начала и завершения streaming lifecycle. Сетевой слой видит соединение, но не понимает, разговаривает ли пользователь, молча слушает, уже отключился или оставил после себя retry либо health check. Только backend знает, когда сессия действительно активна, завершена, отменена или упала.

Для команды это означает важный архитектурный сдвиг. Привязка сессии и её статус не могут существовать лишь как побочный эффект открытого WebSocket или gRPC-потока. Они становятся управляющим сигналом для маршрутизации. Где именно хранить эту информацию, Google в опубликованном разборе не предписывает, но граница ответственности ясна: источник истины должен опираться на application-level lifecycle, а балансировщик должен получать от backend согласованный снимок.

Здесь особенно неприятны «призрачные» сессии. Если счётчик не уменьшился после завершения разговора, воркер будет выглядеть занятым дольше, чем нужно. Если уменьшился дважды, маршрутизация увидит несуществующую свободную ёмкость и направит туда лишний трафик. Timeout, отмена и разрыв соединения могут сработать одновременно, поэтому cleanup должен быть идемпотентным по смыслу, даже если конкретную реализацию команда выберет сама.

Отдельная задача, которую балансировщик не решит, это потеря воркера. Пока аудиобуферы, контекст и активные tool calls живут в памяти runtime, исчезновение процесса означает исчезновение этого состояния. Значит, до запуска нужно явно определить, какие части разговора можно восстановить, откуда их поднимать и что услышит пользователь во время переподключения. Иначе «поддержка failover» останется красивым названием для нового пустого диалога.

Считать нужно и обещанную, и текущую нагрузку

Просто заменить CPU на число сессий тоже не получится. Сессии имеют разную стоимость, поэтому Google предлагает гибридную модель: utilization показывает текущее давление на CPU и память, а active sessions отражают будущую нагрузку, которую сервер уже обязался выдержать.

Один из описанных подходов переводит число сессий в условную скорость, понятную балансировщику. Например, 90 активных сессий за десятисекундное окно можно представить как девять «условных QPS» и объединить это давление с традиционными метриками. Это не универсальная формула мощности, а способ заставить routing layer учитывать долгие обязательства наряду с мгновенной загрузкой.

Практический вывод для команд в России простой: нагрузочный тест realtime-агента должен проверять не только среднюю задержку и пиковый QPS. Нужны длинные соединения, периоды молчания, одновременное начало речи, перебивания, отмены, обрывы и падение воркера с активными разговорами.

Главный маркер перед запуском: совпадает ли число сессий, которое считает приложение, с реальным числом живых разговоров после серии timeout, cancel и disconnect. Если счётчик расходится или CPU резко взлетает при одновременном выходе молчащих пользователей в речь, обычная балансировка уже не справляется. Продакшен лишь сделает эту ошибку дороже.

Как процитировать

«Realtime-агентам нужен балансировщик, который считает сессии, а не запросы». hegai.media, 17 августа 2026 г.. https://hegai.media/novosti/realtime-agentam-nuzhen-balansirovschik-kotoryy-schitaet-sessii-a-ne-z--610f817a-a906-4df4-8711-17f4fb3e4793

так материал выглядит в мессенджере