Перейти к основному содержимому

Разработка бота

Это часть серии статей, посвященной созданию исходящего обзвона с использованием NLU.

  1. Настройка подключения
  2. Разработка бота (вы находитесь здесь)
  3. Запуск обзвона
  4. Аналитика по диалогам
  5. Расширение сценария
  6. Тестирование

На данном этапе создадим сценарий бота. В скриптовых вставках мы будем обращаться к различным методам объекта $dialer для взаимодействия с телефонией. Для понимания естественного языка воспользуемся NLU-ядром.

Конфигурационный файл

Перейдите в Редактор и создайте стандартный для проектов на NLU конфигурационный файл chatbot.yaml:

name: call-campaign
entryPoint: main.sc

botEngine: v2
language: ru

nlp:
intentNoMatchThresholds:
phrases: 0.2
patterns: 0.2

Основная часть сценария

Создайте файл src/main.sc и поместите в корневую тему theme основную логику сценария:

theme: /

state: Start
q!: $regex</start>
script:
$jsapi.startSession();
$session.userName = $dialer.getPayload().name || "незнакомец";
$dialer.setCallResult("Приветствие");

a: Приветствую вас, {{$session.userName}}!
a: В связ+и с пандемией коронавируса, мировое правительство проводит информирование граждан.
go!: /Симптомы

state: Симптомы
a: Скажите, наблюдаете ли вы за собой высокую температуру т+ела, сухой кашель, быструю утомляемость?

state: Есть
intent: /Согласие
intent: /Болен
a: В таком случае вам нужна срочная медицинская помощь! Немедленно обратитесь к врачу.
script:
$dialer.reportData("Анамнез", "положительный");
$dialer.setCallResult("Состояние известно");
go!: /Прощание

state: Нет
intent: /Отказ
intent: /Здоров
a: Очень рада, что всё в порядке! Тем не менее, не забывайте мыть руки и носить маски и перчатки.
script:
$dialer.reportData("Анамнез", "отрицательный");
$dialer.setCallResult("Состояние известно");
go!: /Прощание

state: Ответ
event!: noMatch
a: Так и записала: {{$parseTree.text}}. Помните о гигиене и о средствах индивидуальной защиты.
script:
$dialer.reportData("Анамнез", $parseTree.text);
$dialer.setCallResult("Состояние известно");
go!: /Прощание

state: Прощание
event!: hangup
a: Будьте здоровы! До свидания!
script:
$dialer.hangUp();

state: NoInput || noContext = true
event!: speechNotRecognized
script:
$session.noInputCounter = $session.noInputCounter || 0;
$session.noInputCounter++;
if: $session.noInputCounter >= 3
a: Кажется, проблемы со связью.
script:
$dialer.setCallResult("Плохое качество связи");
go!: /Прощание
else:
a: Вас плохо слышно. Повторите, пожалуйста!

Создайте также файл test/test.xml, но пока оставьте его пустым:

<test>
<test-case/>
</test>

Начало диалога

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

подсказка

Используйте спецсимвол + в словах, которые могут читаться по-разному, для корректной постановки ударения в контексте фразы: В связ+и.

  1. Помечает сессию как новую и очищает данные предыдущих сессий, если они были.
  2. Извлекает имя клиента из списка клиентов и сохраняет его в хранилище сессионных данных.
  3. Устанавливает результат звонка, соответствующий текущему шагу диалога.

Если информация об имени клиента отсутствует, используется нейтральное обращение.

state: Start
q!: $regex</start>
script:
$jsapi.startSession();
$session.userName = $dialer.getPayload().name || "незнакомец";
$dialer.setCallResult("Приветствие");

a: Приветствую вас, {{$session.userName}}!
a: В связ+и с пандемией коронавируса, мировое правительство проводит информирование граждан.
go!: /Симптомы
подсказка
Подробнее о методах $jsapi.startSession, $dialer.getPayload и $dialer.setCallResult

Запись ответа от клиента в отчет

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

state: Симптомы
a: Скажите, наблюдаете ли вы за собой высокую температуру т+ела, сухой кашель, быструю утомляемость?

state: Есть
intent: /Согласие
intent: /Болен
a: В таком случае вам нужна срочная медицинская помощь! Немедленно обратитесь к врачу.
script:
$dialer.reportData("Анамнез", "положительный");
$dialer.setCallResult("Состояние известно");
go!: /Прощание

state: Нет
intent: /Отказ
intent: /Здоров
a: Очень рада, что всё в порядке! Тем не менее, не забывайте мыть руки и носить маски и перчатки.
script:
$dialer.reportData("Анамнез", "отрицательный");
$dialer.setCallResult("Состояние известно");
go!: /Прощание

state: Ответ
event!: noMatch
a: Так и записала: {{$parseTree.text}}. Помните о гигиене и о средствах индивидуальной защиты.
script:
$dialer.reportData("Анамнез", $parseTree.text);
$dialer.setCallResult("Состояние известно");
go!: /Прощание
подсказка
Подробнее о методе $dialer.reportData

Окончание диалога

На последнем шаге бот прощается и завершает звонок.

state: Прощание
event!: hangup
a: Будьте здоровы! До свидания!
script:
$dialer.hangUp();
предупреждение
Клиент также попадет в этот стейт, если повесит трубку без ответа на вопрос. Информация о статусе звонка и состоянии здоровья клиента в таком случае обновлена не будет.

Обработка нераспознанных фраз

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

state: NoInput || noContext = true
event!: speechNotRecognized
script:
$session.noInputCounter = $session.noInputCounter || 0;
$session.noInputCounter++;
if: $session.noInputCounter >= 3
a: Кажется, проблемы со связью.
script:
$dialer.setCallResult("Плохое качество связи");
go!: /Прощание
else:
a: Вас плохо слышно. Повторите, пожалуйста!
предупреждение
В любой сценарий для телефонного канала добавляйте обработку события speechNotRecognized и ограничение на число нераспознанных фраз, чтобы заведомо нерезультативные звонки быстро завершались и не расходовали пакеты минут.
подсказка
hangup и speechNotRecognized — одни из системных событий, поддерживаемых для телефонии.

Настройка интентов

Перейдите на вкладку NLU > Интенты и создайте интенты, которые мы использовали в сценарии: /Согласие, /Отказ, /Здоров и /Болен. Наполните их тренировочными фразами, передающими соответствующий смысл, например:

Согласиедаагаочень даженаблюдаю
Отказнеаотнюдьвовсе нетне наблюдаю
Здоровя здоровапроблем нетмы в порядкевсе слава богу
Боленболеюя больнавысокая температурау меня коронавирус

Тренировочные фразы для интента /Здоров

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

Теперь все готово для того, чтобы создать и запустить обзвон.