C# LUIS/Bot框架多对话框,将意图处理移动到另一个对话框
我的目标是使用dialogs和LUIS的C#SDK将其实现到Microsoft Bot框架应用程序中。 我试图遵循这条线索和他们的相关文章(在最后引用),但无法让我的代码在实践中发挥作用。这是我的RootDialog类。请注意,我创建了一个处理“GetProduct”意图的方法,当它获得此意图时,它应该使用context.forward()方法将LuisResult转发给ProductsDialog,但我看到的是它直接转到ResumeAfter方法ProductsDialogCompleted。现在,这里可能是我失败的地方,但我找不到显示多个LUIS对话框的示例C# LUIS/Bot框架多对话框,将意图处理移动到另一个对话框,c#,botframework,azure-language-understanding,C#,Botframework,Azure Language Understanding,我的目标是使用dialogs和LUIS的C#SDK将其实现到Microsoft Bot框架应用程序中。 我试图遵循这条线索和他们的相关文章(在最后引用),但无法让我的代码在实践中发挥作用。这是我的RootDialog类。请注意,我创建了一个处理“GetProduct”意图的方法,当它获得此意图时,它应该使用context.forward()方法将LuisResult转发给ProductsDialog,但我看到的是它直接转到ResumeAfter方法ProductsDialogCompleted。
public class RootDialog : LuisDialog<object>
{
[LuisIntent("GetProduct")]
private async Task GetProduct(IDialogContext context, LuisResult result)
{
await context.PostAsync("Calling ProductsDialog...");
await context.Forward(Chain.From(() => new ProductsDialog()), ProductsDialogCompleted, context.Activity, CancellationToken.None);
}
private async Task ProductsDialogCompleted(IDialogContext context, IAwaitable<object> result)
{
var res = await result;
context.PostAsync("ProductsDialogCompleted" + result);
context.Wait(this.MessageReceived);
}
}
public class ProductsDialog : LuisDialog<object>
{
public async Task StartAsync(IDialogContext context)
{
await context.PostAsync("Entered ProductsDialog");
context.Wait(this.MessageReceived);
}
[LuisIntent("None")]
private async Task None(IDialogContext context, LuisResult result)
{
context.Done(true);
}
}
public类RootDialog:LuisDialog
{
[LuisIntent(“GetProduct”)]
私有异步任务GetProduct(IDialogContext上下文,LuisResult结果)
{
wait context.PostAsync(“调用ProductsDialog…”);
wait context.Forward(Chain.From(()=>newproductsdialog()),ProductsDialogCompleted,context.Activity,CancellationToken.None);
}
专用异步任务ProductsDialogCompleted(IDialogContext上下文,IAwaitable结果)
{
var res=等待结果;
PostAsync(“ProductsDialogCompleted”+结果);
context.Wait(this.MessageReceived);
}
}
公共类产品对话框:LuisDialog
{
公共异步任务StartAsync(IDialogContext上下文)
{
wait context.PostAsync(“已输入产品对话框”);
context.Wait(this.MessageReceived);
}
[路易辛顿(“无”)]
专用异步任务无(IDialogContext上下文,LuisResult结果)
{
上下文。完成(true);
}
}
预期的行为如下
[BotAuthentication]
public class MessagesController : ApiController
{
/// <summary>
/// POST: api/Messages
/// Receive a message from a user and reply to it
/// </summary>
public async Task<HttpResponseMessage> Post([FromBody]Activity activity)
{
if (activity.Type == ActivityTypes.Message)
{
await Conversation.SendAsync(activity, () => new RootDialog());
}
else
{
HandleSystemMessage(activity);
}
var response = Request.CreateResponse(HttpStatusCode.OK);
return response;
}
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;
}
}
[BotAuthentication]
公共类消息控制器:ApiController
{
///
///帖子:api/Messages
///接收来自用户的消息并回复
///
公共异步任务发布([FromBody]活动)
{
if(activity.Type==ActivityTypes.Message)
{
wait Conversation.sendaync(活动,()=>newrootdialog());
}
其他的
{
HandleSystemMessage(活动);
}
var response=Request.CreateResponse(HttpStatusCode.OK);
返回响应;
}
私有活动HandleSystemMessage(活动消息)
{
if(message.Type==ActivityTypes.DeleteUserData)
{
//在此处执行用户删除
//如果我们处理用户删除,返回一条真实的消息
}
else if(message.Type==ActivityTypes.ConversationUpdate)
{
//处理会话状态更改,如添加和删除成员
//使用Activity.MembersAdded和Activity.MembersRemoved以及Activity.Action获取信息
//并非所有频道都可用
}
else if(message.Type==ActivityTypes.ContactRelationUpdate)
{
//处理联系人列表中的添加/删除
//Activity.From+Activity.Action表示发生了什么
}
else if(message.Type==ActivityTypes.Typing)
{
//处理知道用户正在键入的内容
}
else if(message.Type==ActivityTypes.Ping)
{
}
返回null;
}
}
尝试从上下文.Forward
调用中删除链From(()
)。不确定添加它的原因,但它不应该在那里
尝试:
await context.Forward(new ProductsDialog(), ProductsDialogCompleted, context.Activity, CancellationToken.None);
顺便说一句,如果转发的消息点击了None
意图,则会点击ProductsDialogCompleted
方法,因为您正在执行context.Done
,这基本上结束了ProductsDialog
另外,请记住
StartAsync
方法存在于LuisDialog
基类中,因此您需要添加override
关键字。我有同样的问题,但我使用的是较新版本的Bot框架,更具体地说,是V4
以下是我的发现:
的BeginDialogAsync
参数接受一组对象,这些对象将在对话框中访问选项
//从配置中获取技能LUIS模型。
localizedServices.LuisServices.TryGetValue(“MySkill”,out var luisService);
if(luisService!=null)
{
//得到路易斯的结果。
var result=innerDc.Context.TurnState.Get(StateProperties.SkillLuisResult);
var intent=结果?.TopIntent().intent;
//行为取决于意图。
开关(意图)
{
案例MySkillLuis.Intent.MyIntent:
{
//结果通过Options参数传递给我的对话框。
等待innerDc.BeginDialogAsync(_myDialog.Id,result);
打破
}
案例MySkillLuis.Intent.None:
违约:
{
//已确定意图,但尚未实施
等待innerDc.Context.SendActivityAsync(_templateEngine.GenerateActivityForLocale(“UnsupportedMessage”);
打破
}
}
}
在第二个对话框中,我们可以通过上下文访问对象,并根据需要执行任何强制转换等操作。在我的例子中,这是一个瀑布式对话框,所以我使用了
stepContext.options
它不起作用。我希望ProductsDialog成为活动对话框,以便它可以捕获传入的消息,就像在程序启动,所以它应该在返回t之前接受另一条触发none的消息