Asterisk распознавание речи через Google + умный IVR

в 7:32, , рубрики: asterisk, Google, ivr, speech recognition, Песочница, метки: , , ,

Asterisk распознавание речи через Google + умный IVR

Доброго времени суток, уважаемые хабра-пользователи.
В одном проекте необходимо было сделать умный IVR на базе IP-АТС Asterisk. Что подразумевается под словом «умный»: при звонке на определенный номер станция просит назвать имя абонента, человек на другом конце провода называет имя и станция связывает его с нужным абонентом.

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

Шаг 1:

Работа с Google

Первое, что необходимо – это каким-то образом распознать речь позвонившего. На хабре было достаточно (раз, два) статей, как это делать с помощью Google Translate. Я же решил взять готовые скрипты, найденные на просторах github: googletts.agi – для того, что бы научить Asterisk говорить и speech-recog.agi – для того, чтобы Asterisk умел распознавать речь.

Файлы googletts.agi и speech-recog.agi закидываем в папку /var/lib/asterisk/agi-bin.
Для успешной работы скриптов необходимо иметь следующие пакеты: Perl, perl-libwww, IO-Socket-SSL, flac, sox, mpg123. Все пакеты у меня успешно скачались и установились с репозиториев (через yum install), за исключением mpg123, его пришлось качать отдельно.

В googletts.agi меняем значение переменной $lang с en на ru, мы ведь хотим, что бы Asterisk заговорил по-русски.
В speech-recog.agi меняем значение переменной $language с en-US на ru-RU для того, чтобы Google возвращал результат на русском языке.
Все, больше в скриптах я не трогал ничего.

Шаг 2:

Написание dial-плана

Как я говорил выше, у меня установлен FreePBX, поэтому все изменения я буду вносить в файл extensions_custom.conf.
Для начала неплохо поприветствовать позвонившего и дать ему комментарий, что делать дальше.

exten => 100,1,Answer()
exten => 100,n,agi(googletts.agi,”Здравствуйте! После звукового сигнала произнесите имя абонента.”,ru)

Дальше с помощью speech-recog.agi, слушаем, что говорит пользователь, записываем, конвертируем, отправляем в Google и получаем от него результаты.

exten => 100,n(record),agi(speech-recog.agi,ru-RU)

Далее с помощью функции GotoIf делаем проверку того, как отработал скрипт.
Скрипт возвращает следующие значения:

status: возвращает статус выполнения. 0 означает успех
utterance: строка, возвращаемая Google
confidence: значение от 0 до 1, показывающее вероятность правильного распознавания

exten => 100,n,GotoIf($[$["${status}" = "0"] & $["${confidence}" > "0.8"]]?if1:retry)

В случае успеха проверки переходим к событию if1, если неудача, переходим к событию retry, в котором попросим пользователя повторить.

exten => 100,n(retry),agi(googletts.agi,”Пожалуйста, повторите”,ru)

Дальше переходим к работе непосредственно с самой строкой, которую мы получили от Google. Необходимо сравнить полученную строку ${utterance} с каким-то шаблоном и решить, что делать дальше. Воспользуемся функцией GotoIf

exten => 100,n(if1),GotoIf($[“${utterance}” = “вася”]?vasya:retry)

Если строка, полученная от Google, совпадает с «вася», переходим к событию vasya, если не совпадает, просим пользователя повторить.

И осталось только позвонить Васе

exten => 100,n(vasya),Dial(SIP/101)

Dial-план полностью:

exten => 100,1,Answer()
exten => 100,n,agi(googletts.agi,”Здравствуйте! После звукового сигнала произнесите имя абонента.”,ru)
exten => 100,n(record),agi(speech-recog.agi,ru-RU)
exten => 100,n,GotoIf($[$["${status}" = «0»] & $["${confidence}" > «0.8»]]?if1:retry)
exten => 100,n(if1),GotoIf($[“${utterance}” = “вася”]?vasya:retry)
exten => 100,n(retry),agi(googletts.agi,”Пожалуйста повторите”,ru)
exten => 100,n(vasya),Dial(SIP/101)
Вариации на тему

  • Для простоты примера я привел всего одно условие сравнения того, что услышали с шаблоном, по факту их может и должно быть больше.
  • Не очень красиво звучат фразы, которые говорит «железная леди» от Google. В рабочем варианте, конечно, неплохо записать фразы «живым» голосом и воспроизводить их при помощи функции Playback.
Тонкости

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

Вот пример грабель, на которые я наступил:
Меня зовут Кирилл (две «Л» на конце). Google по каким-то только ему известным причинам через раз возвращал либо “кирил”, либо “кирилл”.

Послесловие

Есть подозрение, что сравнение можно было реализовать каким-нибудь более технологичным способом, с радостью выслушаю ваше мнение и предложения в комментариях.
И еще остается открытый вопрос в масштабе: что будет, если абонентов много, сколько займет время на прохождение всех сравнений, если, конечно, их реализовывать предложенным мной способом. Но для небольшой АТС примерно на 20 абонентов данный способ является приемлемым.

Спасибо за внимание.

Автор: kgerman

Источник

Поделиться

  1. Иван:

    Привет, спасибо за статью! А с bing мелкомягких не делал такого? Ну текст превращать в голос скрипт есть работает, а вот наоборот что то не нашел я. Ты не пробовал?

  2. Руслан:

    Здравствуйте, проделал, вообщем всё что вы тут написали, и оно работает частично, проговаривая приветствие, она говорит что нужно произнести имя после звукового сигнала, в итоге, звукового сигнала в итоге нет и нет времени для ожидания на произношение, она сразу же выдаёт «Пожалуйста повторите» и переадресовывает нас на абонента 101

  3. Руслан:

    В итоге после 24 часов стараний, я так пока и не смог запустить сие чудо, по моему у меня просто не отрабатывает speech-recog.agi.

  4. Игорь:

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

* - обязательные к заполнению поля