Our bot has a large set of skills (LUIS and QnA Maker intents), but not all skills are useful for all users. We would like to suppress some skills depending on who the user is.
We developed some code to do this for LUIS intents, dynamically filtering intents returned from our model to only include ones appropriate for the current user.
The issue we have though, is that we also have a couple of QnA models in our array of recognizers (recognizer_array) ...
var intents = new builder.IntentDialog({ recognizers: recognizer_array,
intentThreshold: 0.85, recognizeOrder: 'series'});
bot.dialog('/mainDialogue', intents);
But not all users need these QnA models, we would like to exclude them for some users.
Is there a way to dynamically filter intents so that we could exclude these QnA intents for some users?
Related
I am currently using MS LUIS for Chatbot.
Our country usually talks and chats using 2 languages, English and Chinese.
However, in LUIS I can only define one culture.
As a result, when my culture is set to English, and when I imports Chinese text, the confidence level is very low (e.g. English - 0.88, Chinese - 0.1). The other way round is the same.
The situation is the same even after I did tokenize the Chinese text using library like JieBa or THULAC.
Therefore when I did testing, it is usually very easy to fall into an unrelated intent.
I would like to make LUIS recognize both English AND Chinese easily. Are there any way to solve this problem?
Thank you very much for your help.
I would like to make LUIS recognize both English AND Chinese easily. Are there any way to solve this problem?
Yes, the way is to separate your LUIS apps/projects, 1 for each language, and use a language detection before calling LUIS.
That's the official approach from LUIS docs (see here):
If you need a multi-language LUIS client application such as a chat
bot, you have a few options. If LUIS supports all the languages, you
develop a LUIS app for each language. Each LUIS app has a unique app
ID, and endpoint log. If you need to provide language understanding
for a language LUIS does not support, you can use Microsoft Translator
API to translate the utterance into a supported language, submit the
utterance to the LUIS endpoint, and receive the resulting scores.
For the language detection you can use Text Analytics API from Microsoft Cognitive Services for example to get the text language, and then with this result query the right LUIS app.
How to use it?
Documentation of Language detection in Text Analytics API here
Text analytics API: here
As Nicolas mentioned above you can use Multilanguage chat application with separate LUIS apps for each culture.
In order to have single LUIS application, you could use the Translator Text API to translate all incoming messages before they're sent to LUIS. In this case you'll want to use middleware to handle the translation before your LUIS Recognizer is called. You can also use middleware to translate your bot's response so you don't have to use additional localization inside of your bot
Tokenizing in LUIS is different for each language in LUIS.
In the zh-cn culture, LUIS expects the simplified Chinese character set instead of the traditional character set.
Here is one more sample where you can select a language from the bot and continue the consversation as required.
After investigation and several testings, I guess I found a way on how to do that properly:
First of all, I am currently using MS BotFramework - NodeJS (3.14.0) version to create my Bot.
And in botbuilder class, you have a function called IntentDialog, it accepts a list of recognizers. So I wrote something like this:
In luis.js
const builder = require("botbuilder")
// Setting for LUIS.ai
// Universal API key for both apps
let luisAPIKey = process.env.LuisAPIKey;
// First assign variables for Chinese LUIS app
let luisAppId_Chi = process.env.LuisAppId_Chi;
let luisAPIHostName_Chi = process.env.LuisAPIHostName_Chi || 'westus.api.cognitive.microsoft.com';
let LuisModelUrl_Chi = 'https://' + luisAPIHostName_Chi + '/luis/v2.0/apps/' + luisAppId_Chi + '?subscription-key=' + luisAPIKey + '&verbose=true';
// Then assign variables for English LUIS app
let luisAppId_Eng = process.env.LuisAppId_Eng;
let luisAPIHostName_Eng = process.env.LuisAPIHostName_Eng || 'westus.api.cognitive.microsoft.com';
let LuisModelUrl_Eng = 'https://' + luisAPIHostName_Eng + '/luis/v2.0/apps/' + luisAppId_Eng + '?subscription-key=' + luisAPIKey + '&verbose=true';
// Return an object with 2 attributes: Chi for Chinese LUIS and Eng for English LUIS
let luis = {};
luis.chi = new builder.LuisRecognizer(LuisModelUrl_Chi);
luis.eng = new builder.LuisRecognizer(LuisModelUrl_Eng);
module.exports = luis;
In app.js
const luis = require("./luis")
builder.IntentDialog({ recognizers: [luis.chi, luis.eng] });
And when I tested in botEmulator, it seems that it will first check LUIS Chi app, and then go to LUIS Eng app.
I don't know what is the criteria/threshold that this recognizer used to controls whether jumps to another app or not. But at present it works for me to certain extend. It is not accurate by at least a good(?) start. :D
No MS Text translation API need.
By the way, the code will look nicer if I can get the topIntent and LUIS path right in session variable.
Hope it helps someone.
I am planning to use QnA maker, but does it use LUIS in the background ?
If the questions are asked in a different way than the one trained to QnA maker, will it respond ?
does it use LUIS in the background ?
No, but you can Combining Search, QnA Maker, and/or LUIS.
According to the document, the following three ways are suggested to implement QnA together with LUIS.
Call both QnA Maker and LUIS at the same time, and respond to the user by using information from the first one that returns a score of a specific threshold.
Call LUIS first, and if no intent meets a specific threshold score, i.e., "None" intent is triggered, then call QnA Maker. Alternatively, create a LUIS intent for QnA Maker, feeding your LUIS model with example QnA questions that map to "QnAIntent."
Call QnA Maker first, and if no answer meets a specific threshold score, then call LUIS.
Here I post a code sample just for the third approach wrote in C#.
In MessagesController call QnA Maker first:
if (activity.Type == ActivityTypes.Message)
{
await Conversation.SendAsync(activity, () => new Dialogs.MyQnADialog());
}
In MyQnADialog, see if there is matched answer, if not, call LUIS:
[QnAMakerAttribute("QnASubscriptionKey", "QnAKnowledgebaseId", "No Answer in Knowledgebase, seraching in Luis...", 0.5)]
[Serializable]
public class MyQnADialog : QnAMakerDialog
{
protected override async Task DefaultWaitNextMessageAsync(IDialogContext context, IMessageActivity message, QnAMakerResults result)
{
if (result.Answers.Count == 0)
{
await context.Forward(new MyLuisDialog(), this.ResumeAfterNewOrderDialog, message, CancellationToken.None);
}
context.Wait(this.MessageReceivedAsync);
//return base.DefaultWaitNextMessageAsync(context, message, result);
}
private async Task ResumeAfterNewOrderDialog(IDialogContext context, IAwaitable<object> result)
{
var resultfromnewdialog = await result;
context.Wait(this.MessageReceivedAsync);
}
}
QnA does not use LUIS or intent recognition, rather it uses n-grams to detect similarity as the documentation used to state.
Since MS Build 2018, you can use a LUIS dispatch app. It allows you to incorporate multiple LUIS apps and QnA knowledge bases into a single dispatch app. This means sending user input to both LUIS & QnA, or in a particular order depending on the confidence score should be a thing of the past.
The first call you do is directed towards the LUIS dispatch app. The result will tell you if you need to contact a child luis app, or rather a QnA knowledge base. It can do this because the utterances of the LUIS dispatch app are filled with utterances from the QnA knowledge base. You can add multiple LUIS apps and/or QnA knowledge bases to this dispatch.
I suggest looking into the Bot Builder dispatch tool (CLI).
I am building a bot using the given technology stacks:
Microsoft Bot Builder
Node.js
Dialogflow.ai (api.ai)
We used waterfall model to implement a matched intent Dialog, which includes a couple of handler functions and prompts. After following this scenario I need to identify the entities inside an inner handler function, for a user input.
eg:
Bot : Where do you want to fly?
User: Singapore. (For this we added entities like SIN - Singapore,SIN(Synonym), So I need to resolve the value as SIN)
Any help on this scenario is much appreciated.
Here is a post Using api.ai with microsoft bot framework you can refer for your reqirement, and with a sample at https://github.com/GanadiniAkshay/weatherBot/blob/master/api.ai/index.js. The weather api key leveraged in this sample is out of date, but the waterfall and recognizer api key is still working.
Generally speaking:
Use api-ai-recognizer
Instantiate the apiairecognizer and leveraged builder.IntentDialog to include the recognizer:
var recognizer = new apiairecognizer("<api_key>");
var intents = new builder.IntentDialog({
recognizers: [recognizer]
});
In IntentDialogs, use builder.EntityRecognizer.findEntity(args.entities,'<entity>'); to recognize the intent entities.
I have an app in LUIS with one intent "Help" (appart from None) and when I test it with utterances that my intent does not cover (e.g "Hi man"), LUIS resolves to the "Help" intent... I have no utterances in "None" intent...
What should I do? Should I add all the utterances I don't want to match "Help" intent in "None"?
Should I need to know everything a user can ask to my bot which is not related with "Help"?
For me, that's not make sense at all... and I think that is exactly how LUIS works...
Intent are the action which we define, None is predefined Intent which come along with every LUIS model that you create , coming back to your problem. You have only define one intent i.e "help" so whenever LUIS gets the any query it will show the highest scoring intent i.e. "help". whenever you create an intent make to sure to save at least 5-6 co-related utterance, so that LUIS can generate a pattern out of it 'more you define co-related utterance better accuracy of result you will get'
if you want LUIS to respond on "HI man" create a new intent 'greet' save some utterance let LUIS do the remaining task, lastly about None intent If any user input 'asdsafdasdsfdsf' string like this. Your bot should be able to handle it respond accordingly like 'this asdsafdasdsfdsf is irrelevant to me' in simple term 'any irregular action that user want bot to perform come under none intent' i hope this will help
You can check the score of the Luis intent and then accordingly send the default response from code. For the utterances which are configured will have a greater score. Also, Luis app shud be balanced in terms of utterances configured as there is not a defined way that u can point utterances to None intent. Please check this link for best practices.
https://learn.microsoft.com/en-us/azure/cognitive-services/luis/luis-concept-best-practices. Also to highlight Luis does not work in terms of keyword matching to the utterances which you have configured. It works in terms of data you add in Luis in respective intents.
I am developping a bot using the LUIS API by Microsoft. This bot must understand queries related to shopping like "I want potatoes".
The only thing my application is struggling with is detecting intents from composite terms:
For the query "I want chopped steak", LUIS will detect chopped as an intent but not "chopped steak". I tried creating a productName phrase list feature and setting different composite terms including "chopped steak" but this doesn't seem to work.
What could I do to achieve that purpose ?