Google Dialogflow로 챗봇 만들기 — basic (4) Multi-turn대화를 위한 context 정의

Original article was published by 정민수 on Deep Learning on Medium


Google Dialogflow로 챗봇 만들기 — basic (4) Multi-turn대화를 위한 context 정의

Google Dialogflow로 챗봇 만들기 — basic (4) Multi-turn 대화를 위한 context 정의, 2020.09.27.

Multi-turn 대화

챗봇과 QA task의 가장 큰 차이점이라고 하면, context가 있는 multi-turn이 가능한가, 그리고 chit-chat 모델과 같은 일상적인 대화가 가능한가, 이 두 가지를 먼저 떠올릴 수 있을 것 같습니다.

Learning-based 의 챗봇 모델 같은 경우, 해당 데이터셋도 많이 없을 뿐더러, 아직까지 멀티턴 대화를 완벽히 학습하는 딥러닝 모델은 많지 않습니다. (한국어는 더더욱.) 하지만, Rule-based 모델에서는 간단히 구현할 수 있습니다. Dialogflow에서는 context라는 정보를 정의하여 멀티턴 대화 구성을 할 수 있습니다. Intent만 캐치할 수 있다면, context는 자동으로 정의되기 때문에 성능도 꽤 좋습니다. 오늘은 context를 정의하여 멀티턴 대화를 구성하도록 하겠습니다. 이 부분을 잘 익혀두시면, 챗봇을 구성하는 데에 많은 도움을 얻을 수 있습니다!

대화 설계

먼저, 간단한 멀티턴 대화를 설계해보겠습니다. 단순히 일상적인 대화를 구현할 수도 있지만, 앞에서 배운 entity까지 정의해서 어떤 목표나 기능을 수행하는 task-oriented(또는 goal-oriented) 챗봇을 구성하겠습니다. 피자 주문을 받는 챗봇을 만들어볼까요? 관련 데이터셋은 있지만 우린 rule-based로 직접 구성하는 것이므로, 직접 설계해보겠습니다.

우리가 만들 대화의 차트입니다. 간단한 차트이기 때문에 플로우 차트로 작성했지만, intent나 entity 그리고 나중에 배울 event 속성들까지 관리하려면 엑셀파일 등을 이용해서 정리하는 게 좋을 거에요. 엑셀로 정의서 양식을 하나 만들어서 작성하면 나중에 back-end로 개발할 때 굉장히 편할 거에요.

대화 구성

먼저 위 대화를 구성하기 위해 Intents 탭에서 대화의 시작이 되는 pizza-order 인텐트를 만들어보겠습니다.

  • Training phrases : “피자 주문”, “피자 주문 할래요”, “피자 시키고 싶습니다.”
  • Response : “어떤 피자를 주문하시겠어요?”

이제 “어떤 피자를 주문하시겠어요?”라는 말의 응답으로 주문하고 싶은 피자 메뉴를 말해야겠죠? “치즈피자”를 주문한다고 하겠습니다. 이 때, Dialogflow에서는 이 “치즈피자”가 위 pizza-order의 response text인 “어떤 피자를 주문하시겠어요?”라는 말의 대답인지, 아니면 사용자가 갑자기 먹고 싶은 음식이 “치즈피자”이다 라는 말인지 알려줘야 합니다. 이때, context의 개념이 필요한 것입니다. “치즈피자”의 인텐트가 어떤 대화의 문맥에 있냐를 파악할 수 있어야 하는 것이죠.

피자 메뉴에 대한 인텐트를 pizza-order 인텐트와 같은 context로 묶어주기 위해서, Intents 메뉴에서 pizza-order 행에 마우스를 올려놓습니다. 그럼 pizza-order 우측에 세 가지 아이콘이 뜨는 데요, 여기서 Add follow-up intent를 눌러서 여러 가지 follow-up intent 중에서, 첫번째인 “custom”을 누르겠습니다.

그럼 아래 처럼, pizza-order 아래 pizza-order — custom 이라는 인텐트가 자동으로 생성된 것을 확인할 수 있습니다.

pizza-order 인텐트를 다시 클릭해서 보시면, Contexts에 output context가 생긴 것을 확인할 수 있습니다. “pizza-order-followup”이라고 돼있고, 앞에 숫자 2가 있네요. 여기서 숫자2는 life span으로 이 context가 살아있는 대화 턴 수를 의미합니다. pizza-order intent가 나오고, 두 번의 대화 턴 동안 context가 살아있다는 의미입니다. 클릭해서 span을 수정할 수 있습니다.

피자 메뉴에 대한 intent를 만들기 전에, entity 정의를 복습한다는 의미에서 ‘pizza’ entity를 정의하겠습니다. 간단하게 4개의 값만 집어 넣어서 entity를 만들어줍니다.

그럼 다시 Intents 탭에 들어가서 pizza-order — custom 을 클릭한 다음, 정보를 입력하겠습니다.

  • 이름 : pizza-order — custom 에서 이름이 헷갈리지 않도록, pizza-menu라고 바꾸겠습니다.
  • Training phrases : “치즈피자요”, “페퍼로니피자요”, “하와이안피자요”, “포테이토피자요”
  • Responses : “더 필요한 것은 있으신가요?”

이 때, Contexts 부분에 input context가 “pizza-order-followup”으로 상위 인텐트의 output context를 그대로 받은 것을 알 수 있습니다.

Intent를 정의했으면, “더 필요한 것은 있으신가요?”에 대한 대답으로 “아니오” 등의 부정적인 어휘가 나오면 주문을 그만하는 인텐트를 정의하겠습니다. 아까처럼, pizza-menu 인텐트에 Add follow-up intent를 눌러 만드는 데, 이때, 4번째 no를 클릭해서 만들겠습니다. Dialogflow에서는 기본적인 followup intent를 미리 정의해서 training phrases와 같이 제공하고 있습니다. 참 편리하기 때문에 yes나 no와 같은 후속 인텐트는 이 기능을 이용하시면 빨리 작업할 수 있습니다!

pizza-menu-no 인텐트를 클릭하시면 아까처럼 input context가 이미 생성되어 있을 뿐 아니라, training phrases까지 부정적인 대답들로 구성되어 있네요! 여기에 우리의 특징을 포함해야 하기 때문에 “그만 할래요”, “필요한 것 없어요”, “없어요” 정도만 추가해주겠습니다. 그리고, 이 인텐트를 대화의 끝으로 정의해서 context를 종료하겠습니다. 대화의 끝으로 정의하는 것은 Responses 파트에 Set this intent as end of conversation 토글 스위치를 켜주시면 됩니다.

  • Training phrases : 기존 + “그만 할래요”, “필요한 것 없어요”, “없어요”
  • Responses : “네 감사합니다. 주문을 종료합니다. ”
  • Set this intent as end of conversation : Check

이제, 우리가 설계한 대화의 구현은 끝났습니다. pizza-order로 시작해서 pizza-menu-no로 끝나는 일련의 대화를 구성했습니다. Intents 탭에 들어가보시면 이렇게 context가 있는 인텐트들이 꼬리 물기식으로 정렬이 되어있습니다.

이제 테스트를 해보면서 잘 작동하는 지 살펴보겠습니다.