Qna и LUIS прерывают диалог, прежде чем следующий шаг сможет обработать ввод

В мой бот интегрированы QnaMaker и LUIS. Я хочу, чтобы пользователь мог задавать вопросы между разговорами. Я уже обнаружил, что проблема в том, что бот всегда сначала смотрит в luis и qna, прежде чем обрабатывать ввод пользователя.

Например, если у меня есть запрос выбора с «Начать сейчас» и «Остановить сейчас», Luis или qna прервут и обработают ввод, снова вызовут диалоговое окно, что приведет к бесконечному циклу и никогда не достигнет следующего шага.

Я думаю, что это плохой дизайн с моей стороны. есть ли способ для следующего шага сначала обработать результат? Если он не распознал результат, luis и qna должны обработать ввод.

    private async Task<bool> IsTurnInterruptedDispatchToQnAMakerAsync(ITurnContext turnContext, string topDispatch, string appName, CancellationToken cancellationToken = default(CancellationToken))
    {
        var dc = await _dialogs.CreateContextAsync(turnContext);
        const string qnaDispatchKey = "q_xxxxxxxx";

        if (topDispatch.Equals(qnaDispatchKey))
        {
            var results = await _services.QnAServices[appName].GetAnswersAsync(turnContext);
            if (results.Any())
            {
                await turnContext.SendActivityAsync(results.First().Answer, cancellationToken: cancellationToken);
            }

            if (dc.ActiveDialog != null)
            {
                await dc.RepromptDialogAsync();
            }

            return true;
        }

        return false;
    }

        return false;
    }

на OnTurnAsync()

            var interruptedQnaMaker = await IsTurnInterruptedDispatchToQnAMakerAsync(turnContext, topDispatch, QnaConfiguration, cancellationToken);
            if (interruptedQnaMaker)
            {
                await _basicAccessors.ConversationState.SaveChangesAsync(turnContext, false, cancellationToken);
                await _basicAccessors.UserState.SaveChangesAsync(turnContext, false, cancellationToken);
                return;
            }
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
0
237
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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

Использование LUIS и QnA в подсказке выбора

В моем примере показано, как это сделать с помощью LUIS, но здесь вы можете довольно легко заменить QnAMaker.

Передайте свой BotServices в свой диалог (в конструкторе MyBot.cs):

Dialogs.Add(new MyDialog(services));

Примечание. В зависимости от того, где вы это делаете, вы можете передать свой LuisRecognizer вместо всех своих услуг.

Используйте BotServices в конструкторе MyDialog:

public class MyDialog : ComponentDialog
{
    private readonly BotServices _services;
    public MyDialog(BotServices services) : base(nameof(QuickDialog))
    {
        [...]
        _services = services;
    }

Создайте валидатор в ChoicePrompt:

AddDialog(new ChoicePrompt(nameof(ChoicePrompt), luisValidation));

Создайте свой валидатор, который позволит вам настроить ввод пользователя и установить его как нечто другое (например, намерение LUIS):

private async Task<bool> LuisValidationAsync(PromptValidatorContext<FoundChoice> promptContext, CancellationToken cancellationToken)
{
    // ...Succeeded will only be true for a ChoicePrompt if user input matches a Choice
    if (!promptContext.Recognized.Succeeded)
    {
        // User input doesn't match a choice, so get the LUIS result
        var luisResults = await _services.LuisServices["nameOfLuisServiceInBotFile"].RecognizeAsync(promptContext.Context, cancellationToken);
        var topScoringIntent = luisResults?.GetTopScoringIntent();
        var topIntent = topScoringIntent.Value.intent;
        // Save the results and pass them onto the next waterfall step
        promptContext.Recognized.Succeeded = true;
        promptContext.Recognized.Value = new FoundChoice()
        {
            Index = 0,
            Score = 1,
            Value = topIntent
        };
        // We converted to a valid LUIS result, so return true
        return true;
    }
    // ...Succeeded was true, so return true
    return true;
}

Обработать результат

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

switch ((stepContext.Result as FoundChoice).Value)
{
    case "Reply":
        await stepContext.Context.SendActivityAsync("Reply");
        break;
    case "Cancel":
        return await stepContext.EndDialogAsync("Cancel Me");                    
}
return await stepContext.NextAsync();

Если пользователь вызовет намерение «Отменить», это поднимется до MyBot.cs, а dialogResult.Result будет равно «Отменить меня».

Пропуск распознавания LUIS/QnA

Есть два способа пропустить распознавание LUIS:

1. Обход вызовов LUIS и QnA

Если вы не хотите проверять прерывания, настройте условия, при которых вы хотели бы пропустить это. Вы можете использовать что-то вроде:

var interruptedQnaMaker = false;
if (!<yourCondition>)
{
    var interruptedQnaMaker = await IsTurnInterruptedDispatchToQnAMakerAsync(turnContext, topDispatch, QnaConfiguration, cancellationToken);
}

Я сделал что-то похожее в узел-бот, где полностью пропустил luisRecognizer для некоторых диалогов. Для вас это может выглядеть примерно так:

var dc = await _dialogs.CreateContextAsync(turnContext);
if (dc.ActiveDialog != null && dc.ActiveDialog.id == "SkipLuisDialog")
{
    var interruptedQnaMaker = await IsTurnInterruptedDispatchToQnAMakerAsync(turnContext, topDispatch, QnaConfiguration, cancellationToken);
}

2. Настройте приложение LUIS

Похоже, вы настроили его так, что когда LUIS возвращает намерение (topDispatch), которое соответствует qnaDispatchKey, это происходит, когда вы запускаете прерывание. Если «Начать сейчас» и «Остановить сейчас» возвращаются qnaDispatchKey как намерение, вы можете настроить приложение LUIS, чтобы предотвратить это.сильный текст

Спасибо! Это дает мне несколько идей. Путем настройки приложения LUIS, например, удаления высказываний, похожих на «начать сейчас» и «остановить сейчас»?

user10860402 09.04.2019 08:47

Идентификатор моего диалога, похоже, не меняется и всегда «mainDialog». Могу ли я открыть вопрос об этом? Мне нравится ваша идея пропустить диалог для LUIS, если идентификатор диалога совпадает

user10860402 09.04.2019 14:28

Это вопрос, который я открыл относительно идентификаторов. Спасибо stackoverflow.com/questions/55594028/…

user10860402 09.04.2019 15:26

Другие вопросы по теме