Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding activeLearning capabilities to qnaMakerRecognizer #4055

Open
akgargo opened this issue Jan 13, 2022 · 1 comment
Open

Adding activeLearning capabilities to qnaMakerRecognizer #4055

akgargo opened this issue Jan 13, 2022 · 1 comment
Assignees
Labels
feature-request A request for new functionality or an enhancement to an existing one. needs-triage The issue has just been created and it has not been reviewed by the team.

Comments

@akgargo
Copy link

akgargo commented Jan 13, 2022

Use this query to search for the most popular feature requests.

Is your feature request related to a problem? Please describe.
I am migrating a bot using botframework 4.3 to use AdaptiveDialogs, the issue comes when I try to maintain the same functionality in QnA dialogs, I reviewed the source and I see that you are not checking if the activeLearning feature is enabled so it can't be used with qnaMakerRecognizer

Describe the solution you'd like
Please add the corresponding logic for checking if activeLearning is enabled using getAnswersRaw instead of getAnswers in the recognize method, as well as the callTrainAsync method for sending the suggestions to QnAMaker

Describe alternatives you've considered
Keep everything using the old code, or copy the files from your package into a local folder, so I can modify them and use that instead

Additional context
`/**
* Queries the knowledgebase and either passes result to the next step or constructs and displays an active learning card
* if active learning is enabled and multiple score close answers are returned.
**/
async callGenerateAnswer(step) {
const dialogOptions = step.activeDialog.state[this.options];
dialogOptions.qnaMakerOptions.qnaId = 0;
dialogOptions.qnaMakerOptions.context = { previousQnAId: 0, previousUserQuery: '' };

    step.values[this.currentQuery] = step.context.activity.text;
    const previousContextData = step.activeDialog.state[this.qnAContextData] || {};
    var previousQnAId = step.activeDialog.state[this.previousQnAId] || 0;

    if (previousQnAId > 0) {
        dialogOptions.qnaMakerOptions.context = { previousQnAId: previousQnAId, previousUserQuery: '' };
        if (previousContextData[step.context.activity.text]) {
            dialogOptions.qnaMakerOptions.qnaId = previousContextData[step.context.activity.text];
        }
    }

    const qna = this.getQnAClient();

    const response = await qna.getAnswersRaw(step.context, dialogOptions.qnaMakerOptions);

    const qnaResponse = {
        activeLearningEnabled: response.activeLearningEnabled,
        answers: response.answers
    };

    previousQnAId = -1;
    step.activeDialog.state[this.previousQnAId] = previousQnAId;
    const isActiveLearningEnabled = qnaResponse.activeLearningEnabled;

    step.values[this.qnAData] = response.answers;

    if (isActiveLearningEnabled && qnaResponse.answers.length > 0 && qnaResponse.answers[0].score <= this.maximumScoreForLowScoreVariation) {
        qnaResponse.answers = qna.getLowScoreVariation(qnaResponse.answers);

        if (qnaResponse.answers && qnaResponse.answers.length > 1) {
            var suggestedQuestions = [];

            qnaResponse.answers.forEach(answer => {
                suggestedQuestions.push(answer.questions[0]);
            });

            var message = QnACardBuilder.getSuggestionsCard(suggestedQuestions, dialogOptions.qnaDialogResponseOptions.activeLearningCardTitle, dialogOptions.qnaDialogResponseOptions.cardNoMatchText);
            await step.context.sendActivity(message);

            step.activeDialog.state[this.options] = dialogOptions;

            return Dialog.EndOfTurn;
        }
    }
    const result = [];

    if (response.answers && response.answers.length > 0) {
        result.push(response.answers[0]);
    }

    step.values[this.qnAData] = result;
    step.activeDialog.state[this.options] = dialogOptions;
    return await step.next(result);
}
/**
 * If active learning options were displayed in the previous step and the user has selected an option other
 * than 'no match' then the training API is called, passing the user's chosen question back to the knowledgebase.
 * If no active learning options were displayed in the previous step, the incoming result is immediately passed to the next step.
**/
async callTrain(step) {
    const dialogOptions = step.activeDialog.state[this.options];
    const trainResponses = step.values[this.qnAData];
    const currentQuery = step.values[this.currentQuery];

    const reply = step.context.activity.text;

    if (trainResponses && trainResponses.length > 1) {
        const qnaResult = trainResponses.filter(r => r.questions[0] == reply);

        if (qnaResult && qnaResult.length > 0) {
            var results = [];
            results.push(qnaResult[0]);
            step.values[this.qnAData] = results;

            var records = [];
            records.push({
                userId: step.context.activity.id,
                userQuestion: currentQuery,
                qnaId: qnaResult[0].id.toString()
            });

            var feedbackRecords = { feedbackRecords: records };

            await this.getQnAClient().callTrainAsync(feedbackRecords);

            return await step.next(qnaResult);
        } else if (reply == dialogOptions.qnaDialogResponseOptions.cardNoMatchText) {
            const activity = dialogOptions.qnaDialogResponseOptions.cardNoMatchResponse;
            await step.context.sendActivity(activity || this.defaultCardNoMatchResponse);
            return step.endDialog();
        }
        else {
            return await super.runStep.call(this, step, 0, DialogReason.beginCalled);
        }
    }
    return await step.next(step.result);
}`
@akgargo akgargo added feature-request A request for new functionality or an enhancement to an existing one. needs-triage The issue has just been created and it has not been reviewed by the team. labels Jan 13, 2022
@mrivera-ms
Copy link
Contributor

@sahithimurty, please review this issue and let us know if changes are needed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature-request A request for new functionality or an enhancement to an existing one. needs-triage The issue has just been created and it has not been reviewed by the team.
Projects
None yet
Development

No branches or pull requests

3 participants