Как создавать продвинутые голосовые интерфейсы и агентов с Realtime API в Yandex AI Studio

Разбираем Realtime API в Yandex AI Studio: от создания голосового агента и подключения ему знаний и внешних действий до умения держать контекст при перебивании и разделения сложных сценариев на несколько специализированных агентов.

Краткий пересказ YandexGPT
  • Realtime API в Yandex AI Studio — это интерфейс для голосового взаимодействия в реальном времени, который позволяет пользователю говорить, а системе — слушать, понимать и отвечать почти без задержек.
  • Голосовые агенты создаются в среде разработки Agent Atelier и включают в себя несколько компонентов: LLM, модель распознавания речи и модель синтеза речи.
  • Realtime API поддерживает различные сценарии взаимодействия: «голос — голос», «голос — текст» и другие.
  • Попробовать Realtime API можно тремя способами: в AI Playground (песочница в веб-интерфейсе платформы), через прямую интеграцию по протоколу (поддерживается стандарт OpenAI Realtime) или с помощью готовых SDK (например, OpenAI Agents SDK для Python или TypeScript).
  • Промпт для голосового агента должен быть логически согласован и структурирован, в нём можно описать роль агента, его возможности и ограничения, а также условия вызова функций.
  • File Search позволяет подключить агенту внешнюю базу знаний, а Web Search в качестве базы знаний использует весь интернет.
  • Function calling даёт возможность описать модели произвольные действия, которые она может выполнять, а MCP стандартизирует взаимодействие с множеством функций, когда их становится слишком много.
  • Truncate позволяет агенту корректно определить момент, когда его перебили, и учесть это в дальнейшем диалоге.
  • Мультиагентность используется, когда одного агента недостаточно для сложного сценария, и позволяет распределить задачи между несколькими агентами с разными голосами, инструментами и контекстом.

Голосовой бот, который распознаёт команду и выполняет одно действие, — это одна история. Агент, который помнит контекст разговора, обращается к базе знаний, вызывает внешние функции и корректно ведёт себя, когда его перебили на середине фразы, — совсем другая. Realtime API в Yandex AI Studio построен под второй сценарий.

Рассмотрим его на сквозном примере — голосовом помощнике для организации настольных игр. На нём видно, как компоненты API складываются в рабочего агента: от простого промпта до мультиагентной системы с подключением к телефонии.

Эту статью мы написали на основе доклада «Как создавать продвинутые голосовые интерфейсы и агентов» в рамках Yandex AI Studio Series Summer Edition.

Что такое Realtime API и где он находится в Yandex AI Studio

Realtime API в Yandex AI Studio — это интерфейс для голосового взаимодействия в реальном времени: пользователь говорит, система слушает, понимает и отвечает почти без задержек.

Голосовые агенты живут в среде разработки Agent Atelier — там же собираются и текстовые. Realtime API отвечает именно за голос и работает с инструментами среды: обращается к внешним системам через MCP, использует общедоступные и приватные, созданные пользователем, голоса из библиотеки синтеза и поддерживает оба вида поиска — по файлам и в интернете.

Из чего состоит голосовой агент

Если смотреть высокоуровнево, Realtime API — это каскад из нескольких моделей и инструментальная обвязка вокруг них:

  • LLM отвечает за логику: что и как говорить, какими знаниями пользоваться — документацией, файлами, аудиозаписями встреч — и когда вызвать инструмент, например обратиться к CRM или трекеру задач.
  • Модель распознавания речи, она же ASR (Automatic speech recognition), или Speech-to-Text, отвечает за голосовой ввод — на русском, казахском, узбекском и других языках Yandex SpeechKit.
  • Модель синтеза речи, Text-to-Speech, отвечает за голосовой вывод всеми голосами платформы.

Схема «голос — голос» не единственная: Realtime API поддерживает и «голос — текст» в разных сочетаниях. Дальше в статье разберём полностью голосовой сценарий как самый показательный.

Путь запроса выглядит так:

  1. Аудио приходит с микрофона, телефона или по WebSocket.
  2. Распознавание переводит его в текст и следит за перебиваниями.
  3. LLM решает, что ответить и какие инструменты вызвать.
  4. Синтез озвучивает ответ выбранным голосом.

Вход и выход симметричны — на обоих концах может быть и файл, если агент работает не с живым собеседником

Где попробовать Realtime API

Есть три варианта:

  • AI Playground — песочница в веб-интерфейсе платформы. Позволяет быстро проверить идею, поуправлять настройками синтеза и потрогать часть инструментов — без единой строки кода.
  • Прямая интеграция по протоколу. Yandex AI Studio поддерживает стандарт OpenAI Realtime: канал открывается по WebSocket, события идут двунаправленным потоком от клиента к серверу и обратно. Такой уровень интеграции даёт наибольшую свободу.
  • Готовые SDK — например, OpenAI Agents SDK для Python® или TypeScript. Протокол открытый и популярный, под него уже есть база готовых решений, поэтому писать интеграцию с нуля не нужно.

Как собрать голосового агента в плейграунде

Зайдите на сайт Yandex AI Studio, нажмите «Войти» и на главной странице выберите карточку «Создать голосового агента». С этого же экрана создаются поисковый индекс и MCP-сервер — то, что понадобится агенту дальше, когда мы начнём подключать ему знания и внешние действия.

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

Второй путь к тому же экрану — через раздел «Голосовые агенты» в Agent Atelier. Здесь же можно найти ссылку на документацию, кнопку создания с нуля и список уже созданных агентов.

Для примера соберём агента-переводчика. Всё его поведение задаётся одним промптом: «ты голосовой агент-переводчик, переводишь с русского на английский» плюс пара ограничений — если фраза неполная или оборвалась, переводить только распознанную часть, а грубую лексику передавать в смягчённой форме. Переменные и инструменты в таком сценарии не нужны.

Настройки речи: что можно подкрутить

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

В настройках распознавания можно задать язык и определить конец реплики: длительность тишины, после которой реплика считается законченной, и чувствительность — баланс между скоростью реакции агента и устойчивостью к коротким паузам внутри фразы. Этот параметр стоит настраивать под канал: по телефону нужен один режим, в мобильном приложении — другой. Слишком низкий порог тишины — и агент начнёт вклиниваться в паузы внутри фразы; слишком высокий — собеседник будет ждать ответа в тишине.

Протестируйте настроенного агента прямо в интерфейсе: выберите микрофон и при необходимости включите опцию «Агент говорит первым» — она нужна, если сценарий подразумевает исходящий звонок. От каждой тестовой сессии остаются артефакты: диалог, идентификатор сессии (пригодится в поддержке, если что-то пошло не так) и лог событий.

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

Простые и агентские сценарии — в чём разница

Бизнес-сценарии для голоса делятся на две категории: простые и сложные.

Простые функциональные сценарии решают одну задачу: распознали и затем что-то с этим сделали. Перевод, заполнение формы, голосование с пульта телевизора. Формально их можно реализовать на базовом распознавании речи из Yandex SpeechKit, но Realtime API добавляет контекстно-зависимую постобработку:

  • Исправление погрешностей распознавания. Если в меню есть «двойной эспрессо», а акустика подвела и распознавание вернуло «двойная экспресса», модель, зная список доступных позиций, вытянет корректный вариант. Злоупотреблять этим не стоит, но и пренебрегать тоже: иногда именно такие небольшие ухищрения спасали интеграцию, которая не справлялась своими силами.
  • Постобработка и извлечение сущностей. Например, собрать продиктованный по буквам адрес электронной почты или привести к нормальному виду номер телефона.
  • Кастомные нормализации под конкретный кейс. Пример из практики: клиент попросил числа от 1 до 10 писать словами, а больше 10 — цифрами. В базовом API это требует доработки на стороне вендора, а в Realtime API такое правило задаётся прямо в промпте.

Сложные агентские сценарии — ситуации, когда агент оперирует контекстом диалога, обращается к базам знаний, вызывает инструменты, уточняет недостающие детали и модерирует ход разговора:

  • Поддержка клиентов — консультация по документации, изменение настроек в профиле, объяснение крупного списания или того, почему пропала опция в личном кабинете.
  • Оформление заказа. Не самый очевидный, но всё более частый сценарий: не «одна пицца и одна кола безо льда», а запрос вроде «что-нибудь попить и поесть на 300 рублей». Агент, зная позиции меню, цены и категории, соберёт подходящий вариант — базовая система с таким запросом не справится.

Чтобы показать возможности платформы на наглядном примере, мы собрали голосового агента, который помогает найти компанию для настольных игр, договориться о времени и месте и разобраться в правилах конкретной игры. Дальше в статье все механики разбираем на нём.

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

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

Что важно учесть:

  • Промпт должен быть логически согласован — это упростит жизнь, когда через несколько дней придётся его дорабатывать.
  • Промпт должен быть структурирован. Набор разделов меняется от сценария к сценарию, но обычно в нём есть роль, что агент может и не может делать, какие у него ограничения.
  • Блок FAQ прямо в промпте часто полезнее, чем сразу уходить в RAG, — если частых вопросов по домену немного.
  • Опишите, когда вызывать функции. Об этом чаще всего забывают, хотя без этого подключённые инструменты работают непредсказуемо.

Промпт агента-помощника по настольным играм получился небольшим, но структурированным — с разметкой в духе Markdown.

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

## Правила общения

— Это голосовой разговор: отвечай коротко, 1–3 предложения. 
— Твой ответа озвучивается голосом: только простой разговорный текст, никакого markdown — ни списков со звёздочками и дефисами, ни заголовков, ни эмодзи. Перечисляй прямо в предложении, через запятую. 
— Если не хватает информации — задай один уточняющий вопрос. 
— Не перечисляй свои инструменты и возможности, если не спросили. 

Формат Markdown не обязателен, но удобен: хорошо читается и человеком, и моделью, ведь LLM обучены на огромном количестве файлов именно в этом формате

Проверяем, что получилось:

Полноэкранное изображение

Промпты для типовых сценариев строятся по схожей логике:

  • для поддержки — FAQ и правила поведения при разных вопросах клиента;
  • для холодного звонка — роль, задача, последовательность шагов и список данных, которые нужно собрать по итогам;
  • для голосового оформления заказа — при небольшом меню его можно включить прямо в текст промпта.

Переменные в промпте

Промпт, созданный в интерфейсе Yandex AI Studio, можно параметризовать — то есть заранее подставлять в разговор известные данные, например имя клиента и услугу, к которой он записан, не прибегая к MCP или Function calling.

В демопроекте мы добавили две переменные — имя агента и тематику вечера. Голос выбрали «Маша», агента назвали «Мудрая Маша», тематику задали «Вечер накануне экзамена». На вопрос «Как тебя зовут и какая сегодня тематика вечера?» агент ответил: «Меня зовут Мудрая Маша. Сегодня у нас вечер в тематике Вечер накануне экзамена» — переменные подхватились корректно.

Параметризация полезна ещё и тем, что позволяет разделить работу: одни люди пишут Function calling и обработку инструментов, другие — сам промпт. Значения переменных передаются как параметры сессии, а сам промпт между клиентом и сервером не гоняется — достаточно его ID. Правки промпта через интерфейс автоматически подхватываются новыми сессиями.

Практический пример

Агент звонит клиенту напомнить о записи: «Анастасия, здравствуйте, вы завтра записаны на укладку к мастеру Евгении». Имя клиента и мастера он получает как переменные, не выясняя их в процессе звонка через CRM. Можно заранее передать и свободные слоты для переноса записи. Да, за время разговора кто-то может успеть их занять, но по нашему опыту шанс попадания в свободный слот всё равно высокий, а диалог получается быстрее и естественнее, чем при обращении к системе в реальном времени.

Файловый поиск даёт агенту доступ к внешней базе знаний. В демопроекте это правила настольных игр: набор файлов в разных форматах загружается и объединяется в единый файловый индекс, у индекса появляется идентификатор, который передаётся агенту в параметрах сессии.

Промпт для File Search простой: сообщите модели, что ей доступен такой инструмент, и подскажите, в каких случаях его использовать — например, при вопросе о правилах игры сходить в поисковый индекс и найти релевантный фрагмент.

Проверяем на правилах «Манчкина»:

Полноэкранное изображение

В плейграунде для File Search нужно выбрать инструмент, индекс для поиска и число чанков, которые модель будет использовать при ответе, — в примере задали пять. Как и для других инструментов, важно прописать, в каких случаях его вызывать.

Для базы знаний подходят разные форматы — вплоть до аудио и видео, но чаще всего индексируют вики-страницы, текстовые файлы и таблицы. Разбить документы на чанки можно двумя способами: чанкованием по умолчанию или собственным — через формат JSONL, где текст заранее размечен на куски.

Отдельная практика для поддержки: каждый удачно отвеченный вопрос добавляют в индекс, чтобы при похожих обращениях модель сразу находила заранее отлаженный и проверенный ответ.

Веб-поиск устроен похоже, но в роли индекса выступает весь интернет — это выручает, когда своей базы знаний недостаточно. В демопроекте так закрыли пробел с играми, правил которых нет в индексе: отслеживать и заранее загружать все новинки нереально, поэтому агенту явно сказали — если спрашивают про то, чего он не знает, нужно идти в веб-поиск.

Технически File Search и Web Search обрабатываются на серверной стороне — в отличие от клиентских функций, о которых речь пойдёт дальше. В интерфейсе Yandex AI Studio для веб-поиска можно указать конкретные домены или оставить поле пустым — тогда поиск идёт по всему интернету.

Если вся документация опубликована на сайте компании, необязательно поднимать под неё MCP-сервер — ответы можно искать прямо через веб-поиск. Или строить универсального голосового ассистента, который отвечает на вопросы о погоде, курсе валют и ситуации на дорогах.

Function calling: как агент выполняет произвольные действия

Function calling — возможность описать модели не только встроенные инструменты, но и произвольные. Идея такая: модель заранее знает, что ей доступно и с какими параметрами, а когда для ответа не хватает данных — возвращает вызов с подставленными значениями. Дальше вызов исполняется: на сервере, если инструмент встроенный, или на стороне клиента, если он ваш собственный. По сути это знакомый разработчикам паттерн RPC.

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

В демопроекте мы добавили функцию «бросить кубик» — чтобы не искать физический кубик во время игры:

Полноэкранное изображение

Формат описания функции и её параметров довольно строгий. Это стоит учитывать при реализации. Связь между вызовом функции, который прилетает от модели, и её фактическим выполнением берёт на себя OpenAI Agents SDK.

Function calling — основа для любого действия агента. File Search и Web Search устроены так же, просто их реализация спрятана на уровне API. За вызовом функции может стоять что угодно: изменение записи в CRM, проверка статуса заказа, перевод звонка на живого оператора.

MCP: когда функций становится слишком много

Когда сценарий разрастается и описывать каждую функцию отдельно становится тяжело, помогает MCP. Он стандартизирует то же взаимодействие, что и Function calling, но уже принят сообществом: модель работает с готовыми MCP-серверами без ручного описания каждого инструмента. MCP-серверы можно разместить и в собственном контуре — это применимо не только к голосовым сценариям, но и, например, к кодовым ассистентам.

В демопроекте мы подключили к голосовому агенту MCP-сервер для работы с Яндекс Календарём — чтобы агент мог не только консультировать по правилам игр, но и планировать встречу и звать участников.

Архитектура представлена стандартным набором компонентов Yandex AI Studio и Yandex Cloud, внутри развёрнуты функции Yandex Cloud Functions — они работают тонкой прослойкой между вызовом инструмента Create event и API Календаря. Приложение в Календаре создаётся заранее, его credentials передаются как параметры функций.

Модель видит схему параметров каждого инструмента MCP-сервера и понимает, какой вызов сделать. Если каких-то параметров не хватает, она дозапрашивает их у пользователя:

Полноэкранное изображение
Полноэкранное изображение
Полноэкранное изображение

Чаще всего MCP применяют для календарей, CRM и баз данных — MCP-обёртка сейчас появляется практически у каждого сервиса. Протокол не поддерживает потоковое взаимодействие, всё происходит в REST-стиле.

Truncate: что происходит, когда пользователь перебивает агента

Truncate — функциональность, которая позволяет агенту корректно определить момент, когда его перебили.

Проблема, которую решает Truncate, выглядит так:

  1. Агент формулирует развёрнутый ответ — например, «Заказ доставят завтра с 10 до 18, за час позвонит курьер, при отсутствии клиента доставка перенесётся».
  2. Пользователь перебивает на середине: «Да, спасибо, понял».
  3. Без Truncate в контексте модели фраза остаётся произнесённой целиком, хотя устройство успело воспроизвести только часть аудио.
  4. Дальше агент строит разговор так, будто все условия озвучены, — а собеседник услышал половину.

Truncate закрывает этот разрыв: клиент сообщает серверу, что пользователь перебил и не дослушал, и указывает, какая часть аудио реально прозвучала. Ключевое событие в протоколе — conversation item truncate: оно помечает фрагмент как обрезанный и уточняет, сколько успело проиграться.

В демопроекте мы проверили это на правилах «Манчкина»: если агента перебить на середине объяснения, он продолжает с места, где остановился, а не начинает заново, — но учитывает, что услышана только часть.

Полноэкранное изображение
Полноэкранное изображение

Основная логика работает на сервере. На клиенте важно две вещи: попросить модель отвечать развёрнуто и учитывать обрезанные ответы, а также отслеживать, сколько аудио реально проиграно, чтобы вовремя отправить событие Truncate.

Ещё это критично, например, при вызове мастера на дом («Мастер приедет завтра с 10 до 18, оплата только наличными») или при напоминании о доставке («Если не снимете трубку за час до прибытия курьера, доставка перенесётся на другой день»). Не дослушав условие, клиент теряет время или деньги.

Альтернатива — разбивать длинные реплики на несколько с проверкой «Поняли?» после каждой. Для техподдержки это работает («Зайдите на сайт. Получилось?»), но там, где сообщение логично произнести одной репликой, диалог становится неестественным и раздражает.

Мультиагентность: когда одного агента становится мало

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

Есть и менее очевидная причина. Не все модели одинаково хорошо работают с большим количеством подключённых инструментов: когда через MCP подключают сотню с лишним, модель хуже выбирает нужный, да и описывать такое количество тяжело. Логичный выход — декомпозировать сценарий на несколько специализированных агентов. По сути это обычная декомпозиция, как в коде.

Самый частый паттерн — агент-диспетчер, который распределяет запросы между специализированными агентами.

В демопроекте мы разделили инструменты на две роли: агент-консультант по правилам игр и агент-организатор встреч, каждому назначили свой голос — чтобы пользователю было понятно, кто сейчас отвечает. В промпте каждого описана его роль и условие: если нужно что-то, что умеет второй агент, разговор передаётся ему. Такая передача называется handoff. Основную оркестрацию берёт на себя OpenAI Agents SDK; в коде второй агент дополнительно настроен под свой голос, а передача разговора реализована отдельной функцией.

Проверяем, что получилось:

Полноэкранное изображение

Так, в поддержке можно настроить разных агентов для разных продуктов или сделать отдельного агента для обработки возражений или сбора обратной связи. Мультиагентность помогает и с переиспользованием: агента для сбора информации о клиенте, написанного под холодный звонок, можно взять и на другие сценарии — не только в тот продукт, для которого он изначально создавался.

Как создавать продвинутые голосовые интерфейсы и агентов с Realtime API в Yandex AI Studio

Войдите, чтобы сохранить пост