QnAMaker의 metadata 및 filter 기능 정보

Qiita 첫 포스트입니다 🎉
QnAmaker의 채팅봇 개발을 하고 있습니다.
이번에는 QnAMaker의 metadata와 filter 기능에 대해 소개합니다.

QnAmaker란?



Microsoft의 CognitiveService의 하나로, 질문과 답변을 준비하면 간단하게 문의 챗봇을 만들 수 있다고 하는 것입니다.
준비한 질문문과 답변문을 학습하고, 질문을 던지면, 질문의 질문문과 가까운 QA의 페어를 돌려줍니다.

metadata란?



metadata란 QnAmaker가 QA를 학습하게 할 때 질문문과 답변문 이외에 정보를 부가할 수 있습니다. 추가하는 정보는 {key:value}의 형태로 추가됩니다.
QnAmaker의 화면에서 보면 아래와 같은 느낌입니다.


filter 기능 사용



filter 기능은 이전의 metadata를 이용하여 답변을 필터링합니다.
QnAmaker가 답변을 반환 할 때 반환하는 답변 중에서 QA에 지정된 {Key}의 {value}로 필터링하여 답변을 반환합니다.

어떤 때 사용하는가?



사용법은 궁리에 따라 다양한 사용할 수 있지만,
같은 질문문에서도 응답문이 다른 경우에 사용하는 것이 기본입니다.
위의 metadata 예제와 같이 동일한 질문 문장 "로그인 할 수 없습니다"에 대해 OS에 따라 답변이 다른 경우입니다.
위의 지식을 사용하여 봇을 만들면 이런 느낌 ↓


구현 방법



위의 챗봇은 아래의 흐름으로 구현됩니다.
  • welcome 메시지 "질문이 있습니까?"
  • 사용자가 질문 문장을 던진다
  • QnAmaker 호출 (filter 기능 없음)
  • 답변 metadata의 키에 OS가 포함되어 있으면 OS의 종류를 듣는다
  • 다시 QnAmaker를 부른다({OS:사용자의 응답한 OS}로 filter)

  • 대화 흐름은 botbuilderV3.0의 기본 템플릿 (C#)을 사용자 정의하고 구현합니다.
    filter 기능을 사용하는 부분의 샘플 코드는 다음과 같습니다.

    GetQnafilter.cs
    public class GetQnAmakerResult
    
        {
            static string qnamakerhost = ConfigurationManager.AppSettings["hostId"];
            static string endpoint_key = ConfigurationManager.AppSettings["endpointKey"];
            static string knowleadgebaseid = ConfigurationManager.AppSettings["QnAKnowledgebaseId"];
            static string service = "/qnamaker";
    
            public class QnamakerReslt
            {
                public Answer[] answers { get; set; }
            }
    
            public class Answer
            {
                public string[] questions { get; set; }
                public string answer { get; set; }
                public float score { get; set; }
                public string id { get; set; }
                public string source { get; set; }
                public Meta[] metadata { get; set; }
            }
            public class Meta
            {
                public string name { get; set; }
                public string value { get; set; }
            }
    
            public class PostQnamaker
            {
                public string question { get; set; }
                public int top { get; set; }
                public List<Filters> strictFilters { get; set; }
    
                public PostQnamaker()
                {
                    strictFilters = new List<Filters>();
                }
    
            }
    
            public class Filters
            {
                public string name { get; set; }
                public string value { get; set; }
            }
    
    
            public static async Task<QnamakerReslt> GetResult(string question, int option)
            {
                PostQnamaker postqnamaker = new PostQnamaker();
                Filters filters = new Filters();
    
                string method = "/knowledgebases/" + knowleadgebaseid + "/generateAnswer?/";
    
                var client = new HttpClient();
                var request = new HttpRequestMessage();
    
                var queryString = HttpUtility.ParseQueryString(string.Empty);
    
                postqnamaker.question = question;
                postqnamaker.top = option;
    
                filters.name = "keyの名前を入れる!";
                filters.value = "valueの名前を入れる!";
    
                postqnamaker.strictFilters.Add(filters);
    
                string requestquestion = JsonConvert.SerializeObject(postqnamaker);
    
                var uri = qnamakerhost + service + method;
    
                request.Method = HttpMethod.Post;
    
                request.RequestUri = new Uri(uri);
    
                request.Headers.Add("Authorization", "EndpointKey " + endpoint_key);
    
                request.Content = new StringContent(requestquestion, Encoding.UTF8, "application/json");
    
                var response = await client.SendAsync(request);
    
                QnamakerReslt jres = await response.Content.ReadAsAsync<QnamakerReslt>(new[] { new JsonMediaTypeFormatter() });
    
                return jres;
    
            }
    
        }
    
    

    기타 사용 예



    카테고리별 문의 대응

    metadata에는 {category:categoryname}을 넣습니다.
    예를 들어 아래와 같은 채팅에서 사용할 수 있습니다.

    office365의 문의는 제품마다 같은 질문문이 있기 때문에 최초로 제품명(카테고리)을 (듣)묻고 답변을 필터 하는 등의 경우입니다.
    지식을 나누는 방법도 있습니다만, 지식을 너무 만들면 돈이 들기 때문에.

    이미지와 함께 답변하기

    본래 QnAmaker의 답변 내용은 문자만이지만 metadata를 이용하면 이미지와 함께 답변을 반환할 수 있습니다. (정공법은 아니지만.)
    metadata에 {picurl:url}을 넣습니다. 예 {picurl : http://blob~}
    취득한 metadata의 URL로부터 응답을 작성하는 것 같은 느낌입니다.



    QnAmaker로 이미지를 내보낼 수 있지만 관리가 어려워지기 때문에 (포털에서 URL 만 알 수 있기 때문에) WordPress에서 QA를 관리하고 QnAmaker와 함께 작동합니다. 자세한 내용은 또한 기사를 만들려고합니다.

    마지막으로



    QnAmaker는 질문과 답변뿐만 아니라 metadata를 사용하여 조금 응용하면 쿼리 채팅봇의 폭도 넓어집니다.
    여러분의 채팅봇 개발의 조금이라도 도움이 되면 다행입니다.

    어, 빨리 botserviceV4.0 시도하지 않으면. . .

    좋은 웹페이지 즐겨찾기