Activations - Denire/jaicf-template-for-jaicp-developers GitHub Wiki
Активация стейтов
State - состояние - некоторое возможное состояние диалога. Диалог может находиться в состоянии Приветствие
, ОбработкаЗаказа
, и так далее. Переход между стейтами осуществляется через механизм активации.
Посмотрим на пример ниже. Здесь пользователь, находясь в стейте Start
, может назвать свое имя. Если пользователь называет имя, мы достаем его из запроса через переданную в сценарий информацию активации.
state("Start") {
action {
reactions.say("Hello! What is your name?")
}
state("GetName") {
activators {
intent("Name")
}
action {
val name = activator.caila?.slots?.get("name")
reactions.say("Your name is $name")
}
}
fallback {
reactions.say("Sorry, can you please say your name?")
}
}
Как протестировать?
Если мы хотим протестировать работу сценария вне зависимости от работы NLU системы, мы можем воспользоваться классом ScenarioTest. Он предоставляет различные методы для написания тестов. Ниже используются методы:
- withCurrentState - устанавливает, что перед началом теста клиент будет помещен в контекст
/Start
- intent - отправляет интент с определенным именем в сценарий
- goesToState - проверяет, что результат выполнения запроса (в этом случае, интента) попадает в определенный стейт.
class MyTest : ScenarioTest(NameScenario) {
@Test
fun `should activate state with name`(){
withCurrentState("/Start")
intent("Name") goesToState "/Start/GetName"
}
@Test
fun `should go to fallback on any other intent`(){
withCurrentState("/Start")
intent("AnyOther") goesToState "/Start/fallback"
}
}
Что такое Интент?
Intent - намерение - это распознанное намерение пользователя. В нашем случае мы можем определить интент в CAILA, или в другой NLU системе. Мы можем дать ему имя и обращаться к нему из сценария.
Мы можем сказать, что если речь пользователя соответствует определенному интенту, то мы переходим в стейт.
Зачем нужен ScenarioTest?
**ScenarioTest**
- один из предлагаемых вариантов тестирования бота. В нем бот не будет ходить в NLU систему. Это значит, что написание сценария можно более эффективно делить на написание бизнес-логики и написание NLU-логики:
- Разработчик бизнес логики может написать сценарий, написать имена интентов и интеграции не завися от самих интентов.
Чем это похоже на JAICP DSL?
Сценарий на JAICP будет выглядеть похожим образом. У нас будут стейты, но не будет выделенного блока активации. Логику активации стейта мы помещаем в теги q
.
state: Start
a: Hello! What is your name?
state: GetName
q: * $Name *
a: Your name is {{ $parseTree._Name }}
state: CatchAll
q: *
a: Sorry, can you please say your name?
Другие правила активации
Помимо правила intent
доступны и другие правила активации:
- event - событие в канале. Например
event("contact")
- событие, которое приходит в сценарий, если пользователь отправил свою локацию в telegram-канале. - regex - правило активации по regexp-выражению.
- catchAll - правило, срабатывающее, если ни один другой стейт не был активирован.
- anyIntent - правило, срабатывающее, если речь пользователя классифицировалась с определенным интентом, но этот интент не обрабатывается нигде в текущем контексте.
- anyEvent - как anyIntent, только про ивенты.
Кастомные правила активации
Помимо предоставляемым фреймворком правил активации, разработчик может писать любое удобное для него правило активации. Например, можно написать правило, по которому мы будем переходить в стейт, если NLU система обнаружила нужную сущность в запросе.
Фреймворк не может предугадать все потребности разработчика, так что мы выдаем множество точек расширения, чтобы разработчик сам адаптировал механизмы написания сценария под свои задачи.
Порядок срабатывания активаторов
Activator - это некоторая NLU система, к которой JAICF посылает запросы для того, чтобы определить нужный стейт по реквесту пользователя.
В приведенном ниже примере мы передаем список активаторов в конструктор бота.
val templateBot = BotEngine(
scenario = mainScenario,
activators = arrayOf(
CailaIntentActivator.Factory(Configuration.caila),
LexActivator.Factory(...),
RegexActivator
)
)
JAICF, выбирая стейт, вызывает каждый активатор поочередно. Это значит, что в первую очередь фреймворк обратится за распознаванием интентов в CAILA. Если по интентам, полученным от Кайлы стейт не нашелся, фреймворк обратиться к Lex-активатору (см. Amazon Lex), и так далее по списку.
-
Лайфхак, как сломать себе проект
Положите
CatchAllActivator
первым в списке и у вас будет работать толькоcatchAll()
иfallback