如何在MS Bot中将LUIS实体转发至子对话框?
如何将LuisResults中的实体转发到子对话框?
嘿,我来帮你搞定把LUIS识别出的实体传递给子对话框的事儿!你的思路其实已经对了一半,用context.Forward是正确的方向,只是子对话框需要做一点调整来接收这个参数。下面是完整的实现方案:
父LUIS对话框的代码
首先保持你原来的Foo意图方法,注意context.Forward的第三个参数就是要传递给子对话框的实体集合,同时要准备好回调方法处理子对话框返回的结果:
// Luis对话框类 [LuisIntent("Foo")] public async Task Foo(IDialogContext context, LuisResult result) { var entities = result.Entities; // 用Forward传递实体,第三个参数就是要转发的对象 await context.Forward(new FooDialog(), AfterFooDialog, entities, CancellationToken.None); } // 子对话框结束后的回调方法 private async Task AfterFooDialog(IDialogContext context, IAwaitable<IEnumerable<EntityRecommendation>> result) { // 获取子对话框返回的数据 var processedEntities = await result; await context.PostAsync("子对话框已经处理完实体啦!"); // 回到父对话框的等待状态 context.Wait(MessageReceived); }
子对话框(FooDialog)的修改
默认的StartAsync不会接收传递的参数,所以我们需要重写带参数的重载版本,同时让对话框实现IDialog<T>接口来指定返回类型:
// Foo对话框类 public class FooDialog : IDialog<IEnumerable<EntityRecommendation>> { // 重写带参数的StartAsync,接收父对话框传递的实体 public async Task StartAsync(IDialogContext context, IAwaitable<object> argument) { // 解析传递过来的实体集合 var entities = await argument as IEnumerable<EntityRecommendation>; // 这里就可以直接使用实体做操作了,比如告知用户收到的内容 if (entities != null && entities.Any()) { var entityList = string.Join(", ", entities.Select(e => $"{e.Entity}(类型:{e.Type})")); await context.PostAsync($"我收到这些实体啦:{entityList}"); } else { await context.PostAsync("没有收到任何实体哦"); } // 继续等待用户输入或者直接处理后续逻辑 context.Wait(MessageReceivedAsync); } private async Task MessageReceivedAsync(IDialogContext context, IAwaitable<IMessageActivity> result) { var userMessage = await result; await context.PostAsync($"在子对话框里收到你的消息:{userMessage.Text}"); // 结束子对话框,把实体返回给父对话框(也可以返回其他处理后的结果) context.Done(context.UserData.GetValueOrDefault<IEnumerable<EntityRecommendation>>("entities")); } }
关键要点说明
- 子对话框必须实现
IDialog<T>接口,T是你想要返回给父对话框的数据类型(这里我们用实体集合IEnumerable<EntityRecommendation>) - 一定要重写
StartAsync(IDialogContext context, IAwaitable<object> argument)这个方法,才能接收context.Forward传递过来的参数 - 可以把实体存储在
context.UserData里,方便子对话框的其他方法调用 - 父对话框的回调方法
AfterFooDialog的泛型参数要和子对话框IDialog<T>的T保持一致,这样才能正确接收返回值
内容的提问来源于stack exchange,提问作者Adam
相关产品推荐
相关产品推荐

