- Дата публикации
Как собрать продакшн-голосового ассистента за вечер: Stream Vision Agents и Amazon Nova 2 Sonic
Что нового
Stream и AWS предлагают связку из трёх компонентов для реальных голосовых ассистентов, которые работают в браузере и на мобильных устройствах в режиме реального времени:
-
Amazon Nova 2 Sonic через Amazon Bedrock
- Фундаментальная speech‑to‑speech‑модель.
- Принимает аудио и отдаёт аудио — без отдельного STT и TTS.
- Поддерживает двунаправленный стриминг: модель одновременно слушает и отвечает.
- Встроенное определение границ реплик (turn detection).
- Встроенный function calling: модель может вызывать ваши Python‑функции (доступ к БД, API, CRM и т.д.) прямо в ходе разговора.
- Обработка контекста по ходу сессии, в том числе с учётом результатов вызванных функций.
-
Stream Vision Agents (open source, Python)
- Фреймворк для реальных голосовых и видео‑агентов.
- Плагинная архитектура с 25+ интеграциями: Amazon Bedrock, Deepgram, Cartesia, Amazon Polly и другие.
- Готовые клиентские SDK: React, iOS, Android, Flutter, React Native.
- Декораторы для регистрации функций, которые может вызывать модель (tool calling).
- Встроенная поддержка Voice Activity Detection (Silero VAD), автоматического переподключения и управления жизненным циклом сессий.
- Можно использовать как с реальным времени (Nova 2 Sonic), так и с обычными LLM (например, Claude через Bedrock) с отдельными STT/TTS.
-
Глобальная edge‑сеть Stream
- SFU‑инфраструктура (Selective Forwarding Unit) для WebRTC‑звонков.
- Типичные показатели:
- время входа в звонок — менее 500 мс,
- аудио‑латентность — менее 30 мс на транспортном уровне.
- Передача аудио по RTP поверх UDP для предсказуемой задержки и отсутствия head‑of‑line blocking.
Ключевой практический результат: в примере из поста полноценный голосовой ассистент на Nova 2 Sonic поднимается менее чем в 30 строках Python‑кода, а Stream даёт 333 000 participant‑минут в месяц для Audio API без доплаты.
Как это работает
Архитектура на высоком уровне
Роли распределены жёстко:
-
Stream отвечает за:
- WebRTC, SFU, TURN/STUN, сигналинг;
- доставку аудио между браузером/мобилкой и бэкендом агента;
- edge‑узлы, которые принимают RTP и пересылают его дальше.
-
Vision Agents живёт в AWS и отвечает за:
- приём аудио от Stream как «ещё один участник звонка»;
- декодирование в PCM и стриминг в Amazon Bedrock;
- отправку ответного аудио обратно в звонок;
- VAD, обработку барж‑ина (когда пользователь перебивает ассистента), вызовы функций, управление контекстом.
-
Amazon Nova 2 Sonic в Amazon Bedrock:
- получает PCM‑аудио по realtime‑API;
- определяет границы реплик, распознаёт речь, понимает запрос, формирует ответ и синтезирует голос;
- при необходимости инициирует toolUse — запрос на вызов вашей функции.
Поток аудио end‑to‑end
-
Пользователь подключается из веба или мобильного приложения.
Клиентский SDK Stream запрашивает микрофон (и при необходимости камеру) и присоединяется к звонку с включённым AI‑участником. -
Аудио уходит в ближайший SFU Stream:
- WebRTC‑соединение устанавливается с edge‑узлом в ближайшем регионе.
- Аудио идёт как RTP по UDP — это даёт низкую задержку и устойчивость к потере пакетов.
- SFU занимается NAT‑traversal, оценкой пропускной способности, simulcast.
-
SFU пересылает трек в Vision Agent:
- Для SFU агент — просто ещё один peer в звонке.
- Vision Agent worker держит собственный PeerConnection для этой сессии.
-
Vision Agent декодирует аудио и стримит в Bedrock:
- Аудио декодируется в сырой PCM.
- Плагин
aws.Realtimeоткрывает realtime‑сессию к Amazon Nova 2 Sonic. - PCM‑фреймы примерно по 32 мс отправляются как
audioInput‑события.
-
Nova 2 Sonic обрабатывает разговор:
- Сессия стартует с
sessionStart(maxTokens, temperature, top‑p, turn detection). - Затем идёт
promptStart: формат аудио (24 kHz PCM), выбор голоса, описание доступных инструментов. - Системные инструкции приходят как блок с ролью SYSTEM.
- По мере прихода аудио Nova 2 Sonic:
- определяет, когда пользователь закончил фразу;
- при необходимости вызывает функции (toolUse);
- продолжает разговор с учётом контекста и результатов функций;
- стримит ответ как
audioOutput.
- Сессия стартует с
-
Vision Agent пакует ответ обратно в RTP:
- Аудиофреймы от Nova 2 Sonic режутся на куски, упаковываются в RTP.
- Таймстемпы растут монотонно, чтобы не было разрывов и дрейфа.
- Пакеты уходят обратно через SFU в браузер/мобилку.
-
Клиент воспроизводит звук:
- WebRTC‑стек декодирует аудио и проигрывает с задержкой до 500 мс от голоса пользователя до ответа ассистента.
VAD, барж‑ин и эхо
- Vision Agents использует Silero VAD для детекции начала и конца речи и для барж‑ина.
- Эхо‑подавление в браузере снижает риск, что голос ассистента снова сработает как входной сигнал.
- Когда пользователь перебивает ассистента, клиент отправляет сигнал по
RTCDataChannel.
Worker останавливает стриминг ответа Nova 2 Sonic и сбрасывает локальный буфер, чтобы не доигрывать «старую» реплику.
Как устроен realtime‑API Amazon Nova 2 Sonic
Плагин aws.Realtime в Vision Agents оборачивает довольно сложный событийный протокол. В упрощённом виде поток выглядит так:
sessionStart— конфигурация инференса:
def _create_session_start_event(self) -> Dict[str, Any]:
return {
"event": {
"sessionStart": {
"inferenceConfiguration": {
"maxTokens": 1024,
"topP": 0.9,
"temperature": 0.7,
}
},
"turnDetectionConfiguration": {
"endpointingSensitivity": "MEDIUM"
},
}
}
promptStart— формат аудио, голос, список инструментов.- System‑инструкции — текстовый блок с ролью SYSTEM.
audioInput— поток PCM‑фреймов ~32 мс.audioOutput— поток ответных аудиофреймов.promptEndиsessionEnd— корректное завершение сессии.
Любой контент идёт в паттерне contentStart → payload → contentEnd. Это позволяет модели корректно вести контекст и чередовать речь, текст и tool‑результаты.
Function calling: как Nova 2 Sonic вызывает ваши функции
- Модель решает, что ей нужен внешний инструмент, и отправляет
toolUseс именем функции и аргументами. - Плагин Vision Agents перехватывает это событие, десериализует аргументы и вызывает зарегистрированную Python‑функцию.
- Результат отправляется обратно в Nova 2 Sonic как
toolResultв том же паттернеcontentStart → toolResult → contentEnd. - Модель использует результат в следующей реплике и продолжает разговор.
Это работает и для простых вычислений, и для сложных цепочек: запрос к БД, проверка инвентаря, создание заказа — всё в рамках одной голосовой сессии.
Что это значит для вас
Где это реально помогает
-
Голосовые интерфейсы там, где экран неудобен или опасен
Примеры сценариев:- вождение;
- выездное обслуживание и ремонт;
- логистика и склад;
- медицина и госпитали;
- любые «грязные» или шумные производства, где руки заняты.
Что даёт связка Vision Agents + Nova 2 Sonic:
- разговор в реальном времени без явных пауз между репликами;
- возможность перебить ассистента и скорректировать запрос;
- сохранение контекста: не нужно повторять адрес, номер заказа или диагноз каждый раз;
- интеграция с бэкендом через function calling: ассистент не просто отвечает, а меняет состояние систем (обновляет статус задачи, логирует заметки, вызывает человека).
-
Масштабируемый inbound‑саппорт по телефону
Архитектура SFU + Nova 2 Sonic хорошо подходит для контакт‑центров:- низкая задержка — разговор не ощущается «роботизированным» только из‑за лагов;
- встроенный function calling — ассистент может:
- проверять баланс или статус заказа;
- создавать тикеты;
- переключать на живого оператора, если сценарий вышел за рамки;
- Vision Agents берёт на себя reconnection, обработку сбоев и таймаутов.
-
Внутренние голосовые ассистенты и workflow‑автоматизация
- Быстрый доступ к документации, базе знаний, аналитике.
- Голосом запускать пайплайны: «создай отчёт за вчера», «запусти тесты», «создай задачу в issue‑трекере».
- Возможность строить кастомные пайплайны: отдельный STT, LLM и TTS, если Nova 2 Sonic вам не подходит по цене или возможностям.
-
Мультиязычные ассистенты
- Nova 2 Sonic поддерживает несколько языков (в посте перечисление языков не приводится, но архитектура построена под мультиязычность).
- Vision Agents не ограничивает вас одним провайдером: можно комбинировать Amazon Bedrock, Deepgram, Cartesia, Amazon Polly и другие, чтобы собрать нужный стек.
Кому это особенно полезно
-
Продуктовым и платформенным командам, которые:
- не хотят сами собирать WebRTC, SFU и reconnection‑логику;
- хотят управлять логикой ассистента в своём AWS‑аккаунте;
- готовы писать минимальное количество Python‑кода.
-
Стартапам и R&D‑командам, которым важно быстро собрать прототип голосового ассистента и протестировать сценарии на реальных пользователях.
-
Enterprise‑командам, которым критично, чтобы данные и бизнес‑логика оставались в их AWS‑аккаунте, а провайдер реального времени отвечал только за медиа‑транспорт.
Где это может не подойти
- Если у вас нет доступа к Amazon Bedrock или AWS Nova 2 Sonic в вашем регионе.
- Если юридические или комплаенс‑ограничения не позволяют использовать внешнюю edge‑сеть (Stream) для медиа‑трафика.
- Если вам нужен полностью on‑prem стек без внешних SaaS‑компонентов.
- Если проект чувствителен к затратам на inference: Nova 2 Sonic тарифицируется по вызовам Bedrock, и это нужно учитывать при большом трафике.
Доступность из России
Amazon Bedrock и Stream официально ориентируются на глобальный рынок, но доступ к AWS и связанным сервисам из России может требовать VPN и может нарушать локальные ограничения. Перед использованием такой архитектуры для продакшн‑систем стоит отдельно проверить юридические и инфраструктурные риски.
Место на рынке
С точки зрения архитектуры это не «ещё один бот на LLM», а связка из:
- специализированной speech‑to‑speech‑модели (Amazon Nova 2 Sonic);
- продакшн‑готовой RTC‑инфраструктуры (Stream SFU);
- open source‑фреймворка для glue‑кода (Vision Agents).
В оригинальном материале нет прямых сравнений с GPT‑4o, Gemini Live, Claude Voice или другими голосовыми стеками, поэтому можно говорить только о том, что явно описано:
-
По латентности транспорта:
- Stream заявляет <500 мс end‑to‑end задержки разговора и <30 мс аудио‑латентности на своём edge‑уровне.
- Это укладывается в требования к естественному диалогу и соответствует уровню других крупных провайдеров RTC.
-
По архитектуре:
- Nova 2 Sonic не требует отдельного STT и TTS — это упрощает интеграцию и снижает количество точек отказа.
- Для сравнения: многие существующие решения до сих пор собирают пайплайн из трёх сервисов (STT → LLM → TTS), что усложняет управление задержкой и ошибками.
-
По инструментам для разработчиков:
- Vision Agents даёт Python‑фреймворк с плагинами для Bedrock, Deepgram, Cartesia, Amazon Polly и других.
- Есть готовые SDK для популярных клиентских платформ, что сокращает время до первого прототипа.
Если вам нужен именно «комбайн» для голосовых ассистентов с готовой RTC‑инфраструктурой и функциями, которые модель вызывает в реальном времени, эта связка закрывает большую часть задач без необходимости собирать низкоуровневый стек самостоятельно.
Установка
Ниже — шаги из оригинального поста, полностью и без сокращений.
Предварительные требования
Перед стартом нужно:
-
Настроенные AWS‑креденшалы через переменные окружения, IAM‑роль или профиль AWS CLI.
- Для продакшна лучше использовать IAM‑роли, привязанные к compute‑ресурсам.
- Для локальной разработки — AWS CLI профили (
aws configure) или AWS SSO. - Не коммить
.envс ключами в Git.
-
Аккаунт Stream с Audio API key и secret.
- Ожидаемый лимит — 333 000 participant‑минут в месяц без доплаты.
-
Python 3.12+.
-
Пакетный менеджер uv:
pip install uv
- Установленный Vision Agents:
uv add vision-agents
Шаг 1. Создаём проект и ставим Vision Agents с AWS‑плагином
mkdir voice-agent
cd voice-agent
uv init
uv add "vision-agents[getstream,aws]" python-dotenv
Экстра vision-agents[aws] подтянет Amazon Bedrock‑плагин и зависимости: boto3, aws-sdk-bedrock-runtime и Silero VAD.
Шаг 2. Настраиваем переменные окружения
Создайте файл .env в корне проекта. Рекомендуемый подход — указывать AWS_PROFILE, а не прямые ключи.
# Stream API credentials
STREAM_API_KEY=test/geststream/api_key
STREAM_API_SECRET=test/getstream/api_secret
# AWS credentials
AWS_PROFILE=your_aws_profile_name
AWS_REGION=us-east-1
Vision Agents автоматически подхватывает эти переменные при старте, их не нужно передавать вручную в каждый клиент.
Как запустить
Шаг 3. Первый голосовой ассистент на Nova 2 Sonic
Создайте main.py со следующим содержимым:
import asyncio
from dotenv import load_dotenv
from vision_agents.core import Agent, User, Runner
from vision_agents.core.agents import AgentLauncher
from vision_agents.plugins import aws, getstream
load_dotenv()
async def create_agent(**kwargs) -> Agent:
agent = Agent(
edge=getstream.Edge(),
agent_user=User(name="Helpful Assistant", id="agent"),
instructions="You are a helpful voice assistant. Be concise and friendly.",
llm=aws.Realtime(
model="amazon.nova-2-sonic-v1:0",
region_name="us-east-1",
voice_id="matthew",
),
)
return agent
async def join_call(agent: Agent, call_type: str, call_id: str, **kwargs) -> None:
call = await agent.create_call(call_type, call_id)
async with agent.join(call):
await asyncio.sleep(2)
await agent.llm.simple_response(
text="Greet the user warmly and ask how you can help."
)
await agent.finish()
# Run until the call ends
if __name__ == "__main__":
Runner(AgentLauncher(create_agent=create_agent, join_call=join_call)).cli()
Шаг 4. Запуск ассистента
uv run main.py run
На этом этапе у вас есть рабочий голосовой ассистент в реальном времени на Amazon Nova 2 Sonic, доступный из клиента Stream. Всё это — меньше чем в 30 строках кода.
Function calling: примеры кода
Ниже — пример, как добавить функции, которые Nova 2 Sonic может вызывать в ходе разговора.
import asyncio
from dotenv import load_dotenv
from typing import Dict, Any
from vision_agents.core import Agent, User, Runner
from vision_agents.core.agents import AgentLauncher
from vision_agents.plugins import aws, getstream
load_dotenv()
async def create_agent(**kwargs) -> Agent:
agent = Agent(
edge=getstream.Edge(),
agent_user=User(name="Weather Assistant", id="agent"),
instructions="""You are a helpful weather assistant. When users ask about weather, use the get_weather function to fetch current conditions. You can also help with simple calculations.""",
llm=aws.Realtime(
model="amazon.nova-2-sonic-v1:0",
region_name="us-east-1",
),
)
@agent.llm.register_function(
name="get_weather", description="Get the current weather for a given city"
)
async def get_weather(location: str) -> Dict[str, Any]:
# In production, call a real weather API
return {
"city": location,
"temperature": 72,
"condition": "Sunny",
"humidity": "45%",
}
@agent.llm.register_function(
name="calculate", description="Perform a mathematical calculation"
)
def calculate(operation: str, a: float, b: float) -> dict:
operations = {
"add": lambda x, y: x + y,
"subtract": lambda x, y: x - y,
"multiply": lambda x, y: x * y,
"divide": lambda x, y: x / y if y != 0 else None,
}
result = operations.get(operation, lambda x, y: None)(a, b)
return {"operation": operation, "a": a, "b": b, "result": result}
return agent
async def join_call(agent: Agent, call_type: str, call_id: str, **kwargs) -> None:
await agent.create_user()
call = await agent.create_call(call_type, call_id)
async with agent.join(call):
await asyncio.sleep(2)
await agent.llm.simple_response(
text="Greet the user and let them know you can check the weather."
)
await agent.finish()
if __name__ == "__main__":
Runner(AgentLauncher(create_agent=create_agent, join_call=join_call)).cli()
Как это работает в рантайме
- Nova 2 Sonic решает, что нужно вызвать
get_weatherилиcalculate, и отправляетtoolUseс аргументами. - Vision Agents вызывает соответствующую Python‑функцию.
- Результат возвращается в модель как
toolResult. - Модель озвучивает ответ уже с учётом полученных данных.
Кастомные пайплайны: отдельный LLM, STT и TTS
Если Nova 2 Sonic по каким‑то причинам не подходит, AWS‑плагин Vision Agents позволяет собрать собственный конвейер.
Пример: LLM через Bedrock + Deepgram STT + Cartesia TTS
from vision_agents.core import Agent, User
from vision_agents.plugins import aws, getstream, cartesia, deepgram, smart_turn
agent = Agent(
edge=getstream.Edge(),
agent_user=User(name="Custom Pipeline Agent"),
instructions="Be helpful and concise.",
llm=aws.LLM(
model="anthropic.claude-3-haiku-20240307-v1:0",
region_name="us-east-1"
),
tts=cartesia.TTS(),
stt=deepgram.STT(),
turn_detection=smart_turn.TurnDetection(
buffer_duration=2.0,
confidence_threshold=0.5,
),
)
aws.LLM поддерживает:
- стриминг ответов через
converse_stream(); - хранение истории диалога;
- vision‑входы для моделей вроде Claude;
- мультирундовый tool calling — до трёх раундов функций на один запрос.
Text‑to‑speech через Amazon Polly
Если вы используете не realtime‑LLM, а обычный текстовый, можно подключить Amazon Polly для TTS:
from vision_agents.plugins import aws
tts = aws.TTS(
region_name="us-east-1",
voice_id="Joanna",
engine="neural", # 'standard' or 'neural'
language_code="en-US"
)
Polly даёт:
- стандартный и neural‑движки;
- поддержку SSML для тонкой настройки речи;
- множество языков и голосов.
Neural‑движок звучит более естественно и хорошо подходит для кастомных пайплайнов STT → LLM → TTS на инфраструктуре AWS.
Управление ресурсами и стоимость
Для остановки Stream‑звонка и завершения процессов Vision Agent:
uv run main.py stop
Amazon Bedrock тарифицирует все вызовы к Amazon Nova 2 Sonic. Активные сессии продолжают стоить денег, пока вы их явно не завершите. Команда остановки помогает избежать лишних расходов.
Практические сценарии использования
-
No‑screen / low‑attention интерфейсы
- Водители: запрос следующей точки маршрута, отметка выполненной доставки, звонок в диспетчерскую — всё голосом.
- Полевые инженеры: запрос инструкции, логирование выполненных шагов, создание тикетов.
- Медперсонал: голосовое внесение заметок, запрос истории пациента, вызов коллег.
-
Контакт‑центры и горячие линии
- Обработка типовых запросов без участия оператора.
- Автоматическое заполнение CRM по итогам разговора.
- Интеллектуальная маршрутизация к нужному отделу по голосовому описанию проблемы.
-
Внутренние ассистенты для сотрудников
- Быстрый доступ к базе знаний и документации.
- Голосовой интерфейс к BI‑системам и отчётам.
- Запуск внутренних пайплайнов и автоматизация рутинных задач.
-
Обучение и онбординг
- Голосовые тренажёры для новых сотрудников.
- Сценарии «разговор с клиентом» с автоматической оценкой ответов.
- Интерактивные FAQ с живым голосом.
Эта связка особенно интересна тем, кто не хочет тратить месяцы на собственный WebRTC‑стек и при этом не готов мириться с ограничениями «чёрных ящиков» вроде простых телефонных ботов без доступа к коду. Здесь вы управляете логикой в своём AWS‑аккаунте, а Stream и Vision Agents берут на себя тяжёлую инфраструктуру для реального времени.