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

nBest

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

В сценариях со сложным механизмом выбора правил активации для перехода в стейт вы можете получить доступ к наиболее вероятным правилам из любого места сценария через $context.nBest.

Конфигурационный файл

Чтобы включить заполнение $context.nBest, в конфигурационный файл chatbot.yaml нужно добавить секцию:

nlp:
nbest: 3
подсказка
В значении параметра nlp.nbest укажите необходимое число правил, к которым нужно иметь доступ из сценария. Значение по умолчанию — 1.

Содержимое массива

После настройки конфигурационного файла в объекте $context, представляющем собой текущий контекст обработки запроса, становится доступно поле nBest.

подсказка
В значении $context.nBest содержится массив из nlp.nbest объектов, представляющих собой наиболее вероятные правила для перехода в какой-либо стейт.

Объект на первом месте в массиве $context.nBest отбирается в зависимости от того, задан ли в сценарии собственный механизм выбора правил активации через обработчик selectNLUResult:

  • Если обработчик задан, то на первом месте $context.nBest всегда идет правило, которое было записано обработчиком в поле $context.nluResults.selected.
  • Если не задан, то на первом месте расположено правило, по которому произошел переход в целевой стейт, с учетом стандартного приоритета в порядке от паттернов к интентам.

Правила на втором и последующих местах отсортированы по убыванию значения score.

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

Фильтр по типу правил активации

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

nlp:
nbestPatterns: 1
nbestIntents: 2

Поле nbestPatterns задает длину $context.nBestPatterns — массива правил активации, сработавших только при помощи паттернов. Если поле не указано, то этот массив недоступен. nbestIntents работает аналогично для интентов.

Сценарий

Без обработчика selectNLUResult

Рассмотрим простой сценарий, в котором используются оба типа правил активации. Интент /привет предварительно обучен на тренировочной фразе привет:

init:
bind("postProcess", function($context) {
log(toPrettyString($context.nBest));
});

theme: /

state: Pattern
q!: привет

state: Intent
intent!: /привет

В блоке init настроен обработчик postProcess, который после каждого запроса логирует содержимое $context.nBest. При запросе привет в лог запишется массив:

[
// Первый объект — правило для перехода по паттерну
{
"clazz": "/Pattern", // Путь к стейту, в который попал запрос
"score": 0.79, // Вес, с которым сработало правило
"pt": {
// Алиас для поля `parseTree`
},
"debugInfo": {
// Служебная информация о сработавшем правиле
},
"ruleType": "pattern", // Тип сработавшего правила
"parseTree": {
// Полное дерево разбора запроса
},
"targetState": "/Pattern", // Стейт, в который произошел переход
},
// Второй объект — правило для перехода по интенту
{
"clazz": "/Intent",
"score": 1,
"pt": {
// ...
},
"debugInfo": {
// ...
},
"ruleType": "intent",
"parseTree": {
// ...
},
"targetState": "/Intent"
}
]

С обработчиком selectNLUResult

Добавим в блок init обработчик, который переопределяет порядок срабатывания правил активации так, чтобы наибольший приоритет был у интентов:

bind("selectNLUResult", function($context) {
if ($context.nluResults.intents.length > 0) {
$context.nluResults.selected = $context.nluResults.intents[0];
return;
}

if ($context.nluResults.patterns.length > 0) {
$context.nluResults.selected = $context.nluResults.patterns[0];
}
});

Теперь, если повторить предыдущий запрос, порядок объектов в массиве $context.nBest изменится:

[
{
"clazz": "/Intent",
"score": 1
// ...
},
{
"clazz": "/Pattern",
"score": 0.79
// ...
}
]