Skip to content

Грамматика запросов

Dmitry Che edited this page Mar 4, 2016 · 10 revisions

Что это такое

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

Как это выглядит

Это обычный XML файл, который должен лежать в корне архива с вашим модулем и иметь название, совпадающее с названием модуля. То есть если ваш модуль называется my-module.jar или my-module-1.0.0.jar, то файл грамматики должен иметь имя my-module.xml.

Что внутри

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

Пример переключения контекста

Пользователь спрашивает "Какой день недели?". Модуль отвечает ему, после чего пользователь может спросить "А завтра?" Вот пример переключения контекста. Если пользователь скажет "А завтра?" без первого вопроса, то он будет бессмысленным. Контекст должен включиться только когда сработал первый вопрос.

Синтаксис грамматики

Грамматика состоит из элементов module, command и pattern. На примере показано, как их использовать.

<module>
    <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>
</module>

В этой грамматике описаны две команды. У каждой команды (command) должен быть идентификатор. Именно он определяет имя того события, которое Агрегат пошлет модулю, когда сработает команда.

Элементы шаблонов (pattern) описывают те шаблоны фраз, под которые должен подходить распознанный текст пользовательского запроса. Синтаксис этих шаблонов можно изучить здесь.

Можно указать шаблон и вне команды. Такой шаблон может использоваться внутри других шаблонов и так далее. Это удобно для организации команд и последующего извлечения данных. Например:

<module>
    <pattern name="BrowserSite" value="*.*"/>

    <command id="cmd.browser.open">
        <pattern value="* (сайт*|site) $BrowserSite"/>
    </command>
</module>

Здесь мы создали простой шаблон с именем BrowserSite, который подходит для любого адреса сайта (google.com, yandex.ru и так далее). А затем ссылаемся на этот шаблон внутри шаблона команды. Это дает нам возможность в нашем модуле вытащить часть фразы из пользовательского запроса, которая содержит только адрес сайта:

Markup markup = request.markup.get("BrowserSite");

Обратите внимание на знак $ в шаблоне перед именем шаблона, на который мы ссылаемся.

Автоматические контексты

Как вы видите в примере, команда cmd.datetime.date содержит внутри себя другую команду с таким же идентификатором и гораздо более коротким шаблоном. Это позволяет Агрегату автоматически переключить контекст, как только пользователь спросил о дате. Таким образом следующая фраза пользователя может быть просто "А завтра?" или "А что через неделю?"

В данном случае контекст просто расширяется. Если пользователь произнесет какую-то другую фразу, то ничего страшного не произойдет - просто сработает другая команда, а данный контекст будет свернут. Если же фраза подойдет, то этот контекст будет активен по-прежнему. То есть следующей фразой пользователь снова может спросить "Ну а что 31 декабря?"

Не автоматические контексты

Если решение о том, нужно ли переключать контекст, зависит от результата выполнения кода модуля, то такой контекст нужно описать в файле грамматики отдельно в тэге module и дать ему идентификатор. А в коде модуля переключать контекст в ответе с указанием этого идентификатора. Например:

<module id="com.aggregate.dusi">
    <command id="cmd.dusi">
        <pattern value="*"/>
    </command>
</module>

Тут описан контекст с идентификатором com.aggregate.dusi, у которого есть единственная команда cmd.dusi, которая реагирует вообще на любую фразу пользователя.

Код модуля может переключить Агрегат на этот контекст следующим образом:

vertx.eventBus().send("response", new Response(speeches, modal ? "com.aggregate.dusi" : null, modal));

После этого Агрегат расширит (или наоборот сузит) контекст команд для пользователя.

Вы можете указать множество контекстов внутри одного файла грамматики:

<module>
  <module id="context1">
    ...
  </module>

  <module id="context2">
    ...
  </module>

  ...
</module>

Sorry, there was an error rendering this page.

Clone this wiki locally