将必应 Web 搜索 API 与 QnA 聊天机器人集成



我正在使用 QnA 模板(Microsoft Azure(制作聊天机器人。基本上,用户提出问题,机器人将尝试在常见问题解答文档中找到答案。如果失败,我希望它使用用户的查询运行必应搜索,并使用最准确的答案进行回复。我找到了这个使用必应 Web 搜索 API 的示例:https://learn.microsoft.com/en-us/azure/cognitive-services/bing-web-search/quickstarts/nodejs。例如,现在,我只希望机器人回复搜索的第一个链接。 但是,我不知道如何将链接中的代码与 QnA 机器人生成的代码(在 Node.js 中(合并:

var restify = require('restify');
var builder = require('botbuilder');
var botbuilder_azure = require("botbuilder-azure");
var builder_cognitiveservices = require("botbuilder-cognitiveservices");
var request = require('request');
// Setup Restify Server
var server = restify.createServer();
server.listen(process.env.port || process.env.PORT || 3978, function () {
console.log('%s listening to %s', server.name, server.url); 
});
// Create chat connector for communicating with the Bot Framework Service
var connector = new builder.ChatConnector({
appId: process.env.MicrosoftAppId,
appPassword: process.env.MicrosoftAppPassword,
openIdMetadata: process.env.BotOpenIdMetadata 
});
// Listen for messages from users 
server.post('/api/messages', connector.listen());
var tableName = 'botdata';
var azureTableClient = new botbuilder_azure.AzureTableClient(tableName, process.env['AzureWebJobsStorage']);
var tableStorage = new botbuilder_azure.AzureBotStorage({ gzipData: false }, azureTableClient);
// Create your bot with a function to receive messages from the user
var bot = new builder.UniversalBot(connector);
bot.set('storage', tableStorage);
// Recognizer and and Dialog for GA QnAMaker service
var recognizer = new builder_cognitiveservices.QnAMakerRecognizer({
knowledgeBaseId: process.env.QnAKnowledgebaseId,
authKey: process.env.QnAAuthKey || process.env.QnASubscriptionKey, // Backward compatibility with QnAMaker (Preview)
endpointHostName: process.env.QnAEndpointHostName
});
var basicQnAMakerDialog = new builder_cognitiveservices.QnAMakerDialog({
recognizers: [recognizer],
defaultMessage: 'Sorry, I cannot find anything on that topic',
qnaThreshold: 0.3
});
// Override the invokeAnswer function from QnAMakerDialog 
builder_cognitiveservices.QnAMakerDialog.prototype.invokeAnswer = function (session, recognizeResult, threshold, noMatchMessage) {
var qnaMakerResult = recognizeResult;
session.privateConversationData.qnaFeedbackUserQuestion = session.message.text;
if (qnaMakerResult.score >= threshold && qnaMakerResult.answers.length > 0) {
if (this.isConfidentAnswer(qnaMakerResult) || this.qnaMakerTools == null) {
this.respondFromQnAMakerResult(session, qnaMakerResult);
this.defaultWaitNextMessage(session, qnaMakerResult);
}
else {
this.qnaFeedbackStep(session, qnaMakerResult);
}
}
else {
this.noMatch(session, noMatchMessage, qnaMakerResult);
}
};
// API call to Bing
basicQnAMakerDialog.noMatch = function (session, noMatchMessage, qnaMakerResult) {
var term = session.message.text;
var key = 'i hid it';
var options = {
url: "https://api.cognitive.microsoft.com/bing/v7.0/search?q=" + term,
method: 'GET',
headers : {
'Ocp-Apim-Subscription-Key' : key
}
}; 
request(options, function(err,res, body){
if(err){
console.error(err);
session.send(noMatchMessage);
}
body = JSON.parse(body);
session.send("I found a thing: " + body["webPages"]["value"][0]["name"]);
});
};
bot.dialog('basicQnAMakerDialog', basicQnAMakerDialog);
bot.dialog('/', //basicQnAMakerDialog);
[ 
function (session, results) {
session.replaceDialog('basicQnAMakerDialog');
},
]);

在bot.dialog内部的函数中,我认为我应该添加一个条件,例如:如果机器人返回默认消息,请打开一个网页,让要搜索的"术语"成为用户的最后一条消息。但是,我不知道如何准确编码,以及在哪里编码。另外,我不知道如何退出 replaceDialog 函数以回复默认消息或常见问题解答中的答案以外的内容。

PS:我在javascript或Web开发方面没有太多经验。任何帮助将不胜感激:)

您正在实现的内容涉及两个步骤,将"noMatch"案例提取到方法中,以便您可以发出完整的响应消息,然后是 API 调用本身。

"noMatch"方法。

首先,您需要重写 QnAMakerDialog 中的 invokeAnswer 函数(此重写只会为 noMatch 案例添加对单独方法的调用。

builder_cognitiveservices.QnAMakerDialog.prototype.invokeAnswer = function (session, recognizeResult, threshold, noMatchMessage) {
var qnaMakerResult = recognizeResult;
session.privateConversationData.qnaFeedbackUserQuestion = session.message.text;
if (qnaMakerResult.score >= threshold && qnaMakerResult.answers.length > 0) {
if (this.isConfidentAnswer(qnaMakerResult) || this.qnaMakerTools == null) {
this.respondFromQnAMakerResult(session, qnaMakerResult);
this.defaultWaitNextMessage(session, qnaMakerResult);
}
else {
this.qnaFeedbackStep(session, qnaMakerResult);
}
}
else {
this.noMatch(session, noMatchMessage, qnaMakerResult);
}
};

在此之后,您将像往常一样定义 basicQnAMakerDialog,但请考虑将默认消息字段设置为错误案例或"未找到结果"的内容。(这并不重要,因为您可以在noMatch方法中任意决定发回的内容,但是在那里有默认值很好(

var basicQnAMakerDialog = new builder_cognitiveservices.QnAMakerDialog({
recognizers: [recognizer],
defaultMessage: 'Sorry, I can't find anything on that topic'
qnaThreshold: 0.3
});

在此之后,您可以单独定义 noMatch 方法。

basicQnAMakerDialog.noMatch = function (session, noMatchMessage, qnaMakerResult) {
session.send(noMatchMessage); //Contains the default message
this.defaultWaitNextMessage(session, qnaMakerResult);
}

在这种方法中,我们可以调用 API 或基本上做任何我们想做的事情。

在此覆盖上归功于滑翔

API 调用。

在 noMatch 方法中,我们将对必应进行 API 调用

basicQnAMakerDialog.noMatch = function (session, noMatchMessage, qnaMakerResult) {
var term = session.message.text;
var key = <Environment Var containing the Bing key>;
var options = {
url: "https://api.cognitive.microsoft.com/bing/v7.0/search?q=" + term,
method: 'GET',
headers : {
'Ocp-Apim-Subscription-Key' : key
}
}; 
request(options, function(err,res, body){
if(err){
console.error(err);
session.send(noMatchMessage);
}
body = JSON.parse(body);
session.send("I found a thing: " + body["webPages"]["value"][0]["name"]);
});
};

在从搜索结果中获取结果后,您可以根据需要自定义要发回的消息。

最新更新