Как не потерять поток диалога с chatbot v4? - PullRequest
1 голос
/ 15 января 2020

Я создал чатбота v4 с Microsoft Bot Framework, и он работал нормально. У нас есть две среды QA и PROD. Со временем у бота появилось больше функций и диалогов.

Мы обнаружили, что в PROD (который имеет тот же код, что и QA) он не работает нормально, иногда он выходит из текущего диалога и возвращается в init.

Я уже пытался подключите базу QnA QA к PROD, чтобы увидеть, если это проблема с БД, но это не решило проблему.

это часть моего кода

в Bot.cs в OnTurnAsyn c

if (activity.Type == ActivityTypes.Message)
{
    // Continue the current dialog
    var dialogResult = await dc.ContinueDialogAsync();

    // examine results from active dialog
    switch (dialogResult.Status)
    {
        case DialogTurnStatus.Empty:
            await NewConversationFlow(turnContext, dc, conversationId, cancellationToken);
            break;

        case DialogTurnStatus.Waiting:
            // The active Dialog is waiting for a response from the user, so do nothing.
            break;

        case DialogTurnStatus.Complete:
            await dc.EndDialogAsync();
            // do things
            await NewConversationFlow(turnContext, dc, conversationId, cancellationToken);
            break;

        default:
            await dc.CancelAllDialogsAsync();
            break;
    }
}

в Bot.cs в NewConversationFlow

var response = await _services.QnAServices["QnA"].GetAnswersAsync(turnContext, new QnAMakerOptions() { Top = 5, ScoreThreshold = 0.1F });
QueryResult qnaAnswer = GetQnaAnswer(response, 0.60);

await _flowService.ShortDelayWithTypingActionAsync(turnContext);
await turnContext.SendActivityAsync(response.Answer, cancellationToken: cancellationToken);

var flowValue = response.Metadata?.Where(metadata => metadata.Name == "flow").Select(metadata => metadata.Value).FirstOrDefault();
if (!string.IsNullOrEmpty(flowValue))
{
    switch (flowValue)
    {
        case ONE:
        ...
        default:
            await dc.BeginDialogAsync(nameof(OneAnswerDialog));
            break;
        case TWO:
        ...
            await dc.BeginDialogAsync(nameof(TwoAnswerDialog));
            break;
        case SEARCH:
            await dc.BeginDialogAsync(nameof(SearchDialog));
            break;
    }
}

в OneAnswerDialog

// Dialog IDs
profileDialog = nameof(OneAnswerDialog);

// Add control flow dialogs
var firstCaseWaterfallSteps = new WaterfallStep[]
{
            GetAnswerAsync,
            SearchStepAsync,
};
AddDialog(new WaterfallDialog(profileDialog, firstCaseWaterfallSteps));
AddDialog(new TextPrompt(ResponsePrompt, ValidateResponseAsync));

Обычно происходит сбой после того, как пользователь вставляет ответ после первого вопроса (тот, который напечатан в NewConversationFlow). Я не знаю, происходит ли сбой в GetAnswerAsyn c или в ValidateResponseAsyn c, потому что я не могу отладить код в PRD.

в GetAnswerAsyn c

return await stepContext.PromptAsync(ResponsePrompt, new PromptOptions());

in ValidateResponseAsyn c

PositiveResponse = false;
var value = promptContext?.Recognized?.Value?.Trim() ?? string.Empty;

if (value != string.Empty)
{
    promptContext.Recognized.Value = value;

    bool userSayYes = false;
    var response = await _services.QnAServices["QnA"].GetAnswersAsync(promptContext.Context, new QnAMakerOptions() { Top = 5, ScoreThreshold = 0.1F });
    if (response != null && response.Length > 0)
    {
        var responses = response.Where(resp => resp.Metadata?.Any(metadata => metadata.Name == "metadata") ?? false).Select(x => x.Metadata);

        PositiveResponse = responses.Any(metadatas => metadatas.Any(metadata => metadata.Value == "more" || metadata.Value == "no"));
        if (!PositiveResponse && responses.Any(metadatas => metadatas.Any(metadata => metadata.Value == "yes")))
        {
            userSayYes = true;
            await _flowService.DelayWithTypingActionAsync(promptContext.Context);
            await promptContext.Context.SendActivityAsync("Can I help you with anything else?", cancellationToken: cancellationToken);
        }
    }

    if (response == null || response.Length <= 0 || (!PositiveResponse && !userSayYes))
    {
        await _flowService.AddOrUpdateQuestion(promptContext.Context.Activity.Conversation.Id, value);
    }
    else if (userSayYes)
    {
        await _flowService.RemoveFlowTypeAndQuestion(promptContext.Context.Activity.Conversation.Id);
    }
}

return true;

(если PositiveResponse имеет значение false, в последующем проходе Диалог завершается и возвращается в Bot.cs)

По какой-то причине в PROD бот «запутывается» и выходит из диалога в GetAnswerAsyn c или ValidateResponseAsyn c и вспомните NewConversationFlow .

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

В чем может быть проблема? Что может вызвать преждевременный выход из диалога?

Заранее спасибо.

--------------------- ----- РЕДАКТИРОВАТЬ --------------------------

Я туннелировал PRD с помощью ngrok и отладки это с VS, в данном случае бот работает ...

Что может быть? Есть какая-нибудь конфигурация Azure, которая может вызвать это? Я уже проверил тарифный план, и он не бесплатный.

------------------------- - РЕДАКТИРОВАТЬ 2 --------------------------

Я обновил GetAnswerAsyn c чтобы быть уверенным в том, что бот вводит в диалоге:

protected async Task<DialogTurnResult> GetAnswerAsync(
                                        WaterfallStepContext stepContext,
                                        CancellationToken cancellationToken)
{
    await stepContext.Context.SendActivityAsync("What do you think? Does it answer your question?");
    await stepContext.PromptAsync(ResponsePrompt, new PromptOptions());
    return new DialogTurnResult(DialogTurnStatus.Waiting);
}

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

chat with the bot

(«Ох, жаль это слышать!» Это болтовня, это не следующий шаг WaterFall)

Иногда бот работает. Кажется, что-то «случайное».

Working flow

----------------- --------- РЕДАКТИРОВАТЬ 3 -------------------------- У меня все еще есть эта проблема ... У меня есть попытался удалить все настройки из Azure, чтобы приложение прочитало его из файла. Я использовал те же настройки в PRD и QA, но ничего ... Есть идеи?

1 Ответ

1 голос
/ 24 января 2020

В вашем файле "GetAnswerAsyn c" попробуйте заменить ваш код приведенным ниже фрагментом. Я обычно работаю в Node, и иногда я слышал, что диалоговое окно «сбрасывается», если я только возвращаю ожидаемое действие «отправить» / «запросить». Если я явно отправлю DialogTurnStatus, то поток переместится, как и ожидалось (т.е. перейдет к следующему шагу).

await stepContext.PromptAsync(ResponsePrompt, new PromptOptions());
return new DialogTurnStatus(DialogTurnStatus.waiting);

Если не так, могут ли оценки ответа QnA быть слишком близкими к порогу .60 в GetQnaAnswer()? Поскольку результаты не детерминированы c (имеется в виду, что оценка может колебаться от экземпляра к экземпляру), возможно, ответ не всегда соответствует порогу?

Надежда на помощь!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...