Перейти к основному содержимому

Слот-филлинг

Слот-филлинг — процесс уточнения информации, необходимой для выполнения запроса клиента.

Слоты — сущности, которые клиент упоминает в запросе либо в процессе уточнения информации.

В данной статье рассматриваются следующие вопросы:

Извлечение слотов

Если представить интент как функцию, которую клиент может вызвать, то слот можно рассматривать как параметр этой функции.

Допустим, в классификаторе предусмотрен интент /Погода, который обрабатывает запросы вида Какая погода в Москве?.

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

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

Параметры слотов

Название и Сущность

У каждого слота должны быть указаны два обязательных параметра:

  • Название — имя для обращения к каждому слоту из сценария, например City и Date.
  • Сущность — системная либо пользовательская сущность, соответствующая слоту:
    • для Date это может быть системная сущность @duckling.time;
    • для City нужно предусмотреть справочник городов, для которых доступен прогноз.

При обработке запросов в них производится поиск сущностей, соответствующих слотам, подлежащим заполнению. Для примера фразы Какая погода сегодня в Москве? в слот City попадет Москва, в Date — указание на сегодняшний день.

Если для интента настроено несколько слотов с одинаковыми сущностями, при обработке запросов они будут заполняться последовательно.

При необходимости обработать произвольное количество слотов с одинаковыми сущностями обращайтесь к структуре $entities, в которую передаются все найденные в запросе сущности в исходном виде.

Обязательность

Каждый слот может быть обязательным или необязательным.

Если переключатель Обязательно активен, то запросы, в которых этот слот не заполнен, будут попадать в сценарий уточнения незаполненных слотов. При этом требуется, чтобы параметр Вопросы для данного слота был непустым.

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

Если переключатель не активен, интент будет обработан, даже если слот не заполнен.

Массив

При необходимости обработать в сценарии несколько повторяющихся сущностей из одного слота, необходимо пометить слот как массив.

Если переключатель Массив:

  • Не активен: в слот помещается первое обработанное значение данной сущности.
  • Активен: в слот помещается массив всех сущностей данного типа. Если обнаружено только одно значение сущности, оно также оформляется как массив.

Подключение модуля слот-филлинга

Для подключения модуля слот-филлинга укажите в сценарии в файле main.sc:

require: slotfilling/slotFilling.sc
module = sys.zb-common

Обработка слотов в сценарии

В сценарии к заполненным слотам можно обратиться через структуру $parseTree.

Если у сущности, к которой привязан слот, есть значение DATA, то поле $parseTree._<ИмяСлота> будет содержать это значение DATA, а при его отсутствии — текст той части запроса, которая попала в сущность.

Использование заполненных слотов в сценарии:

state:
intent!: /Погода
script:
if ($parseTree._Date) {
$temp.date = $parseTree._Date.value;
} else {
$temp.date = "сегодня";
}
a: Погода в {{$parseTree._City}} на {{$temp.date}}
подсказка
Поскольку в нашем примере слот Date необязателен, перед обработкой его нужно проверить и установить значение по умолчанию, если он не заполнен.

Уточнение незаполненных слотов

Для всех обязательных слотов, которые остались незаполненными в изначальном запросе, система будет по очереди задавать уточняющие вопросы, указанные в поле Вопросы.

В ответах клиента будет производиться поиск сущностей, соответствующих слотам. Если подходящие сущности найдены, то слот будет заполнен.

После того, как все слоты заполнены, управление передается в основной сценарий со всеми заполненными слотами в $parseTree.

Рассмотрим пример:

Заполнение слотов

Здесь @City — пользовательская сущность, в которой указаны все доступные города.

Запрос клиентаДействие бота
Погода на завтра в МосквеОба слота заполнены. Управление сразу перейдет в сценарий.
Погода на завтраСлот City не заполнен, и он обязателен. Будет задан уточняющий вопрос.
Погода в МосквеСлот Date не заполнен, но он необязателен. Управление перейдет в сценарий.

Прерывание слот-филлинга

Прерывание слот-филлинга позволяет досрочно выйти из сценария заполнения слотов, если клиент не отвечает на уточняющие вопросы.

подсказка
Используйте прерывание слот-филлинга, чтобы диалог не зацикливался при неуспешном заполнении слотов и клиент мог свободно перевести разговор на другие темы.

Условия прерывания слот-филлинга конфигурируются в файле chatbot.yaml в разделе injector:

injector:
slotfilling:
maxSlotRetries: 1
stopOnAnyIntent: true
stopOnAnyIntentThreshold: 0.2
предупреждение
Независимо от этой конфигурации из слот-филлинга всегда можно досрочно выйти по команде /start. При этом произойдет переход в стейт /Start.

Прерывание по превышению числа переспросов

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

Если клиент ответил указанное количество раз и слот не был заполнен, процесс слот-филлинга будет прерван. Последняя фраза клиента будет обработана в основном сценарии бота.

Прерывание по интенту

Прерывание по интенту регулируют параметры:

  • stopOnAnyIntent включает или выключает прерывание. Принимает булево значение true/false.
  • stopOnAnyIntentThreshold — минимальная вероятность вхождения фразы в один из классов. Принимает вещественное значение.
подсказка
В ходе разработки NLU-сервиса было эмпирически определено, что оптимальное значение этого параметра 0.2.

Если параметр stopOnAnyIntent включен и запросу клиента соответствует интент со степенью уверенности выше, чем stopOnAnyIntentThreshold, слот-филлинг будет прерван по интенту.

предупреждение
Важно учитывать контекст, где начался слот-филлинг. Если при прерывании в стейт с соответствующим интентом невозможно попасть из текущего (например, если тег intent не глобальный), то запрос попадет в стейт с активатором event!: noMatch.

Параметры по умолчанию

Если параметры для прерывания в конфигурационном файле chatbot.yaml не указаны, слот-филлинг будет прерываться согласно параметрам по умолчанию:

injector:
slotfilling:
maxSlotRetries: 2
stopOnAnyIntent: false
stopOnAnyIntentThreshold: 0.2