Голосовой робот на TTS API: автоответчик, который не бесит


Если нужен text to speech api именно для телефонного разговора, требования к нему отличаются от требований к озвучке ролика. В звонке человек ждёт ответ в реальном времени, слышит каждую паузу и замечает повторяющиеся фразы. Поэтому для голосового робота важны не только сам голос, но и длина реплик, подстановка данных, кэширование и задержка до первого звука.

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

У сервиса операция «Озвучка текста (tts)» стоит 18 ₽ за запуск на 1000 знаков. Оплата идёт за запуск без абонентской платы и минимального платежа, а при выпуске первого ключа на баланс начисляется 50 ₽ для пробы.

Чем озвучка для разговора отличается от озвучки для видео

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

Для видео удобно сначала подготовить весь текст, затем получить один или несколько файлов и смонтировать их. В телефонии сценарий обычно собирается из отдельных реплик. Например, «Здравствуйте, Иван» и «Ваш заказ на 3490 рублей готов» относятся к разным частям сценария, причём вторая реплика зависит от данных конкретного звонка.

Это влияет и на структуру приложения. Вместо одного большого текста можно держать шаблоны:

Здравствуйте, {name}. Вас беспокоит автоматический помощник.
Сумма к оплате — {amount} рублей.
Дата доставки — {date}.

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

Для API у сервиса предусмотрена операция tts. Общий API находится по адресу https://genius-bot.ru/wp-json/genius/v1, авторизация выполняется через заголовок Authorization: Bearer <ключ>. Ключ выдаётся в разделе API после входа и показывается один раз, поэтому его лучше сразу сохранить в секретах приложения, а не прописывать непосредственно в исходниках.

Перед интеграцией полезно получить список доступных операций и цен. Это также позволяет проверить авторизацию независимо от TTS-запроса:

curl https://genius-bot.ru/wp-json/genius/v1/services \
  -H "Authorization: Bearer $GENIUS_API_KEY"

Здесь намеренно не задаётся не указанная в документации схема тела /generate: точные поля запроса для запуска TTS должны браться из актуального описания операции. Из известных маршрутов API следует рабочая последовательность: POST /generate запускает операцию, а GET /tasks/{id} возвращает её состояние и результат.

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

import os
import requests

BASE_URL = "https://genius-bot.ru/wp-json/genius/v1"
API_KEY = os.environ["GENIUS_API_KEY"]

response = requests.get(
    f"{BASE_URL}/balance",
    headers={"Authorization": f"Bearer {API_KEY}"},
    timeout=20,
)

response.raise_for_status()
print(response.json())

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

Голосовой робот на TTS API: схема разговора
Голосовой робот на TTS API: схема разговора

Переменные в репликах: имя, сумма, дата

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

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

Здравствуйте, {name}. Сумма вашего заказа — {amount} рублей.
Доставка запланирована на {date}.

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

Для суммы полезно заранее определить единый формат. Если одна часть приложения передаёт 3490, другая — «3 490», а третья — «три тысячи четыреста девяносто», робот может произносить похожие данные с разной манерой. Единый формат подготовки текста уменьшает такие расхождения.

С датой ситуация аналогичная. Для пользователя телефонного робота фраза «доставка 2026-09-24» выглядит как машинное значение, тогда как сценарий может преобразовать дату в естественную словесную форму до передачи в TTS. Само преобразование даты относится к вашему приложению, а не к утверждаемым возможностям API.

Читать  API нейросети: как это устроено и что происходит после запроса

Ещё один практический приём — ограничивать размер динамического фрагмента. Если в шаблон случайно попадает длинное описание заказа на несколько тысяч символов, короткая телефонная реплика превращается в длинный монолог. Для разговора лучше заранее определить допустимый размер каждого динамического поля.

Операция Цена Что важно для телефонии
Озвучка текста (tts) 18 ₽ за 1000 знаков Подходит для генерации голосовых реплик
Расшифровка записи (stt) 10 ₽ за запуск Может использоваться отдельно для обработки записи
Убрать шум (denoise) 36 ₽ за запуск Отдельная операция обработки звука
Звук по описанию (sfx) 9 ₽ за запуск Не является заменой речевому TTS

У TTS цена указана за 1000 знаков. Поэтому для оценки расходов имеет смысл считать не только количество звонков, но и объём действительно генерируемого текста. Если одна и та же фраза повторяется в тысячах разговоров, именно кэширование позволяет не запускать одну операцию снова и снова.

Кэш фраз: как не платить за одно и то же тысячу раз

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

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

def cache_key(text, voice_version):
    return f"tts:{voice_version}:{text.strip()}"

text = "Здравствуйте. Ваш заказ принят."
key = cache_key(text, "v1")

audio = cache.get(key)

if audio is None:
    audio = generate_tts(text)  # вызов API /generate
    cache.set(key, audio)

return audio

В этом примере generate_tts — ваш слой над API, а не название конкретного метода сервиса. Такой слой полезен потому, что телефонный сценарий не должен знать детали HTTP-запроса, проверки задачи и хранения результата.

Кэш-ключу стоит привязать версию шаблона. Если реплика изменилась с «Ваш заказ принят» на «Ваш заказ оформлен», новая строка автоматически станет отдельным элементом. То же относится к изменениям параметров генерации, если они предусмотрены конкретной операцией.

Для переменных фразы кэшировать можно не только целиком. Например, «Здравствуйте, {name}» нельзя использовать как готовый звук для всех клиентов, если имя должно звучать внутри одной аудиореплики. Зато неизменяемые фразы вокруг динамического участка можно организовать как отдельные заранее созданные сегменты, если это соответствует вашему сценарию воспроизведения.

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

При проектировании учитывайте ограничение API: не больше 60 запросов в минуту на один ключ. Кэш уменьшает не только расходы на повторяющиеся TTS-запуски, но и количество запросов, проходящих через это ограничение.

Кэш озвученных фраз для голосового робота
Кэш озвученных фраз для голосового робота

Задержка до первого звука и почему она решает

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

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

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

API предоставляет асинхронную модель задач: после POST /generate можно отслеживать состояние через GET /tasks/{id}. Также предусмотрен необязательный параметр callback_url: когда задача готова, на указанный адрес приходит POST.

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

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

Читать  Улучшить качество видео нейросетью: что реально исправляется

Интонация и паузы: где робот звучит грубо

Даже короткая реплика может звучать плохо, если в ней слишком много информации. Фраза «Здравствуйте, Иван, ваш заказ номер 4812 на сумму 3490 рублей будет доставлен 24 сентября с 10 до 18 часов, подтвердите, пожалуйста, получение» требует от слушателя удерживать сразу несколько значений.

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

Здравствуйте, Иван.

Ваш заказ на сумму 3490 рублей
будет доставлен 24 сентября.

Подтвердите, пожалуйста, получение.

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

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

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

Именно поэтому «озвучка ivr» — это не просто передача длинного текста в TTS. Нужно проектировать реплики как элементы диалога: одна мысль, одно действие и понятная точка, в которой пользователь может ответить.

Подстановка переменных в реплику робота
Подстановка переменных в реплику робота

Сценарий из десяти реплик: рабочий пример

Ниже — пример структуры разговора для уведомления о заказе. Он показывает, какие фразы можно подготовить заранее, а какие зависят от данных пользователя.

1. Здравствуйте.
2. Вас беспокоит автоматический помощник магазина.
3. Иван, звоню по вашему заказу.
4. Номер заказа — 4812.
5. Сумма заказа — 3490 рублей.
6. Доставка запланирована на 24 сентября.
7. Курьер прибудет в согласованный временной интервал.
8. Подтвердите, пожалуйста, что заказ можно доставить.
9. Спасибо, подтверждение получено.
10. Хорошего дня.

Реплики 1, 2, 7 и 10 потенциально являются стабильными и хорошо подходят для предварительного кэширования. Реплики 3, 4, 5 и 6 содержат данные конкретного заказа. Реплика 8 также стабильна, если текст вопроса не зависит от типа заказа.

С точки зрения приложения это можно представить как массив объектов, где шаблон хранится отдельно от значений:

scenario = [
    {"id": "hello", "text": "Здравствуйте.", "dynamic": False},
    {"id": "assistant", "text": "Вас беспокоит автоматический помощник магазина.", "dynamic": False},
    {"id": "customer", "text": "Иван, звоню по вашему заказу.", "dynamic": True},
    {"id": "order", "text": "Номер заказа — 4812.", "dynamic": True},
    {"id": "amount", "text": "Сумма заказа — 3490 рублей.", "dynamic": True},
    {"id": "date", "text": "Доставка запланирована на 24 сентября.", "dynamic": True},
]

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

Для запуска операции API используется маршрут POST /generate. После запуска приложение получает идентификатор задачи и может проверить её через GET /tasks/{id}; альтернативно можно передать callback_url и принять POST после готовности задачи.

Не стоит делать один большой TTS-запрос на все десять реплик только ради уменьшения количества HTTP-вызовов. В разговорном сценарии отдельные фрагменты дают больше контроля над кэшем, повторным воспроизведением и ветвлением диалога. Конкретный баланс между количеством задач и длиной аудиофрагментов лучше определить по вашему сценарию и измерениям задержки.

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

export GENIUS_API_KEY="ваш_ключ"

Ключ не стоит помещать в JavaScript телефонного клиента или коммитить в репозиторий. Запросы к API должны выполняться из серверной части, где секрет можно хранить отдельно от кода.

Для контроля расходов полезно вести минимум три счётчика: количество запусков TTS, количество символов и количество попаданий в кэш. Цена TTS составляет 18 ₽ за 1000 знаков, поэтому эти метрики позволяют связать техническое поведение голосового робота с фактическими расходами.

У сервиса нет абонентской платы и минимального платежа, а расчёт идёт за запуск. При первом выпуске ключа начисляется 50 ₽ на баланс; это можно использовать для проверки своего сценария до подключения полноценного потока звонков.

В итоге голосовой робот API лучше проектировать не как «озвучить текст», а как слой диалога между телефонией и TTS. Короткие стабильные реплики уходят в кэш, персональные значения подставляются перед генерацией, а время ожидания результата измеряется отдельно от остальных задержек системы.

Читать  Text to speech API: подключение озвучки за один вечер

Частые вопросы

Сколько стоит озвучка текста?

Операция TTS стоит 18 ₽ за 1000 знаков. Цены в справке указаны в рублях за один запуск; для озвучки единица расчёта — 1000 знаков.

Можно ли использовать API без абонентской платы?

Да. Оплата выполняется за запуск, без абонентской платы и без минимального платежа. При выпуске первого ключа на баланс начисляется 50 ₽ для пробы.

Как проверить, готова ли задача?

После запуска через POST /generate состояние и результат можно получать через GET /tasks/{id}. Также для готовой задачи предусмотрен необязательный callback_url, на который приходит POST.

Есть ли ограничение на частоту запросов?

На один ключ допускается не более 60 запросов в минуту. Кэширование повторяющихся реплик помогает не отправлять одинаковые TTS-запросы без необходимости.

Где получить API-ключ?

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

Подходит ли такой API для сценария с переменными?

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

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