Dev48
ЯЗЫК
  • О нас
  • Услуги
  • Индустрии
  • Технологии
  • Статьи
  • Контакты
Забронировать звонок
    Главная/Статьи/Dobavlenie instrumentov i perevoda na zhivogo operatora v golosovogo agenta vona
Dev48

© 2026 · All rights reserved.

Добавление инструментов и перевода на живого оператора в голосового агента Vonage + Deepgram

Источник: Vonage API Developer

Добавление инструментов и перевода на живого оператора в голосового агента Vonage + Deepgram

Источник: Vonage API Developer

Расширьте базового голосового агента Vonage и Deepgram с помощью инструмента проверки статуса заказа, строгих тайм-аутов, полезных запасных вариантов, реального перевода звонка на живого оператора и записей звонков.

28 сентября 2026 г.•Обновлено: 28 сентября 2026 г.

Введение

Руководство по Vonage Voice API и Deepgram продвигает вас на удивление далеко.

К концу руководства вы сможете позвонить на номер Vonage, поговорить с ИИ-агентом, прервать его во время разговора и вести естественный голосовой диалог на базе Deepgram Voice Agent API.

Но агент всё ещё не может реально сделать для вас многое (у него нет инструментов!).

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

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

Эта специфическая для аудио проблема ИИ-агентов была представлена в статье Don’t Loop the Latency: Where Agent Loops Belong in Voice AI. Одна из идей в его посте — сохранять работу, выполняемую во время живого телефонного звонка, небольшой и предсказуемой.

Цель этого поста — превратить разговорное демо в агента, который может выполнять полезные задачи, предсказуемо сбоить и — самое главное — оставлять достаточно информации для последующего улучшения. В этом руководстве мы расширим существующего агента Vonage + Deepgram, чтобы он мог:

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

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

  • установить жёсткий тайм-аут для поиска

установить жёсткий тайм-аут для поиска

  • обрабатывать сбои, не заставляя звонящего ждать

обрабатывать сбои, не заставляя звонящего ждать

  • переводить запросы, которые агент не может обработать, на реальный телефонный номер

переводить запросы, которые агент не может обработать, на реальный телефонный номер

  • сохранять запись о том, что произошло во время каждого звонка

сохранять запись о том, что произошло во время каждого звонка

TL;DR Краткое руководство доступно на GitHub.

TL;DR Краткое руководство доступно на .

Предварительные требования

Вам понадобятся:

  • Учётная запись Vonage API

Учётная запись Vonage API

  • Приложение Vonage с включённым Voice

Приложение Vonage с включённым Voice

  • Номер телефона Vonage, привязанный к этому приложению

Номер телефона Vonage, привязанный к этому приложению

  • Второй номер телефона, который можно использовать как направление для поддержки оператором

Второй номер телефона, который можно использовать как направление для поддержки оператором

  • Учётная запись Deepgram с доступом к Voice Agent

Учётная запись Deepgram с доступом к Voice Agent

  • ngrok

ngrok

Дайте агенту инструмент

Мы намеренно сделаем вариант использования простым: проверка статуса заказа. Звонящий говорит:

«Где заказ A1001?»

«Где заказ A1001?»

Deepgram понимает, что агенту нужна внешняя информация, и просит наше приложение вызвать:

getOrderStatus("A1001")

getOrderStatus("A1001")

Наше приложение выполняет поиск и отправляет результат обратно в Deepgram. Затем модель превращает этот результат в естественный голосовой ответ.

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

Также есть несколько специальных идентификаторов заказов для тестирования:

  • Идентификаторы, начинающиеся с SLOW, возвращаются за две секунды.

Идентификаторы, начинающиеся с SLOW, возвращаются за две секунды.

  • Идентификаторы, начинающиеся с FAIL, имитируют временный сетевой сбой.

Идентификаторы, начинающиеся с FAIL, имитируют временный сетевой сбой.

  • Всё остальное возвращает not_found.

Всё остальное возвращает not_found.

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

Зарегистрируйте инструмент в Deepgram

API Voice Agent от Deepgram поддерживает вызов функций на стороне клиента. Мы описываем функцию в сообщении Settings агента:

Мы не передаём Deepgram HTTP-эндпоинт для функции. Вместо этого Deepgram отправляет нашему WebSocket запрос FunctionCallRequest. Это означает, что наше приложение сохраняет контроль над фактическим запуском инструмента.

Это полезно, потому что мы можем решить:

  • разрешён ли инструмент

разрешён ли инструмент

  • как долго он может работать

как долго он может работать

  • следует ли повторять попытку при сбое

следует ли повторять попытку при сбое

  • что услышит звонящий, если это не сработает

что услышит звонящий, если это не сработает

Промпт агента также остаётся узким:

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

Установите крайний срок для поиска

Именно здесь разработка для телефонного звонка начинает отличаться от разработки обычного чат-бота. Представьте, что сервису заказов требуется шесть секунд, чтобы ответить. С точки зрения сервера это просто медленный запрос.

С точки зрения звонящего, он задал вопрос, а затем услышал шесть секунд тишины.

Поэтому в этом примере поиску даётся 1500 миллисекунд:

Обёртка соревнует вызов серверной части с этим крайним сроком:

Важно то, что есть три возможных исхода:

Исход

Что это значит

Что мы делаем

result

Серверная часть ответила

Вернуть результат

timeout

Не ответила в течение 1500 мс

Использовать запасной вариант

transport_error

Соединение не удалось

Повторить один раз

Ответ not_found по-прежнему является успешным поиском. Серверная часть ответила; просто не нашла заказ.

Это отличается от тайм-аута.

Ограничьте то, что может произойти во время звонка

Для этого примера правила намеренно минимальны:

Каждый телефонный звонок получает собственный экземпляр политики:

Тайм-аут не повторяется.

Мы уже ждали 1,5 секунды. Повторный запуск того же медленного запроса может просто дать нам ещё 1,5 секунды тишины.

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

Обработка вызова функции

Когда Deepgram отправляет FunctionCallRequest, обработчик WebSocket применяет эти правила перед запуском инструмента.

Основной поток выглядит так:

Фактический обработчик также записывает вызов инструмента и время, но именно эта часть управляет тем, что испытывает звонящий.

Используйте фиксированный запасной вариант

Если поиск не удался, вы не хотите, чтобы модель придумывала собственный план восстановления.

Приложение внедряет фиксированный ответ:

InjectAgentMessage от Deepgram позволяет нам поместить этот ответ непосредственно в разговор:

Поведение прерывания здесь важно.

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

Также обратите внимание на имя поля: это message, а не content.

Обе эти детали в противном случае могут привести к тому, что звонок замолчит без особых указаний на причину.

Переводите неподдерживаемые запросы оператору

Агент по статусу заказов не должен пытаться отвечать на всё.

Если кто-то говорит:

«Я хочу оспорить платёж.»

«Я хочу оспорить платёж.»

Мы классифицируем это как запрос, связанный с оплатой:

Для этой демонстрации классификация намеренно ограничена и детерминирована:

Здесь нет второго вызова модели.

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

transferToHuman() обновляет активный звонок Vonage с помощью нового NCCO.

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

Затем мы переводим активный вызов:

Для локального тестирования SUPPORT_PHONE_NUMBER может быть просто другим телефоном, который находится рядом с вами.

Позвоните на свой номер Vonage с одного телефона, попросите оспорить платеж, и второй телефон должен зазвонить.

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

Настройка перевода вызова

Чтобы обеспечить реальную передачу вызова, добавьте эти значения в ваше окружение:

Вам также понадобится существующая конфигурация:

Используйте номера в формате E.164 для номеров Vonage и поддержки.

Сохранение информации о вызове

Приложение также записывает небольшую запись в SQLite, когда вызов завершается.

Это не база данных заказов. Это запись самого голосового взаимодействия.

Запись может рассказать нам:

  • что сказали вызывающий абонент и агент

что сказали вызывающий абонент и агент

  • какой инструмент был вызван

какой инструмент был вызван

  • сколько времени это заняло

сколько времени это заняло

  • использовался ли запасной вариант

использовался ли запасной вариант

  • был ли переведен вызывающий абонент

был ли переведен вызывающий абонент

  • почему произошел перевод

почему произошел перевод

  • как завершился вызов

как завершился вызов

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

Это полезно, даже если вы не создаете вокруг этого сложную систему оценки.

Если вызывающие абоненты продолжают переводиться по одной и той же причине, вы это увидите. Если время ожидания начинает расти, вы тоже это увидите. А если вы позже измените промпт, модель или инструменты, поле agent_version даст вам простой способ определить, какая версия обрабатывала какие вызовы.

Как запустить агента

Сначала запустите ngrok:

Вставьте этот HTTPS URL в BASE_URL и в вебхуки Answer и Event вашего приложения Vonage.

Затем запустите приложение:

Вы можете проверить вебхук Answer перед звонком:

Возвращаемый NCCO должен содержать конечную точку WebSocket, похожую на:

wss://YOUR-NGROK-URL/socket?callUuid=test123

Попробуйте четыре вызова

Попробуйте протестировать основные сценарии в виде отдельных телефонных вызовов.

Вызов

Что сказать

Что должно произойти

«Где заказ A1001?»

Агент зачитывает статус доставки

«Где заказ SLOW999?»

Поиск завершается по таймауту, и воспроизводится фиксированный запасной вариант

«Где заказ XYZ123?»

Агент сообщает, что заказ не найден

«Я хочу оспорить платеж.»

Вызов переводится на ваш телефон поддержки

Каждый вызов должен быть новым. В этом примере разрешен один поиск заказа за вызов.

После этого проверьте записи:

Вы должны увидеть разные пути в данных:

completed fallback completed handoff

Для последнего вызова handoff_reason должно быть billing.

Заключение

Оригинальный учебник Vonage + Deepgram позволяет голосовому ИИ-агенту общаться по реальному телефонному звонку. Здесь мы дали этому агенту одну полезную задачу: найти заказ, перестать ждать, когда серверная часть слишком медленная, корректно перейти к запасному варианту при сбое и переводить неподдерживаемые запросы на человека.

Серверная часть заказов имитируется, но подход тот же, если вы замените getOrderStatus() на свою собственную базу данных или API.

Это идея Винса «не зацикливайся на задержке» на практике: пока вызывающий абонент ждет, выполняйте небольшую работу, устанавливайте дедлайны для внешних вызовов и предусмотрите полезный путь выхода.

После вызова эти ограничения по задержке исчезают. Именно здесь становятся полезными сохраненные записи: транскрипты, вызовы инструментов, результаты, причины перевода и версии агента.

Если, например, возвраты все чаще появляются как причина перевода, мы можем использовать эти вызовы, чтобы решить, что строить дальше, добавить возможность возврата в версию-кандидат и протестировать ее на сохраненных вызовах, прежде чем показывать ее вызывающим абонентам.

Это начало рабочего процесса loop-engineering. Но об этом в следующем посте!

← Все статьи

Ещё в разделе «Телеком и сети»

Все →
SpaceX готовится отправить ракету Starship в орбиту впервыеПресса
SpaceX

SpaceX готовится отправить ракету Starship в орбиту впервые

Обновленное обязательство по отношению к Единому рынку
Telefónica

Обновленное обязательство по отношению к Единому рынку

Очистка и проверка телефонных номеров для электронной коммерции
Vonage API Platform

Очистка и проверка телефонных номеров для электронной коммерции

Почему лидерство является стратегическим фактором для развития передового административного управления?
Telefónica

Почему лидерство является стратегическим фактором для развития передового административного управления?

Пресс-релизы
SES

Пресс-релизы

Пресс-релизы
SES

Пресс-релизы

Ещё от Vonage API Platform

Очистка и проверка телефонных номеров для электронной коммерции
Vonage API Platform

Очистка и проверка телефонных номеров для электронной коммерции

Знакомьтесь с новейшими ИИ-стартапами в сфере здравоохранения, присоединяющимися к Vonage
Vonage API Platform

Знакомьтесь с новейшими ИИ-стартапами в сфере здравоохранения, присоединяющимися к Vonage