[英]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.cs中OnTurnAsync
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 中打印的問題)之后插入答案后失敗。 我不知道它是否在GetAnswerAsync或ValidateResponseAsync 中失敗,因為我無法在 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 中,機器人“感到困惑”並從GetAnswerAsync或ValidateResponseAsync 中的 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.