Настройка AIVR

Материал из Call Office Wiki
Перейти к навигации Перейти к поиску

AIVR (англ. Artificial Intelligence Voice Responder) - интерактивный голосовой автоответчик с распознаванием голоса. Система способна вести диалог с абонентом в соответствии с заданной логикой. Логика диалога настраивается через веб-интерфейс. В данном материалы мы изучим интерфейс и базовые настройки бота.

Интерфейс бота разделён на 2 основных блока:

  Диалоги - здесь вы найдёте логи всех диалогов бота. 
  Правила - этот раздел посвящён логике бота, её структуре и настройке.

Разверните разделы кликом на значке +, чтобы увидеть их содержимое. Разберём подробнее эти блоки.


Диалоги

Раздел диалоги представлен списком состоявшихся диалогов бота. Имена элементов списка состоят из номера диалога, даты и времени диалога и номера телефона (или IP-адреса, если источником связи был веб-интерфейс) абонента. Кликом по элементу списка вы откроете подробную информацию о нём.


Интерфейс диалога

Интерфейс диалога

Шапка диалога содержит мета-информацию о нём. Ниже расположен скрипт разговора, сформированный на основе результатов распознавания.

Элементы скрипта разговора:

  • Клиент - распознанный запрос абонента.
  • Ответ робота - То, что бот ответил абоненту
  • Сработавшее правило - Правило логики бота, инициировавшее ответ. Обратите внимание, если вы измените правило, то в этом блоке будет отображаться ответ бота в соответствии с текущими правилами. Однако блок "Ответ робота" всегда останется неизменным. Таким образом удобно отслеживать изменения логики работы бота на основе старых диалогов.
  • Время начала воспроизведения и Время завершения воспроизведения - тайминги речевой активности. Удобны для отслеживания скорости синтеза и продолжительности произнесения ответа ботом.


Интерактивные элементы интерфейса диалога

Создание нового правила на основе ответа абонента

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

Создание правила


Редактирование текущего правила на основе ответов бота

Клик на значок ручки в разделе "Правило" откроет упрощённый интерфейс для его редактирования.

Редактирование правила


Правила

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

Древовидная логика

Разворачивая элементы сценария кликом по + рядом с ними, вы можете увидеть дочерние правила. Клик по самому правилу откроет подробную информацию о нём.

Пара слов о терминологии

Интерфейс правила

  1. В работе мы используем термин "Контекст". Под контекстом мы подразумеваем набор (иначе, список) правил, произошедших от одного родителя и находящихся на одном уровне. Правила в одном контексте считаются сёстрами и, как правило, объединены одной тематикой. У каждого контекста, кроме базового, есть родительское правило, которое находится в родительском контексте. Так же вы можете встретить фразы типа "Бот находится в таком-то контексте". Это означает, что сработало родительское правило и следующий ответ абонента будет обрабатываться правилами "такого-то контекста".
  2. Базовый контекст - список правил самого верхнего уровня. Как правило, он содержит правила наиболее общей тематики, именно в него вернётся бот, если не найдёт подходящего правила в текущем контексте. Часто вы можете обнаружить самым первым правилом "^Входящий звонок:\s+(.*)" (для автоответчика) или "^Звонок по номеру:\s+(.*)" (для исходящего обзвона). Это "техническое правило" инициализирует бота, а "базовый контекст" следует прямо за ним.


Правила сценария диалога

Создание и редактирование правил

Разберём подробнее структуру интерфейса правила:

  • Родительский вопрос. Содержит ссылку на "родительское правило". Подробнее в разделе 3.2.1
  • Бот. Указывает к какому боту относится правило. В одном аккаунте может быть несколько ботов.
  • Название. Просто название правило. Влияет только на отображение правила в древовидной структуре сценария.
  • Текст вопроса. Обязательный элемент и основное условия выполнения правила. Должен содержать текст или регулярное выражение, на которое среагирует текущее правило. Подробнее о создании текста вопроса мы разберём позднее.
  • Текст ответа. Обязательный элемент. Должен содержать текст, который будет синтезирован и произнесён роботом в случае выполнения условия "Текст вопроса".
  • Перейти в контекст. Итогом выполнения правила может быть переход к другому (не дочернему). Такое правило должно принадлежать текущему боту и содержать собственные дочерние элементы.
  • Порядок сортировки. Определяет, какое правило сработает, если запрос абонента соответствует условиям (текстам вопроса) сразу нескольких правил одного уровня.
  • Ссылка на пользователя указывает на профиль автора правила.
  • Дата создания. Здесь всё понятно.

Отдельно необходимо упомянуть интерактивный элемент интерфейса правила "Правило сработало на фразах (показать)". Клик на этом элементе выведет список фраз из истории диалогов бота, соответствующих условию (текст вопроса) текущего правила. Это удобно для проверки созданного вами правила. Обратите внимание, если ваш бот имеет долгую историю диалогов, то поиск соответствий может потребовать некоторого времени.

Ассоциации правила


Создание и редактирование правил сценария диалога

В интерфейсе правила вы найдёте три основных кнопки для настройки вашего бота: "Добавить", "Редактировать" и "Удалить".

  • Кнопка "Добавить" инициирует создание нового правила через дублирование текущего. То есть открывается интерфейс создания правила и доступные поля заполняются данными из текущего правила.
  • А "Редактировать" открывает интерфейс для изменения параметров текущего правила.

Интерфейсы для создания и редактирования правил соответствуют основному интерфейсу правила, появляется только одно новое поле "Примечание". Его содержимое не влияет на работу правила.


Порядок сортировки

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

  1. Чем шире правило - тем оно "тяжелее", тем больше число в поле "Порядок сортировки" и ниже его позиция в списке.
  2. Универсальные правила, например ".*" или "^\s*$", должны иметь максимальный порядок сортировки. Мы используем 10000.
  3. Как правило, для рядовых элементов контекста мы используем порядок сортировки в сотнях: 100, 200, 300 и т.д. Это позволяет добавлять новые элементы без обновления порядка сортировки всего списка, например, 150, 175 и т.д.


Родительские и дочерние правила

Наследование

Линейная логика подразумевает последовательное выполнение предопределённых команд. При таком подходе подходе все команды по отношению друг к другу являются предыдущими и последующими или родительскими и дочерними. Отсутствие родителя означает, что правила находиться в "основном контексте" или на первой линии. Наличие родительского правила означает, что, помимо основного основного условия "текст вопроса", должно быть выполнено дополнительное условие - следование за родителем. Родственные связи правил изображаются вложенностью в древовидном интерфейсе сценария диалога: дочерние элементы "вложены" в родительские и разворачиваются нажатием на кнопку +.


Переход в контекст

Итогом выполнения правила может быть переход ни только к дочерним, но и к любому другому произвольному правилу. Его можно указать в поле "Переход в контекст".

Переход

Есть несколько условий:

  1. Такое правило должно принадлежать текущему боту и содержать собственные дочерние элементы.
  2. Переход выполняется последним в списке действий для текущего правила. То есть сначала будет произнесён текст и т.д. и последним будет переход.
  3. Переход по сути подменяет дочерние элементы. Дело в том, что целевое для переходя правило вообще не играет роли: его условия не выполняются, текст не произносится и т.д., просто вслед за выполнением текущего правила мы начинаем выполнять дочерние правила от целевого.
  4. Если указан переход, то собственные дочерние элементы игнорируются.

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

Создание текста вопроса

Поле "текст вопроса" содержит условия обработчика результатов распознавания речи абонента. Если обработчик находит совпадение с указанным условием, то правило срабатывает. Можно выделить 4 основных инструмента для формирования условий обработчика, но все они взаимно дополняют друг-друга и пересекаются.


Простой текст

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

  • как дела - сработает, если текст запроса содержит фразу "как дела".
  • ^как дела$ - используйте, если запрос должен содержать только этот текст. ^ - начало строки, $ - конец строки.

Варианты

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

  • (каша|крупа|ячмень|греча) - правило сработает, если обработчик встретит в ответе абонента любое из слов. Можно значительно расширить выборку, если убрать окончания слов.
  • (каш|круп|ячмен|греч) - сработает в том числе и на словоформы "гречка", "кашица" и т.д.
  • как (дела|жизнь) - сработает на фразах "как дела" и "как жизнь".
  • как\s+(дела|жизнь) - сработает на фразах "как дела" и "как жизнь", причем между "как" и остальной фразой может быть любое количество пробельных символов.
  • как.+(дела|жизнь) - сработает на фразах "как дела" и "как жизнь", причем между "как" и остальной фразой может быть 1 или больше любых символов.

Макросы

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

     Диалоговые макросы
     [hello] - Приветствие. Включает в себя самые популярные варианты старта телефонного разговора, в том числе "Алло", "Слушаю" и т.д.
     [yes] - Да. Позитивный ответ во всём его многообразии. В том числе макрос защищён от "Да нет" и других противных исключений
     [no] - Нет. Негативный ответ.
     [dnu] - 	Не понял. Макрос сработает, если абонент как-либо выразил непонимание. 
     [nothear] - Не слышу. Реагирует на "плохо слышно", "ничего не слышу" и т.д.
     [cnt] - Сбор контактных данных. Получит произнесённый абонентом электронный адрес или номер телефона. Полученные данные могут быть передано в Call Office для последующей обработки.
     Для обзвона
     [ivr] - Автоответчик. Макрос сработает, если обнаружит в тексте ключевые фразы, типичные для автоответчиков и IVR.
     [tvr] - Голосовые сообщения телефонии о ошибках. Например, "номер не обслуживается", "вне зоны доступа", "звонок на данное направление недоступен".
     [ntg] - Не туда попали.
     [busy] - Занят. "Сейчас занят", "Мне некогда", "Перезвоните" и т.д.
     Макросы ответа (Эти макросы работают в ответе бота)
     [last] - Бот повторяет свой последний ответ. Может быть использован для ответа на запрос абонента "Не расслышал, повторите."

Регулярные выражения

Регулярки - это просто и удобно. В них нет ничего страшного. Мы изучим самые основные

     1. Символы
        Этот класс регулярных выражений используется для обозначения различных элементов текста, в том числе букв, цифр, пробелов и спецсимволов. Чаще всего используются:
        . - любой символ
        (...) - группа, может содержать любой набор символов
        \s - пробел
        \S - не пробел
     2. Кванторы
        Нужны для обозначения количества символов
        * - 0 или больше
        + - 1 или больше
        ? - 0 или 1

Пример:

     .* - любое количество любых символов
     \s+ - 1 или более пробелов
     соедини\S*\s+(меня\s+)?с\s+директором - "меня" может быть или не быть, конструкция \S*\s+ означает "любое количество непробельных символов и 1 или больше пробелов"

Пара слов о ".*"

Правил на одном уровне может быть любое количество, однако не стоит надеяться, что вы сможете охватить все возможные варианты ответа абонента. Если бот не найдёт в ответе абонента текст, соответствий текущему набору правил, то он вернётся в базовый контекст (на самый верхний уровень) и повторит поиск по нему. Если вы не хотите, чтобы бот возвращался в начало пути, то используйте универсальное правило ".*". Это регулярное выражение означает просто "любые символы в любом количестве", используйте его как условие для завершающего правила контекста, чтобы обеспечить порядок наследования структуры диалога.

Внимание! Данное правило срабатывает всегда и должно быть последним в контексте! Укажите ему максимальный порядок сортировки! Мы всегда используем порядок сортировки равный 10000.

Настройка работы регулярных выражений и макросов с результатами распознавания

AIVR может использовать 2 формата обработки результатов распознавания: промежуточные результаты распознавания и окончательный вариант. Для того, чтобы существенно сократить время реакции бота на вопросы абонента вы можете использовать обработку промежуточных результатов. Данный параметр включается в настройках распознавания в Call Office. Однако промежуточные результаты подходят не для всех задач. Например, нельзя обрабатывать контактные данные, полученные из промежуточных результатов распознавания, они будут неполными. Если ваша задача требует использования окончательного результата распознавания, используйте в правиле <nointerim> в синтаксисе

 <nointerim>[макрос] или (регулярное выражение)

Если вам необходимо обрабатывать только промежуточные результаты, используйте <interim> в синтаксисе:

 <interim>[макрос] или (регулярное выражение)

Передача команд Call Office из бота

Call Office может выполнять запрограммированные действия по команде бота. Для этого используется формальная конструкция вида

 Action (Вид действия:[$1]);

Где [$1] - информация, полученная регулярным выражением из запроса абонента (не обязательно)

При получении такой конструкции в ответе бота, Call Office может выделить её и интерпретировать. Например, мы реализуем это решение такими средствами:

1. Call Office при получении ответа от бота, кладёт его в переменную Out. Затем мы обробатываем его регуляркой

  function () {
     var Find = /^Action\s*\((.*)\);\s*(.*)/.exec (Script.GetVariable ('Out'));
     if (Find !== null) {
        Script.AddVariable ('Action', Find[1]);    // Это наша команда
        Script.AddVariable ('Out', Find[2]);       // Это текст, который будет озвучен
     }
  }

2. Затем в одном скрипте мы задаём Call Office задачу посредством конструкции switch. Например:

  function () {
    Script.SendInfo ('Выполняем действие: ' + Script.GetVariable ('Action'));
      switch (Script.GetVariable ('Action')) {
        case 'Transfer':                              // Если передана команда "Перевод звонка на оператора"
           Script.AddVariable ('IsTransfer', true);   // Ставим задачу на перевод
           Script.SendInfo ('Перевод на оператора');  // Шлём уведомление в интерфейс бота
           Script.InLogInfo ('Перевод на оператора'); // Пишем уведомление в лог
      break;
      default:
        if (Script.GetVariable ('Action').substring (0, 5) == "DTMF:") {      // Если пришла команда на воспроизведение тонального сигнала Action(DTMF:число)
           var Sign = Script.GetVariable ('Action').match(/DTMF:([0-9*#]+)/); // Вычленяем число
           if (Sign != null) {
              Script.SendInfo ('Отправляем тональные сигналы: ' + Sign[1]);   // Пишем в лог
              Script.InLogInfo ('Отправляем тональные сигналы: ' + Sign[1]);  // Пишем в интерфейс бота
              Device.SendDTMF (Sign[1]);                                      // Воспроизводим тональный сигнал в телефонную линию
           }
        }
        break;
        if (Script.GetVariable ('Action').substring (0, 4) == "CNT:") {       // Если получены контактные данные Action(CNT:номер телефона или email)
           var Cont = Script.GetVariable ('Action').match(/CNT:(.*)/);        // Вычленяем данные
           if (Cont != null) {
              Script.SendInfo ('Получены контактные данные: ' + Cont[1]);     // Пишем данные в лог
              Script.InLogInfo ('Получены контактные данные: ' + Cont[1]);    // Пишем данные в интерфейс бота
           }
        }
        break;
     }
  }

Таким образом можно задать любые действия: от изменения статуса звонка, до запланированной отправки SMS.