Botframework Microsoft Bot Framework-用户被重定向到错误的对话框
我正在使用Microsoft Bot Framework(用于.NET)、QnA Maker和QnAMakerDialog()开发聊天机器人。托管聊天盒控件的bot和web项目部署在Azure中。我是 使用直达线路作为通道 对话流程非常简单。用户从主分支开始。根据用户输入,对话将继续使用QnAMakerDialog或用于反馈的自定义对话框 问题如下: 用户从主分支开始。只要用户不键入“end”,我就将对话转发到QnA对话框,并尝试回答他的问题。在某些情况下,用户键入“end”。因此,我启动反馈对话框。用户输入反馈。现在,应该感谢他的反馈,并将其发送回QnA对话。相反,他得到的答复是,在QnA知识数据库中没有找到好的答案。这意味着,不知何故,他发现自己走错了路!机器人认为他在QnA分支上,但事实上他应该在反馈分支上 按照相同的步骤,无法始终再现此错误。它随机发生,没有模式。更重要的是,它只发生在某些环境中。它从来不会发生在我的开发机器上,它很少发生在一个环境中,而且经常发生在第三个环境中。(这两个环境的配置几乎相同,因此不会出现问题)。此外,问题不可能来自QnAMakerDialog–我使用自定义QnADialog进行了测试,该QnADialog始终返回静态消息,而不是来自QnAMaker的答案,并且问题仍然存在 这是密码。任何想法都是非常受欢迎的Botframework Microsoft Bot Framework-用户被重定向到错误的对话框,botframework,direct-line-botframework,qnamaker,Botframework,Direct Line Botframework,Qnamaker,我正在使用Microsoft Bot Framework(用于.NET)、QnA Maker和QnAMakerDialog()开发聊天机器人。托管聊天盒控件的bot和web项目部署在Azure中。我是 使用直达线路作为通道 对话流程非常简单。用户从主分支开始。根据用户输入,对话将继续使用QnAMakerDialog或用于反馈的自定义对话框 问题如下: 用户从主分支开始。只要用户不键入“end”,我就将对话转发到QnA对话框,并尝试回答他的问题。在某些情况下,用户键入“end”。因此,我启动反馈对
[BotAuthentication]
public class MessagesController : ApiController
{
private readonly ILog log;
public MessagesController(ILog log)
{
this.log = log;
}
internal static IDialog<object> MakeRoot()
{
return Chain.From(() => new HomeDialog());
}
public virtual async Task<HttpResponseMessage> Post([FromBody] Activity activity)
{
var client = new ConnectorClient(new Uri(activity.ServiceUrl));
try
{
switch (activity.GetActivityType())
{
case ActivityTypes.Message:
var typingReply = activity.CreateReply();
typingReply.Type = ActivityTypes.Typing;
await client.Conversations.ReplyToActivityAsync(typingReply);
await Conversation.SendAsync(activity, MakeRoot);
break;
default:
HandleSystemMessage(activity);
break;
}
}
catch (Exception ex)
{
var errorReply = activity.CreateReply();
errorReply.Type = ActivityTypes.Message;
errorReply.Text ="I'm sorry, I'm having issues understanding you. Let's try again.";
await client.Conversations.ReplyToActivityAsync(errorReply);
log.Error("Issue in the bot.", ex);
}
return new HttpResponseMessage(System.Net.HttpStatusCode.Accepted);
}
private Activity HandleSystemMessage(Activity message)
{
if (message.Type == ActivityTypes.DeleteUserData)
{
}
else if (message.Type == ActivityTypes.ConversationUpdate)
{
}
else if (message.Type == ActivityTypes.ContactRelationUpdate)
{
}
else if (message.Type == ActivityTypes.Typing)
{
}
else if (message.Type == ActivityTypes.Ping)
{
}
return null;
}
}
[Serializable]
public class HomeDialog : IDialog<object>
{
public async Task StartAsync(IDialogContext context)
{
context.Wait(MessageReceivedAsync);
}
private async Task MessageReceivedAsync(IDialogContext context, IAwaitable<IMessageActivity> result)
{
await RedirectToQnaDialog(context);
}
private async Task RedirectToQnaDialog(IDialogContext context)
{
await context.Forward(new QnaDialog(), QnaDialogResumeAfter, context.Activity, CancellationToken.None);
}
private async Task QnaDialogResumeAfter(IDialogContext context, IAwaitable<object> result)
{
var message = await result;
PromptDialog.Text(context,
ResumeAfterQuestionTyped,
"Type your question or 'end' to end this conversation.",
"Please retry", 3);
}
private async Task ResumeAfterQuestionTyped(IDialogContext context, IAwaitable<string> inputFromUser)
{
var question = await inputFromUser;
if (question.ToLower().Equals("end"))
{
await context.PostAsync("You would really help me out by giving feedback. " +
"What subjects should we include to provide answers for your questions?");
context.Call(new FeedbackDialog(), FeedbackDialogResumeAfter);
}
else
{
await context.Forward(new QnaDialog(), QnaDialogResumeAfter, context.Activity, CancellationToken.None);
}
}
private async Task FeedbackDialogResumeAfter(IDialogContext context, IAwaitable<object> result)
{
await context.PostAsync("Thank you for your feedback. You can now continue to ask me more questions.");
context.Wait(MessageReceivedAsync);
}
[Serializable]
public class QnaDialog : QnAMakerDialog
{
public QnaDialog() : base(new QnAMakerService
(new QnAMakerAttribute(ConfigurationManager.AppSettings["QnaSubscriptionKey"],
ConfigurationManager.AppSettings["QnaKnownledgeBaseKey"],
ConfigurationManager.AppSettings["QnaNotFoundReply"],
Convert.ToDouble(ConfigurationManager.AppSettings["QnaPrecentageMatch"]), 5)))
{
}
protected override async Task RespondFromQnAMakerResultAsync(IDialogContext context, IMessageActivity message,
QnAMakerResults results)
{
if (results.Answers.Count > 0)
{
var response = results.Answers.First().Answer;
await context.PostAsync(response);
}
}
protected override async Task DefaultWaitNextMessageAsync(IDialogContext context, IMessageActivity message,
QnAMakerResults result)
{
context.Done<IMessageActivity>(null);
}
[Serializable]
public class FeedbackDialog : IDialog<object>
{
public async Task StartAsync(IDialogContext context)
{
context.Wait(MessageReceivedAsync);
}
private async Task MessageReceivedAsync(IDialogContext context, IAwaitable<IMessageActivity> result)
{
var message = await result;
context.Done(message);
}
}
[BotAuthentication]
公共类消息控制器:ApiController
{
私有只读ILog日志;
公共消息控制器(ILog日志)
{
this.log=log;
}
内部静态IDialog MakeRoot()
{
返回链。从(()=>新建HomeDialog());
}
公共虚拟异步任务发布([FromBody]活动)
{
var client=newconnectorclient(新Uri(activity.ServiceUrl));
尝试
{
开关(activity.GetActivityType())
{
案例活动类型。消息:
var typingReply=activity.CreateReply();
typingReply.Type=ActivityTypes.Typing;
等待client.Conversations.ReplyToActivityAsync(键入Reply);
wait Conversation.sendaync(活动,MakeRoot);
打破
违约:
HandleSystemMessage(活动);
打破
}
}
捕获(例外情况除外)
{
var errorReply=activity.CreateReply();
errorReply.Type=ActivityTypes.Message;
errorReply.Text=“对不起,我在理解您时遇到问题。让我们再试一次。”;
等待client.Conversations.ReplyToActivityAsync(errorReply);
日志错误(“bot中的问题”,例如);
}
返回新的HttpResponseMessage(System.Net.HttpStatusCode.Accepted);
}
私有活动HandleSystemMessage(活动消息)
{
if(message.Type==ActivityTypes.DeleteUserData)
{
}
else if(message.Type==ActivityTypes.ConversationUpdate)
{
}
else if(message.Type==ActivityTypes.ContactRelationUpdate)
{
}
else if(message.Type==ActivityTypes.Typing)
{
}
else if(message.Type==ActivityTypes.Ping)
{
}
返回null;
}
}
[可序列化]
公共类HomeDialog:IDialog
{
公共异步任务StartAsync(IDialogContext上下文)
{
Wait(MessageReceivedAsync);
}
专用异步任务消息ReceivedAsync(IDialogContext上下文,IAwaitable结果)
{
等待重定向到qnadialog(上下文);
}
专用异步任务重定向到QNADialog(IDialogContext上下文)
{
wait context.Forward(new QnaDialog(),qnadialogresumefafter,context.Activity,CancellationToken.None);
}
专用异步任务QnaDialogResumeAfter(IDialogContext上下文,IAwaitable结果)
{
var消息=等待结果;
PromptDialog.Text(上下文,
简历输入后,
“键入您的问题或“结束”以结束此对话。”,
“请重试”,3);
}
私有异步任务ResumeAfterQuestionTyped(IDialogContext上下文,IAwaitable inputFromUser)
{
var问题=等待用户输入;
如果(question.ToLower().Equals(“end”))
{
wait context.PostAsync(“你会通过提供反馈来帮助我的。”+
“我们应该包括哪些主题来回答您的问题?”);
调用(new FeedbackDialog(),FeedbackDialogResumeAfter);
}
其他的
{
wait context.Forward(new QnaDialog(),qnadialogresumefafter,context.Activity,CancellationToken.None);
}
}
专用异步任务反馈对话框ResumeAfter(IDialogContext上下文,IAwaitable结果)
{
wait context.PostAsync(“谢谢你的反馈。你现在可以继续问我更多问题了。”);
Wait(MessageReceivedAsync);
}
[可序列化]
公共类QnaDialog:QnAMakerDialog
{
public QnaDialog():基本(新的QnAMakerService
(新的QnAMakerAttribute(ConfigurationManager.AppSettings[“QnaSubscriptionKey”],
ConfigurationManager.AppSettings[“QnaKnownledgeBaseKey”],
ConfigurationManager.AppSettings[“QnanoFoundReply”],
Convert.ToDouble(ConfigurationManager.AppSettings[“QnaPrecentageMatch”]),5)
{
}
受保护的重写异步任务RespondFromQnAMakerResultAs
[Serializable]
public class HomeDialog : IDialog<object>
{
public async Task StartAsync(IDialogContext context)
{
context.Wait(MessageReceivedAsync);
}
private async Task MessageReceivedAsync(IDialogContext context, IAwaitable<IMessageActivity> result)
{
await QnaDialogResumeAfter(context, result);
}
private async Task QnaDialogResumeAfter(IDialogContext context, IAwaitable<object> result)
{
var message = await result;
PromptDialog.Text(context,
ResumeAfterQuestionTyped,
"Type your question or 'end' to end this conversation.",
"Please retry", 3);
}
private async Task ResumeAfterQuestionTyped(IDialogContext context, IAwaitable<string> inputFromUser)
{
var question = await inputFromUser;
if (question.ToLower().Equals("end"))
{
await context.PostAsync("You would really help me out by giving feedback. " +
"What subjects should we include to provide answers for your questions?");
context.Call(new QnaDialog.FeedbackDialog(), FeedbackDialogResumeAfter);
}
else
{
await context.Forward(new QnaDialog(), QnaDialogResumeAfter, context.Activity, CancellationToken.None);
}
}
private async Task FeedbackDialogResumeAfter(IDialogContext context, IAwaitable<object> result)
{
PromptDialog.Text(context,
ResumeAfterQuestionTyped,
"Thank you for your feedback. You can now continue to ask me more questions.",
"Please retry", 3);
}
[Serializable]
public class QnaDialog : QnAMakerDialog
{
public QnaDialog() : base(new QnAMakerService
(new QnAMakerAttribute(ConfigurationManager.AppSettings["QnaSubscriptionKey"],
ConfigurationManager.AppSettings["QnaKnownledgeBaseKey"],
ConfigurationManager.AppSettings["QnaNotFoundReply"],
Convert.ToDouble(ConfigurationManager.AppSettings["QnaPrecentageMatch"]), 5)))
{
}
protected override async Task RespondFromQnAMakerResultAsync(IDialogContext context, IMessageActivity message,
QnAMakerResults results)
{
if (results.Answers.Count > 0)
{
var response = results.Answers.First().Answer;
await context.PostAsync(response);
}
}
protected override async Task DefaultWaitNextMessageAsync(IDialogContext context, IMessageActivity message, QnAMakerResults result)
{
context.Done<IMessageActivity>(null);
}
[Serializable]
public class FeedbackDialog : IDialog<object>
{
public async Task StartAsync(IDialogContext context)
{
context.Wait(MessageReceivedAsync);
}
private async Task MessageReceivedAsync(IDialogContext context, IAwaitable<IMessageActivity> result)
{
var message = await result;
context.Done(message);
}
}
}
}
var store = new InMemoryDataStore(); // volatile in-memory store
builder.Register(c => store)
.Keyed<IBotDataStore<BotData>>(AzureModule.Key_DataStore)
.AsSelf()
.SingleInstance();