我使用 Microsoft Bot Framework 创建了一个聊天机器人 v4,它运行良好。我们有两个环境 QA 和 PROD。随着时间的推移,机器人拥有更多的功能和对话框。
我们发现在 PROD(与 QA 具有相同的代码)中它不能正常工作,有时它会从当前对话框退出并返回到 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,则在后续传递中对话结束并在 Bot.cs 中返回)
出于某种原因,在 PROD 中,机器人会“感到困惑”,并从 GetAnswerAsync 或 ValidateResponseAsync 中退出对话框,并调用 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()
中的 0.60 阈值?由于结果是不确定的(意味着分数可能在不同实例之间波动),也许响应并不总是满足阈值?
希望得到帮助!
关于c# - 如何不丢失聊天机器人 v4 的对话流?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59756337/