Дата публикации
ai_products

Voice Live научился WebRTC: живой голос, аватары и функции в одном API

Что нового

Microsoft расширила Voice Live API (версия 2026-01-01-preview) и добавила ключевую вещь — поддержку WebRTC для аватаров. Теперь поверх WebSocket-подключения к Voice Live можно поднимать отдельный WebRTC‑канал для видео, анимации и мимики персонажа.

Если коротко, что появляется в этой превью-версии:

  1. WebRTC‑аватары

    • Новый клиентский и серверный событийный протокол для WebRTC‑сессий:
      • session.avatar.connect (клиент → сервер) с SDP‑оффером клиента в base64.
      • session.avatar.connecting (сервер → клиент) с SDP‑ответом сервера.
    • Поддержка видеопотока с настройкой разрешения и битрейта, например:
      • Разрешение 1920×1080.
      • Битрейт 2 000 000 бит/с.
    • Анимационные данные: blendshapes, viseme‑ID и временные метки аудио.
  2. Расширенный real‑time голосовой стек
    Voice Live по-прежнему работает поверх WebSocket и JSON‑событий, но теперь чётко структурирован под живую диалоговую логику с аватарами:

    • Поддерживаемые голосовые типы:
      • Голоса OpenAI (type: "openai", пример — "alloy").
      • Azure Custom Voice (type: "azure-custom") с endpoint_id, стилями и температурой.
      • Azure standard и personal voices (упомянуты как классы голосов).
    • Аудио‑кодеки и форматы:
      • PCM16 (в том числе с частотой дискретизации 24 000 Гц).
      • G.711 (из описания про кодеки).
    • Встроенная обработка звука:
      • Шумоподавление azure_deep_noise_suppression.
      • Эхоподавление (указано как часть возможностей).
  3. Интеллектуальное определение границ реплики (VAD)

    • Несколько вариантов Voice Activity Detection:
      • Azure Semantic VAD (type: "azure_semantic_vad") с параметрами:
        • threshold: 0.5.
        • prefix_padding_ms: 300.
        • silence_duration_ms: 500.
      • Режим server VAD, когда сервер сам решает, когда коммитить буфер.
    • События для отслеживания речи:
      • input_audio_buffer.speech_started.
      • input_audio_buffer.speech_stopped.
  4. Гибкая работа с аудио‑буфером

    • Клиентские события:
      • input_audio_buffer.append — добавление аудио (до 15 MiB в одном сообщении при отключённом server VAD).
      • input_audio_buffer.commit — фиксация буфера и создание user‑сообщения.
      • input_audio_buffer.clear — очистка буфера.
    • Серверные ответы:
      • input_audio_buffer.committed.
      • input_audio_buffer.cleared.
    • При server VAD клиент может не отправлять commit: сервер сам решает, когда сообщение закончено.
  5. Полный событийный протокол для диалога и мультимодальности
    Voice Live теперь даёт детализированный поток событий для всего цикла общения:

    • Работа с сессией:
      • session.update / session.updated.
      • session.created.
    • Работа с контекстом диалога:
      • conversation.item.create / conversation.item.created.
      • conversation.item.retrieve / conversation.item.retrieved.
      • conversation.item.truncate / conversation.item.truncated.
      • conversation.item.delete / conversation.item.deleted.
      • События транскрипции входящего аудио:
        • conversation.item.input_audio_transcription.delta.
        • conversation.item.input_audio_transcription.completed.
        • conversation.item.input_audio_transcription.failed.
    • Генерация ответа:
      • response.create / response.created / response.done.
      • Потоковый текст: response.text.delta, response.text.done.
      • Потоковое аудио: response.audio.delta, response.audio.done.
      • Потоковые субтитры к аудио: response.audio_transcript.delta, response.audio_transcript.done.
      • Анимация:
        • response.animation_blendshapes.delta / .done.
        • response.animation_viseme.delta / .done.
        • response.audio_timestamp.delta / .done.
  6. Интеграция инструментов и агентов

    • Функции и инструменты:
      • Поток аргументов функции: response.function_call_arguments.delta / .done.
      • Поддержка MCP‑инструментов:
        • mcp_list_tools.in_progress / .completed / .failed.
        • response.mcp_call_arguments.delta / .done.
        • response.mcp_call.in_progress / .completed / .failed.
      • Foundry‑агенты:
        • response.foundry_agent_call_arguments.delta / .done.
        • response.foundry_agent_call.in_progress / .completed / .failed.
    • Новый объект mcp_approval_response в conversation.item.create для ручного одобрения вызовов.
  7. Pre‑generated ответы

    • В response.create можно передать заранее подготовленный ассистентский текст через pre_generated_assistant_message.
    • Сервис сгенерирует только аудио и анимацию для этого текста и добавит сообщение в историю диалога.
  8. Гибкая настройка голосового поведения

    • Параметры в сессии и ответе:
      • temperature (например, 0.7–0.8).
      • max_response_output_tokens (включая "inf").
      • instructions на уровне сессии и конкретного ответа.
      • Настройка голосового стиля, например "style": "cheerful" или "excited".

Цен, лимитов по токенам и скоростных бенчмарков в описании нет. Версия помечена как preview, это важно учитывать для продакшена.


Как это работает

Архитектура: WebSocket + WebRTC

Voice Live API строится вокруг двух каналов:

  1. WebSocket‑соединение

    • Основной управляющий канал.
    • Все команды, статусы и данные (кроме WebRTC‑медиа) идут как JSON‑события.
    • Клиент и сервер обмениваются событиями с полем type, которое определяет действие.
  2. WebRTC‑соединение для аватара

    • Поднимается только если вы используете аватара.
    • Клиент отправляет SDP‑оффер в base64 через событие:
{
  "type": "session.avatar.connect",
  "client_sdp": "<client_sdp>"
}
  • Сервер отвечает событием:
{
  "type": "session.avatar.connecting",
  "server_sdp": "<server_sdp>"
}
  • Дальше медиа (видео, анимация) идёт по WebRTC, а управление — по WebSocket.

Сессия: единая точка конфигурации

Сессию вы настраиваете через session.update. Здесь задаются:

  • Модальности: "modalities": ["text", "audio"] или "audio", "animation" и т.д.
  • Голос:
    • OpenAI:
{
  "type": "session.update",
  "session": {
    "modalities": ["text", "audio"],
    "voice": {
      "type": "openai",
      "name": "alloy"
    },
    "instructions": "You are a helpful assistant. Be concise and friendly.",
    "input_audio_format": "pcm16",
    "output_audio_format": "pcm16",
    "input_audio_sampling_rate": 24000,
    "turn_detection": {
      "type": "azure_semantic_vad",
      "threshold": 0.5,
      "prefix_padding_ms": 300,
      "silence_duration_ms": 500
    },
    "temperature": 0.8,
    "max_response_output_tokens": "inf"
  }
}
  • Azure Custom Voice с шумоподавлением и аватаром:
{
  "type": "session.update",
  "session": {
    "voice": {
      "type": "azure-custom",
      "name": "my-custom-voice",
      "endpoint_id": "12345678-1234-1234-1234-123456789012",
      "temperature": 0.7,
      "style": "cheerful"
    },
    "input_audio_noise_reduction": {
      "type": "azure_deep_noise_suppression"
    },
    "avatar": {
      "character": "lisa",
      "customized": false,
      "video": {
        "resolution": {
          "width": 1920,
          "height": 1080
        },
        "bitrate": 2000000
      }
    }
  }
}
  • Важный момент: модель (model) внутри сессии менять нельзя. Если вы инициализировали сессию с одним движком, переключиться на другой в рамках этой сессии не получится.

Входящее аудио: буфер, VAD и транскрипция

Клиент шлёт аудио по WebSocket через input_audio_buffer.append:

{
  "type": "input_audio_buffer.append",
  "audio": "UklGRiQAAABXQVZFZm10IBAAAAABAAEARKwAAIhYAQACABAAZGF0YQAAAAA="
}

Ключевые детали:

  • audio — base64‑строка в формате, который вы указали в input_audio_format (например, pcm16).
  • При отключённом server VAD вы можете отправлять куски до 15 MiB.
  • Сервер не отвечает отдельным подтверждением на input_audio_buffer.append.

Дальше два режима:

  1. Server VAD включён

    • Сервер сам решает, когда пользователь закончил говорить.
    • Когда нужно — создаёт новый user‑item в диалоге.
    • Вы получаете события input_audio_buffer.speech_started и input_audio_buffer.speech_stopped.
    • input_audio_buffer.commit отправлять не нужно.
  2. Server VAD отключён

    • Вы сами контролируете, где заканчивается реплика.
    • После серии append отправляете:
{
  "type": "input_audio_buffer.commit"
}
  • Сервер отвечает input_audio_buffer.committed и создаёт user‑сообщение.
  • Если буфер пуст, сервер вернёт ошибку.

Очистка буфера:

{
  "type": "input_audio_buffer.clear"
}

Сервер ответит input_audio_buffer.cleared.

Если вы включили input_audio_transcription в настройках сессии, сервер будет:

  • Стримить текст входящего аудио:
    • conversation.item.input_audio_transcription.delta.
    • conversation.item.input_audio_transcription.completed.
  • Или прислать conversation.item.input_audio_transcription.failed при ошибке.

Контекст диалога: conversation.item.*

Voice Live хранит историю общения как массив items. Вы управляете им событиями:

Создание элементов

Простой текстовый запрос пользователя:

{
  "type": "conversation.item.create",
  "previous_item_id": "item_ABC123",
  "item": {
    "id": "item_DEF456",
    "type": "message",
    "role": "user",
    "content": [
      {
        "type": "input_text",
        "text": "Hello, how are you?"
      }
    ]
  }
}

Аудио‑сообщение с транскриптом:

{
  "type": "conversation.item.create",
  "item": {
    "type": "message",
    "role": "user",
    "content": [
      {
        "type": "input_audio",
        "audio": "UklGRiQAAABXQVZFZm10IBAAAAABAAEARKwAAIhYAQACABAAZGF0YQAAAAA=",
        "transcript": "Hello there"
      }
    ]
  }
}

Результат вызова функции:

{
  "type": "conversation.item.create",
  "item": {
    "type": "function_call_output",
    "call_id": "call_123",
    "output": "{\"location\": \"San Francisco\", \"temperature\": \"70\"}"
  }
}

Ответ на запрос одобрения MCP:

{
  "type": "conversation.item.create",
  "item": {
    "type": "mcp_approval_response",
    "approval_request_id": "mcp_approval_req_456",
    "approve": true
  }
}

Сервер в ответ пришлёт conversation.item.created с полным объектом элемента.

Получение, обрезка и удаление

Получить конкретный item (например, чтобы посмотреть очищенное от шума аудио):

{
  "type": "conversation.item.retrieve",
  "item_id": "item_ABC123"
}

Сервер ответит conversation.item.retrieved с полным содержимым, в том числе с аудио и транскриптом.

Обрезка аудио ассистента (например, если пользователь прервал ответ):

{
  "type": "conversation.item.truncate",
  "item_id": "item_ABC123",
  "content_index": 0,
  "audio_end_ms": 5000
}

Сервер вернёт:

{
  "type": "conversation.item.truncated",
  "item_id": "<item_id>",
  "content_index": 0,
  "audio_end_ms": 0
}

Эта операция не только обрезает аудио, но и удаляет текстовый транскрипт после точки обрезки, чтобы в контексте не осталось текста, который пользователь не слышал.

Удаление элемента:

{
  "type": "conversation.item.delete",
  "item_id": "item_ABC123"
}

Сервер ответит conversation.item.deleted.

Генерация ответа: response.*

Чтобы запустить генерацию, отправляете response.create:

{
  "type": "response.create",
  "response": {
    "modalities": ["text", "audio"],
    "instructions": "Be extra helpful and detailed.",
    "voice": {
      "type": "openai",
      "name": "alloy"
    },
    "output_audio_format": "pcm16",
    "temperature": 0.7,
    "max_response_output_tokens": 1000
  }
}

Параметры в response перекрывают настройки сессии только для этого ответа.

Пример с инструментом:

{
  "type": "response.create",
  "response": {
    "modalities": ["text"],
    "tools": [
      {
        "type": "function",
        "name": "get_current_time",
        "description": "Get the current time",
        "parameters": {
          "type": "object",
          "properties": {}
        }
      }
    ],
    "tool_choice": "get_current_time",
    "temperature": 0.3
  }
}

Пример с анимацией для аватара:

{
  "type": "response.create",
  "response": {
    "modalities": ["audio", "animation"],
    "animation": {
      "model_name": "default",
      "outputs": ["blendshapes", "viseme_id"]
    },
    "voice": {
      "type": "azure-custom",
      "name": "my-expressive-voice",
      "endpoint_id": "12345678-1234-1234-1234-123456789012",
      "style": "excited"
    }
  }
}

Пример с заранее подготовленным текстом ассистента:

{
  "type": "response.create",
  "response": {
    "pre_generated_assistant_message": {
      "type": "message",
      "role": "assistant",
      "content": [
        {
          "type": "text",
          "text": "repeat what I say"
        }
      ]
    }
  }
}

В этом случае Voice Live не придумывает текст, а только синтезирует аудио и добавляет сообщение в историю.

Поток ответов идёт через набор событий:

  • Старт: response.created.
  • Набор output‑items: response.output_item.added / response.output_item.done.
  • Части контента: response.content_part.added / response.content_part.done.
  • Текст: response.text.delta / response.text.done.
  • Аудио: response.audio.delta / response.audio.done.
  • Субтитры: response.audio_transcript.delta / .done.
  • Анимация: blendshapes, viseme, timestamps.
  • Завершение: response.done.

Отмена генерации:

{
  "type": "response.cancel"
}

Сервер немедленно прекращает генерацию и поток аудио.

Жизненный цикл сессии

После установления WebSocket‑подключения вы первым делом получаете:

{
  "type": "session.created",
  "session": {
    "id": "sess_ABC123DEF456",
    "object": "realtime.session",
    "model": "gpt-realtime",
    "modalities": ["text", "audio"],
    "instructions": "You are a helpful assistant.",
    "voice": {
      "type": "openai",
      "name": "alloy"
    },
    "input_audio_format": "pcm16",
    "output_audio_format": "pcm16",
    "input_audio_sampling_rate": 24000,
    "turn_detection": {
      "type": "azure_semantic_vad",
      "threshold": 0.5,
      "prefix_padding_ms": 300,
      "silence_duration_ms": 500
    },
    "temperature": 0.8,
    "max_response_output_tokens": "inf"
  }
}

После session.update сервер пришлёт session.updated с обновлёнными полями:

{
  "type": "session.updated",
  "session": {
    "id": "sess_ABC123DEF456",
    "voice": {
      "type": "azure-custom",
      "name": "my-voice",
      "endpoint_id": "12345678-1234-1234-1234-123456789012"
    },
    "temperature": 0.7,
    "avatar": {
      "character": "lisa",
      "customized": false
    }
  }
}

Ошибки и предупреждения приходят событиями error и warning.


Что это значит для вас

Кому это реально пригодится

  1. Разработчики голосовых ассистентов и колл‑центров
    Voice Live даёт полный цикл: приём аудио, VAD, шумоподавление, синтез, управление контекстом.
    Можно строить голосовые ассистенты, которые работают в браузере через WebRTC‑аватар или через нативные клиенты.

    Практически:

    • Подключаете WebSocket к Voice Live.
    • Настраиваете session.update под ваш голос и формат.
    • Стримите микрофон через input_audio_buffer.append.
    • Получаете response.audio.delta и проигрываете.
  2. Создатели цифровых аватаров и виртуальных ведущих
    WebRTC‑поддержка и события анимации (blendshapes, viseme) позволяют синхронизировать лицо и речь.
    Это полезно для:

    • Виртуальных консультантов на сайте.
    • Ведущих в онлайн‑трансляциях.
    • Обучающих интерактивных персонажей.

    Вы можете:

    • Настроить аватара с разрешением 1920×1080 и битрейтом 2 Мбит/с.
    • Получать анимационные данные через response.animation_blendshapes.delta и response.animation_viseme.delta.
    • Синхронизировать их с response.audio_timestamp.delta.
  3. Команды, которые уже сидят в Azure‑экосистеме
    Поддержка Azure Custom Voice и Azure‑шумоподавления делает Voice Live логичным выбором, если у вас уже есть кастомные голоса и инфраструктура в Azure.
    Вы можете переиспользовать существующие endpoint_id и стили голоса.

  4. Разработчики, которым важен полный контроль над диалогом
    Детализированный событийный протокол позволяет:

    • Точно управлять историей (conversation.item.*).
    • Обрезать ответы ассистента до нужного момента.
    • Встраивать свои функции и MCP‑инструменты.
    • Подменять генерацию текста своим, используя pre_generated_assistant_message.

Где Voice Live особенно уместен

  • Браузерные голосовые интерфейсы: WebRTC‑аватары + WebSocket‑управление — естественный стек для фронтенда.
  • Интерактивные презентации и демо‑стенды: можно быстро собрать «говорящую голову» с кастомным голосом и лицом.
  • Обучающие продукты: языковые тренажёры, симуляции собеседований, диалоговые тренеры.

Где лучше не спешить

  1. Жёсткий продакшен с миллионами пользователей
    Версия помечена как preview. Для массовых нагрузок лучше иметь запасной вариант и внимательно следить за изменениями API.

  2. Сценарии, где критична полная офлайн‑работа
    Voice Live — облачный сервис. Для полностью автономных устройств без стабильного интернета он не подойдёт.

  3. Проекты, где нужны чёткие ценовые гарантии и бенчмарки
    В описании нет данных по стоимости, скорости отклика и лимитам. Для больших бюджетов придётся дополнительно считать экономику и тестировать задержки.

Доступность из России

Voice Live — часть Azure AI Services. Для доступа из России в большинстве случаев нужен обход региональных ограничений (VPN или облачный прокси за пределами РФ).
Юридические и комплаенс‑риски стоит оценивать отдельно: корпоративным пользователям лучше прогнать сценарий через юристов и службу безопасности.


Место на рынке

Voice Live конкурирует не с одной моделью, а с целым классом real‑time‑API для голоса и аватаров.

По тому, что есть в описании, можно выделить несколько особенностей:

  1. Против классического text‑only API (GPT‑4o, Claude 3.5 и т.п.)

    • Voice Live даёт полноценный событийный протокол для аудио и анимации, а не только текстовый стрим.
    • Есть VAD, шумоподавление, транскрипция входящего аудио и генерация анимации для аватаров.
    • В отличие от простых streaming‑endpoint’ов, вы управляете историей диалога на уровне отдельных элементов и можете обрезать аудио.
  2. Против чисто TTS‑сервисов

    • Обычный TTS даёт «текст на вход — аудио на выход».
    • Voice Live объединяет TTS, STT, диалоговую модель, инструменты и анимацию в одном протоколе.
    • Это особенно полезно, если вы строите именно ассистента, а не просто голосовой движок.
  3. Интеграция с Azure Custom Voice

    • Если у вас уже есть кастомные голоса в Azure, Voice Live даёт способ использовать их в живом диалоге без дополнительного «клея» между сервисами.
    • Поддержка стилей ("style": "cheerful", "excited") и температуры на уровне голоса делает Voice Live ближе к диалоговому движку, чем к классическому TTS.

Цифровых сравнений по скорости, стоимости и качеству речи с конкурентами в описании нет. Сценарии использования и богатый событийный протокол показывают, что Voice Live ориентирован на тех, кто строит сложные голосовые интерфейсы и готов инвестировать в интеграцию.


Как запустить: базовый сценарий по шагам

Ниже — минимальный рабочий флоу, который можно использовать как чек‑лист при интеграции.

1. Установить WebSocket‑подключение

  • Открываете WebSocket к Voice Live endpoint’у Azure (URL зависит от вашей подписки и региона).
  • После подключения ждёте первое событие session.created с базовой конфигурацией.

2. Настроить сессию

Отправляете session.update с нужными параметрами:

{
  "type": "session.update",
  "session": {
    "modalities": ["text", "audio"],
    "voice": {
      "type": "openai",
      "name": "alloy"
    },
    "instructions": "You are a helpful assistant. Be concise and friendly.",
    "input_audio_format": "pcm16",
    "output_audio_format": "pcm16",
    "input_audio_sampling_rate": 24000,
    "turn_detection": {
      "type": "azure_semantic_vad",
      "threshold": 0.5,
      "prefix_padding_ms": 300,
      "silence_duration_ms": 500
    },
    "temperature": 0.8,
    "max_response_output_tokens": "inf"
  }
}

Ждёте session.updated.

Если нужен кастомный голос и аватар:

{
  "type": "session.update",
  "session": {
    "voice": {
      "type": "azure-custom",
      "name": "my-custom-voice",
      "endpoint_id": "12345678-1234-1234-1234-123456789012",
      "temperature": 0.7,
      "style": "cheerful"
    },
    "input_audio_noise_reduction": {
      "type": "azure_deep_noise_suppression"
    },
    "avatar": {
      "character": "lisa",
      "customized": false,
      "video": {
        "resolution": {
          "width": 1920,
          "height": 1080
        },
        "bitrate": 2000000
      }
    }
  }
}

3. Подключить аватара по WebRTC (опционально)

  • Локально создаёте WebRTC‑оффер.
  • Кодируете SDP в base64 и отправляете:
{
  "type": "session.avatar.connect",
  "client_sdp": "<client_sdp>"
}
  • Ждёте session.avatar.connecting с server_sdp.
  • Завершаете WebRTC‑handshake на клиенте.

4. Стримить микрофон

  • Регулярно отправляете куски аудио через input_audio_buffer.append.
  • Если не используете server VAD — после фразы отправляете input_audio_buffer.commit.
  • При ошибке или смене сценария можно сделать input_audio_buffer.clear.

5. Запрашивать ответы

  • Либо рассчитываете на автоответ после коммита буфера (если так настроено),
  • Либо явно вызываете response.create с нужными модальностями.

Пример с анимацией и кастомным голосом:

{
  "type": "response.create",
  "response": {
    "modalities": ["audio", "animation"],
    "animation": {
      "model_name": "default",
      "outputs": ["blendshapes", "viseme_id"]
    },
    "voice": {
      "type": "azure-custom",
      "name": "my-expressive-voice",
      "endpoint_id": "12345678-1234-1234-1234-123456789012",
      "style": "excited"
    }
  }
}
  • Читаете стрим response.audio.delta, response.audio_transcript.delta, response.animation_blendshapes.delta и response.animation_viseme.delta.
  • По необходимости можете остановить ответ через response.cancel.

6. Управлять историей диалога

  • Добавлять сообщения вручную через conversation.item.create.
  • Получать и анализировать отдельные элементы через conversation.item.retrieve.
  • Обрезать старые аудио‑ответы через conversation.item.truncate.
  • Удалять лишнее из контекста через conversation.item.delete.

Voice Live 2026‑01‑01‑preview — это конструктор для real‑time голосовых ассистентов и аватаров с довольно низкоуровневым управлением. Он подойдёт тем, кто готов строить вокруг него полноценную продуктовую логику и кому важна связка «голос + диалог + анимация» в одном API.


Читайте также