使用C#在一个Bot中进行多个QnA服务

我有3个QnA服务。 我希望它们能够同时用于单个BOT。 如何使用C#实现这一点。 我最初的想法是将KB ID和Sub Key放入一个数组(如何实现它或者数组是否有效?)..我在Node.JS中看到了一些代码,但我无法弄清楚如何在C#中转换代码。

public class QnaDialog : QnAMakerDialog { public QnaDialog() : base( new QnAMakerService(new QnAMakerAttribute(ConfigurationManager.AppSettings["QnaSubscriptionKey1"], ConfigurationManager.AppSettings["QnaKnowledgebaseId1"], "Hmm, I wasn't able to find an article about that. Can you try asking in a different way?", 0.5)), new QnAMakerService(new QnAMakerAttribute(ConfigurationManager.AppSettings["QnaSubscriptionKey2"], ConfigurationManager.AppSettings["QnaKnowledgebaseId2"], "Hmm, I wasn't able to find an article about that. Can you try asking in a different way?", 0.5)), new QnAMakerService(new QnAMakerAttribute(ConfigurationManager.AppSettings["QnaSubscriptionKey3"], ConfigurationManager.AppSettings["QnaKnowledgebaseId4"], "Hmm, I wasn't able to find an article about that. Can you try asking in a different way?", 0.5)) ) { } } 

通过在属性中提供多个服务,您可以在单个机器人中使用多个QnAMaker知识库。

使用QnAMakerDialogBotBuilder.CognitiveServices基本实现将是:

 [Serializable] [QnAMaker("QnaSubscriptionKey1", "QnaKnowledgebaseId1", "Hmm, I wasn't able to find an article about that. Can you try asking in a different way?", 0.50, 3)] [QnAMaker("QnaSubscriptionKey2", "QnaKnowledgebaseId2", "Hmm, I wasn't able to find an article about that. Can you try asking in a different way?", 0.5, 3)] [QnAMaker("QnaSubscriptionKey3", "QnaKnowledgebaseId3", "Hmm, I wasn't able to find an article about that. Can you try asking in a different way?", 0.5, 3)] public class RootDialog : QnAMakerDialog { } 

但是 (是的,有一个“但是”)在某些情况下,您可能会在处理邮件时遇到exception。 由于QnAMakerDialog是开源的(源代码在这里 ),您可以在MessageReceivedAsync轻松发现问题在于实现服务调用的返回:

 var sendDefaultMessageAndWait = true; qnaMakerResults = tasks.FirstOrDefault(x => x.Result.ServiceCfg != null)?.Result; if (tasks.Count(x => x.Result.Answers?.Count > 0) > 0) { var maxValue = tasks.Max(x => x.Result.Answers[0].Score); qnaMakerResults = tasks.First(x => x.Result.Answers[0].Score == maxValue).Result; if (qnaMakerResults != null && qnaMakerResults.Answers != null && qnaMakerResults.Answers.Count > 0) { if (this.IsConfidentAnswer(qnaMakerResults)) { await this.RespondFromQnAMakerResultAsync(context, message, qnaMakerResults); await this.DefaultWaitNextMessageAsync(context, message, qnaMakerResults); } else { feedbackRecord = new FeedbackRecord { UserId = message.From.Id, UserQuestion = message.Text }; await this.QnAFeedbackStepAsync(context, qnaMakerResults); } sendDefaultMessageAndWait = false; } } if (sendDefaultMessageAndWait) { await context.PostAsync(qnaMakerResults.ServiceCfg.DefaultMessage); await this.DefaultWaitNextMessageAsync(context, message, qnaMakerResults); } 

在此代码中,如果您的所有服务都没有针对您的问题的答案,则此行代码将中断(即:如果您的QnAMaker KB中至少有一个没有针对您的问题的答案)

 tasks.Max(x => x.Result.Answers[0].Score); 

解决方法:您可以通过获取源并以此方式修复方法来实现您自己的QnAMakerDialog,例如:

 public async Task MessageReceivedAsync(IDialogContext context, IAwaitable argument) { var message = await argument; if (message != null && !string.IsNullOrEmpty(message.Text)) { var tasks = this.services.Select(s => s.QueryServiceAsync(message.Text)).ToArray(); await Task.WhenAll(tasks); if (tasks.Any()) { var sendDefaultMessageAndWait = true; qnaMakerResults = tasks.FirstOrDefault(x => x.Result.ServiceCfg != null)?.Result; var qnaMakerFoundResults = tasks.Where(x => x.Result.Answers.Any()).ToList(); if (qnaMakerFoundResults.Any()) { var maxValue = qnaMakerFoundResults.Max(x => x.Result.Answers[0].Score); qnaMakerResults = qnaMakerFoundResults.First(x => x.Result.Answers[0].Score == maxValue).Result; if (qnaMakerResults?.Answers != null && qnaMakerResults.Answers.Count > 0) { if (this.IsConfidentAnswer(qnaMakerResults)) { await this.RespondFromQnAMakerResultAsync(context, message, qnaMakerResults); await this.DefaultWaitNextMessageAsync(context, message, qnaMakerResults); } else { feedbackRecord = new FeedbackRecord { UserId = message.From.Id, UserQuestion = message.Text }; await this.QnAFeedbackStepAsync(context, qnaMakerResults); } sendDefaultMessageAndWait = false; } } if (sendDefaultMessageAndWait) { await context.PostAsync(qnaMakerResults.ServiceCfg.DefaultMessage); await this.DefaultWaitNextMessageAsync(context, message, qnaMakerResults); } } } }