当我第二次尝试相同的输入时,LUIS无法识别意图

时间:2018-08-08 14:36:34

标签: node.js botframework luis azure-search qnamaker

我第一次在同一代码中同时使用LUIS进行天蓝色搜索和QnA识别器。

我正在使用 intent.match 来匹配识别器。

我的问题是:

第一次,如果我问一个与QnA意图相匹配的问题,它将返回QnA基数的答案。

之后是与azuresearch意图匹配的问题。 Azure搜索也可以提供结果。

但是,如果我重复必须与QnA匹配的问题,它会说“没有为空找到意图处理程序”

var util = require('util');
var _ = require('lodash');
var builder = require('botbuilder');
var restify = require('restify');
var cognitiveservices = require('botbuilder-cognitiveservices');
/// <reference path="../SearchDialogLibrary/index.d.ts" />
var SearchLibrary = require('../SearchDialogLibrary');
var AzureSearch = require('../SearchProviders/azure-search');

var qintent;
// 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 bot and listen for messages
var connector = new builder.ChatConnector({
    appId: process.env.MICROSOFT_APP_ID,
    appPassword: process.env.MICROSOFT_APP_PASSWORD

});
server.post('/api/messages', connector.listen());
// Bot Storage: Here we register the state storage for your bot. 
// Default store: volatile in-memory store - Only for prototyping!
// We provide adapters for Azure Table, CosmosDb, SQL Azure, or you can implement your own!
// For samples and documentation, see: https://github.com/Microsoft/BotBuilder-Azure
var inMemoryStorage = new builder.MemoryBotStorage();

var qnarecognizer = new cognitiveservices.QnAMakerRecognizer({
    knowledgeBaseId: '6b30ac2a-5ce9-4576-a1cb-c89abfb73889',
    authKey: 'd457c897-71cf-46bf-a3d9-9a1f51246fad',
    endpointHostName: 'https://qnadispatchwg.azurewebsites.net/qnamaker'
    });

const LuisModelUrl = 'https://westeurope.api.cognitive.microsoft.com/luis/v2.0/apps/180a9aaa-9d67-4d40-b3d3-121917f4dbb8?subscription-key=39155bb750dc4b2abd84d410d80fce21&timezoneOffset=0&q=';
var recognizer = new builder.LuisRecognizer(LuisModelUrl);
// Bot with main dialog that triggers search and display its results
var bot  = new builder.UniversalBot(connector);
bot.set('storage', inMemoryStorage);

var intents = new builder.IntentDialog({ recognizers: [recognizer, qnarecognizer] });
bot.dialog('/', intents);

intents.matches('Greeting',  (session) => {
    session.send('You reached the Greeting intent. You said \'%s\'.', session.message.text);
    session.endDialog();
});

intents.matches('qna', [
    function (session, args) {
        console.log("my args in qna:=========================================================================================== %o", args);
        var answerEntity = builder.EntityRecognizer.findEntity(args.entities, 'answer');
        session.send(answerEntity.entity);
    }
]);

intents.matches('Search.Aco', [
    function (session, args, next) {
        console.log("my args in SearchDialog:=========================================================================================== %o", args);
        var intent = args.intent;
        console.log("our intent is " + intent);
        var entities = builder.EntityRecognizer.findEntity(args.entities, 'businessterm');
        console.log("recognnized entitiy is: "+ entities.entity);
       // qintent = title;
        //session.send('You reached the Search.Aco intent. You enquire for the entitiy \'%s\'.', qintent);
        //console.log(" SearchDialog: before updating the  session.message.text------------->" + session.message.text);
        session.message.text= entities.entity;
        //console.log(" SearchDialog: after updating the  session.message.text------------->" + session.message.text);
        SearchLibrary.begin(session);
    },

    function (session, args, results) {
        // Process selected search results
        session.send(
            'Done! For future reference, you selected these properties: %s',
            args.selection.map(function (i) { return i.key; }).join(', '));
    }
]);

var azureSearchClient = AzureSearch.create('aco-intel2', '4105C6676D0CDD9B2E7891952B9E9E00', 'azureblob-index');
var jobsResultsMapper = SearchLibrary.defaultResultsMapper(jobToSearchHit);

// Register Search Dialogs Library with bot
bot.library(SearchLibrary.create({
    multipleSelection: true,
    search: function (query) { return azureSearchClient.search(query).then(jobsResultsMapper); },
    refiners: ['people', 'content', 'location']
}));

// Maps the AzureSearch Job Document into a SearchHit that the Search Library can use
function jobToSearchHit(acosearch) {
    console.log("inside jobToSearchHit");
    console.log("inside acosearch.DocUrl" + acosearch.DocUrl + "-------" + acosearch.metadata_storage_name);
    return {
        key: acosearch.id,
        title: acosearch.metadata_storage_name,
        description: acosearch.content.substring(0, 100)+"...",
        documenturl:acosearch.DocUrl,
        imageUrl: acosearch.imageurl
    };
}

module.exports = { qintent:  "qintent"};
如果我混用第二次

它是这样显示的:

Emulator output

能帮我了解一下intent.match和dialog'匹配之间的区别是什么?我也尝试了以下方法,但它无法识别应答实体。如何从以下代码中调用QnA?

var util = require('util');
var _ = require('lodash');
var builder = require('botbuilder');
var restify = require('restify');
var cognitiveservices = require('botbuilder-cognitiveservices');
/// <reference path="../SearchDialogLibrary/index.d.ts" />
var SearchLibrary = require('../SearchDialogLibrary');
var AzureSearch = require('../SearchProviders/azure-search');

var qintent;
// 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 bot and listen for messages
var connector = new builder.ChatConnector({
    appId: process.env.MICROSOFT_APP_ID,
    appPassword: process.env.MICROSOFT_APP_PASSWORD

});
server.post('/api/messages', connector.listen());
// Bot Storage: Here we register the state storage for your bot. 
// Default store: volatile in-memory store - Only for prototyping!
// We provide adapters for Azure Table, CosmosDb, SQL Azure, or you can implement your own!
// For samples and documentation, see: https://github.com/Microsoft/BotBuilder-Azure
var inMemoryStorage = new builder.MemoryBotStorage();

var qnarecognizer = new cognitiveservices.QnAMakerRecognizer({
    knowledgeBaseId: '6b30ac2a-5ce9-4576-a1cb-c89abfb73889',
    authKey: 'd457c897-71cf-46bf-a3d9-9a1f51246fad',
    endpointHostName: 'https://qnadispatchwg.azurewebsites.net/qnamaker'
    });

const LuisModelUrl = 'https://westeurope.api.cognitive.microsoft.com/luis/v2.0/apps/180a9aaa-9d67-4d40-b3d3-121917f4dbb8?subscription-key=39155bb750dc4b2abd84d410d80fce21&timezoneOffset=0&q=';
var recognizer = new builder.LuisRecognizer(LuisModelUrl);
// Bot with main dialog that triggers search and display its results
var bot = new builder.UniversalBot(connector, function (session, args) {
    session.send('You reached the default message handler. You said \'%s\'.', session.message.text);
}).set('storage', inMemoryStorage);

bot.recognizer(recognizer, qnarecognizer);

bot.dialog('GreetingDialog',
    (session) => {
        session.send('You reached the Greeting intent. You said \'%s\'.', session.message.text);
        session.endDialog();
    }
).triggerAction({
    matches: 'Greeting'
})

bot.dialog('HelpDialog',
    (session) => {
        session.send('You reached the Help intent. You said \'%s\'.', session.message.text);
        session.endDialog();
    }
).triggerAction({
    matches: 'Help'
})

bot.dialog('CancelDialog',
    (session) => {
        session.send('You reached the Cancel intent. You said \'%s\'.', session.message.text);
        session.endDialog();
    }
).triggerAction({
    matches: 'Cancel'
})

bot.dialog('QnADialog',[
    function (session, args, next) {
        var answerEntity = builder.EntityRecognizer.findEntity(args.entities, 'answer');
        console.log(answerEntity);
        session.send(answerEntity.entity);
    }
]).triggerAction({
    matches: 'Search.QnA'
})

bot.dialog('SearchDialog', [
    function (session, args) {
        console.log("my args in SearchDialog:=========================================================================================== %o", args);
        var intent = args.intent;
        title = builder.EntityRecognizer.findEntity(intent.entities, 'businessterm');
        console.log(title.entity);
        qintent = title.entity;
        //session.send('You reached the Search.Aco intent. You enquire for the entitiy \'%s\'.', qintent);
        //console.log(" SearchDialog: before updating the  session.message.text------------->" + session.message.text);
        session.message.text= qintent;
        //console.log(" SearchDialog: after updating the  session.message.text------------->" + session.message.text);
        SearchLibrary.begin(session);
    },

    function (session, args, results) {
        // Process selected search results
        session.send(
            'Done! For future reference, you selected these properties: %s',
            args.selection.map(function (i) { return i.key; }).join(', '));
    }
]).triggerAction({
    matches: 'Search.Aco'
});

var azureSearchClient = AzureSearch.create('aco-intel2', '4105C6676D0CDD9B2E7891952B9E9E00', 'azureblob-index');
var jobsResultsMapper = SearchLibrary.defaultResultsMapper(jobToSearchHit);

// Register Search Dialogs Library with bot
bot.library(SearchLibrary.create({
    multipleSelection: true,
    search: function (query) { return azureSearchClient.search(query).then(jobsResultsMapper); },
    refiners: ['people', 'content', 'location']
}));

// Maps the AzureSearch Job Document into a SearchHit that the Search Library can use
function jobToSearchHit(acosearch) {
    console.log("inside jobToSearchHit");
    console.log("inside acosearch.DocUrl" + acosearch.DocUrl + "-------" + acosearch.metadata_storage_name);
    return {
        key: acosearch.id,
        title: acosearch.metadata_storage_name,
        description: acosearch.content.substring(0, 100)+"...",
        documenturl:acosearch.DocUrl,
        imageUrl: acosearch.imageurl
    };
}

module.exports = { qintent:  "qintent"};

这段代码给了我如下痕迹: logs

请帮助我了解上述代码中的错误。将会有很大的帮助。 另外,intent.match和对话框匹配之间的区别。根据我的理解,机器人可以识别session.message并将其与“ match:”参数相匹配并调用对话框。因此它可以在对话框之间来回切换。

在第一种情况下,它对我来说很奇怪,因为它第二次不这样做。

预先感谢, 维维克

1 个答案:

答案 0 :(得分:0)

使用IntentDialog类(例如var intents = new builder.IntentDialog( ...)不允许像直接将对话框注册到bot那样中断意图。

给出以下示例对话框:

const bot = new UniversalBot(connector); // Assume an already created ChatConnector
bot.recognizer(new LuisRecognizer(LuisModelUrl); // LUIS model with HowAreYou and Weather intents.

bot.dialog('HowAreYou',[
  function (session, args, next) {
    builder.Prompts.text(session, `I\'m doing great! How are you?`);
  },
  function (session, args) {
    var result = session.message.text;
    session.send(`I\'m glad to hear you\'re doing ${result}!`);
]).triggerAction({
  matches: 'HowAreYou'
});

bot.dialog('Weather', [
  function (session, args) {
    builder.Prompts.text(session `Which city do you want to find the weather forecast for?`);
  },
  function (session, args) {
    // some logic to handle the response and call a weather api
  }
  ]).triggerAction({
    matches: 'Weather'
  });

当用户询问"How are you?"时,LUIS会检测到'HowAreYou'的意图,并且机器人会开始相应的对话框。然后,漫游器会提示用户"I'm doing great! How are you?'。如果用户随后对机器人"Show me the weather"说了话,则该机器人将收到该消息并检测到"Weather"的意图。完成此操作后,它将"Weather"对话框添加到对话框堆栈的顶部,并开始“天气”对话框。

当检测到新的意图时,UniversalBot不会阻止您切换对话框。在意图对话框的code中,该对话框会继续您已经进入的所有对话框,并且不支持切换到新的意图/对话框。