---
metadata:
  - name: generator
    content: Diplodoc Platform v5.39.1
alternate:
  - https://yandex.ru/dev/dialogs/alice/doc/ru/nlu.md
---
> **Documentation Index:** Fetch the complete configuration index at https://yandex.ru/dev/dialogs/alice/doc/ru/llms.txt

# Обработка естественного языка (NLP)

{% include notitle [neuroexpert-button](_includes/reusables/neuroexpert-button-99270fdba323.md) %}


Чтобы с навыком можно было общаться на естественном языке, он должен уметь корректно
 обрабатывать реплики пользователей:

- распознавать задачу, которую хочет решить пользователь (например, заказать такси),
- извлекать нужные детали (на какое число и по какому адресу).

Для упрощения задач NLP (Natural Language Processing) Диалоги предоставляют специальный
 инструмент — встроенный язык описания пользовательского запроса. С его помощью в консоли разработчика вы
 можете описать правила, по которым Диалоги будут классифицировать запросы и извлекать из них
 нужные данные.

Когда пользователь произносит команду, Диалоги распознают текст и извлекают те фразы, которые
 описывают намерения пользователя согласно вашим правилам. Распознанные данные Диалоги
 присылают в навык.

<div style="
    border:1px solid #d1d5db;
    border-radius:20px;
    overflow:hidden;
    max-width:100%;
">
  <iframe src="https://runtime.strm.yandex.ru/player/video/vplvow6kziyg56evmmm5?autoplay=0&mute=0"
    frameborder="0"
    allowfullscreen
    style="
      display:block;
      width:100%;
      height:360px;
      "></iframe>
</div>

## Что такое интент, форма и слоты {#concept_nxd_wdj_2kb}

Чтобы формализовать разбор реплик, Диалоги используют интенты, формы и слоты.

_Интент_ — это задача, которую пользователь формулирует в конкретной реплике.
 Например, `узнать погоду`. Каждому интенту соответствует одна форма.

_Форма_ — контейнер с информацией, который Диалоги заполняют, распознавая запрос
 пользователя. Форма всегда соответствует одному интенту и содержит набор типизированных
 слотов.

_Слот_ — поле формы. Каждый слот имеет название, тип данных и признак обязательности.
 Например, из реплики `погода на завтра в Питере` для заполнения слотов будут
 извлечены дата (`завтра`) и место (`в Питере`).

При обработке реплики Диалоги сначала определяют, к какому интенту она относится. После
 этого извлекают из реплики необходимые параметры и заполняют ими слоты формы. Распознанные
 данные Диалоги отправят в навык в поле запроса `request.nlu`. Если реплика не
 относится ни к одному интенту, поле `request.nlu` будет пустым ([подробнее](#data_to_skill)).


## Синтаксис  {#granet_sntx}

Ниже показан пример описания интента:

```bash
# Описание интента "turn.on" для включения устройств.
# Эта грамматика позволит распознавать такие фразы как "включи свет на кухне"
# или "включи кондиционер в спальне". 

# Корневой элемент грамматики. Описывает шаблон, по которому будет
# отбираться реплика.
root:
    включи $What $Where

# Описание слотов. Диалоги будут отправлять это описание навыку.
slots:
    what:
        source: $What                   
    where:
        source: $Where
$What:
    свет | кондиционер
$Where:
    в ванной | на кухне | в спальне
```

Вложенные элементы следует отбивать отступом в 4 пробела.

Описание интента состоит из ключевых слов `root`, `slots` и
 `filler`, а также _нетерминалов_ — фраз на естественном
 языке, описывающих, на какие запросы должна срабатывать грамматика. Нетерминалы
 обозначаются символом `$`. Они эквиваленты переменным в языках
 программирования. Нетерминалы можно скрыть, чтобы они были доступны только внутри родительского нетерминала.
 
{% cut "Пример" %}

```bash
$PlayGame:
    $Play в $Game
    $Play:
        %lemma
        играть
    $Game:
        игру

$Game:
    %lemma
    игра
```

Внутри нетерминала `$PlayGame` `$Game` сработает только на слово «игру», а снаружи — на все падежи слова «игра».

{% endcut %}

Поддерживаемые ключевые слова:

- `root` — обозначение корневого элемента. Описывает шаблон, по которому будет отбираться вся реплика целиком.

    {% cut "Пример" %}
    
    ```python
    root:
    [включи $What $Where (и $Where)*]
    ```
    
    В этом примере используются [квантификатор](#quantifier) и [оператор []](#words_bag).

    {% endcut %}
    
- `slots` — описание слотов запроса. Это поле будет присутствовать в JSON, который Диалоги отправят в навык после обработки запроса. Подробнее см. [Какие данные передаются в навык](#data_to_skill).
    
    {% cut "Пример" %}
    
    ```bash
    slots:
        what:
            source: $What                   
        where:
            source: $Where     
    $What:
        свет | кондиционер
    $Where:
        # Подойдет любая строка, которую введет пользователь.
        .+
    ```

    {% endcut %}
    
- `filler` — стоп-слова, которые можно отбросить при разборе запроса. Для исключения незначащих, неинформативных слов используется специальный классификатор, использующий контекст предложения. Например, для разбора из примера выше срабаботает как фраза «включи свет», так и «включи свет, пожалуйста».

    {% cut "Пример" %}
    
    ```bash
    filler:
        мне | как всегда | еще раз | нужно
    ```
    
    {% endcut %}
    

Порядок описания элементов в грамматике не имеет значения.

### Типизированные слоты {#naming-entities}

Слоты могут содержать не только строковое значение, но и именованные сущности:

- `YANDEX.NUMBER` — числа;
- `YANDEX.FIO` — имена;
- `YANDEX.DATETIME` — даты;
- `YANDEX.GEO` — геообъекты.

Для указания типизированного слота используются поля `type` и нетерминал,
 содержащий этот тип:

```bash
slots:
    from:
        source: $From
        type: YANDEX.NUMBER
    to:
        source: $To
        type: YANDEX.NUMBER
root:
    назови число от $From до $To
$From:
    $YANDEX.NUMBER
$To:
    $YANDEX.NUMBER
```

### Пользовательские сущности в слотах {#user-entities}

Чтобы задать собственные типы слотов, опишите их в разделе
 **Сущности**, например:

```bash
entity ChessPiece:
    values:
        queen:
            ферзь
            королева
        pawn:
            пешка
```

После этого тип станет доступен в качестве нетерминала грамматики и типа слота:

```bash
slots:
    piece:
        type: ChessPiece
        source: $Piece
root:
    ход $Piece
$Piece:
    $ChessPiece
```

При указании `lemma: true` в описании сущности все ее элементы будут сравниваться без учета формы слова.
 
{% cut "Пример" %}

```bash
entity ChessPiece:
    lemma: true
    values:
        queen:
            ферзь
            королева
        pawn:
            пешка
```

{% endcut %}

Сработает на `пешка`, `пешку`, `пешкой`.

`lemma: true` распространяется на всю сущность и не отменяется при помощи директивы `%exact`

### Директивы {#command}

Директива — это специальная команда, переключающая парсер запросов в определенный режим
 работы. Директивы всегда начинаются с символа `%`. Например:

```bash
# Все последующие нетерминалы будут сравниваться без учета формы слова.
# Сработает как "включи свет", так и "включай свет".
root:
    %lemma
    включи свет
```

Действие директивы распространяется на все последующие нетерминалы. Директиву можно
 указать в начале всей грамматики, а также непосредственно перед нетерминалом. В последнем
 случае директива будет действовать до конца отступа или до отменяющей директивы.
 Пример:
```bash
filler:
    # Директива %lemma действует до %exact. Формы слов не учитываются.
    %lemma
    большое спасибо

    # Отменяем действие %lemma. Сработает только "всегда пожалуйста".
    %exact
    всегда пожалуйста
```

Ниже перечислены поддерживаемые директивы.

{% cut "%lemma" %} 

Нетерминалы будут сравниваться без учета формы слова. Пример, в котором запросы `включи свет` и `включай свет` будут засчитаны как совпадение:

```bash
root:
    %lemma
    включи свет
```

{% endcut %}

{% cut "%exact" %}

Нетерминалы будут сравниваться по точному совпадению. Пример, в котором попадет под правило только запрос `включи свет`:

```bash
root:
    %exact
    включи свет
```

{% endcut %}

{% cut "%negative" %}


{% note alert %}

Отрицательные правила должны быть более конкретными, чем положительные. Например, если в обозначении корневого элемента `root` указать элемент `включи сказку .*`, а в `%negative` — `включи .*`, то фраза `включи сказку о лисе` будет положительной в такой грамматике.

{% endnote %}


С помощью директивы `%negative` можно указать отрицательные примеры для элемента. Пример формы, которая сработает для условия `включи игру города` и не сработает для `включи игру престолов`:
 
```bash
form start_game:
    root:
        включи игру .*
        %negative
        включи игру $NotAGame
$NotAGame:
    %lemma
    престол
```

Директива `%positive` делает все последующие правила положительными.

{% endcut %}

### Оператор [] {#words_bag}

Позволяет игнорировать порядок слов в грамматике.
 Пример:
```bash
root:
    [включи свет] 
```

В этом примере положительными срабатываниями будут `включи свет` и
 `свет включи`.

### Квантификаторы {#quantifier}

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

- `?` — одно или ноль вхождений;
- `*` — ноль или больше вхождений;
- `+` — хотя бы одно вхождение.

{% cut "Пример «включи свет»" %} 

```bash
root: 
    включи (пожалуйста)? свет
```

Совпадением будет как `включи свет`, так и `включи, пожалуйста, свет`.

{% endcut %}

{% cut "Пример «включи свет на кухне»" %} 

```python
root:
    включи свет $Where (и $Where)*
$Where:
    .+ # Хотя бы одно произвольное слово.
```

Совпадениями будут `включи свет на кухне`, `включи свет на кухне и во всем доме` и т. д.

{% endcut %}

{% cut "Пример «включи свет на кухне и в ванной»" %}

```bash
root:
    включи свет $Where (и $Where)+
$Where:
    на кухне | в ванной | в коридоре
```

Совпадениями будут `включи свет на кухне и в ванной`, `включи свет на кухне, и в ванной, и в коридоре` и т. д., но не просто «включи свет на кухне».

{% endcut %}

В слот попадет только первый распознанный нетерминал, если в одном интенте он
 используется несколько раз (только первый `$Where` из примеров выше
 попадет в слот).


## Встроенные интенты {#predefined-intents}

Если в навыке есть хотя бы один интент, Яндекс Диалоги дополнительно отправляют интенты,
 универсальные для большинства навыков:

- `YANDEX.CONFIRM` — согласие;
- `YANDEX.REJECT` — отказ;
- `YANDEX.HELP` — запрос подсказки;
- `YANDEX.REPEAT` — просьба повторить последний ответ навыка.


## Какие данные передаются в навык {#data_to_skill}

После того как запрос будет обработан, Диалоги отправят навыку распознанные
 данные — в поле `request.nlu`. Это поле содержит
 идентификатор интента, а также описание заполненных слотов. Например:

```json
"request": {
    "command": "включи свет на кухне, пожалуйста",
    "nlu": {
      "intents": {
        "turn.on": { // Интент.
          "slots": {  // Список слотов.
            "what": {
              "type": "YANDEX.STRING", 
              "value": "свет"          
            },
            "where": {
              "type": "YANDEX.STRING",
              "value": "на кухне"
            }
        }
      }
    },
    ...
}
```

Если реплика не относится ни к одному интенту, поле `request.nlu` будет
 пустым.

В случае типизированных слотов в запросе будет указан тип слота и его каноническое
 значение.

{% cut "Пример для чисел" %} 

```json
"request": {
    "command": "назови число от одного до шести",
    "nlu": {
        "intents": {
            "random_number": { // Интент.
                "slots": {  // Список слотов.
                    "from": {
                        "type": "YANDEX.NUMBER",
                        "value": 1
                    },
                    "to": {
                        "type": "YANDEX.NUMBER",
                        "value": 6
                    }
                }
            }
        }
    },
    ...
}
```

{% endcut %}

{% cut "Пример «Закажи такси»" %}

```json
"request": {
    "command": "закажи такси на льва толстого 16 на 14:00",
    "nlu": {
      "intents": {
        "taxi": {
          "slots": {
            "where": {
              "type": "YANDEX.GEO",
              "tokens": {
                "start": 2,
                "end": 6
              },
              "value": {
                "street": "льва толстого",
                "house_number": "16"
              }
            },
            "time": {
              "type": "YANDEX.DATETIME",
              "tokens": {
                "start": 6,
                "end": 9
              },
              "value": {
                "hour": 14,
                "minute": 0
              }
            }
          }
        }
      }
    },
    ...
}
```

{% endcut %}

{% cut "Пример для пользовательского типа" %}

```json
{
  "request": {
    "command": "включи свет на кухне, пожалуйста",
    "nlu": {
      "intents": {
        "turn.on": {
          "slots": {
            "what": {
              "type": "YANDEX.STRING",
              "value": "свет"
            },
            "where": {
              "type": "YANDEX.STRING",
              "value": "на кухне"
            }
          }
        }
      }
    }
  },
  ...
}
```

{% endcut %}

### Полезные видео {#useful-video}

{% cut "Рекомендации от Алисы: что должен уметь разработчик" %}

<div style="
    border:1px solid #d1d5db;
    border-radius:20px;
    overflow:hidden;
    max-width:100%;
">
  <iframe src="https://runtime.strm.yandex.ru/player/video/vplvcgmkhhmfrcu3dr3m?autoplay=0&mute=0"
    frameborder="0"
    allowfullscreen
    style="
      display:block;
      width:100%;
      height:360px;
      "></iframe>
</div>

{% endcut %}

{% cut "Разработка прототипа голосового приложения (с 16:39)" %}

<div style="
    border:1px solid #d1d5db;
    border-radius:20px;
    overflow:hidden;
    max-width:100%;
">
  <iframe src="https://runtime.strm.yandex.ru/player/video/vplvba3haj2wbsimewde?autoplay=0&mute=0"
    frameborder="0"
    allowfullscreen
    style="
      display:block;
      width:100%;
      height:360px;
      "></iframe>
</div>

{% endcut %}

{% include [index-support-button](_includes/index/id-index/support-button-8d89a88806fa.md) %}


