使用C#在一个Bot中进行多个QnA服务 [英] Multiple QnA Service in one Bot using C#
问题描述
我确实有3个QnA服务.我希望它们可以同时在单个BOT中使用.如何使用C#来实现.我最初的想法是将KB ID和Sub Key放入数组中(如何实现该数组或数组是否起作用?).我在Node.JS中看到了一些代码,但无法弄清楚如何在C#中转换代码.
I do have 3 QnA Service. I want them to be used in a single BOT at the same time. How can this be implemented using C#. My initial idea is to put the KB ID and Sub Key into an array (how to implement that or would an array works?).. I saw some code in Node.JS but I cannot figure it out how to convert the code in 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))
)
{
}
}
推荐答案
通过在属性中提供多种服务,您可以在单个bot中使用多个QnAMaker
知识库.
You can use several QnAMaker
knowledge bases in a single bot by providing several services in the attributes.
使用Nuget包BotBuilder.CognitiveServices
中的QnAMakerDialog
的基本实现是:
A basic implementation using QnAMakerDialog
from Nuget package BotBuilder.CognitiveServices
would be:
[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
{
}
但(是的,但是有一个但是"),在某些情况下,您在处理邮件时可能会遇到异常.由于QnAMakerDialog
是开源的(来源在此处),您可以在MessageReceivedAsync
中轻松发现问题在于返回服务调用:
BUT (yes, there is a "but") you may encounter an exception during the treatment of your messages in some cases. As QnAMakerDialog
is open-sourced (sources are here) you can easily discover that the problem is in the implementation of the return of the services calls, in 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中至少有一个没有对您的问题的回答),则此行代码将中断. strong>
In this code, this line of code will break if not all of your services have an answer for your question (ie: if at least one of your QnAMaker KB does not have an answer for your question)
tasks.Max(x => x.Result.Answers[0].Score);
解决方法:例如,您可以通过获取源代码并修复这种方法来实现自己的QnAMakerDialog:
Workaround: you can implement you own QnAMakerDialog by getting the sources and fixing the method like this for example:
public async Task MessageReceivedAsync(IDialogContext context, IAwaitable<IMessageActivity> 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);
}
}
}
}
这篇关于使用C#在一个Bot中进行多个QnA服务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!