-
Notifications
You must be signed in to change notification settings - Fork 40
Грамматика запросов
Грамматика пользовательских запросов - это обязательный элемент для любого функционального модуля. То есть модуля, который должен обрабатывать пользовательские голосовые запросы и реагировать на них.
Это обычный XML файл, который должен лежать в корне архива с вашим модулем и иметь название, совпадающее с названием модуля. То есть если ваш модуль называется my-module.jar или my-module-1.0.0.jar, то файл грамматики должен иметь имя my-module.xml.
Грамматика описывает шаблоны тех команд, которые хочет обрабатывать ваш модуль. Также грамматика содержит информацию о контекстах, в которые Агрегат будет переключаться автоматически или из кода модуля при срабатывании тех или иных команд. Это позволяет осуществить переключение диалоговых контекстов для общения с пользователем на естественном языке.
Пользователь спрашивает "Какой день недели?". Модуль отвечает ему, после чего пользователь может спросить "А завтра?" Вот пример переключения контекста. Если пользователь скажет "А завтра?" без первого вопроса, то он будет бессмысленным. Контекст должен включиться только когда сработал первый вопрос.
Грамматика состоит из элементов module, command и pattern. На примере показано, как их использовать.
<context>
<command id="cmd.datetime.time">
<pattern value="* который * час *"/>
<pattern value="* скольк* * врем* *"/>
<pattern value="время"/>
</command>
<command id="cmd.datetime.date">
<pattern value="[* как*] {(день [недели] | дата) [* $Date]}"/>
<command id="cmd.datetime.date">
<pattern value="* $Date"/>
</command>
</command>
</context>В этой грамматике описаны две команды в корневом контексте. У каждой команды (command) должен быть идентификатор. Именно он определяет имя того события, которое Агрегат пошлет модулю, когда сработает команда.
Элементы шаблонов (pattern) описывают те шаблоны фраз, под которые должен подходить распознанный текст пользовательского запроса. Синтаксис этих шаблонов можно изучить здесь.
Шаблоны также можно генерировать "на лету" из кода, конфигурации или с удаленного HTTP сервера. Подробнее об этом читайте в разделе Динамические шаблоны
Вы также можете использовать некоторый набор стандартных шаблонов, которые реализует сам Агрегат, чтобы не писать их заново. Их список можно найти здесь.
Можно указать шаблон и вне команды. Такой шаблон может использоваться внутри других шаблонов и так далее. Это удобно для организации команд и последующего извлечения данных. Например:
<context>
<pattern name="BrowserSite" value="*.*"/>
<command id="cmd.browser.open">
<pattern value="* (сайт*|site) $BrowserSite"/>
</command>
</context>Здесь мы создали простой шаблон с именем BrowserSite, который подходит для любого адреса сайта (google.com, yandex.ru и так далее). А затем ссылаемся на этот шаблон внутри шаблона команды. Это дает нам возможность в нашем модуле вытащить часть фразы из пользовательского запроса, которая содержит только адрес сайта:
На Java
Markup markup = request.markup.get("BrowserSite");Обратите внимание на знак $ в шаблоне перед именем шаблона, на который мы ссылаемся.
Как вы видите в примере, команда cmd.datetime.date содержит внутри себя другую команду с таким же идентификатором и гораздо более коротким шаблоном. Это позволяет Агрегату автоматически переключить контекст, как только пользователь спросил о дате. Таким образом следующая фраза пользователя может быть просто "А завтра?" или "А что через неделю?"
В данном случае контекст просто расширяется. Если пользователь произнесет какую-то другую фразу, то ничего страшного не произойдет - просто сработает другая команда, а данный контекст будет свернут. Если же фраза подойдет, то этот контекст будет активен по-прежнему. То есть следующей фразой пользователь снова может спросить "Ну а что 31 декабря?"
Если решение о том, нужно ли переключать контекст, зависит от результата выполнения кода модуля, то такой контекст нужно описать в файле грамматики отдельно в тэге module и дать ему идентификатор. А в коде модуля переключать контекст в ответе с указанием этого идентификатора. Например:
<context id="com.aggregate.dusi">
<command id="cmd.dusi">
<pattern value="*"/>
</command>
</context>Тут описан контекст с идентификатором com.aggregate.dusi, у которого есть единственная команда cmd.dusi, которая реагирует вообще на любую фразу пользователя.
Код модуля может переключить Агрегат на этот контекст следующим образом:
vertx.eventBus().send("response", new Response(speeches, modal ? "com.aggregate.dusi" : null, modal));После этого Агрегат расширит (или наоборот сузит) контекст команд для пользователя.
Вы можете указать множество контекстов внутри одного файла грамматики:
<context>
<context id="context1">
...
</context>
<context id="context2">
...
</context>
...
</context>Модальность обозначает, что контекст команд сужается до одного единственного. То есть если модуль указал Агрегату, что нужно включить контекст и сделать его модальным, то ни одна другая команда не получит управление в следующей фразе пользователя. Даже если пользователь скажет что-то, что не подходит ни к одной команде такого контекста.
Это удобно, если вам нужно в какой-то момент получить от пользователя какой-то запрос без боязни за то, что его перехватит другой модуль.
Модальные контексты можно включить только программно из кода вашего модуля.
Если же пользователь сказал что-то "мимо" всех команд модального контекста, то Агрегат все равно пошлет событие вашему модулю. Но в качестве имени события будет выступать идентификатор контекста (например "context1"). А в поле markup запроса не будет ничего, так как фраза пользователя не подошла ни под одну из команд.
После срабатывания или не срабатывания модального контекста Агрегат выключает его, снова возвращаясь в первоначальное состояние.
- Разработка в Eclipse
- Разработка в IntelliJ IDEA
- List of available modules
-
Where to get
-
How to install
-
How to use
-
Setting up
- Java
- Javascript
- Typescript
- Groovy
- Ruby
-
Query grammar
-
Pattern syntax
-
Dynamic patterns
-
Standard patterns
- Developing in Eclipse
- Developing in IntelliJ IDEA