首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >可以在多提示对话框中使用Luis和多个QnA Maker知识库吗?

可以在多提示对话框中使用Luis和多个QnA Maker知识库吗?
EN

Stack Overflow用户
提问于 2019-07-26 22:46:53
回答 1查看 266关注 0票数 1

我目前正在使用带有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:

代码语言:javascript
复制
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:

代码语言:javascript
复制
// Helper code that makes the actual HTTP calls to QnA Maker. It is injectable for local unit testing.
        services.AddHttpClient<IQnAService, QnAService>();

以下是我的设置,未对示例代码进行任何修改:

在主对话框中:

代码语言:javascript
复制
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方法中提供了端点,对话框就会正确启动,并且多提示符也会起作用--但是我还不知道如何在这个设置中使用多个知识库。

EN

回答 1

Stack Overflow用户

发布于 2019-07-30 07:21:29

在开始之前阅读完整的答案,因为我在中途改变了我的想法。

如果不是QnADialog接受一个IQnAService,而是向它传递一个IBotServices的修改版本--它的实现是here

您可以删除LuisRecognizer属性,因为它不是必需的,并使QnAMaker属性成为一个集合,然后从appsettings读取所有QnA键以创建QnAMaker对象,然后将其插入到集合中。然后,您需要在QnADialog中使用something来遍历和查询各种KB,如果没有找到答案,则进行处理。

粗略的概括如下:

  • 创建具有单个属性的IBotServices接口(类似于实现IBotServices interface.
  • In BotServices类的构造函数的property.

BotServices类您应该:

  • 使用QnaMakerService文件中的密钥为每个KB创建appSettings.json对象。<代码>H224<代码>H125将D26对象添加到<代码>D27

  • services.AddHttpClient<IQnAService, QnAService>();
  • with
  • services.AddHttpClient<IBotService, BotService>();

  • In Startup.cs replace

  • IQnAService qnaService
  • with
  • IBotService botServiceQnABot的构造函数中的
    • QnABot
    • 使用botService.

替换: base调用内部的

  • 的第一个参数

  • In QnADialog.csIQnAService的用法替换为IBotService,并将ProcessAsync方法中的逻辑变量重命名为:

代码语言:javascript
复制
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中的循环。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57222415

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档