一旦消息根据意图从 LUIS 转发到 QnA,就不会从第二个实例返回到 c# 中的 LUIS。该怎么办?
Once the message forwarded from LUIS to QnA depending on the intent, not returning to LUIS in c# from the second instance. What to do?
我试图连接 LUIS 和 QnA,但是从消息控制器开始,它首先会转到 luis,如果需要,则相应地转到 QnA,但是一旦进入 QnA,下一条消息就不会发送到 LUIS,只能执行通过 QnA。有人可以帮忙吗?
messageControler.cs
public virtual async Task<HttpResponseMessage> Post([FromBody] Activity activity)
{
//await Conversation.SendAsync(activity, () => new BasicLuisDialog());
// check if activity is of type message
if (activity.GetActivityType() == ActivityTypes.Message)
{
//await Conversation.SendAsync(activity, () => new BasicQnAMakerDialog());
await Conversation.SendAsync(activity, () => new BasicLuisDialog());
}
else
{
//await Conversation.SendAsync(activity, () => new BasicQnAMakerDialog());
HandleSystemMessage(activity);
}
return new HttpResponseMessage(System.Net.HttpStatusCode.Accepted);
}
private Activity HandleSystemMessage(Activity message)
{
if (message.Type == ActivityTypes.DeleteUserData)
{
// Implement user deletion here
// If we handle user deletion, return a real message
}
else if (message.Type == ActivityTypes.ConversationUpdate)
{
// Handle conversation state changes, like members being added and removed
// Use Activity.MembersAdded and Activity.MembersRemoved and Activity.Action for info
// Not available in all channels
}
else if (message.Type == ActivityTypes.ContactRelationUpdate)
{
// Handle add/remove from contact lists
// Activity.From + Activity.Action represent what happened
}
else if (message.Type == ActivityTypes.Typing)
{
// Handle knowing tha the user is typing
}
else if (message.Type == ActivityTypes.Ping)
{
}
return null;
}
}
}
BasicLuisDialog.cs
这是基本 luisdialog 的代码,从这里开始,如果意图匹配,那么它应该提供所需的回复,否则如果 none 它将搜索重定向到基本 qna。这只是第一次执行。从第二个实例开始,如果它在 qna 中,它就不会从 luis 开始。
public class BasicLuisDialog : LuisDialog<object>
{
[LuisIntent("")]
[LuisIntent("None")]
public async Task None(IDialogContext context, IAwaitable<IMessageActivity> message, LuisResult result)
{
var mForward = await message as Activity;
var username = context.Activity.From.Name;
string reply = $"Hello {username}! Your query we are taking forward, as we are not aware about what exactly you want to know.";
//await context.PostAsync(reply);
await context.Forward(new IDialog(), this.ResumeAfterQnA, mForward, CancellationToken.None);
}
private async Task ResumeAfterQnA(IDialogContext context, IAwaitable<object> result)
{
context.Wait(MessageReceived);
}
[LuisIntent("leave.apply")]
public async Task ApplyLeave(IDialogContext context, IAwaitable<IMessageActivity> message, LuisResult result)
{
var username = context.Activity.From.Name;
string reply = $"Hello {username}! we are processing it";
await context.PostAsync(reply);
}
[LuisIntent("it")]
public async Task IT(IDialogContext context, IAwaitable<IMessageActivity> message, LuisResult result)
{
var username = context.Activity.From.Name;
string reply = $"Hello {username}! we would look into your IT problems shortly";
await context.PostAsync(reply);
}
}
BasicQnAMakerDialog
下面给出了基本的 QnA 代码。请帮我找出问题的确切位置。
public class IDialog : IDialog<object>
{
public async Task StartAsync(IDialogContext context)
{
/* Wait until the first message is received from the conversation and call MessageReceviedAsync
* to process that message. */
context.Wait(this.MessageReceivedAsync);
}
private async Task MessageReceivedAsync(IDialogContext context, IAwaitable<IMessageActivity> result)
{
/* When MessageReceivedAsync is called, it's passed an IAwaitable<IMessageActivity>. To get the message,
* await the result. */
var message = await result;
var activity = await result as Activity;
var qnaAuthKey = ConfigurationManager.AppSettings["QnAAuthKey"];
var qnaKBId = ConfigurationManager.AppSettings["QnAKnowledgebaseId"];
var endpointHostName = ConfigurationManager.AppSettings["QnAEndpointHostName"];
// QnA Subscription Key and KnowledgeBase Id null verification
if (!string.IsNullOrEmpty(qnaAuthKey) && !string.IsNullOrEmpty(qnaKBId))
{
// Forward to the appropriate Dialog based on whether the endpoint hostname is present
if (string.IsNullOrEmpty(endpointHostName)) {
await context.Forward(new BasicQnAMakerPreviewDialog(), AfterAnswerAsync, message, CancellationToken.None);
}
else
{
await context.Forward(new BasicQnAMakerDialog(), AfterAnswerAsync, message, CancellationToken.None);
}
}
else
{
await context.PostAsync("Please set QnAKnowledgebaseId, QnAAuthKey and QnAEndpointHostName (if applicable) in App Settings. Learn how to get them at https://aka.ms/qnaabssetup.");
}
//var activity = await result as Activity;
//await context.Forward(new BasicLuisDialog(), ResumeAfterLuisDialog, activity, CancellationToken.None);
}
当对话框完成它应该做的事情时,您需要调用 context.Done(new MyDialogResult())
。机器人框架为每个对话保留一堆对话,每当您执行 context.Forward
时,它都会将一个新对话推送到堆栈,并且发送给机器人的每条消息将始终进入堆栈顶部的对话并跳过下面的其他人,所以当你执行 context.Done
时,它会从堆栈中弹出当前对话框,并将对话 returns 弹出到上一个对话框。
我试图连接 LUIS 和 QnA,但是从消息控制器开始,它首先会转到 luis,如果需要,则相应地转到 QnA,但是一旦进入 QnA,下一条消息就不会发送到 LUIS,只能执行通过 QnA。有人可以帮忙吗?
messageControler.cs
public virtual async Task<HttpResponseMessage> Post([FromBody] Activity activity)
{
//await Conversation.SendAsync(activity, () => new BasicLuisDialog());
// check if activity is of type message
if (activity.GetActivityType() == ActivityTypes.Message)
{
//await Conversation.SendAsync(activity, () => new BasicQnAMakerDialog());
await Conversation.SendAsync(activity, () => new BasicLuisDialog());
}
else
{
//await Conversation.SendAsync(activity, () => new BasicQnAMakerDialog());
HandleSystemMessage(activity);
}
return new HttpResponseMessage(System.Net.HttpStatusCode.Accepted);
}
private Activity HandleSystemMessage(Activity message)
{
if (message.Type == ActivityTypes.DeleteUserData)
{
// Implement user deletion here
// If we handle user deletion, return a real message
}
else if (message.Type == ActivityTypes.ConversationUpdate)
{
// Handle conversation state changes, like members being added and removed
// Use Activity.MembersAdded and Activity.MembersRemoved and Activity.Action for info
// Not available in all channels
}
else if (message.Type == ActivityTypes.ContactRelationUpdate)
{
// Handle add/remove from contact lists
// Activity.From + Activity.Action represent what happened
}
else if (message.Type == ActivityTypes.Typing)
{
// Handle knowing tha the user is typing
}
else if (message.Type == ActivityTypes.Ping)
{
}
return null;
}
}
}
BasicLuisDialog.cs 这是基本 luisdialog 的代码,从这里开始,如果意图匹配,那么它应该提供所需的回复,否则如果 none 它将搜索重定向到基本 qna。这只是第一次执行。从第二个实例开始,如果它在 qna 中,它就不会从 luis 开始。
public class BasicLuisDialog : LuisDialog<object>
{
[LuisIntent("")]
[LuisIntent("None")]
public async Task None(IDialogContext context, IAwaitable<IMessageActivity> message, LuisResult result)
{
var mForward = await message as Activity;
var username = context.Activity.From.Name;
string reply = $"Hello {username}! Your query we are taking forward, as we are not aware about what exactly you want to know.";
//await context.PostAsync(reply);
await context.Forward(new IDialog(), this.ResumeAfterQnA, mForward, CancellationToken.None);
}
private async Task ResumeAfterQnA(IDialogContext context, IAwaitable<object> result)
{
context.Wait(MessageReceived);
}
[LuisIntent("leave.apply")]
public async Task ApplyLeave(IDialogContext context, IAwaitable<IMessageActivity> message, LuisResult result)
{
var username = context.Activity.From.Name;
string reply = $"Hello {username}! we are processing it";
await context.PostAsync(reply);
}
[LuisIntent("it")]
public async Task IT(IDialogContext context, IAwaitable<IMessageActivity> message, LuisResult result)
{
var username = context.Activity.From.Name;
string reply = $"Hello {username}! we would look into your IT problems shortly";
await context.PostAsync(reply);
}
}
BasicQnAMakerDialog 下面给出了基本的 QnA 代码。请帮我找出问题的确切位置。
public class IDialog : IDialog<object>
{
public async Task StartAsync(IDialogContext context)
{
/* Wait until the first message is received from the conversation and call MessageReceviedAsync
* to process that message. */
context.Wait(this.MessageReceivedAsync);
}
private async Task MessageReceivedAsync(IDialogContext context, IAwaitable<IMessageActivity> result)
{
/* When MessageReceivedAsync is called, it's passed an IAwaitable<IMessageActivity>. To get the message,
* await the result. */
var message = await result;
var activity = await result as Activity;
var qnaAuthKey = ConfigurationManager.AppSettings["QnAAuthKey"];
var qnaKBId = ConfigurationManager.AppSettings["QnAKnowledgebaseId"];
var endpointHostName = ConfigurationManager.AppSettings["QnAEndpointHostName"];
// QnA Subscription Key and KnowledgeBase Id null verification
if (!string.IsNullOrEmpty(qnaAuthKey) && !string.IsNullOrEmpty(qnaKBId))
{
// Forward to the appropriate Dialog based on whether the endpoint hostname is present
if (string.IsNullOrEmpty(endpointHostName)) {
await context.Forward(new BasicQnAMakerPreviewDialog(), AfterAnswerAsync, message, CancellationToken.None);
}
else
{
await context.Forward(new BasicQnAMakerDialog(), AfterAnswerAsync, message, CancellationToken.None);
}
}
else
{
await context.PostAsync("Please set QnAKnowledgebaseId, QnAAuthKey and QnAEndpointHostName (if applicable) in App Settings. Learn how to get them at https://aka.ms/qnaabssetup.");
}
//var activity = await result as Activity;
//await context.Forward(new BasicLuisDialog(), ResumeAfterLuisDialog, activity, CancellationToken.None);
}
当对话框完成它应该做的事情时,您需要调用 context.Done(new MyDialogResult())
。机器人框架为每个对话保留一堆对话,每当您执行 context.Forward
时,它都会将一个新对话推送到堆栈,并且发送给机器人的每条消息将始终进入堆栈顶部的对话并跳过下面的其他人,所以当你执行 context.Done
时,它会从堆栈中弹出当前对话框,并将对话 returns 弹出到上一个对话框。