Skip to content

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

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

Что это такое

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

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

Это обычный 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 запроса не будет ничего, так как фраза пользователя не подошла ни под одну из команд.

После срабатывания или не срабатывания модального контекста Агрегат выключает его, снова возвращаясь в первоначальное состояние.

Russian Version (Русская версия)





IDE


English Version

Main Page

Modules

  • List of available modules

User Guide

  • Where to get

  • How to install

  • How to use

  • Setting up


Developer Guide

Aggregate Architecture

Events List

Command Line


How to Create a Module

  • Java
  • Javascript
  • Typescript
  • Groovy
  • Ruby

Functional Modules

  • Query grammar

  • Pattern syntax

  • Dynamic patterns

  • Standard patterns

Activation Modules

Speech Recognition Modules

Text-to-Speech Modules


IDEs

  • Developing in Eclipse
  • Developing in IntelliJ IDEA

Change Log

Clone this wiki locally