JAICP

nBest


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

  1. Паттерны.
  2. Примеры и группы примеров.
  3. Интенты.

В сценариях со сложным механизмом выбора правил активации для перехода в стейт вы можете получить доступ к наиболее вероятным правилам из любого места сценария через $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
  nbestExamples: 3

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

nbestIntents и nbestExamples работают аналогично для интентов и примеров.

Сценарий

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

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

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

theme: /

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

    state: Example
        e!: привет

    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"
  },
  // Третий объект — правило для перехода по примеру
  {
    "clazz": "/Example",
    "score": 0.6069870970795817,
    "pt": {
      // ...
    },
    "debugInfo": {
      // ...
    },
    "ruleType": "example",
    "pattern": "привет",
    "parseTree": {
      // ...
    },
    "targetState": "/Example"
  }
]

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

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

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

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

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

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

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