public async Task <QnAResult[]> QueryQnAServiceAsync(string query, QnABotState qnAcontext) { var requestUrl = $"{_endpoint.Host}/knowledgebases/{_endpoint.KnowledgeBaseId}/generateanswer"; var request = new HttpRequestMessage(HttpMethod.Post, requestUrl); var jsonRequest = JsonConvert.SerializeObject( new { question = query, top = _options.Top, context = qnAcontext, strictFilters = _options.StrictFilters, metadataBoost = _options.MetadataBoost, scoreThreshold = _options.ScoreThreshold, }, Formatting.None); request.Headers.Add("Authorization", $"EndpointKey {_endpoint.EndpointKey}"); request.Content = new StringContent(jsonRequest, System.Text.Encoding.UTF8, "application/json"); var response = await _httpClient.SendAsync(request); response.EnsureSuccessStatusCode(); var contentString = await response.Content.ReadAsStringAsync(); var result = JsonConvert.DeserializeObject <QnAResultList>(contentString); return(result.Answers); }
protected override async Task <(object newState, IEnumerable <Activity> output, object result)> ProcessAsync(object oldState, Activity inputActivity) { var resultActivity = new List <Activity>(); QnABotState newState = null; var query = inputActivity.Text; var qnaResult = await _qnaService.QueryQnAServiceAsync(query, (QnABotState)oldState); var qnaAnswer = qnaResult[0].Answer; var prompts = qnaResult[0].Context?.Prompts; if (prompts == null || prompts.Length < 1) { if (qnaAnswer == "No good match found in KB.") { resultActivity.Add(MessageFactory.Text("ขออภัยค่ะ ฉันไม่เข้าใจ")); resultActivity.Add(MessageFactory.Text("พิมพ์ \"FAQ\" เพื่อกลับสู่บริการตอบคำถาม")); } else { resultActivity.Add(MessageFactory.Text(qnaAnswer)); resultActivity.Add(MessageFactory.Text("พิมพ์ \"ถามอีกครั้ง\" หรือ \"ถามอีกครั้งได้ไหม\" เพื่อถามเรื่องอื่น ๆ")); } } else { // Set bot state only if prompts are found in QnA result newState = new QnABotState { PreviousQnaId = qnaResult[0].Id, PreviousUserQuery = query }; resultActivity.Add(CardHelper.GetHeroCard(qnaAnswer, prompts)); } return(newState, resultActivity, null); }
private async Task <(object newState, IEnumerable <Activity> output, object result)> QueryQnA(QnABotState oldState, Activity inputActivity) { Activity outputActivity = null; QnABotState newState = null; // new question var query = inputActivity.Text; var qnaResult = await _qnaService.QueryQnAServiceAsync(query, (QnABotState)oldState); // get answers that are above the two thresholds var highConfidenceResults = qnaResult.Where(answer => answer.Score > (highConfidenceThreshold * 100)).ToList(); var lowConfidenceResults = qnaResult.Where(answer => answer.Score > (lowConfidenceThreshold * 100)).ToList(); // however, if this query was done after a multi-turn, then we just take the first result, and thus force this first result to be displayed if (oldState != null && oldState.PreviousPrompts != null) { var matchingPrompt = oldState.PreviousPrompts.Where(x => x.DisplayText.ToLower() == query.ToLower()); if (matchingPrompt.Count() > 0) { highConfidenceResults = new List <QnAResult> { qnaResult.First() }; } } if (highConfidenceResults.Count >= 1) { // take the first high confidence match found var qnaAnswer = highConfidenceResults[0].Answer; var prompts = highConfidenceResults[0].Context?.Prompts; var qnaId = highConfidenceResults[0].Id; // handle prompts, if there are any, as part of the multi-turn structures if (prompts == null || prompts.Length < 1) { outputActivity = MessageHelper.GetMessageActivity(qnaAnswer, inputActivity); } else { // Set bot state only if prompts are found in QnA result newState = new QnABotState { PreviousQnaId = qnaId, PreviousUserQuery = query, PreviousPrompts = prompts }; outputActivity = CardHelper.GetHeroCard(qnaAnswer, prompts); } } else if (highConfidenceResults.Count == 0 && lowConfidenceResults.Count == 0) { // no matches found outputActivity = MessageHelper.GetMessageActivity(noQnAResults, inputActivity); } else { // more than 1 match found, so we need to present an opportunity to learn from the user var suggestedQuestions = new List <string>(); foreach (var qna in lowConfidenceResults) { suggestedQuestions.Add(qna.Questions[0]); } // Get hero card activity outputActivity = CardHelper.GetHeroCard(suggestedQuestions, learningCardTitle, learningCardNoMatchText); newState = new QnALearningState { PreviousQnaId = 0, PreviousUserQuery = inputActivity.Text, QnAData = lowConfidenceResults }; } // return the result return(newState, new Activity[] { outputActivity }, null);