我目前正在使用带有Luis的Enterprise Bot模板来将意图路由到正确的QnAMaker知识库。QnAMaker知识库端点存储在bot文件中。我请求启用多提示符:https://github.com/microsoft/BotBuilder-Samples/tree/master/experimental/qnamaker-prompting/csharp_dotnetcore
在所提供的示例中,QnAMaker知识库端点在appsettings.json中,我不知道如何将其他知识库端点添加到应用程序设置中并将意图发送到适当的知识库,或者如何让多提示对话框从bot文件中提取端点信息。
在本例中,知识库是在启动时设置的
BotBuilder-Samples-master\BotBuilder-Samples-master\experimental\qnamaker-prompting\csharp_dotnetcore\Helpers\QnAService.cs:
private static (QnAMakerOptions options, QnAMakerEndpoint endpoint) InitQnAService(IConfiguration configuration)
{
var options = new QnAMakerOptions
{
Top = 3
};
var hostname = configuration["QnAEndpointHostName"];
if (!hostname.StartsWith("https://"))
{
hostname = string.Concat("https://", hostname);
}
if (!hostname.EndsWith("/qnamaker"))
{
hostname = string.Concat(hostname, "/qnamaker");
}
var endpoint = new QnAMakerEndpoint
{
KnowledgeBaseId = configuration["QnAKnowledgebaseId"],
EndpointKey = configuration["QnAEndpointKey"],
Host = hostname
};
return (options, endpoint);
}BotBuilder-Samples-master\BotBuilder-Samples-master\experimental\qnamaker-prompting\csharp_dotnetcore\Startup.cs:
// Helper code that makes the actual HTTP calls to QnA Maker. It is injectable for local unit testing.
services.AddHttpClient<IQnAService, QnAService>();以下是我的设置,未对示例代码进行任何修改:
在主对话框中:
else if (intent == Dispatch.Intent.q_RJH_Test_multiprompt)
{
_services.QnAServices.TryGetValue("RJH_Test_multiprompt", out var qnaService);
if (qnaService == null)
{
throw new Exception("The specified QnA Maker Service could not be found in your Bot Services configuration.");
}
else
{
QnABotState newState = null;
var query = dc.Context.Activity.Text;
var qnaResult = await _qnaService.QueryQnAServiceAsync(query, newState);
if (qnaResult != null && qnaResult.Count() > 0)
{
// start QnAPrompt dialog
await dc.BeginDialogAsync(nameof(QnADialog));
}
else
{
await _responder.ReplyWith(dc.Context, MainResponses.ResponseIds.Confused);
}
}
}如果在InitQnAService方法中提供了端点,对话框就会正确启动,并且多提示符也会起作用--但是我还不知道如何在这个设置中使用多个知识库。
发布于 2019-07-30 07:21:29
在开始之前阅读完整的答案,因为我在中途改变了我的想法。
如果不是QnADialog接受一个IQnAService,而是向它传递一个IBotServices的修改版本--它的实现是here。
您可以删除LuisRecognizer属性,因为它不是必需的,并使QnAMaker属性成为一个集合,然后从appsettings读取所有QnA键以创建QnAMaker对象,然后将其插入到集合中。然后,您需要在QnADialog中使用something来遍历和查询各种KB,如果没有找到答案,则进行处理。
粗略的概括如下:
IBotServices接口(类似于实现IBotServices interface.BotServices类的构造函数的property. BotServices类您应该:
QnaMakerService文件中的密钥为每个KB创建appSettings.json对象。<代码>H224<代码>H125将D26对象添加到<代码>D27
services.AddHttpClient<IQnAService, QnAService>();services.AddHttpClient<IBotService, BotService>();:
Startup.cs replace
IQnAService qnaServiceIBotService botService,QnABot的构造函数中的QnABotbotService.替换: base调用内部的
QnADialog.cs将IQnAService的用法替换为IBotService,并将ProcessAsync方法中的逻辑变量重命名为:var query = inputActivity.Text;
var index = 0;
foreach (var qnaKb in _botServices.QnAMakerKbs)
{
// Passing in the state won't be supported
var qnaResult = await qnaKb.GetAnswersAsync(query, (QnABotState)oldState);
var qnaAnswer = qnaResult[0].Answer;
// If no answer was found in the KB then go to the next KB,
// unless it is the last KB in the collection, then we will
// fall through to the default else handling below
if (qnaAnswer == "Default no answer found string" && index < _botServices.QnAMakerKbs.Length - 1)
{
continue;
}
var prompts = qnaResult[0].Context?.Prompts;
if (prompts == null || prompts.Length < 1)
{
outputActivity = MessageFactory.Text(qnaAnswer);
}
else
{
// Set bot state only if prompts are found in QnA result
newState = new QnABotState
{
PreviousQnaId = qnaResult[0].Id,
PreviousUserQuery = query
};
outputActivity = CardHelper.GetHeroCard(qnaAnswer, prompts);
}
index++;
}OP的一个练习是将传递状态的逻辑添加到请求中,以便保持提示状态。我的代码是基于this sample的,它不使用提示。在您正在使用的示例中,使用了一个定制的QnAService,它根据this code手动构建请求,并在QnABotState中传递,以跟踪提示的进度。
这应该会让你走上正确的道路。
编辑
使用我上面提供的知识,您可能只需修改QnAService类(和IQnaService接口),将QnAMakerEndpoint属性更改为一个集合,并处理QueryQnAServiceAsync中的循环。
https://stackoverflow.com/questions/57222415
复制相似问题