根据 MS Bot Framework 中的响应分支 dialogs/forms
Branching dialogs/forms based on response in MS Bot Framework
我们正在试验 MS Bot Framework,但尚未完全弄清楚如何执行此方案:
我们有一个 LUIS 对话(类型 <object>
),它工作正常并且经过了适当的训练。使用常见的三明治示例,LUIS 意图的基础是用户询问订单状态。如果在问题中提供了订单号 ("What is the status of order 1234?"),则 LUIS 对话框会进行查找并直接报告状态(当前全部正常)。
但是,如果用户只是触发了意图而没有提供订单号 ("I'd like to look up the status of an order."),我想启动另一个 dialog/form 来询问用户是否愿意查看按地址或订单号查询订单,然后根据他们的回答进行适当的数据库查找。
我只是不确定如何配置 Form/Dialog(甚至在这种情况下哪个是最好的)以根据他们选择地址还是号码查找来执行不同的查找。
目前的意图如下:
private readonly BuildFormDelegate<OrderStatusDialog> OrderStatusDelegate;
[LuisIntent(nameof(LuisIntents.OrderStatus))]
public async Task OrderStatus(IDialogContext context, LuisResult result)
{
// Order number(s) were provided
if (result.Entities.Any(Entity => Entity.Type == nameof(LuisEntityTypes.OrderNumber)))
{
// Loop in case they asked about multiple orders
foreach (var entity in result.Entities.Where(Entity => Entity.Type == nameof(LuisEntityTypes.OrderNumber)))
{
var orderNum = entity.Entity;
// Call webservice to check status
var request = new RestRequest(Properties.Settings.Default.GetOrderByNum, Method.GET);
request.AddUrlSegment("num", orderNum);
var response = await RestHelper.SendRestRequestAsync(request);
var parsedResponse = JObject.Parse(response);
if ((bool)parsedResponse["errored"])
{
await context.PostAsync((string)parsedResponse["errMsg"]);
continue;
}
// Grab status from returned JSON
var status = parsedResponse["orderStatus"].ToString();
await context.PostAsync($"The status of order {orderNum} is {status}");
}
context.Wait(MessageReceived);
}
// Order number was not provided
else
{
var orderStatusForm = new FormDialog<OrderStatusDialog>(new OrderStatusDialog(), OrderStatusDelegate,
FormOptions.PromptInStart);
context.Call<OrderStatusDialog>(orderStatusForm, CallBack);
}
}
private async Task CallBack(IDialogContext context, IAwaitable<object> result)
{
context.Wait(MessageReceived);
}
以及表格:
public enum OrderStatusLookupOptions
{
Address,
OrderNumber
}
[Serializable]
public class OrderStatusDialog
{
public OrderStatusLookupOptions? LookupOption;
public static IForm<OrderStatusDialog> BuildForm()
{
return new FormBuilder<OrderStatusDialog>()
.Message("In order to look up the status of a order, we will first need either the order number or your delivery address.")
.Build();
}
}
FormFlow 路由是一个有效选项。您的表单流程中缺少的是在选择查找选项后要求输入 address/order 编号。
在这种情况下,您可以在 OrderStatusDialog
class 中再添加两个字段:OrderNumber
和 DeliveryAddress
。
然后你需要使用选中的OrderStatusLookupOptions
到activate/deactivate下一个字段
代码,从我的脑海中,会是这样的:
[Serializable]
public class OrderStatusDialog
{
public OrderStatusLookupOptions? LookupOption;
public int OrderNumber;
public string DeliveryAddress
public static IForm<OrderStatusDialog> BuildForm()
{
return new FormBuilder<OrderStatusDialog>()
.Message("In order to look up the status of a order, we will first need either the order number or your delivery address.")
.Field(nameof(OrderStatusDialog.LookupOption))
.Field(new FieldReflector<OrderStatusDialog>(nameof(OrderStatusDialog.OrderNumber))
.SetActive(state => state.LookupOption == OrderStatusLookupOptions.OrderNumber))
.Field(new FieldReflector<OrderStatusDialog>(nameof(OrderStatusDialog.DeliveryAddress))
.SetActive(state => state.LookupOption == OrderStatusLookupOptions.Address))
.Build();
}
}
然后在您的回调方法中,您将收到填写的表格,您可以进行数据库查找。
或者,您可以只使用 PromptDialogs 并引导用户完成相同的体验。查看 MultiDialogs 示例以了解不同的替代方案。
我在此 here 上添加了一个工作示例。
我们正在试验 MS Bot Framework,但尚未完全弄清楚如何执行此方案:
我们有一个 LUIS 对话(类型 <object>
),它工作正常并且经过了适当的训练。使用常见的三明治示例,LUIS 意图的基础是用户询问订单状态。如果在问题中提供了订单号 ("What is the status of order 1234?"),则 LUIS 对话框会进行查找并直接报告状态(当前全部正常)。
但是,如果用户只是触发了意图而没有提供订单号 ("I'd like to look up the status of an order."),我想启动另一个 dialog/form 来询问用户是否愿意查看按地址或订单号查询订单,然后根据他们的回答进行适当的数据库查找。
我只是不确定如何配置 Form/Dialog(甚至在这种情况下哪个是最好的)以根据他们选择地址还是号码查找来执行不同的查找。
目前的意图如下:
private readonly BuildFormDelegate<OrderStatusDialog> OrderStatusDelegate;
[LuisIntent(nameof(LuisIntents.OrderStatus))]
public async Task OrderStatus(IDialogContext context, LuisResult result)
{
// Order number(s) were provided
if (result.Entities.Any(Entity => Entity.Type == nameof(LuisEntityTypes.OrderNumber)))
{
// Loop in case they asked about multiple orders
foreach (var entity in result.Entities.Where(Entity => Entity.Type == nameof(LuisEntityTypes.OrderNumber)))
{
var orderNum = entity.Entity;
// Call webservice to check status
var request = new RestRequest(Properties.Settings.Default.GetOrderByNum, Method.GET);
request.AddUrlSegment("num", orderNum);
var response = await RestHelper.SendRestRequestAsync(request);
var parsedResponse = JObject.Parse(response);
if ((bool)parsedResponse["errored"])
{
await context.PostAsync((string)parsedResponse["errMsg"]);
continue;
}
// Grab status from returned JSON
var status = parsedResponse["orderStatus"].ToString();
await context.PostAsync($"The status of order {orderNum} is {status}");
}
context.Wait(MessageReceived);
}
// Order number was not provided
else
{
var orderStatusForm = new FormDialog<OrderStatusDialog>(new OrderStatusDialog(), OrderStatusDelegate,
FormOptions.PromptInStart);
context.Call<OrderStatusDialog>(orderStatusForm, CallBack);
}
}
private async Task CallBack(IDialogContext context, IAwaitable<object> result)
{
context.Wait(MessageReceived);
}
以及表格:
public enum OrderStatusLookupOptions
{
Address,
OrderNumber
}
[Serializable]
public class OrderStatusDialog
{
public OrderStatusLookupOptions? LookupOption;
public static IForm<OrderStatusDialog> BuildForm()
{
return new FormBuilder<OrderStatusDialog>()
.Message("In order to look up the status of a order, we will first need either the order number or your delivery address.")
.Build();
}
}
FormFlow 路由是一个有效选项。您的表单流程中缺少的是在选择查找选项后要求输入 address/order 编号。
在这种情况下,您可以在 OrderStatusDialog
class 中再添加两个字段:OrderNumber
和 DeliveryAddress
。
然后你需要使用选中的OrderStatusLookupOptions
到activate/deactivate下一个字段
代码,从我的脑海中,会是这样的:
[Serializable]
public class OrderStatusDialog
{
public OrderStatusLookupOptions? LookupOption;
public int OrderNumber;
public string DeliveryAddress
public static IForm<OrderStatusDialog> BuildForm()
{
return new FormBuilder<OrderStatusDialog>()
.Message("In order to look up the status of a order, we will first need either the order number or your delivery address.")
.Field(nameof(OrderStatusDialog.LookupOption))
.Field(new FieldReflector<OrderStatusDialog>(nameof(OrderStatusDialog.OrderNumber))
.SetActive(state => state.LookupOption == OrderStatusLookupOptions.OrderNumber))
.Field(new FieldReflector<OrderStatusDialog>(nameof(OrderStatusDialog.DeliveryAddress))
.SetActive(state => state.LookupOption == OrderStatusLookupOptions.Address))
.Build();
}
}
然后在您的回调方法中,您将收到填写的表格,您可以进行数据库查找。
或者,您可以只使用 PromptDialogs 并引导用户完成相同的体验。查看 MultiDialogs 示例以了解不同的替代方案。
我在此 here 上添加了一个工作示例。