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

Расширение сценария

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

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

На данном шаге рассмотрим, как дополнить сценарий нашего обзвона следующими возможностями:

Перезвон

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

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

Сперва поддержим соответствующий класс запросов в NLU.

  1. Перейдите в NLU > Сущности > Системные и включите сущность @duckling.time для распознавания даты и времени.
  2. Перейдите в NLU > Интенты и добавьте новый интент /Перезвоните со следующими настройками:

Интент /Перезвоните

В Тренировочные фразы включите примеры как с упоминанием даты и времени, так и без него. Вместо указания конкретного времени используйте название системной сущности @duckling.time.

Далее активируйте для данного интента слот-филлинг с одним обязательным слотом dateTime, соответствующим сущности @duckling.time, и добавьте несколько уточняющих вопросов, например:

  • Когда вам перезвонить?
  • Когда можно будет позвонить?
  • Когда я могу вам позвонить?

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

Конфигурация слот-филлинга

Перейдем в редактор сценариев. Сперва откройте конфигурационный файл chatbot.yaml и дополните его полем injector, в котором укажите настройки прерывания слот-филлинга:

injector:
slotfilling:
maxSlotRetries: 3
stopOnAnyIntent: false
stopOnAnyIntentThreshold: 0.2

В данном случае параметр maxSlotRetries: 3 означает, что бот дважды переспросит время перезвона, если не распознает его в ответах. Если клиент назовет некорректное время в третий раз, слот-филлинг прервется, а запрос попадет в стейт /Симптомы/Ответ по активатору event!: noMatch.

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

Дополнение сценария

Осталось подключить в main.sc модуль слот-филлинга и добавить в корневую тему theme новый стейт:

require: slotfilling/slotFilling.sc
module = sys.zb-common

theme: /

state: Перезвоните
intent!: /Перезвоните
a: Хорошо, перезвоню вам позже!
script:
$dialer.setCallResult("Просьба перезвонить");
$dialer.redial({startDateTime: new Date($parseTree._dateTime.timestamp)});
go!: /Прощание

Метод $dialer.redial запланирует новый звонок с учетом нужного времени и включит его в обзвон.

Перебивание

Не всегда целесообразно ждать, когда бот закончит говорить, чтобы дать клиенту возможность ответить. Чтобы клиент мог перебивать бота, настройте в сценарии прерывание речевого потока.

Между подключением модуля слот-филлинга и объявлением корневой темы добавьте блок init, в котором установите обработчик postProcess:

init:
bind("postProcess", function(ctx) {
ctx.response.bargeIn = {
bargeIn: "forced",
bargeInTrigger: "interim",
noInterruptTime: 1000
};
}, "/");

В данном случае:

  • bargeIn: "forced" означает, что в случае прерывания бот не договаривает реплику до конца и прерывается сразу;
  • bargeInTrigger: "interim" — режим прерывания с промежуточными результатами распознавания;
  • установка времени noInterruptTime в 1 000 миллисекунд значит, что в течение 1 секунды после начала ответа перебить бота нельзя. Это полезно для защиты от случайных шумов.
подсказка

Обработчик postProcess в данном случае привязан к корневой теме, то есть ко всем стейтам сценария. Для более тонкой настройки перебивания воспользуйтесь методом $dialer.bargeInResponse.

Воспроизведение аудио

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

предупреждение
Аудиофайлы должны удовлетворять ряду требований.

Допустим, что записана реплика Кажется, проблемы со связью, а аудиофайл размещен по адресу https://example.com/comms-issue.wav. Тогда в стейте /NoInput замените строку

a: Кажется, проблемы со связью.

на

audio: https://example.com/comms-issue.wav

Перейдем к тестированию разработанного сценария.