簡體   English   中英

如何不丟失聊天機器人 v4 的對話流程?

[英]How not to lose dialog flow with chatbot v4?

我已經使用 Microsoft Bot Framework 創建了一個聊天機器人 v4,它運行良好。 我們有兩個環境 QA 和 PROD。 隨着時間的推移,機器人有更多的功能和對話框。

我們發現在 PROD(與 QA 具有相同的代碼)中它不能正常工作,有時它會從當前 Dialog 退出並返回到 init。

我已經嘗試將 QnA QA base 連接到 PROD 以查看它是否是 DB 問題,但它並沒有解決問題。

這是我的代碼的一部分

Bot.csOnTurnAsync

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.csNewConversationFlow

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 中打印的問題)之后插入答案后失敗。 我不知道它是否在GetAnswerAsyncValidateResponseAsync 中失敗,因為我無法在 PRD 中調試代碼。

GetAnswerAsync 中

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

ValidateResponseAsync 中

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,則在連續傳遞中 Dialog 結束並在 Bot.cs 中返回)

出於某種原因,在 PROD 中,機器人“感到困惑”並從GetAnswerAsyncValidateResponseAsync 中的 Dialog 退出並調用NewConversationFlow

我在另一篇文章中讀到點輸入的延遲會導致這個問題,我已經刪除了它們,但問題仍然存在......

可能是什么問題呢? 什么會導致過早退出對話框?

提前致謝。

- - - - - - - - - - - - - 編輯 - - - - - - - - - - - - ---

我已經用 ngrok 隧道傳輸 PRD 並用 VS 調試它,在這種情況下,它正在工作的機器人......

可以是什么? 有任何 Azure 配置會導致它嗎? 我已經檢查了計費計划,它不是免費的。

-------------------------- 編輯 2 ---------------------- ----

我已更新GetAnswerAsync以確保機器人正在進入對話框:

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);
}

此時似乎退出對話框,等待用戶提示時...

與機器人聊天

(“哦,很抱歉聽到這個!”是閑聊,這不是瀑布的下一步)

有時,機器人會起作用。 這似乎是“隨機”的東西。

工作流程

-------------------------- 編輯 3 -------------- ----我仍然有這個問題......我試圖從 Azure 中刪除所有設置以強制應用程序從文件中讀取它。 我在 PRD 和 QA 中使用了相同的設置,但什么都沒有......知道嗎?

在您的“GetAnswerAsync”文件中,嘗試用以下代碼段替換您的代碼。 我通常在 Node 中工作,如果我只返回等待的“發送”/“提示”活動,我偶爾會遇到對話框會“重置”。 如果我明確發送DialogTurnStatus ,那么流程會按預期移動(即進入以下步驟)。

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

如果不是這樣,QnA 響應分數是否可能太接近GetQnaAnswer()的 .60 閾值? 由於結果是不確定的(意味着分數可能因實例而異),也許響應並不總是滿足閾值?

希望得到幫助!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM