Настройка AIVR: различия между версиями

Материал из Call Office Wiki
Перейти к навигации Перейти к поиску
 
(не показано 46 промежуточных версий 2 участников)
Строка 6: Строка 6:


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


== Диалоги ==
== Диалоги ==


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


=== Интерфейс диалога ===
=== Интерфейс диалога ===
Строка 21: Строка 23:
* '''Сработавшее правил'''о - Правило логики бота, инициировавшее ответ. Обратите внимание, если вы измените правило, то в этом блоке будет отображаться ответ бота в соответствии с текущими правилами. Однако блок "Ответ робота" всегда останется неизменным. Таким образом удобно отслеживать изменения логики работы бота на основе старых диалогов.  
* '''Сработавшее правил'''о - Правило логики бота, инициировавшее ответ. Обратите внимание, если вы измените правило, то в этом блоке будет отображаться ответ бота в соответствии с текущими правилами. Однако блок "Ответ робота" всегда останется неизменным. Таким образом удобно отслеживать изменения логики работы бота на основе старых диалогов.  
* '''Время начала воспроизведения''' и '''Время завершения воспроизведения''' - тайминги речевой активности. Удобны для отслеживания скорости синтеза и продолжительности произнесения ответа ботом.
* '''Время начала воспроизведения''' и '''Время завершения воспроизведения''' - тайминги речевой активности. Удобны для отслеживания скорости синтеза и продолжительности произнесения ответа ботом.
     
 
 
=== Интерактивные элементы интерфейса диалога ===
=== Интерактивные элементы интерфейса диалога ===
 
 
 
==== Создание нового правила на основе ответа абонента ====
==== Создание нового правила на основе ответа абонента ====
Кликните на '''зелёный плюсик''' рядом с ответом абонента, чтобы открыть упрощённый интерфейс создания нового правила. Эта опция удобна для быстрого дополнения логики бота на основе не отвеченных запросов из истории диалогов. Ниже мы подробнее разберём процесс создания новых правил.


[[Файл:2_l_add.png|1000px|Создание правила]]
[[Файл:2_l_add.png|1000px|Создание правила]]
     
 
Кликните на '''зелёный плюсик''' рядом с ответом абонента, чтобы открыть упрощённый интерфейс создания нового правила. Эта опция удобна для быстрого дополнения логики бота на основе не отвеченных запросов из истории диалогов. Ниже мы подробнее разберём процесс создания новых правил.
 
     
==== Редактирование текущего правила на основе ответов бота ====
==== Редактирование текущего правила на основе ответов бота ====
Клик на '''значок ручки''' в разделе "Правило" откроет упрощённый интерфейс для его редактирования.


[[Файл:3_l_edit.png|1000px|Редактирование правила]]
[[Файл:3_l_edit.png|1000px|Редактирование правила]]
     
 
Клик на '''значок ручки''' в разделе "Правило" откроет упрощённый интерфейс для его редактирования.


== Правила ==
== Правила ==
Строка 42: Строка 48:
[[Файл:4_r_rules.png|1000px|Древовидная логика]]
[[Файл:4_r_rules.png|1000px|Древовидная логика]]


Разворачивая элементы сценария кликом по + рябом с ними, вы можете увидеть дочерние правила. Клик по самому правилу откроет подробную информацию о нём.
Разворачивая элементы сценария кликом по + рядом с ними, вы можете увидеть дочерние правила. Клик по самому правилу откроет подробную информацию о нём.
 
'''Пара слов о терминологии'''
 
[[Файл:5_r_rule.png|1000px|Интерфейс правила]]


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


=== Правила сценария диалога ===
=== Правила сценария диалога ===
[[Файл:5_r_rule.png|1000px|Интерфейс правила]]
[[Файл:7_r_edit.png|800px|Создание и редактирование правил]]
    
    
Разберём подробнее '''структуру интерфейса правила''':
Разберём подробнее '''структуру интерфейса правила''':
Строка 64: Строка 74:
Отдельно необходимо упомянуть интерактивный элемент интерфейса правила '''"Правило сработало на фразах (показать)'''". Клик на этом элементе выведет список фраз из истории диалогов бота, соответствующих условию ('''текст вопроса''') текущего правила. Это удобно для проверки созданного вами правила. Обратите внимание, если ваш бот имеет долгую историю диалогов, то поиск соответствий может потребовать некоторого времени.
Отдельно необходимо упомянуть интерактивный элемент интерфейса правила '''"Правило сработало на фразах (показать)'''". Клик на этом элементе выведет список фраз из истории диалогов бота, соответствующих условию ('''текст вопроса''') текущего правила. Это удобно для проверки созданного вами правила. Обратите внимание, если ваш бот имеет долгую историю диалогов, то поиск соответствий может потребовать некоторого времени.


[[Файл:6_r_associate|1000px|Ассоциации правила]]
[[Файл:6_r_associate.png|1000px|Ассоциации правила]]
     
 
 
=== Создание и редактирование правил сценария диалога ===
=== Создание и редактирование правил сценария диалога ===
[[Файл:7_r_edit.png|800px|Создание и редактирование правил]]
    
    
В интерфейсе правила вы найдёте три основных кнопки для настройки вашего бота: "'''Добавить'''", "'''Редактировать'''" и "'''Удалить'''".
В интерфейсе правила вы найдёте три основных кнопки для настройки вашего бота: "'''Добавить'''", "'''Редактировать'''" и "'''Удалить'''".
Строка 74: Строка 84:
        
        
Интерфейсы для создания и редактирования правил соответствуют основному интерфейсу правила, появляется только одно новое поле "'''Примечание'''". Его содержимое не влияет на работу правила.
Интерфейсы для создания и редактирования правил соответствуют основному интерфейсу правила, появляется только одно новое поле "'''Примечание'''". Его содержимое не влияет на работу правила.
     
 
 
=== Порядок сортировки ===
=== Порядок сортировки ===
Вы свободны в указании любых значений в поле "Порядок сортировки". Однако мы рекомендуем следовать нескольким простым принципам, чтобы избежать проблем:
Вы свободны в указании любых значений в поле "Порядок сортировки". Однако мы рекомендуем следовать нескольким простым принципам, чтобы избежать проблем:
Строка 81: Строка 92:
# Универсальные правила, например ".*" или "^\s*$", должны иметь максимальный порядок сортировки. Мы используем 10000.
# Универсальные правила, например ".*" или "^\s*$", должны иметь максимальный порядок сортировки. Мы используем 10000.
# Как правило, для рядовых элементов контекста мы используем порядок сортировки в сотнях: 100, 200, 300 и т.д. Это позволяет добавлять новые элементы без обновления порядка сортировки всего списка, например, 150, 175 и т.д.
# Как правило, для рядовых элементов контекста мы используем порядок сортировки в сотнях: 100, 200, 300 и т.д. Это позволяет добавлять новые элементы без обновления порядка сортировки всего списка, например, 150, 175 и т.д.
     
 
 
=== Родительские и дочерние правила ===
=== Родительские и дочерние правила ===


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


[[Файл:9_r_transit.png|1000px|Переход]]
[[Файл:9_r_transit.png|1000px|Переход]]
        
        
Итогом выполнения правила может быть переход ни только к дочерним, но и к любому другому произвольному правилу. Его можно указать в поле "'''Переход в контекст'''". Есть несколько условий:  
Есть несколько условий:  
        
        
# Такое правило должно принадлежать текущему боту и содержать собственные '''дочерние элементы'''.
# Такое правило должно принадлежать текущему боту и содержать собственные '''дочерние элементы'''.
Строка 101: Строка 116:
        
        
Используя наследование и переходы можно создавать сценарии диалогов практически любой сложности, в том числе зацикленные. Кроме того, использование переходов сэкономит вам существенное кличество времени на дублировании идентичных правил для разных ветвей диалога.
Используя наследование и переходы можно создавать сценарии диалогов практически любой сложности, в том числе зацикленные. Кроме того, использование переходов сэкономит вам существенное кличество времени на дублировании идентичных правил для разных ветвей диалога.
     
 
== Создание текста вопроса ==
== Создание текста вопроса ==
Поле "'''текст вопроса'''" содержит условия обработчика результатов распознавания речи абонента. Если обработчик находит совпадение с указанным условием, то правило срабатывает. Можно выделить 4 основных инструмента для формирования условий обработчика, но все они взаимно дополняют друг-друга и пересекаются.


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


=== Простой текст ===
=== Простой текст ===
Просто укажите текст, на который должен среагировать бот. В данном случае происходит поиск по полному, добуквенному соответствию.
Просто укажите '''текст''', на который должен среагировать бот. В данном случае происходит поиск по полному, '''добуквенному''' соответствию.
 
*'''как дела''' - сработает, если текст запроса содержит фразу "как дела".
*'''^как дела$''' - используйте, если запрос должен содержать '''только''' этот текст. ^ - начало строки, $ - конец строки.
 
=== Варианты ===
=== Варианты ===
Расширьте вариативность поиска, добавив варианты текста в одно правило. Варианты указываются в скобках и разделяются символом |. Пример: (каша|крупа|ячмень|греча). Правило сработает, если обработчик встретит в ответе абонента любое из слов. Можно значительно расширить выборку, если убрать окончания слов. Например, правило (каш|круп|ячмен|греч) сработает в том числе и на словоформы "гречка", "кашица" и т.д.
Расширьте вариативность поиска, добавив варианты текста в одно правило. Варианты указываются в скобках и разделяются символом |.  
 
*'''(каша|крупа|ячмень|греча)''' - правило сработает, если обработчик встретит в ответе абонента любое из слов. Можно значительно расширить выборку, если убрать окончания слов.  
=== Макросы ===
*'''(каш|круп|ячмен|греч)''' - сработает в том числе и на словоформы "гречка", "кашица" и т.д.
Мы создали несколько универсальных "текстов вопроса", которые могут существенно упростить вам создание вашего бота. Соответствующие им реакции абонентов встречаются чаще всего. Просто добавьте их в поле "текст вопроса" в квадратных скобках и вам не потребуется тратить время на создание сложных регулярных выражений.
*'''как (дела|жизнь)''' - сработает на фразах "как дела" и "как жизнь".
*'''как\s+(дела|жизнь)''' - сработает на фразах "как дела" и "как жизнь", причем между "как" и остальной фразой может быть любое количество пробельных символов.
*'''как.+(дела|жизнь)''' - сработает на фразах "как дела" и "как жизнь", причем между "как" и остальной фразой может быть 1 или больше любых символов.


      Диалоговые макросы
=== Регулярные выражения ===
      [hello] - Приветствие. Включает в себя самые популярные варианты старта телефонного разговора, в том числе "Алло", "Слушаю" и т.д.
      [yes] - Да. Позитивный ответ во всём его многообразии. В том числе макрос защищён от "Да нет" и других противных исключений
      [no] - Нет. Негативный ответ.
      [dnu] - Не понял. Макрос сработает, если абонент как-либо выразил непонимание.
      [nothear] - Не слышу. Реагирует на "плохо слышно", "ничего не слышу" и т.д.


      Для обзвона
'''Регулярки''' - это просто и удобно. В них нет ничего страшного. Мы изучим самые основные
      [ivr] - Автоответчик. Макрос сработает, если обнаружит в тексте ключевые фразы, типичные для автоответчиков и IVR.
      [ntg] - Не туда попали.
      [busy] - Занят. "Сейчас занят", "Мне некогда", "Перезвоните" и т.д.
 
=== Регулярные выражения ===
Регулярки - это просто и удобно. В них нет ничего страшного. Мы изучим самые основные


     
       '''1. Символы'''
       '''1. Символы'''
         Этот класс регулярных выражений используется для обозначения различных элементов текста, в том числе букв, цифр, пробелов и спецсимволов. Чаще всего используются:
         Этот класс регулярных выражений используется для обозначения различных элементов текста, в том числе букв, цифр, пробелов и спецсимволов. Чаще всего используются:
Строка 149: Строка 156:
       \s+ - 1 или более пробелов
       \s+ - 1 или более пробелов
       соедини\S*\s+(меня\s+)?с\s+директором - "меня" может быть или не быть, конструкция \S*\s+ означает "любое количество непробельных символов и 1 или больше пробелов"
       соедини\S*\s+(меня\s+)?с\s+директором - "меня" может быть или не быть, конструкция \S*\s+ означает "любое количество непробельных символов и 1 или больше пробелов"
       
=== Пара слов о ".*" ===
Правил на одном уровне может быть любое количество, однако не стоит надеяться, что вы сможете охватить все возможные варианты ответа абонента. Если бот не найдёт в ответе абонента соответствий текущему набору правил, то он '''вернётся в базовый контекст''' (на самый верхний уровень) и повторит поиск по нему. Если вы не хотите, чтобы бот возвращался в начало пути, то используйте универсальное правило "'''.*'''". Это регулярное выражение означает просто "'''любые символы в любом количестве'''", используйте его как условие для завершающего правила контекста, чтобы обеспечить порядок наследования структуры диалога.


'''Внимание! Данное правило срабатывает всегда и должно быть последним в контексте! Укажите ему максимальный порядок сортировки!'''
Пара слов о ".*"
Правил на одном уровне может быть любое количество, однако не стоит надеяться, что вы сможете охватить все возможные варианты ответа абонента. Если бот не найдёт в ответе абонента текст, соответствий текущему набору правил, то он '''вернётся в базовый контекст''' (на самый верхний уровень) и повторит поиск по нему. Если вы не хотите, чтобы бот возвращался в начало пути, то используйте универсальное правило "'''.*'''". Это регулярное выражение означает просто "'''любые символы в любом количестве'''", используйте его как условие для завершающего правила контекста, чтобы обеспечить порядок наследования структуры диалога.
 
'''Внимание! Данное правило срабатывает всегда и должно быть последним в контексте! Укажите ему максимальный порядок сортировки! Мы всегда используем порядок сортировки равный 10000.'''
 
=== Макросы ===
 
Мы создали несколько универсальных "'''текстов вопроса'''", которые могут существенно упростить вам создание вашего бота. Соответствующие им реакции абонентов встречаются чаще всего. Просто добавьте их в поле "'''текст вопроса'''" в квадратных скобках и вам не потребуется тратить время на создание сложных регулярных выражений.
 
      Диалоговые макросы
      [hello] - Приветствие. Включает в себя самые популярные варианты старта телефонного разговора, в том числе "Алло", "Слушаю" и т.д.
      [yes] - Да. Позитивный ответ во всём его многообразии. В том числе макрос защищён от "Да нет" и других противных исключений
      [no] - Нет. Негативный ответ.
      [dnu] - Не понял. Макрос сработает, если абонент как-либо выразил непонимание.
      [nothear] - Не слышу. Реагирует на "плохо слышно", "ничего не слышу" и т.д.
      [cnt] - Сбор контактных данных. Получит произнесённый абонентом электронный адрес или номер телефона. Полученные данные могут быть переданы в Call Office для последующей обработки.
 
      Для обзвона
      [ivr] - Автоответчик. Макрос сработает, если обнаружит в тексте ключевые фразы, типичные для автоответчиков и IVR.
      [tvr] - Голосовые сообщения телефонии о ошибках. Например, "номер не обслуживается", "вне зоны доступа", "звонок на данное направление недоступен".
      [ntg] - Не туда попали.
      [busy] - Занят. "Сейчас занят", "Мне некогда", "Перезвоните" и т.д.
 
      Макросы ответа (Эти макросы работают в ответе бота)
      [last] - Бот повторяет свой последний ответ. Может быть использован для ответа на запрос абонента "Не расслышал, повторите.[last]"
      [calling] - Текст правила вызвавшего контекста.
      [ruletext] или [ruletext: N] - Вставка текста из правила с номером N, или если номер не указан, вставка текста из правила в который осуществляется переход.
      [$N] - текст сработавшей группы регулярного выражения с номером N. Например, текст вопроса: ^Входящий звонок:\s+(.*), выделит номер телефона, который можно подставить в ответ используя макрос [$1].
 
Сейчас [calling] работает из общих правил, [ruletext] работает при явном указании правила для перехода, [ruletext] и [calling] не работабт при переходе в родительский контекст
 
=== Теги ===
Теги используются как в тексте вопроса, так и в тексте ответа и выполняют функцию дополнительной обработки.
*Теги, допустимые в тексте вопроса:
** <interim> - проверка регулярного выражения будет выполнена только если результат распознавания промежуточный.
** <nointerim> - проверка регулярного выражения будет выполнена только если результат распознавания не промежуточный.
** <replace: ("<выражение поиска>", "<текст замены>")> - выполнит замену текста запроса регулярным выражением <выражение поиска> на <текст замены>.
** <expression: (<условие>)> - перед проверкой регулярного выражения будет выполнена проверка <условия>. Если условие будет выполнено, продолжится дальнейшая обработка правила. Условие - выражение на языке php. Например: <expression: (date("G") == 20)> будет выполнено только с 20 до 21 часа.
** <include: (<номер правила>)> - в этом случае будет выполнен поиск в контексте с указанным номером правила. Если в указанном контексте будет найдено подходящее правило, дальнейшая обработка правил прекращается.
*Теги, допустимые в тексте ответа:
** <rand: (<текст 1>, <текст 2>, ... )> - в текст ответа будет подставлен один из вариантов текст 1 - текст N случайным образом.
** <order: (<текст 1>, <текст 2>, ... )> - в текст ответа будет подставлен один из вариантов текст 1 - текст N по порядку.
 
=== Настройка работы регулярных выражений и макросов с результатами распознавания ===
 
AIVR может использовать 2 формата обработки результатов распознавания: промежуточные результаты распознавания и окончательный вариант. Для того, чтобы существенно сократить время реакции бота на вопросы абонента вы можете использовать обработку промежуточных результатов. Данный параметр включается в настройках распознавания в Call Office.
Однако промежуточные результаты подходят не для всех задач. Например, нельзя обрабатывать контактные данные, полученные из промежуточных результатов распознавания, они будут неполными. Если ваша задача требует использования окончательного результата распознавания, используйте в правиле <nointerim> в синтаксисе
  <nointerim>[макрос] или (регулярное выражение)
Если вам необходимо обрабатывать только промежуточные результаты, используйте <interim> в синтаксисе:
  <interim>[макрос] или (регулярное выражение)
Например:
  <interim>[yes]
  <nointerim>(да|хорошо|ок)
 
Макрос [cnt] всегда по умолчанию использует окончательные (<nointerim>) результаты распознавания.
 
== Общие правила ==
 
"Общие правила" - это специальный раздел правил бота, задача которых собрать правила, которые должны срабатывать в любом контексте. Например, к таким правилам можно отнести универсальные макросы: [dnu], [nothear], [cnt], [ivr], [tvr], [ntg], [busy] и т.д.<br>
Суть их в том, что они в каждом контексте обробатываются перед собственными правилами контекста.
 
=== Как объявить "Общие правила" ===
Создать правило с названием "Общие правила" в Основном (корневом) контексте после ".*". Содержание вопроса и ответа не существенны. Все правила, которые будут расположены в контексте "Общие правила" станут такими.
 
=== Важно ===
В общих правилах нельзя размещать ".*", так как они проверяются до собственных правил контекста.
 
== Передача команд для Call Office из бота ==
 
=== Актуальный подход ===
 
Сейчас используется универсальный приём с передачей JSON формата:
  {Action: 'Имя активности', Text: 'Текст который произнесёт робот'}
Создания специальных правил для обработки такого сообщения не требуется, однако, если ваш текст должен содержать переменные конфигурации, например, получаемые из базы, имеет смысл использовать констукцию
  Script.GetExpressionValue ("[Out]")
в правилах "Звуковое сообщение" для повторной обработки [Переменных]: 'Какой-то текст '''[Выборка.ИмяПеременной]'''.'.
 
=== Устаревший подход ===
 
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.

Текущая версия на 08:14, 22 февраля 2022

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 или больше любых символов.

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

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

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

Пример:

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

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

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

Макросы

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

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

Сейчас [calling] работает из общих правил, [ruletext] работает при явном указании правила для перехода, [ruletext] и [calling] не работабт при переходе в родительский контекст

Теги

Теги используются как в тексте вопроса, так и в тексте ответа и выполняют функцию дополнительной обработки.

  • Теги, допустимые в тексте вопроса:
    • <interim> - проверка регулярного выражения будет выполнена только если результат распознавания промежуточный.
    • <nointerim> - проверка регулярного выражения будет выполнена только если результат распознавания не промежуточный.
    • <replace: ("<выражение поиска>", "<текст замены>")> - выполнит замену текста запроса регулярным выражением <выражение поиска> на <текст замены>.
    • <expression: (<условие>)> - перед проверкой регулярного выражения будет выполнена проверка <условия>. Если условие будет выполнено, продолжится дальнейшая обработка правила. Условие - выражение на языке php. Например: <expression: (date("G") == 20)> будет выполнено только с 20 до 21 часа.
    • <include: (<номер правила>)> - в этом случае будет выполнен поиск в контексте с указанным номером правила. Если в указанном контексте будет найдено подходящее правило, дальнейшая обработка правил прекращается.
  • Теги, допустимые в тексте ответа:
    • <rand: (<текст 1>, <текст 2>, ... )> - в текст ответа будет подставлен один из вариантов текст 1 - текст N случайным образом.
    • <order: (<текст 1>, <текст 2>, ... )> - в текст ответа будет подставлен один из вариантов текст 1 - текст N по порядку.

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

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

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

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

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

Например:

 <interim>[yes]
 <nointerim>(да|хорошо|ок)

Макрос [cnt] всегда по умолчанию использует окончательные (<nointerim>) результаты распознавания.

Общие правила

"Общие правила" - это специальный раздел правил бота, задача которых собрать правила, которые должны срабатывать в любом контексте. Например, к таким правилам можно отнести универсальные макросы: [dnu], [nothear], [cnt], [ivr], [tvr], [ntg], [busy] и т.д.
Суть их в том, что они в каждом контексте обробатываются перед собственными правилами контекста.

Как объявить "Общие правила"

Создать правило с названием "Общие правила" в Основном (корневом) контексте после ".*". Содержание вопроса и ответа не существенны. Все правила, которые будут расположены в контексте "Общие правила" станут такими.

Важно

В общих правилах нельзя размещать ".*", так как они проверяются до собственных правил контекста.

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

Актуальный подход

Сейчас используется универсальный приём с передачей JSON формата:

  {Action: 'Имя активности', Text: 'Текст который произнесёт робот'}

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

  Script.GetExpressionValue ("[Out]")

в правилах "Звуковое сообщение" для повторной обработки [Переменных]: 'Какой-то текст [Выборка.ИмяПеременной].'.

Устаревший подход

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.