Слот-филлинг
Слот-филлинг — процесс уточнения информации, необходимой для выполнения запроса клиента.
Слоты — сущности, которые клиент упоминает в запросе либо в процессе уточнения информации.
В данной статье рассматриваются следующие вопросы:
- Извлечение слотов.
- Параметры слотов.
- Подключение модуля слот-филлинга.
- Обработка слотов в сценарии.
- Уточнение незаполненных слотов.
- Прерывание слот-филлинга.
Извлечение слотов
Если представить интент как функцию, которую клиент может вызвать, то слот можно рассматривать как параметр этой функции.
Допустим, в классификаторе предусмотрен интент /Погода, который обрабатывает запросы вида Какая погода в Москве?.
- С одной стороны, бот не может корректно отреагировать на данный интент, не узнав, какой город имеет в виду клиент.
- С другой стороны, клиент может упомянуть дату, которая его интересует, и эту информацию нужно учитывать при обработке.
В данном случае город и дата являются слотами, которые необходимо извлечь из запроса.
Подробнее о настройке слотов в интерфейсе
Параметры слотов
Название и Сущность
У каждого слота должны быть указаны два обязательных параметра:
- Название — имя для обращения к каждому слоту из сценария, например
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