[GCP]Dialogflow 를 이용한 간단 챗봇 만들기

안녕하세요 이정운 입니다.

이번에 제가 공유할 이야기는 그동안 제가 가장 많은 관심을 가지면서 보고 있는 Google 의 챗봇 플랫폼인 Dialogflow 입니다. 그동안 올린다, 올린다 말만 하면서 짬을 못내다가 이제서야 이야기를 공유하네요. Dialogflow 는 이미 상단에 간단히 언급드린 것처럼 챗봇을 쉽게 만들 수 있는 플랫폼으로서 2016년에 Api.ai 라고 하는 시장에서 가장 유명한 챗봇 플랫폼을 Google 이 인수하였고 그것을 그대로 사용한 것이 아니라 챗봇 플랫폼의 가장 중요한 부분인 자연어 처리(NLP)나 Intent 매칭과 같은 대화식 인터페이스의 핵심 엔진인 머신러닝 엔진을 Google 의 머신러닝 엔진으로 변경해서 좀 더 강화한 형태로 만든 챗봇 플랫폼이 바로 Dialogflow 입니다.(Api.ai 의 편리함에 Google 머신러닝의 강력함이 결합)

https://dialogflow.com/

Dialogflow 에는 Google 의 머신러닝 엔진이 장착되었기 때문에 Dialgoflow 의 가장 큰 차별점은 한국어를 가장 잘 인식할 뿐만 아니라 다양한 언어 지원 부분입니다. 하단의 링크를 보시면 아시겠지만 기본적인 한국어, 영어, 중국어 뿐만 아니라 태국어, 인도네시아어, 우크라이나어 등 다양한 언어를 지원 가능하며 그 지원 범위를 지속적으로 넓히고 있습니다.

https://cloud.google.com/dialogflow-enterprise/docs/reference/language

머신러닝 측면을 제외하고 챗봇 플랫폼으로서의 Dialogflow 의 가장 큰 특징은 기존의 챗봇 플랫폼과는 다르게 가급적 코딩을 사용하는 방식을 지양하고 이름 그대로 Dialog(대화)의 Flow(흐름)를 만들기만 하면 이를 통해 챗봇을 만들수 있다는 용이성 입니다. 다시 말해서 자연어 그대로 입력을 해서 대화 구성을 하게 되면 그게 바로 챗봇이 되는 형태로 되어 있습니다.

서론이 좀 길어졌는데 실제로 가이드를 따라 해보면서 Dialogflow 에 대해서 조금 더 이해할 수 있는 시간을 가져보도록 하겠습니다. 늘 그렇지만 해당 강좌는 하단의 좋은 링크들을 참고해서 구성하였습니다.

Getting started
https://dialogflow.com/docs/getting-started

Step by step guide to DialogFlow (API.AI)
https://miningbusinessdata.com/step-by-step-guide-to-api-ai/

A Guide to Building an Intelligent Chatbot for Slack using Dialogflow API
https://www.analyticsvidhya.com/blog/2018/03/how-to-build-an-intelligent-chatbot-for-slack-using-dialogflow-api/

[DialogFlow] 다이얼로그 플로우로 주문 챗봇 만들기
http://codevkr.tistory.com/74

Dialogflow 활용을 통한 챗봇의 구성과 소통의 이해
http://evey.hol.es/?p=90


#1) Dialogflow 개념 이해

먼저 Dialogflow 를 실제로 다루기 이전에 이해에 도움을 주기 위하여 중요한 개념만 몇가지 확인하고 넘어가도록 하겠습니다. 기본적으로 Dialogflow 는 대화를 구성해서 챗봇을 만들기 때문에 대화를 구성하는 기본 개념인 화자의 의도인 Intent, 속성인 Entity, 문맥인 Context 를 이해하는 것이 중요하며 이를 잘 지원하도록 설계 되어 있습니다.

기본적으로 상단과 같은 대화가 있다고 가정했을때 화자의 의도인 intent 는 실제 대화를 의미합니다. 그리고 화자의 의도를 파악한다는 것은 지금 챗봇에 들어온 대화를 기반으로 Dialogflow 의 다양한 intent 중에서 사용자가 말한 intent 를 파악하는 것으로 intent matching 이라고 합니다. 예를 들어 ‘수리가 가능할까요?’ 라고 사용자가 물었을때 Dialogflow 는 가지고 있는 다양한 intent 중에 들어온 대화에 맞는 intent 를 matching 한 후 그 intent 에 있는 답변인 ‘어느날로 예약을 하시겠습니까?’ 를 답변으로 내보내는 것 입니다. 좀 더 전문적으로 이야기하면 intent 는 사용자가 말하는 것과 Dialogflow 가 수행해야 할 작업 간의 매핑을 나타내는 것으로 보시면 됩니다.

https://dialogflow.com/docs/intents

Intent 에 대해서 이야기가 나온 김에 하나만 더 언급을 하고 넘어가면 Fallback intent 라는 것이 있습니다. Fallback intent 는 말 그대로 사용자의 대화가 어떤 intent 와도 매칭되지 않을때 선택되어지는 intent 이며(‘잘 못 알아들었습니다.’ 나 ‘다시 한번 말씀해주세요’ 등을 넣을 수 있겠죠) 나중에 다루겠지만 좀 더 나은 머신러닝을 위한 training 을 할 때 nagative example 을 넣을 수도 있어서 잘못 intent 가 매핑되는 것을 막는 용도로도 활용할 수 있습니다.

다음으로 속성인 Entity 는 ‘내일 오후 2시 되나요’ 라는 사용자의 질의에서 중요한 속성 항목인 ‘내일’, ‘오후 2시’ 를 파라미터로 뽑아 내는 것을 Entity 라고 합니다. 이렇게 뽑아낸 Entity 는 실제 예약을 위해서 프로그램에서 호출할 때 사용하거나 다음 대화에서 다양하게 활용될 수 있겠죠.

https://dialogflow.com/docs/entities

마지막으로 문맥인 context 는 ‘내일 오후 2시 되나요’ 에서 무엇을 위한 ‘내일 오후 2시’ 인가를 파악하기 위해서 전체 대화의 문맥을 사람이 이해하는 것처럼, 그 전에 대화가 되었던 ‘수리’ 라는 것을 기억하는 것을 의미합니다. 이 대화가 결국 수리를 위한 요청이고 ‘내일 오후 2시’ 가 단순한 시간이 아니라 수리를 위한 예약 시간이구나 라는 부분을 이해하도록 할 수 있는 부분을 context 로 이해하시면 됩니다.

https://dialogflow.com/docs/contexts

각 개념의 좀 더 자세한 사항이 궁금하신 분은 각각 제공된 링크에 좀 더 자세한 설명이 있으니 한번씩 살펴보시기 바라겠습니다.


#2) GCP 프로젝트에서 Dialogflow 시작하도록 만들어보기

먼저 Dialogflow 에는 Standard 와 Enterprise 라는 2가지 Edition 이 존재합니다. (하단의 표에 자세한 차이점이 설명되어 있습니다.)

https://cloud.google.com/dialogflow-enterprise/docs/editions

간략히만 이야기 드리면 Standard 는 Dialogflow console 에서 바로 생성할 수 있으며 가장 큰 특징은 개발자를 위해 무상으로 제공되는 Edition 이라는 점입니다. 성능과 기능상의 제약이 조금 있지만 개발 및 테스트 목적으로 만들어서 누구나 바로 개발과 테스트를 해볼 수 있도록 열려있는 Dialogflow 입니다. Standard edition 은 Google 계정 ID 만 있으면 하단과 같이 dialogflow console 로 접속하여 바로 생성 가능합니다.

https://console.dialogflow.com/api-client/#/login

다음으로 Enterprise edition 은 Standard 의 모든 기능을 포함하고 이에 덧붙여 기업 환경에 적합한 성능과 기능을 제공하는 Edition 입니다. 가장 큰 차이로는 단순 텍스트 뿐만 아니라 음성도 지원 가능하며 기업 환경에 적합하게 99.9% 의 SLA 를 보장할 수 있습니다. 이러한 Dialogflow Enterprise edition 을 생성하는 방법은 Standard 와는 조금 다르게 하단과 같이 GCP 관리 콘솔을 통해서 생성해야 합니다.(아마고 SLA 때문에 그렇지 않을까 합니다.) GCP 의 관리콘솔에 접속하여 메뉴 중에 API&Services 를 선택하고 Dialogflow 를 검색하면 하단과 같이 Dialogflow API 를 확인할 수 있습니다. 여기서 Dialogflow API 를 enable 하면 됩니다.

그 후 Dialogflow agent 메뉴를 보시면 Dialogflow Enterprise Edition agent 를 하단과 같이 설정하여 생성할 수 있습니다.

문제가 없이 정상적으로 생성되었다면 하단과 같이 Dialogflow agent 이름과 Edition 종류를 해당 화면에서 확인할 수 있습니다.

참고로 Dialogflow API enable 후에 dialogflow.com 으로 접속하면 생성된 Dialogflow agent 와 관리 콘솔을 하단과 같이 확인할 수 있습니다.


#3) 간단하게 Dialogflow 로 챗봇 만들어 보기

그럼 이제 실제적으로 Dialogflow 로 챗봇을 만들어 보도록 하겠습니다. 왼쪽 메뉴에 있는 Intents 의 ‘+’ 버튼을 클릭하여 Intent 를 하나 만들어 보도록 하겠습니다.

Intent 의 이름을 정의하고 Training phrases 에 intent matching 에 사용할 예문을 집어 넣습니다. 예를 들어 제일 처음에 예제로 넣어놨던 자전거 수리 관련 대화를 진행하는 챗봇으로 가정하고 관련된 예문을 Training phrase 에 넣어봅니다.

그리고 간단하게 답변을 하단과 같이 입력합니다.

해당 사항을 저장 한 후 오른쪽에 있는 Dialogflow 테스트 도구에서 테스트 해보면 하단과 같이 사용자가 입력한 대화에 맞는 Intent 를 찾아서 그 intent 의 적절한 답변이 나오는 것을 확인 가능합니다.

특히 Intent matching 의 경우에는 Dialogflow 내부적으로 머신러닝이 수행되기 때문에 Rule 엔진과는 다르게 Training phrase 에 입력되어지지 않은 대화가 들어오더라도 원하는 답변을 적절하게 보낼 수 있습니다. (이 경우 내부적으로 머신러닝이 수행되어야 하므로 적어도 10~15 개 이상의 예문을 입력하는 것이 좋습니다.)

아주 간단하게 가장 기본적인 대화가 가능하게 설정하고 테스트 하는 것을 확인하였습니다.

그 다음으로 실제 예약 날자를 받는 대화를 추가 구성해 보도록 하겠습니다. 일반적으로 대화가 하나의 intent 만으로 마무리 되지 않는 경우도 많기 때문에 Dialogflow 도 역시 여러 intent 로 구성된 대화를 지원하기 위하여 다양한 Follow-up intent 를 지원하고 있습니다.

일반적으로 follow-up intent 는 그 조건에 맞는 대화가 미리 들어가 있으나 custom 의 경우에는 별도로 미리 지정된 Training phrase 가 없기 때문에 추가 intent 를 만들때 많이 사용되는 편이며 여기서도 custom 을 선택해서 만들도록 하겠습니다. Custom 을 선택하면 빈 intent 가 나오는데 다음과 같이 Training phrase 를 원하시는 형태로 넣으시면 되며 여기서 중요한 포인트는 사용자가 말한 대화중에 예약에 관련된 날자와 시간을 잡기 위해 노란색으로 Entity 를 사용한 부분입니다.

보시면 아시겠지만 @sys.date-time 이라는 system entity 를 사용했고 자동으로 상단과 같이 잡힐 수도 있으며 제대로 system entity 가 안잡히면 마우스를 드래그 하면 원하시는 데로 entity 를 추가 설정 할 수 있습니다. 응답은 우선 단순하게 Entity 가 제대로 추출되는지 확인하기 위해서 @sys.date-time 을 바로 답변으로 찍도록 $data-time 을 반환하도록 설정하였습니다. (system entity 말고 사용자들이 직접 원하는 entity 를 만들 수 있는 developer entity 나 사용자 별로 설정이 가능한 user entity 등이 추가로 있습니다.)

이후 저장을 한 후에 다시 Dialogflow 관리콘솔의 오른쪽에 있는 테스트 화면에 ‘자전거 수리하고 싶습니다’ 를 입력한 후 바로 ‘수리는 내일 10시에 하고 싶습니다’ 를 입력하면 하단과 같이 Parameter 로 date-time 이 정상적으로 확인할 수 있습니다.

마지막으로 방금 만든 intent 에 follow-up intent 를 하나 추가하는데 예약을 확약받는 yes 를 추가 합니다. 필요한 경우 만들어진 Training phrases 에 원하는 예문을 더 추가해도 됩니다.

그리고 일정을 확약하는 최종 답변을 작성합니다.

여기서 중요한 부분이 이전 대화에서 이야기 나누었던 일정과 시간을 기억하는 것입니다. 이 부분이 Dialogflow 의 중요 개념인 Context 라는 부분입니다. 지금 만든 intent 의 제일 상단에 보면 하단과 같이 context 를 받도록 설계 되어 있으며 해당 이름은 자동으로 ‘00010-problemIntent-custom-followup’ 으로 되어 있습니다.

사실 이전에 사용된 intent 의 상단으로 돌아가 보면 보시는 것처럼 follow-up intent 를 만들면서 자동으로 context 를 넘기기 위해서 output context 에 ‘00010-problemIntent-custom-followup’ 이 추가되어 있으며 그 앞에 Life span 이 기본값인 ‘2’로 설정된 것을 확인할 수 있습니다.

여기서 Life span 은 해당 context 를 언제까지 유지할 것인지에 대해서 지정된 수치이며 ‘2’ 라고 하면 다음 두 번의 대화까지 context 를 유지하겠다는 의미입니다. 당연히 필요하다면 더 길게 만들거나 더 짧게 만드는 것이 가능합니다. 그리고 마지막으로 응답에서는 context 로 들어온 파라미터를 출력하기 위하여 #context_name.parameter_name 형식으로 변수를 사용했습니다.

결국 최종 테스트를 해보시면 아시겠지만 하단과 같이 이전에 나왔던 대화 내용을 context 로 기억하고 마지막 답변에 그 내용을 출력해서 보여줄 수 있습니다.

참고적으로 여기까지 잘 따라오셨다면 Intent 구조는 하단과 같이 나오게 됩니다.


#4) Dialogflow 로 만들어진 챗봇 테스트

대화 구성이 완료되어서 이제 테스트를 해보시려면 Dialogflow 의 Integration 메뉴로 갑니다. 그 안에 가면 그동안 만든 챗봇을 다양한 챗봇 인터페이스에 바로 연동할 수 있는 메뉴가 구성되어 있습니다. Google Assistant 나 Facebook Messenger, Line 등에 단순 클릭만으로 쉽게 통합할 수 있도록 되어 있으며 여기서는 간단한 데모이니 Web Demo 로 확인해 보도록 하겠습니다.

Web Demo 를 클릭하면 링크가 생성되고 하단과 같이 웹화면으로 데모를 수행해 볼 수 있습니다.

여기까지 잘 따라오셨다면 기본적으로 Dialogflow 를 이용해서 대화에 대한 흐름만 작성해서 간단한 챗봇을 만드는 것을 잘 완료하신 것입니다. 직접 해보시면 아시겠지만 Dialogflow 의 가장 큰 특징은 챗봇 플랫폼으로서 챗봇을 만드는데 필요한 많은 기능을 플랫폼 형태로 제공하므로 아주 손쉽게 챗봇을 만들고 테스트 해볼 수 있다는 점입니다.

그럼 이번 이야기는 여기서 마무리하고 다음 이야기에서 좀 더 다양한 경우를 고려해서 챗봇에 대한 것을 살펴보도록 하겠습니다. 휘리릭~~~

추신 #1 : Integration 항목에 없는 챗봇 인터페이스와 커뮤니케이션 하고 싶다면 Dialogflow 가 API 서버 역할을 하기 때문에 특별한 것은 없고 하단의 링크를 참고해서 결국은 REST API 의 request/response 형식만 맞추면 가능합니다. 즉, 챗봇 인터페이스가 REST API 를 사용하여 Dialogflow 가 이해할 수 있는 request 형태로 맞추어서 요청을 보내고 들어온 응답을 response 형식에 맞추어서 필요한 부분을 실제 화면에 뿌려준다면 어떤 챗봇 인터페이스라도 연동이 가능합니다.

Detecting Intent from Text
https://cloud.google.com/dialogflow-enterprise/docs/detect-intent-text

Method: projects.agent.environments.users.sessions
https://cloud.google.com/dialogflow-enterprise/docs/reference/rest/v2beta1/projects.agent.environments.users.sessions/detectIntent

참고적으로 Dialogflow 관리콘솔의 테스트 화면에 ‘Copy Curl’ 명령을 사용하면 하단과 같이 쉽게 curl 명령을 REST API 규약에 맞게 가지고 오실 수 있습니다.

curl -H “Content-Type: application/json; charset=utf-8” -H “Authorization: Bearer ya29.c.EloBBnQacO5hFYmj1zxEumM7K2wAKsPXC2r7s-qVB8ulwaq2DeQINpYx7zi0V-H_I8MJ3s6YNxfCvh8ZN_tEJNklYxM1FiL5s7ak28M3CNwRW0_KczsgmJKEq-8” -d “{\”queryInput\”:{\”text\”:{\”text\”:\”자전거 수리하고 싶습니다.\”,\”languageCode\”:\”ko\”}},\”queryParams\”:{\”timeZone\”:\”Asia/Seoul\”,\”sentimentAnalysisRequestConfig\”:{\”analyzeQueryTextSentiment\”:true}}}” “https://dialogflow.googleapis.com/v2beta1/projects/jwlee-myproject-01/agent/sessions/8a9xxxxx-5be6-09ab-4fd9-d6a1abfcc8e4:detectIntent"

추신 #2 : 이번 이야기를 위해서 제가 만든 샘플은 공유를 위해서 github 에 올려놨으니 참고하시기 바라겠습니다.

https://github.com/jwlee98/GCP/tree/master/dialogflow/lecture01