[GCP]Dialogflow 를 이용한 간단 챗봇 만들기 2탄 — Fulfillment

이정운 (Jungwoon Lee)
14 min readJul 26, 2018

--

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

지난 시간에 Dialogflow 를 이용해서 간단한 챗봇을 만드는 것을 이야기로 풀어 봤습니다. (지난 이야기 링크) 이미 지난 시간에 살펴봤지만 Dialogflow 의 강점은 코딩없이 간단하게 대화 구성만으로 챗봇을 만들 수 있다는 점이며 추가적으로 Google 의 머신러닝 엔진을 통해서 강력한 자연어 처리와 intent matching 이 가능한다는 것을 확인하셨을 것 입니다. 이번 이야기에서는 이를 좀 더 확장해서 더 다양한 형태로 챗봇을 구현해보고자 합니다.

여러가지 요소가 있겠지만 이번에는 챗봇을 좀 더 풍성하게 만들 수 있는 Webhook 을 통한 서버 연동에 대해서 살펴보도록 하겠습니다. 챗봇이 단순하게 질의/응답 목적으로만 쓰이기 보다는 재고를 확인해서 알려준다던지, 고객의 요청에 응답만 하는 것이 아니라 DB 에 저장하여 향후 다른 목적으로 사용한다던지 Webhook 을 사용하면 좀 더 다양한 유즈케이스에 대응하는 챗봇을 만들 수 있습니다.

Dialogflow 는 이러한 Webhook 연동을 fulfillment 라는 기능을 통해서 쉽게 연동할 수 있도록 지원하고 있으며 하단의 링크에 자세한 설명이 나와있지만, 결국 request/response 의 형식만 맞추어서 REST API 로 통신하면 어떤 서버도 webhook 으로 연동 가능합니다.

https://dialogflow.com/docs/fulfillment

그럼 조금 더 자세한 사항은 직접 Dialogflow 의 fulfillment 기능을 사용해보면서 살펴보도록 하겠습니다. 늘 그렇지만 하단과 같은 좋은 자료를 참고해서 본 이야기를 구성하였습니다.

How to make a Webhook for Dialogflow Fulfillment
https://medium.com/@pallavtrivedi03/how-to-make-a-webhook-for-dialogflow-fulfillment-d02835cc50bf

Creating NodeJS Webhook for Dialogflow
https://chatbotsmagazine.com/creating-nodejs-webhook-for-dialogflow-2b050f76cd75

Dialogflow Fulfillment Webhook Template for Node.js and Cloud Functions for Firebase
https://github.com/dialogflow/fulfillment-webhook-nodejs

#1) Developer entity 추가

먼저 Dialogflow 에서 Webhook 연동을 살펴보기 전에 좀 더 다양한 정보를 가지고 연동하기 위하여 이전에 작성한 intent 에서 추가적으로 ‘자전거’ 라는 entity 를 뽑는 작업을 추가해 보도록 하겠습니다. 이를 위해서는 가장 먼저 사용자가 원하는 형태의 developer entity 를 만들어야 합니다. Dialogflow 관리콘솔에서 Entities 메뉴의 ‘+’ 버튼을 클릭하여 하단과 같이 새로운 entity 를 만듭니다.

보시면 아시겠지만 entity 의 이름은 productname 이고 ‘자전거’와 ‘오토바이’를 entity 로 지정하였습니다. 추가적으로 ‘Define synonyms’ 를 켜서 동의어를 다양하게 등록하였습니다. 특히, 동의어의 경우 여러 한국어 변화에 대해서도 동일한 entity 로 인식할 수도 있으며 추가적으로 자주 발생되는 오타의 경우 이를 동의어로 등록하여 entity 에서 오타가 발생한 경우도 적절히 잘 entity 를 파라미터로 추출할 수 있도록 지원할 수 있습니다.

이제 Developer entity 를 만들었으니 이를 실제 intent 에 적용하기 위하여 필요한 intent 수정 화면으로 들어갑니다. 그리고 developer entity 를 등록하기 위하여 예문 중에서 원하는 부분을 드래그하면 하단과 같이 entity 등록 화면이 나오고 이때 이번에 만든 developer entity 이름인 @productname 을 선택합니다.

그러면 하단과 같이 예문에 developer entity 가 매핑된 것을 색깔을 통해 확인할 수 있습니다.

마지막으로 추출된 entity 를 context 로 끝까지 보내기 위해서 life span 을 하단과 같이 조금 더 늘려줍니다.

이렇게 하고 테스트를 하시면 하단과 같이 ‘자전거 수리하고 싶습니다’ 라고 사용자가 질의를 하면 답변이 나가는 것 뿐만 아니라 파라미터로 ‘자전거’ 가 나오는 것을 확인할 수 있습니다. 즉, 원하는 형태대로 entity 를 잘 추출하는 것을 확인할 수 있습니다.

#2) Webhook 연동을 위한 fulfillment 기능 사용하기

이제부터는 본격적으로 이번 이야기의 주제인 Webhook 연동을 위한 fulfillment 기능을 사용하는 것을 테스트 해보도록 하겠습니다. 이를 위해서는 Dialogflow 관리콘솔에서 Fulfilment 메뉴를 확인합니다. 해당 메뉴에 가보면 2가지 기능을 선택해서 쓸 수 있는데 Webhook 을 직접 연동하는 방법과 Inline Editior 를 통해서 Cloud Functions 를 사용하는 방법입니다.(사실 둘 다 같은 Webhook 방식이지만 별도로 만들어서 쓸지, 제공되는 것을 쓸지의 차이가 있습니다. 그래서 둘 중 하나만 선택해서 사용할 수 있습니다.)

Webhook 을 직접 연동하는 방식은 직접 webhook 을 처리하는 서비스를 만든 후에 하단과 같이 URL 만 입력하여 그 URL 호출을 통해서 처리를 수행하는 방식입니다. 필요한 경우 Basic Auth 를 추가하거나 header 를 덧붙일수 있습니다.

그 다음으로 Inline Editor 를 통해서 Cloud Functions 를 사용하는 방식은 하단에 보시면 아시겠지만 필요한 코드를 직접 Dialogflow 에서 입력 및 수정 가능하며 해당 서비스는 자동으로 serverless 컴포넌트인 Firebase 의 Cloud Functions 로 배포 및 수행되어 사용되는 형태입니다. (serverless 이기 때문에 추가적으로 Cloud Functions 에 필요한 서버에 대해서는 신경쓰지 않으셔도 됩니다. Google 이 알아서 관리합니다.)

두가지 방식 중에 원하는 방식을 선택해서 사용하시면 되며 여기서는 간단하게 테스트를 하는 것이 목적이므로 Inline Editor 를 사용하도록 하겠습니다.

Getting started with Dialogflow fulfillment
https://dialogflow.com/docs/how-tos/getting-started-fulfillment

Inline Editor 의 코드를 살펴보시면 아시겠지만 현재는 Node.js 로 샘플이 구성되어 있으며 주석이 상세하게 달려있으므로 해당 부분을 참고하시면 프로그래밍을 하실 수 있는 분들은 대략적인 이해가 가능할 것으로 판단됩니다. (또는, 상단의 링크에 추가 설명이 있으니 이를 참고하시기 바라겠습니다.)

아주 간략히만 설명드리면(Node.js 기준 입니다.) event 를 받는 메인 함수 안에서 필요한 액션을 수행하는 handler 함수를 정의하고 intentMap 에 intent 이름과 매핑해서 해당 함수를 등록하면 실제적으로 해당 함수가 호출되는 구조입니다.

그 함수 안에서는 WebhookClient 를 구현한 agent 에 add 로 응답을 추가해서 필요한 답변을 원하는 형태로 추가할 수 있습니다. 또한, getContext() 메소드를 통해서 대화의 문맥을 기억하고 있는 context 를 반환받아서 사용하는 것도 가능합니다. 참고로 WebhookClient 에는 그외의 다양한 메소드 들이 있어서 일일이 다 설명하기는 어렵고 API 문서를 같이 공유드리오니 참고하시면 원하시는 형태로 더 다양한 액션을 만드실 수 있지 않을까 합니다.

WebhookClient
https://dialogflow.com/docs/reference/fulfillment-library/webhook-client

이렇게 Inline Editor 로 코드를 작성한 후에 사용을 하려면 하단에 있던 Deploy 버튼을 클릭하시면 됩니다. 정상적으로 배포가 완료되었다는 메세지를 받으시면 테스트가 가능한데 그 전에 해당 intent 에서 답변을 바로 보내는 것이 아니라 Webhook 을 호출하도록 하단과 같이 Fulfilment 기능을 on 해줍니다.

저장이 완료된 후 테스트를 해보시면 하단과 같이 최종 답변을 지정한 그대로 하는 것이 아니라 하단에서 보시는 것처럼 Webhook 을 호출에서 Node.js 프로그래밍으로 만들어진 답변이 나오는 것을 확인 가능합니다. (참고로 날자가 undefined 로 나오시는 분들은 이야기 하단을 참고해서 ‘context.parameters[“date-time”].date_time’ 로 테스트 해보시기 바라겠습니다.)

추가적으로 Dialogflow 에는 공식적으로 이 작업을 도와드리기 위하여 Webhook 에 대한 다양한 샘플을 하단의 링크에서 제공하오니 가져다 쓰셔도 되며 소스가 오픈되어 있으므로 필요한 부분은 참고해서 Webhook 작성을 조금 더 편하게 하실 수 있습니다.

Samples
https://dialogflow.com/docs/examples

마지막으로 In-line editor 하단의 ‘View execution logs in the Firebase console’ 를 클릭하시면 자동으로 Firebase cloud functions 화면에 접속 가능하며 하단과 같이 로그나 상태 등을 확인할 수 있으며 이를 통해서 디버그를 하실 수 있으니 참고하시기 바라겠습니다.

#3) Firebase 에서 GCP 의 Cloud functions 로 대체하기

Dialgoflow 의 In-line editor 는 언급드린 것처럼 serverless 인 Firebase cloud functions 를 서버로 사용합니다. 그런데 불편한 점은 GCP 를 사용하는 경우 별도로 Firebase 도 관리해야 한다는 거죠. 근데 사실 이게 숨겨진 것이 하나 더 있습니다. Dialogflow 를 만들때 사용한 GCP 프로젝트의 관리콘솔로 접속해 보면 바로 아실 수 있는데 (standard 의 경우 프로젝트가 자동 생성되므로 ‘설정’ 메뉴에서 하단에 보이는 것처럼 자동으로 GCP Project ID 를 확인 가능하고 이를 클릭하면 바로 이동합니다. )

GCP 관리콘솔에서 Cloud functions 를 클릭해보면 하단과 같이 GCP 관리 콘솔에서 방금 작성한 Webhook 을 위한 Firebase Cloud functions 서비스를 그대로 확인 가능합니다. (결국 내부적으로는 같은 애들인 것처럼 보이네요.)

해당 서비스 이름을 클릭해보면 Firebase 보다 더 디테일한 상세 사항을 확인 가능합니다. (예를 들어 모니터링, 메모리, 지역, 에러 등등)

참고: Google Cloud functions 는 하단에 문서를 보시면 아시겠지만 serverless 로 다양한 서비스를 제공할 수 있으며 현재 기준으로 node.js 와 python 을 지원할 수 있습니다. (이제 GA 까지 되었습니다.^^&)

Google Cloud Functions Documentation
https://cloud.google.com/functions/docs/

여기서 ‘View logs’ 를 클릭하면 Stackdriver logging 을 통해서 자세한 로그도 확인 가능합니다. 결국은 GCP 기반에서 Stackdriver logging 의 고급필터 라던가 메트릭 기반의 알람, BigQuery 연동등의 풍부한 모든 기능을 활용할 수 있습니다.

특히, GCP 의 Cloud functions 관리 화면에는 하단과 같이 테스팅 기능도 제공해서 좀 더 편리하고 다양하게 테스트도 직접 해보실 수 있습니다.

마지막으로 GCP 의 Cloud Functions 는 Node.js 도 여러 버전을 지원하며 Python 도 지원 가능하므로 언어 선택의 자유도 가질 수 있습니다.

그럼 이제 실제 제대로 GCP 에서 작동/수정 가능한지 Edit 버튼을 클릭하여 소스와 설정 내용을 확인합니다. 이후 소스를 클릭하면 Editor 화면으로 확대됩니다. Editor 화면에서 제가 일부러 한글을 좀 틀리게 썼었는데 ‘얘약’ 을 ‘예약’으로 변경하고 ‘context.parameters[“date-time”].endDateTime’ 을 ‘context.parameters[“date-time”].date_time’ 로 변경 후 ‘OK’를 클릭하여 저장하고 이후 ‘Save’ 를 눌러서 재배포 합니다.

참고 : 한번이라도 Dialogflow Inline Editor 가 아니라 GCP 관리콘솔에서 수정을 하시면 그 이후부터는 Dialogflow 에서는 추가 수정이 가능하지 않으며 계속적으로 GCP 관리콘솔에서 작업해야 합니다. 이점 유념하고 작업하시길 바라겠습니다.

저장을 하면 Cloud functions 에 대한 자동 배포가 들어가고 하단과 같이 배포중과 배포완료의 여부를 쉽게 확인이 가능합니다.

배포가 완료되면 이전에 테스트한 것처럼 Dialogflow 의 Web Demo 를 이용해서 테스트해보시면 하단과 같이 결과가 변경되어서 잘 나오는 것을 확인 가능합니다.

여기까지 잘 따라오셨다면 기존의 기본적인 챗봇 형태의 구성에서 이제 대표적인 Serverless 솔루션인 GCP 의 Cloud Functions 를 활용하여 Webhook 연동을 통해서 좀 더 챗봇에서 필요한 부분을 프로그래밍 적으로 추가해서 답변을 만들어 내는 방안까지 테스트를 잘 완료하신 것입니다. 잘 아시겠지만 Webhook 연동을 하면 실제적으로 프로그래밍이 들어가므로 이해는 조금 어려울 수 있어도 프로그래밍이 가능한 범위로 다양한 유연성을 가질 수 있으며 필요한 연계 시스템과 통신하여 개인화나 좀 더 풍성한 답변을 만들어 제공할 수 있는 많은 장점이 있어서 필수적으로 사용해야 하지 않을까 합니다.

그럼 이번 이야기는 여기까지로 마무리하기로 하며 다음에는 좀 더 고민하여 다른 Dialogflow 이야기로 다시 돌아오겠습니다. 휘리릭~~~

추신 : 이번 이야기를 위해서 사용한 소스는 공유를 위해서 github 에 올려놨으니 참고하시기 바라겠습니다.

* Disclaimer: 본 글의 작성자는 Google 직원이지만 Google cloud 를 공부하는 한 개인으로서 작성된 글입니다. 본 글의 내용, 입장은 Google 을 대변하지 않으며 Google 이 해당 콘텐츠를 보장하지 않습니다.

--

--

이정운 (Jungwoon Lee)

Technical engineer who dreams better future. (These thoughts are my own personal opinions, and do not reflect or represent Google’s opinions or plans.)