Skip to content

ru ResponseSelectors

dilyararimovna edited this page May 9, 2023 · 2 revisions

Выбор финальных ответов в Dream

Схема управления диалогами

Dream построен на платформе агента DeepPavlov с открытым исходным кодом (https://github.com/deeppavlov/dp-agent), поэтому Dream основан на архитектуре агента DeepPavlov. Управление диалогами в DeepPavlov Agent Framework представляет собой скоординированный оркестр компонентов Skill Selector и Response Selector. Селектор навыков выбирает список навыков, которые будут пытаться генерировать ответы для текущего контекста. Селектор ответа выбирает окончательный ответ, который также может состоять из нескольких различных гипотез.

В отличие от Skill Selector, сервис Response Selector должен выбирать окончательный вариант ответа. Сервис возвращает имя выбранного навыка, текст (может быть перезаписан из исходного ответа навыка) и уверенность (также может быть перезаписан):

{"skill_name": "chitchat",
 "text": "Hello, Joe!",
 "confidence": 0.3}

Также селектор ответа может перезаписать любые атрибуты человека или бота:

{"skill_name": "chitchat",
 "text": "Hello, Joe!",
 "confidence": 0.3,
 "human_attributes": {"name": "Ivan"}}

Подходы селектора ответов

Эмпирическая формула для обеспечения уверенности в ответах ботов

В модульной диалоговой системе каждый навык обычно возвращает кандидата ответа и уверенности в данном кандидате ответа. Уверенность представляет собой значение с плавающей запятой от 0 до 1, где 1 соответствует самому высокому уровню уверенности навыка.

Опишем алгоритм выбора ответа, основанный на максимизации достоверности. Этот подход имеет два основных недостатка: (1) несколько ответов-кандидатов могут иметь одинаковые значения достоверности, (2) значения достоверности для разных навыков имеют разное происхождение. Если первую задачу можно решить случайным выбором или выбором на основе некоторых правил, то решение второй задачи приведет к несправедливости сравнения. Действительно, распределения значений достоверности для нейросетевых моделей могут существенно различаться, и, кроме того, значения достоверности для навыков на основе шаблонов обычно задаются разработчиком. При этом (1) навыки, как правило, разрабатываются разными авторами, поэтому невозможно создать стандартную методику определения достоверности из-за большого разнообразия сценариев и подходов; (2) нет гарантии, что разработчик настроил значения достоверности; (3) может возникнуть необходимость учитывать дополнительную информацию о текущем ответе кандидата.

Поэтому во время «Alexa Prize Challenge 3» селектор ответов социального бота Dream основывался на эмпирической формуле, сочетающей уверенность в навыках и оценку ответов кандидата. Последнее обеспечивается [моделью оценки разговора CoBot] (https://www.aclweb.org/anthology/W19-8608), которая оценивает ответ в контексте диалога по следующим параметрам:

  • соответствие теме;
  • интересен ли ответ;
  • вовлеченность пользователей;
  • полнота ответа;
  • правильность.

Во-первых, селектор ответов отфильтровывает «плохие» кандидаты на ответы, т.е. содержащие нецензурные выражения, нецензурные выражения, токсичность или имеющие высокую вероятность того, что пользователь остановит диалог после данного ответа. Чтобы разнообразить лексикологию социального бота, мы уменьшаем значение достоверности, если предложение в ответах кандидатов повторяется в диалоге в краткосрочной перспективе.

Во-вторых, селектор ответов использует эмпирическую формулу для расчета окончательной оценки, объединяющей значение достоверности и прогнозы оценки ответа-кандидата. Кстати, селектор ответов может объединять несколько вариантов ответа в окончательный ответ. Селектор ответов может добавлять вопросы-ссылки к некоторым утверждениям и направлять диалог к одному из запрограммированных навыков. Таким образом, мы можем плавно перемещать пользователя с одной заскриптованной темы на другую.

Селектор ответов на основе тегов

Dream сочетает в себе множество различных навыков, в том числе основанные на шаблонах, поисковые и генеративные навыки. Основываясь на технических отчетах других команд «Alexa Prize Challenge 3», мы выяснили, что они охватывают самые популярные темы (например, фильмы, книги, спорт и другие) и создали сценарии для обеспечения глубокого контролируемого разговора. Мы добавили некоторые правила приоритизации для сценариев ответов, но в целом мы не смогли обеспечить плавный диалог с использованием различных типов навыков. Таким образом, во время «Alexa Prize Challenge 4» мы сосредоточились на новом селекторе ответов, который может плавно сочетать навыки разного происхождения. Обобщенные подходы к управлению диалогом представлены на рисунке ниже.

Мы предложили два дополнительных тега для каждого кандидата ответа: (1) флаг продолжения, (2) части ответа. Оба тега назначаются навыком, предлагающим его, поэтому могут быть варианты ответа с одинаковыми тегами или теги, которым не назначен ни один из кандидатов ответа. Флаг продолжения построен для того, чтобы показать возможность продолжения разговора на следующем ходу после предложенного кандидата ответа. Части ответа для каждого кандидата ответа представляют собой список, указывающий, какие части ответа присутствуют в кандидате ответа. Части ответа бывают трех типов: подтверждение (перефразировка того, что только что сказал пользователь), тело (основная часть ответа) и подсказка (фраза для дальнейшего развития диалога).

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

Во-первых, алгоритм выбора проверяет особые намерения пользователя, на которые может немедленно реагировать специальный компонент. Если пользователь хочет переключиться или запросить определенную тему, приоритет отдается кандидатам с подсказками. Наконец, если диалоговое действие пользователя требует каких-либо действий со стороны социального бота (например, если пользователь запрашивает мнение, от социального бота ожидается выражение мнения), приоритет отдается кандидатам на ответ, содержащим требуемые диалоговые действия. В остальных случаях алгоритм использует следующие приоритеты:

(1) ответ кандидата с помощью заскриптованного навыка, с которым идет диалог;

(2) ответы-кандидаты части сценария, содержащие сущности (не обязательно именованные сущности) из последнего высказывания пользователя;

(3) одношаговые ответы-кандидаты, содержащие сущности из последнего высказывания пользователя;

(4) ответы-кандидаты других частей сценария;

(5) другие одношаговые ответы-кандидаты.

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

Разработка собственного селектора ответов

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

#!/usr/bin/env python

import logging
import numpy as np
import time

from flask import Flask, request, jsonify
from os import getenv
import sentry_sdk


logging.basicConfig(format="%(asctime)s - %(name)s - %(levelname)s - %(message)s", level=logging.INFO)
logger = logging.getLogger(__name__)

app = Flask(__name__)


@app.route("/respond", methods=["POST"])
def respond():
    st_time = time.time()

    dialogs = request.json["dialogs"]
    response_candidates = [dialog["utterances"][-1]["hypotheses"] for dialog in dialogs]

    selected_skill_names = []
    selected_responses = []
    selected_confidences = []

    for i, dialog in enumerate(dialogs):
        confidences = []
        responses = []
        skill_names = []

        for skill_data in response_candidates[i]:
            if skill_data["text"] and skill_data["confidence"]:
                logger.info(f"Skill {skill_data['skill_name']} returned non-empty hypothesis with non-zero confidence.")

            confidences += [skill_data["confidence"]]
            responses += [skill_data["text"]]
            skill_names += [skill_data["skill_name"]]

        best_id = np.argmax(confidences)

        selected_skill_names.append(skill_names[best_id])
        selected_responses.append(responses[best_id])
        selected_confidences.append(confidences[best_id])

    total_time = time.time() - st_time
    logger.info(f"rule_based_response_selector exec time = {total_time:.3f}s")
    return jsonify(list(zip(selected_skill_names, selected_responses, selected_confidences)))


if __name__ == "__main__":
    app.run(debug=False, host="0.0.0.0", port=3000)

Регистрация собственного селектора ответа

Регистрация нового селектора ответов осуществляется путем добавления его конфигурации в файл docker-compose.yml, расположенный в корневом каталоге, и в файл pipeline_conf.json, расположенный в подкаталоге /agent репозитория. После добавления нового навыка его следует собрать и запустить с помощью docker-compose -f docker-compose.yml up --build _response_selector_name_, а затем собрать и запустить агент, выполнив команду `docker-compose -f docker-compose.yml агент сборки», за которым следует «docker-compose -f docker-compose.yml up agent».

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

Ссылки

Clone this wiki locally