如何重写QnAMakerDialog未匹配逻辑以禁用默认回复?
解决QnAMakerDialog未匹配时阻止默认回复并转发到LuisDialog的问题
我完全懂你的困扰——RespondFromQnAMakerResultAsync确实只会在QnA Maker找到有效匹配时触发,无匹配的场景它根本不会执行,所以直接改默认消息为空也没用,框架还是会自动蹦出那个"No match found!"。要实现无匹配时直接转发到LuisDialog且不发任何默认消息,你可以通过重写QnAMakerDialog的两个关键方法来搞定:
方法一:重写OnQnAMakerResponseAsync(推荐)
这个方法是处理QnA Maker所有响应的入口,不管有没有匹配都会触发。你可以在这里判断是否有有效答案,没有的话直接跳转到LuisDialog:
public class CustomQnADialog : QnAMakerDialog { public CustomQnADialog(IConfiguration config) : base(new QnAMakerEndpoint { KnowledgeBaseId = config["QnAKnowledgeBaseId"], EndpointKey = config["QnAEndpointKey"], Host = config["QnAEndpointHostName"] }) { } protected override async Task OnQnAMakerResponseAsync(DialogContext dc, QnAMakerResponse response, CancellationToken cancellationToken = default) { // 自定义判断:检查是否有分数达标的有效答案(阈值可根据你的需求调整) var hasValidAnswer = response.Answers != null && response.Answers.Any(answer => answer.Score >= 0.6); if (!hasValidAnswer) { // 无匹配,直接启动LuisDialog,跳过默认回复 await dc.BeginDialogAsync(nameof(YourLuisDialog), null, cancellationToken); return; } // 有有效答案时,执行原有的QnA回复逻辑 await base.OnQnAMakerResponseAsync(dc, response, cancellationToken); } }
方法二:重写DefaultWaitNextMessageAsync
当QnA Maker无匹配时,框架会调用这个方法来发送默认的"No match found!"消息。你可以重写它,让它直接跳转到LuisDialog,完全跳过默认消息的发送:
protected override Task DefaultWaitNextMessageAsync(DialogContext dc, CancellationToken cancellationToken = default) { // 直接启动LuisDialog,不发送任何默认回复 return dc.BeginDialogAsync(nameof(YourLuisDialog), null, cancellationToken); }
注意事项
- 确保你的
YourLuisDialog已经在对话框集合中注册(比如在Startup.cs或者Program.cs里通过AddDialog添加),不然BeginDialogAsync会找不到对应的对话框。 - 分数阈值(比如上面的0.6)可以根据你的业务需求调整,确保只有足够置信度的答案才会被QnA处理,低置信度的直接转Luis。
内容的提问来源于stack exchange,提问作者Kevin D.
相关产品推荐
相关产品推荐

