Описание сервиса
Сервис автосекретарь распознает имя и фамилию абонента, которому вы хотите позвонить. После чего производит вызов на данного абонента.
Пример:
Абонент снимает трубку и набирает номер, на который завязан ivr-скрипт автосекретаря. После приветствия, абонент произносит фразу: Владислав Блинов. Система распознает данные слова и пытается найти в телефонной книге, соответствие имени и фамилии с номером. В случае успеха, система производит вызов на номер абонента.
Архитектура
- Clerk — он же ecss-clerk или автосекретарь. HTTP-сервер (elixir/phoenix), принимающий запросы на распознавание и отдающий результаты в виде JSON;
- Asr Manager — HTTP-сервер (python), который управляет TCP-инстансами Kaldi. Может пересобрать модель, добавив новые слова, держать несколько экземпляров tcp-серверов и управлять ими;
- TCP Asr Server — собственно, один из инстансов, которым управляет Asr Manager.
Принцип работы
Пользователь снимает трубку и набирает номер, на который завязан ivr-скрипт автосекретаря. После синтезированного приветствия, в котором пользователя просят произнести имя и фамилию, поток с его микрофона отправляется на специальный порт MSR, который работает по следующему принципу: определяет тишину и нарезает по ней чанки. Каждый чанк отправляется отдельным HTTP POST-запросом в сторону ecss-clerk (через restfs) с заголовком "Content-type: Transfer-Encoding". По имени wav-файла ecss-clerk и идентифицирует чанк. Каждый чанк отправляется на распознавание, по результату которого phonebook пытается найти подходящий номер. Если не удалось, clerk просит следующий чанк и так до тех пор, пока не получится найти номер или не сработает таймаут в ivr-скрипте.
В случае успеха, json с номером летит на MSR через restfs, MSR отдает json ядру. Промежуточные ответы тоже доходят до ядра. Они имеют HTTP-код 206 и не содержат в прилагаемом теле json-а поля с номером, но имеют поле с распознанной строкой. Имея эту строку, по таймауту ivr может синтезировать ответ для пользователя, уведомив о том, что найти распознанную строку не удалось. Если до таймаута ecss-clerk не пришлёт ответ ядру, то синтезированное уведомление не будет содержать распознанной строки.
Синтез происходит через restfs. Resfts проксирует запрос на настроенный tts-сервер.
После получения PCM ecss-clerk выполняет следующие действия:
- Отправляет pcm на распознавание (через TCP);
- По результату распознавания пытается найти номер в телефонной книге;
- Посылает ответ.
Принцип поиска распознанной строки в телефонной книге
Ответ от ASR
На этапе поиска по телефонной книге уже получен ответ от ASR.
Причем ответ — это не просто строка, а список строк.
Условный пример ответа от ASR:
алексей
алексей лосев
алексей лысенко
Который преобразуем в список вида:
["алексей лысенко", "алексей лосев", "алексей"]
Где "алексей лысенко" финальный результат, а остальные промежуточные.
Причина, по которой мы учитываем промежуточные варианты проста — в них может быть правильный вариант распознавания. Вероятность этого мала, но она есть.
По какой книге производится поиск
Поиск производится по xml-книге, взятой с restfs.
Restfs, в свою очередь, формирует xml по данным из одного выбранного источника: ssw, mysql, ldap.
При старте автосекретаря производится импорт xml. По ней формируется структура вида ключ-значение, где ключ — имя, значение — телефон.
Кроме этого, формируется ещё одна подобная структура, содержащая уникальные имена и фамилии из книги, где ключ — уникальное имя, значение — полное имя.
По этим двум мапам — телефонной книге и уникальным именам и производится поиск.
Алгоритм поиска
- Берем строку из списка;
- Проверяем, содержится ли данная строка в таблице hard_aliases;
- Раскрываем сокращения (алиасы из таблицы aliases) и добавляем их в список, по которому будет производиться рекурсивный поиск;
- По каждой строке в сформированном списке делаем поиск:
- Формируем список с перестановками для строки:
- Проверяем, содержится ли строка (именно целиком, а не как подстрока) в уникальных именах. Если да — заменяем эту строку на полное имя;
- Ищем строку в телефонной книге. Если номер найден — поиск закончен.
- Формируем список с перестановками для строки:
- Если в списке из пункта 3 ещё остались строки, то берем следующую.
Пример
Имеем ответ от ASR:
["женя казарцев", "женя казарцев", "женя"]
Двигаемся согласно алгоритму:
- Берем строку "женя казарцев" из списка;
- Проверяем, содержится ли данная строка в таблице hard_aliases. В нашем примере её нет, так что передаем строку дальше как "женя казарцев";
- Раскрываем сокращения ["женя казарцев", "божена казарцев", "евгений казарцев", "евгения казарцев"];
По каждой строке в сформированном списке делаем поиск строки;
Строки "женя казарцев" и "божена казарцев" пропущены, т.к. пройдя всю цепочку ниже номера для них не были найдены.
Выбираем строку "евгений казарцев":
- Формируем список с перестановками для строки ["евгений казарцев", "казарцев евгений"]
- Проверяем, содержится ли строка (именно целиком, а не как подстрока) в уникальных именах. Если да — заменяем эту строку на полное имя. Если не содержится, передаем как есть — "евгений казарцев";
- Ищем строку в телефонной книге. Если не найден — берем следующий элемент из списка с перестановками евгений казарцев -> 4819;
- Формируем список с перестановками для строки ["евгений казарцев", "казарцев евгений"]
- Если в списке из пункта 3 ещё остались строки, то берем следующую. Здесь мы пропустили строки "женя казарцев" и "божена казарцев".
Установка
Установка выполняется из репозитория:
deb [arch=amd64] http://archive.eltex.org/ssw/bionic/clerk/1.0 unstable main extras external
Необходимо установить пакет ecss-clerk:
sudo apt install ecss-clerk
Во время установки необходимо ответить на все задаваемые вопросы, особенно важно указать правильный url для импорта телефонной книги в формате xml и данные mysql пользователя.
Ответы на вопросы более детально описаны ниже.
Во время установки будут применены миграции в бд (создание базы данных, таблицы и т.д.).
Во время первого запуска начнут создаваться стандартная база слов (около 6,5 тысяч).
После создания базы рекомендуется запустить рекомпиляцию asr-модели.
Ответы на вопросы:
Вопросы | Ответы |
---|---|
Выберите IPv4 для ecss-clerk (Choise IPv4 for ecss-clerk) | IP хоста |
Укажите порт для ecss-clerk (Enter ecss-clerk port) | 9010 |
Хотите ли вы сохранить записи? (Do you want save records?) | yes |
Введите частоту дискретизации (Enter sample rate) | 8000 |
Введите URL-адрес для импорта xml-телефонной книги (Enter url for import xml phonebook) | http://system.restfs.ecss:9990/ssw?host=book&user_agent=cisco_search&translit=false&skip_no_disp=true |
Уровень логирования (Log level) | debug |
Как вы хотите настроить пользователя mysql? (How do you want configure mysql user?) | create |
Введите логин пользователя MySQL (Enter login for mysql user) | ecss-clerk |
Введите размещения пользователя MySQL (Enter mysql user host) | 127.0.0.1 |
Введите пароль для пользователя mysql (Enter password for mysql user) | password |
Управление через systemd
Убедитесь, что сервисы запущены:
sudo systemctl status ecss-clerk
sudo systemctl status kaldi-ru
В противном случае сервис необходимо включить.
sudo systemctl start ecss-clerk
sudo systemctl start kaldi-ru
Конфигурация
Конфигурация происходит при установке deb-пакета ecss-clerk. Сам файл с конфигурацией расположен по пути /etc/ecss/ecss-clerk/config.yaml:
http: url: localhost # ip адрес ecss-clerk port: 9010 # порт ecss-clerk asr: manager: ip: localhost # ip адрес http сервера kaldi (kaldi-ru) port: 9011 # порт http сервера kaldi (kaldi-ru) backend: tcp_kaldi # сервис, с помощью чего kaldi-ru запускает модель (сейчас не используется) frequency: 8000 # частота, на которой будет запущен asr pcm: save_pcm: true # сохранять ли приходящие pcm pcm_dir: /var/lib/ecss/ecss-clerk/pcm_files # куда сохранять pcm, если нужно phonebook: url_xml: http://system.restfs.ecss:9990/ssw?host=book&user_agent=cisco_search&translit=false&skip_no_disp=true # url для импорта xml книги log: level: debug # уровень лога console_level: info # уровень консольного лога (видно через journalctl) path: /var/log/ecss/ecss-clerk # куда писать лог database: database: ecss_clerk_db_repo # название бд в mysql username: ecss-clerk password: password hostname: localhost aliases_dir: /var/lib/ecss/ecss-clerk/default_aliases # директория, в которой хранятся файлы с дефолтными сокращениями (для миграции)
Править конфигурацию руками не рекомендуется, лучше делать это через dpkg-reconfigure
sudo dpkg-reconfigure ecss-clerk
Проверка работоспособности
Для проверки работоспособности можно обратиться к сервису через curl:
curl <host>:9010/test.pcm -T test.pcm
Где
- host — адрес хоста, на котором запущен ecss-clerk;
- test.pcm — частота из config.yaml, кодек pcm_s16le, 1 канал (можно с wav заголовком).
Настройка на стороне ECSS-10
Интеграция с ECSS-10 выполнена через IVR-скрипт.
После звонка на ivr, голос от абонента идет на asr_service. Если до таймаута приходит ответ с номером, то происходит звонок на этого абонента. В противном случае мы оказываемся в другой ветке, из которой делается повторный запрос (блок goto, который выполняется 2 раза). Причем, если промежуточный ответ от автосекретаря содержал не пустое поле с распознанной строкой, то она будет произнесена. Кроме этого есть два RPС блока, необходимые для вызова коллбеков на стороне ecss-clerk. Они тегируют запросы как удачные и не удачные. Соответственно, если было падение с таймаутом, то будет вызван негативный коллбек (negative_url). Если в ответе был номер, то будет вызван удачный коллбек (positive_url).
После установки ecss-clerk скрипт можно найти в папке /etc/ecss/ecss-clerk/simple_auto_attendant5.json
Импортировать скрипт можно через интерфейс командной строки:
domain/<DOMAIN>/ivr/script/.import --id simple_auto_attendant5 --json <IVR-скрипт>
Пример
admin@[sip1@ecss1#ECSS 010145]:/$ domain/arko/ivr/script/.import --id simple_auto_attendant5 --json {"actions":{"begin_1":{"name":"begin","params":{"description":""},"pos":{"x":2,"y":0},"cases":{"next":"ivr_2"} / ... / "emotion":"good","terminate_if_tts_failed":false}},"id":"163xd8a7ecfd21v5"} Script successfully imported with id <<"simple_auto_attendant5">>
После импорта нужно зайти IVR редактор, выбрать скрипт "simple_auto_attendant5" и в поле "адрес сервиса распознавания речи" блока "ivr" указать ip-адрес и порт сервера с установленным ecss-clerk.
Затем необходимо настроить нового абонента, включить на нём услугу «personal ivr» и выбрать скрипт, проимпортированный ранее.
Для добавления собственных слов в базу нужно воспользоваться HTTP API сервиса ecss-clerk. Более подробно об этом написано в данном разделе.
Добавить комментарий