LUIS/Bot Framework 多对话框,将意图处理移动到另一个对话框
LUIS / Bot Framework multiple dialog, move intent handling to another dialog
我的目标是使用他们的 C# SDK 将对话框和 LUIS 实现到 Microsoft Bot Framework 应用程序中。
我尝试关注此线程 https://github.com/Microsoft/BotBuilder/issues/127 及其相关帖子(最后引用),但无法让我的代码在实践中运行。这是我的 RootDialog class。请注意,我创建了一个处理 "GetProduct" 意图的方法,当它得到这个意图时,它应该使用 context.Forward() 方法将 LuisResult 转发给 ProductsDialog,但我看到的只是它直接进行到 ResumeAfter 方法,ProductsDialogCompleted。现在,这可能是我失败的地方,但我找不到显示多个 LUIS 对话框的示例。
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);
}
}
预期的行为如下
- 用户触发 GetProduct 意图
- 机器人创建一个新对话框并转到 StartAsync 方法,等待另一个用户输入
- 用户触发了 None 意图
- 对话框关闭,returns true 并触发 ProductsDialogCompleted。
我好像没有正确绑定对话框。我该如何解决?
编辑:添加了 MessageController,版本为 3.8.1
[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;
}
}
尝试从 context.Forward
调用中删除 Chain.From(()
。不确定为什么要添加它,但它根本不应该存在。
试试:
await context.Forward(new ProductsDialog(), ProductsDialogCompleted, context.Activity, CancellationToken.None);
顺便说一句,如果您转发的消息达到 None
意图,ProductsDialogCompleted
方法将被触发,因为您正在执行 context.Done
,这基本上结束了 ProductsDialog
.
此外,请记住 StartAsync
方法存在于 LuisDialog<T>
基础 class 中,因此您需要添加 override
关键字。
我有同样的问题,但我使用的是更新版本的 Bot Framework,更具体地说,是 V4。
这是我的发现:
BeginDialogAsync
的 options
参数采用一个对象数组,然后可以在您的对话框中访问这些对象。
// Get skill LUIS model from configuration.
localizedServices.LuisServices.TryGetValue("MySkill", out var luisService);
if (luisService != null)
{
// Get the Luis result.
var result = innerDc.Context.TurnState.Get<MySkillLuis>(StateProperties.SkillLuisResult);
var intent = result?.TopIntent().intent;
// Behavior switched on intent.
switch (intent)
{
case MySkillLuis.Intent.MyIntent:
{
// result is passed on to my dialog through the Options parameter.
await innerDc.BeginDialogAsync(_myDialog.Id, result);
break;
}
case MySkillLuis.Intent.None:
default:
{
// intent was identified but not yet implemented
await innerDc.Context.SendActivityAsync(_templateEngine.GenerateActivityForLocale("UnsupportedMessage"));
break;
}
}
}
在我们的第二个对话框中,我们可以通过上下文访问对象并根据需要执行任何转换等。在我的例子中,它是一个瀑布对话框,所以我使用了 stepContext.options
。
我的目标是使用他们的 C# SDK 将对话框和 LUIS 实现到 Microsoft Bot Framework 应用程序中。 我尝试关注此线程 https://github.com/Microsoft/BotBuilder/issues/127 及其相关帖子(最后引用),但无法让我的代码在实践中运行。这是我的 RootDialog class。请注意,我创建了一个处理 "GetProduct" 意图的方法,当它得到这个意图时,它应该使用 context.Forward() 方法将 LuisResult 转发给 ProductsDialog,但我看到的只是它直接进行到 ResumeAfter 方法,ProductsDialogCompleted。现在,这可能是我失败的地方,但我找不到显示多个 LUIS 对话框的示例。
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);
}
}
预期的行为如下
- 用户触发 GetProduct 意图
- 机器人创建一个新对话框并转到 StartAsync 方法,等待另一个用户输入
- 用户触发了 None 意图
- 对话框关闭,returns true 并触发 ProductsDialogCompleted。
我好像没有正确绑定对话框。我该如何解决?
编辑:添加了 MessageController,版本为 3.8.1
[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;
}
}
尝试从 context.Forward
调用中删除 Chain.From(()
。不确定为什么要添加它,但它根本不应该存在。
试试:
await context.Forward(new ProductsDialog(), ProductsDialogCompleted, context.Activity, CancellationToken.None);
顺便说一句,如果您转发的消息达到 None
意图,ProductsDialogCompleted
方法将被触发,因为您正在执行 context.Done
,这基本上结束了 ProductsDialog
.
此外,请记住 StartAsync
方法存在于 LuisDialog<T>
基础 class 中,因此您需要添加 override
关键字。
我有同样的问题,但我使用的是更新版本的 Bot Framework,更具体地说,是 V4。
这是我的发现:
BeginDialogAsync
的options
参数采用一个对象数组,然后可以在您的对话框中访问这些对象。
// Get skill LUIS model from configuration.
localizedServices.LuisServices.TryGetValue("MySkill", out var luisService);
if (luisService != null)
{
// Get the Luis result.
var result = innerDc.Context.TurnState.Get<MySkillLuis>(StateProperties.SkillLuisResult);
var intent = result?.TopIntent().intent;
// Behavior switched on intent.
switch (intent)
{
case MySkillLuis.Intent.MyIntent:
{
// result is passed on to my dialog through the Options parameter.
await innerDc.BeginDialogAsync(_myDialog.Id, result);
break;
}
case MySkillLuis.Intent.None:
default:
{
// intent was identified but not yet implemented
await innerDc.Context.SendActivityAsync(_templateEngine.GenerateActivityForLocale("UnsupportedMessage"));
break;
}
}
}
在我们的第二个对话框中,我们可以通过上下文访问对象并根据需要执行任何转换等。在我的例子中,它是一个瀑布对话框,所以我使用了 stepContext.options
。