在LUIS意图中调用CarouselCardsDialog遇问题求助
这俩问题都是Bot对话流程管理里的典型小坑,我来给你拆解解决:
问题1:输入两次HELP才触发轮播对话框
这大概率是你的CarouselCardsDialog没在启动时主动发送轮播卡片,而是在等用户输入后才触发。第一次输HELP时,LUIS识别到意图并调用Help方法,context.Call启动了子对话框,但子对话框没主动发消息,Bot就卡在了等待子对话框输入的状态;第二次输HELP时,消息被子对话框接收,才触发了轮播发送。
解决方法:修改CarouselCardsDialog的StartAsync方法,让它启动就立刻生成并发送轮播卡片,不用等用户输入。示例代码如下:
public class CarouselCardsDialog : IDialog<object> { public async Task StartAsync(IDialogContext context) { // 构造轮播卡片(这里用HeroCard示例,你可以换成适配的卡片类型) var card1 = new HeroCard(Title: "帮助主题1", Subtitle: "账号相关问题"); var card2 = new HeroCard(Title: "帮助主题2", Subtitle: "功能使用指南"); var carousel = new Attachment { ContentType = "application/vnd.microsoft.card.carousel", Content = new List<HeroCard> { card1, card2 } }; var reply = context.MakeMessage(); reply.Attachments.Add(carousel); await context.PostAsync(reply); // 发送完轮播后直接结束子对话框,把控制权交回主对话 context.Done<object>(null); } }
这样改完后,第一次输入HELP时,子对话框启动就会发送轮播,不用再输入第二次。
问题2:加载轮播后输入任何消息都返回轮播
这是因为子对话框没正确结束,导致后续所有输入都被CarouselCardsDialog拦截,没回到LUIS的主对话流程。
解决方法:确保CarouselCardsDialog完成任务后(不管是展示完轮播,还是用户选完卡片),调用context.Done<object>(null)结束子对话框。这样控制权会回到DialogsCompleted方法,context.Wait(MessageReceived)会让Bot回到监听用户消息并交给LUIS处理的状态。
另外检查主对话的MessageReceived方法,确保它正确把用户消息交给LUIS处理:
private async Task MessageReceived(IDialogContext context, IAwaitable<IMessageActivity> result) { var message = await result; // 把消息传给LUIS做意图识别 await _luisService.ResolveAsync(context, message); }
子对话框结束后,DialogsCompleted发送提示消息,然后调用context.Wait(MessageReceived),之后用户的任何输入都会被LUIS处理,不会再触发轮播。
内容的提问来源于stack exchange,提问作者anonymous1110

