SlideShare a Scribd company logo
1 of 61
FaaS를 이용한
Clova Extension 개발
Clova Platform Evangelist
옥상훈
2018-06-28
발표자료: https://www.slideshare.net/ClovaPlatform/
Clova 스피커용 음성게임 예제 – 구구단놀이, 나라수도맞추기, 업다운
목차
• Clova Platform & extension 개요
• Clova extension 개발 준비 개요
• Clova extension 기획
• 인터렉션모델
• 음성기반 게임 예제 – 구구단놀이, 나라수도맞추기, 업다운
• Cloud Function 및 Clova extension 서버 API 개발
• Clova 앱과 스피커에서 익스텐션 호출 테스트
Clova Plaform & extension 개요
Clova Platform Overview
Clova Interface Connect
Clova Interface Connect 적용 사례
LG U+ 블루콤 스피커 LG 전자 스마트씽큐
LG전자 가전기기 제어가능IoT 제품 제어가능
LG U+ IPTV STB
- LG U+ IPTV UHD급 이상의 STB 내 Clova 제공 (2017년 12월 적용)
시청 중,
리모콘 side음성버튼
or (음성) LGU플러스야
로 음성명령 수행
‘효리네민박 틀어줘’ ‘스릴러영화 추천해줘’전면 검색키>
전체화면모드, 클로바스러운 검색홈으로 제안
Clova Interface Connect 적용 사례
Clova Interface Connect 적용 사례 (Friends +)
스피커로 '셋탑을 컨트롤' 할 수 있습니다.
브라운과 샐리에게 "유플티비"라는 호출어로 지시해보세요.
"유플티비, 눈물 쏙 빼는 영화 찾아줘"
"유플티비, tvN 틀어줘"
Clova Extensions Kit
Clova extension 이란?
• Clova 플랫폼에서 작동하는 3rd party 애플리케이션으로서, 예를 들면 음성명령으로 음악을
재생하거나 쇼핑, IoT기기 제어 등이 가능합니다.
• 사용자의 의도(예: 음성명령)에 따라 extension이 정확하게 동작할 수 있도록 Clova 플랫폼
내부적으로 음성인식, 대화분석 등 Clova 인공지능 기술이 적용되어 있습니다.
extension으로 무엇을 할 수 있나요?
• Extension 종류
• (서비스중) Custom extension: 3rd party 서버에서 제공하는 응답(예:
음성, 이미지 등)을 제공할 수 있습니다.
• 예) "팟빵에서 뉴스공장 틀어줘" 라고 하면 "팟빵 extension"이 해당 음원을
들려줍니다.
• (서비스중) Chatbot extension: 고객이 자주 묻는 질문(FAQ)과 답변을
등록하여 사업자 대신 챗봇이 답변을 하게 하는 extension입니다.
• 예) ”네이버고객센터 실행해줘  네이버 쇼핑 가격 비교하는 방법
알려줄래?”
• (제휴문의) Clova Home extension: IoT 기기제어가 가능
• 예) "클로바, TV 좀 켜줘" 라고 하면 클로바가 TV를 켭니다
Clova extension 사례 – ‘체리쉬’ 모션베드제어
https://www.youtube.com/watch?v=kpkRRLWHySc
대표발화: 1) 체리쉬에게 자자 2) 체리쉬에게 무중력 모드 해줘 3) 체리쉬에게 첫번째 메모리 해줘
Clova extension 사례 – ‘배송지킴이’ 택배조회
https://www.youtube.com/watch?v=27NWVG0yhTQ
대표발화: 1) 배송지키미 시작해줘 2) 배송지키미에서 내 택배 조회해줘 3) 배송지키미 내 택배 언제와
Clova extension 사례 – ‘라마마’ 연애운
https://www.youtube.com/watch?v=uCqQem8_LyQ
대표발화: 1) 라마마 시작해줘 2) 라마마에게 연애운 물어봐줘 3) 라마마에게 남친 언제생길지 물어봐줘
https://drive.google.com/file/d/1Ytzx-M6Lub-20RJhR_SNzqezYmFCHC_Z/view
Clova 챗봇 extension 사례 – ‘멍멍이’ 동물소리 번역기
https://www.facebook.com/ClovaAI/photos/a.1639371196371443.1073741828.1637903373184892/17833965653022
38/
대표발화: 1) 멍멍이 시작해줘
Clova extension 개발 준비 개요
Clova extension 개발 준비 – 1 (필수)
• 익스텐션서버
• REST API 서버로서, Clova platform은 Clova console에 등록한 REST API 서버URL로 응답과 요
청을 주고 받습니다.
• Clova platform은 1) 익스텐션 실행 2) 인텐트 실행 3) 익스텐션 종료라는 3가지 type의 요청을 보
내고, 익스텐션 서버는 여기에 맞게 응답을 하면 됩니다.
• 익스텐션 서버는 https로 외부망으로 통신할 수 있는 서버이어야 하며, 포트는 80 또는 443로만 통
신합니다.
Clova extension 개발 준비 – 1 (필수)
• 익스텐션서버
Clova extension 개발 준비 – 2 (필수)
• 인터렉션 모델
• 일종의 대화시나리오와 비슷합니다만, 기계인 익스텐션 서버가 사람의 대화를 이해하여 작동할 수
있도록 Clova console에 입력하는 문장 및 메타정보들입니다.
• 인터렉션 모델에는 사용자로부터 입력될 만한 문장들과 각 문장이 어떤 실행 명령(이를 '인텐트'라
고합니다.)으로 연결될 지를 설정합니다.
• 인텐트를 실행할 때 필요한 정보들은 '슬롯'이라는 것으로 정의하여 처리합니다.
• 예를 들면, 피자주문하는 익스텐션의 경우 인텐트와 슬롯은 아래와 같습니다.
• 예) 사용자의 대화: "페퍼로니 피자 2판 주문해줘" --> 'OrderPizza'라는 이름으로 피자주문 처리용 인텐
트로 정의
• 예) 'OrderPizza'인텐트가 실제 피자를 주문하기 위해 필요한 정보는 '피자명'과 '수량'이며, 이는 각기
'pizzaType', 'pizzaAmount'라는 슬롯으로 정의
Clova extension 개발 준비 – 3 (선택)
• OAuth 인증 서버
• 만약 익스텐션이 써드파티 계정
인증이 필요하다면 익스텐션 서
버와 함께 OAuth 인증을 구현하
셔야 필요합니다.
• OAuth 인증 서버는 Clova
console에 등록된 인증정보를 이
용하여 인증을 처리하고, 인증이
완료되면 접근토큰을 반환해야
합니다.
• 인증서버 구축 예) 배달의 민족,
LG 전자, LGU +
관련 가이드: https://www.slideshare.net/ClovaPlatform/clova-tech-summit-3-clova-extension-oauth-89597569
Clova extension 기획
Clova extension 호출명 설정
• 가전기기를 제어하는 Custom extension (이하 '익스텐션') 서비스를 그려 보
도록 하겠습니다.
• 먼저 익스텐션 실행할 때 부르는 이름, 즉 '호출명'을 정해야하는데, 몇 가지
제약이 있습니다.
• 일반적인 명사는 안됨 (예: 박사 (X) )
• 브랜드나 유니크한 명사가 접목된 단어 가능: (예: 짱구박사(O))
• 혹시나 음성인식이 잘 안되는 경우는 다른 호출명으로 하셔야 할 수 있으니,
Clova앱에서 인식이 잘 되는지 확인해보시길 바랍니다.
익스텐션의 작동 시나리오
• 첫번째는 익스텐션에게 바로 질문하고 답을 받는 것입니다. (싱글턴, single-
turn)
• 사용자: 클로바, 짱구박사에서 거실 전등 켜줘
• 익스텐션: 거실 전등이 켜졌습니다.
• 두번째는 익스텐션을 실행한 다음에 질문하고 답을 받는 것입니다. (멀티턴,
multi-turn)
• 사용자: 클로바, 짱구박사를 시작해줘
• 익스텐션: 안녕하세요. 짱구박사가 시작되었습니다. 제어하고 싶은 가전기기와 동작 방
법을 말씀하세요.
• 사용자: 거실 전등 켜줘.
• 익스텐션: 거실 전등이 켜졌습니다.
익스텐션 기본 정보 등록하기
• Clova console에 접속해서 'Clova Extensions Kit'을 클릭한 다음 '새로운 익스텐션 만들기'를 누릅니다.
• URL: https://developers.naver.com/console/clova/
• 익스텐션 정보 설정
• type은 Custom Extension으로 선택하고, 나머지 값들도 입력합니다.
• 오디오플레이어 사용 여부는 '아니오'로 합니다. '예'로 하는 경우는 음원을 재생하는 경우에 사용합니다.
인터렉션 모델
인텐트와 슬롯
익스텐션 작동 시나리오 고려사항
• 이제 해야할 일은 시나리오가 클로바 플랫폼에서 작동하도록 하는 것인데요.
• 문제는 사용자가 같은 말을 물어보더라도, 위에서 정의한 글자그대로 말하지
는 않는다는 점입니다.
• 예) 거실 전등 켜줘
• 예) 거실 점등 해줘
• 예) 거실 불켜줘
• 이렇게 같은 의도이지만 다양한 표현을 입력하고 인터렉션 모델에 이러한 여
러 문장 케이스들을 잘 정리해놔야 더 똑똑한 익스텐션을 만들 수 있겠습니다.
인터렉션 모델 등록하기 – 슬롯 등록
• 짱구박사는 집안의 지역 IoT기기를 제어
할 것이므로 인텐트는 하나만 등록하면
되고, 슬롯은 ’집안의 다양한 장소들이'이
되겠습니다.
• 슬롯 등록하기 전에
• 슬롯에는 커스텀 슬롯과 빌트인 슬롯 2가
지가 있습니다.
• 빌트인 슬롯은 아래와 같이 사람들이 이
미 인지하는 용어들을 모아둔 것으로, 사
용하겠다고 체크하면 편리하게 사용하실
수 있습니다.
• 집안의 다양한 장소들은 커스텀 슬
롯으로 등록합니다.
• IOT_TYPE
• 거실: 리빙룸
• 안방: 침실
• 부억: 키친
• 베란다
인터렉션 모델 등록하기 – 인텐트 등록
• 우측의 '사용중인 Intent' 옆의 + 버튼을 눌러서 ‘turnOnIntent’ 입력하고 '만들기' 버튼을 누릅
니다.
• 사용자 표현 리스트에 사용자들이 입력할 것 같은 대화들을 입력하는데, slot과 의도에 해당
하는 문장들은 다양하게 입력합니다.
• 문장의 가짓수는 많을 수록 더욱 대화의도 파악은 잘 됩니다.
• 거실 전등 켜줘
• 안방 불 켜줘
• 침실 점등 해줘
https://developers.naver.com/console/clova/guide/Design/
Design_Guideline_For_Extension.md#DefineInteractionMod
el
인터렉션 모델 등록하기 – 인텐트 슬롯 등록
• 사용자 표현 리스트에서 ’거실'이라는 단어를 드래그한 다음 앞에서 입력한 ‘homeSlotType’이란 이름
으로 매핑해줍니다.
• 매핑이 완료되면 Slot 에 해당하는 글씨들이 아래와 같이 하이라이트 됩니다.
인터렉션 모델 빌드하기
• ‘저장’ 버튼을 누른 다음
• 우측 상단의 '빌드' 버튼을 눌러 인터렉션 모델을 빌드합니다. 빌드가 완료되면 다시 '빌드'라는 버튼으로 바뀝니다.
인터렉션 모델 테스트
• 체크할 포인트는 인터렉션 모델에 등록한 문장과 비슷한 문장을 입력하더라도 slot과 intent값을 리턴하는지 확인하
는 것입니다.
• 예)
• 거실 전등 켜줘 (인터렉션 모델에 있는 문장)
• 부억 점등 해줘 (인터렉션 모델에 있는 문장과 비슷한 유형이지만, slot 이 다른 문장)
• 침실 불 켜줘 (비슷한 문장)
Clova extension 예제
구구단 놀이
• 개요
• 사용자가 구구단 곱셈의 정답을 맞추는 게임
• 실행 방법
• 시작: “구구단 놀이 시작해줘”
• 구구단 단수 변경: 다른 단수를 말하면 해당 단수로 변경
구구단놀이
• 인터렉션 모델
• Intent
• 게임시작 – gugudanPlay
• 사용자 대답 – gugudanAnswer
• slot
• 숫자 – dan (built-in number slot)
업다운
• 개요
• 사용자가 1~100사이 숫자를 맞추는 게임
• 실행 방법
• 시작: “업다운 시작해줘”
• 사용자가 대답한 숫자가 크면 up, 숫자가 작으면 down이라는 힌
트를 줌
업다운
• 인터렉션 모델
• Intent
• 게임시작 – playGameIntent
• 사용자 대답 -
numberAnswerIntent
• slot
• 숫자 – numberAnswer (built-in
number slot)
나라수도맞추기
• 개요
• 사용자가 특정 국가의 수도 도시명을 맞추는 게임
• 실행 방법
• 시작: “나라수도맞추기 시작해줘”
• 난이도 조절: 1단계 ~ 3단계로 조정가능
• 1단계는 누구가 잘 아는 나라
• 3단계는 잘 모르는 나라
나라수도맞추기
• 인터렉션 모델
• Intent
• 게임시작 – playGameIntent
• 사용자 대답 – answerIntent
• 점수 확인 - getScoreIntent
• slot
• 숫자 – city (도시명입력)
Clova extension 서버 API 개발
서버가 처리해야할 작업 - 1
• Clova 요청 메시지의 request type에 따라 지정된 포맷의 응답 리
턴
• Request type
• LaunchRequest : 익스텐션의 시작 (“짱구박사 시작해줘” 했을 경우)
• SessionEndedRequest : 익스텐션의 종료 (“종료해줘” )
• IntentRequest
• Custom Intent  개발자 콘솔에 입력한 Intent 와 Slot
• Built-in Intent 
https://developers.naver.com/console/clova/guide/CEK/References/CEK_API.md#cek-api-레퍼
런스
서버가 처리해야할 작업 – 2
https://developers.naver.com/console/clova/
guide/CEK/References/CEK_API.md#cek-
api-레퍼런스
응답메시지 구조
서버가 처리해야할 작업 – 3
• 멀티턴 처리
• 응답 메시지의 shouldEndSession은 false
• 계속 유지해야 할 값은 sessionAttribute에 담아서 전송
http://stg.developers.naver.com/console/clova/guide/
CEK/Guides/Build_Custom_Extension.md#DoMultiturn
Dialog
개발 환경 구성
• 개발 도구
• IntelliJ ( with Java )
• 프로젝트 생성
• Spring Initializr로 프로젝트 생성
• 프로젝트 설정
• pom에 api test (rest-assured)에 필요한 dependency 설정
Cloud Functions & CEK
4 / 30
Action
(code)
만들기
CEK URL 등록
NCP
회원 가입
Microservice on Serverless
- UI에서 바로 작성하고 서비스를 배포하는 것이 가능
- 웹 액션으로 만들고 API Gateway를 통해 end-point 설정 및 CEK 연동
Cloud Functions & CEK
Microservice on Serverless
- UI에서 바로 작성하고 서비스를 배포하는 것이 가능
- 웹 액션으로 만들고 API Gateway를 통해 end-point 설정 및 CEK 연동
Cloud Functions & CEK
Cloud Functions & CEK
4 / 30
Action
Cloud Functions & CEK
4 / 30
Action create
Cloud Functions & CEK
Action 실행
https://github.com/naver/clova-extension-sample-rainsound/blob/github-
public/clova/index.js
Cloud Functions & CEK
Node.js 수정
1) 1개의 js 파일로 (include제거 및 관련 변수치환)
2) api 처리하는 부분을 main function으로
const uuid = require('uuid').v4
const _ = require('lodash')
//const { DOMAIN } = require('../config')
Cloud Functions & CEK
Node.js 코드 입력 및 Default parameter 수정
Default parameter
{
"version": "0.1.0",
"session": {
"sessionId": "7b1652d1-5e44-4f4b-9769-ea2f1190cc6f",
"user": {
"userId": "Gz1xLLqxROGBWE71SDN_gQ",
"accessToken": "07c8d684-a2a9-4147-8abc-8a2e2dc50ef0"
},
"new": true
},
"context": {
"System": {
"user": {
"userId": "Gz1xLLqxROGBWE71SDN_gQ",
"accessToken": "07c8d684-a2a9-4147-8abc-8a2e2dc50ef0"
},
"device": {
"deviceId": "7609cb94-eec5-4728-b07b-271d32e188b0",
"display": {
"size": "l100",
"orientation": "landscape",
"dpi": 96,
"contentLayer": {
"width": 640,
"height": 360
}
}
}
}
},
"request": {
"type": "IntentRequest",
"intent": {
"name": "PlayLoopIntent",
"slots": {
"loopCount": {
"name": "loopCount",
"value": "2"
}
}
}
}
}
clearMultiturn() {
this.response.shouldEndSession = true
this.sessionAttributes = {}
}
addDirective(directive) {
this.response.directives.push(directive)
}
setSimpleSpeechText(outputText) {
this.response.outputSpeech = {
type: "SimpleSpeech",
values: {
type: "PlainText",
lang: "ko",
value: outputText,
},
}
}
appendSpeechText(outputText) {
const outputSpeech = this.response.outputSpeech
if (outputSpeech.type != 'SpeechList') {
outputSpeech.type = 'SpeechList'
outputSpeech.values = []
}
if (typeof(outputText) == 'string') {
outputSpeech.values.push({
type: 'PlainText',
lang: 'ko',
value: outputText,
})
} else {
outputSpeech.values.push(outputText)
}
}
}
function main(params) {
const httpReq = {"body": params}
cekResponse = new CEKResponse()
cekRequest = new CEKRequest(httpReq)
cekRequest.do(cekResponse)
return cekResponse
};
intentRequest(cekResponse) {
console.log('intentRequest')
console.log(JSON.stringify(this.request))
const intent = this.request.intent.name
const slots = this.request.intent.slots
switch (intent) {
case "PlayIntent":
case "PlayLoopIntent":
let loopCount
const loopCountSlot = slots.loopCount
if (intent == "PlayIntent") {
loopCount = 1
} else if (slots.length == 0 || !loopCountSlot) {
loopCount = 3
} else {
loopCount = parseInt(loopCountSlot.value)
}
if (loopCount == 1) {
cekResponse.appendSpeechText("빗소리를 재생합니다.")
} else {
cekResponse.appendSpeechText(`빗소리를 ${loopCount}번 재생합니다.`)
}
for (let i = 0; i < loopCount; i++) {
cekResponse.addDirective(audioDirective())
}
break
case "Clova.GuideIntent":
cekResponse.appendSpeechText("죄송해요. 이해할 수 없습니다.")
cekResponse.appendSpeechText("빗소리 틀어줘, 라고 시도해보세요.")
break;
}
}
sessionEndedRequest(cekResponse) {
console.log('sessionEndedRequest')
cekResponse.setSimpleSpeechText("빗소리 익스텐션을 종료합니다.")
cekResponse.clearMultiturn()
}
}
class CEKResponse {
constructor () {
this.response = {
directives: [],
shouldEndSession: true,
outputSpeech: {},
}
this.version = "0.1.0"
this.sessionAttributes = {}
}
setMultiturn(sessionAttributes) {
this.response.shouldEndSession = false
this.sessionAttributes = _.assign(this.sessionAttributes, sessionAttributes)
}
const uuid = require('uuid').v4
const _ = require('lodash')
//const { DOMAIN } = require('../config')
class Directive {
constructor({namespace, name, payload}) {
this.header = {
messageId: uuid(),
namespace: namespace,
name: name,
}
this.payload = payload
}
}
function audioDirective() {
episodeId = Math.floor(Math.random() * 1000)
return new Directive({
namespace: 'AudioPlayer',
name: 'Play',
payload: {
audioItem: {
audioItemId: uuid(),
stream: {
beginAtInMilliseconds: 0,
playType: "NONE",
token: uuid(),
url: `http://**********/rainning_sound.mp3`,
urlPlayable: true
},
// type: "custom",
},
playBehavior: "REPLACE_ALL",
source: {
logoUrl: `http://**********/img_sound_rain_108.png`,
name: "소리 시리즈"
}
}
})
}
class CEKRequest {
constructor (httpReq) {
this.request = httpReq.body.request
this.context = httpReq.body.context
this.session = httpReq.body.session
}
do(cekResponse) {
switch (this.request.type) {
case "LaunchRequest":
return this.launchRequest(cekResponse)
case "IntentRequest":
return this.intentRequest(cekResponse)
case "SessionEndedRequest":
return this.sessionEndedRequest(cekResponse)
}
}
launchRequest(cekResponse) {
console.log('launchRequest')
cekResponse.appendSpeechText("빗소리를 재생합니다.")
cekResponse.addDirective(audioDirective())
}
Node.js 코드 – 빗소리
https://github.com/okgosu/CEK-CloudFunction-Exam
Cloud Functions & CEK
액션실행
Cloud Function Server 주소 설정
Clova 앱과 스피커에서 익스텐션 호출 테스트
테스트 단계
• 개발자 콘솔에 test할 네이버 계정 등록
• 음성 테스트 방법1 – Clova 앱
• Clova 앱에 해당 아이디로 로그인 후
•  “짱구박사 시작해줘” 라고 했을 때 익스텐션 서버로 LaunchRequest가 오는지, 익스텐션의 응답이 음성으로 나가는지 확인
• 음성 테스트 방법2 – Friends 스피커
• 테스터로 등록된 아이디로 Clova앱을 이용해서 스피커 설정
•  “짱구박사 시작해줘” 라고 했을 때 익스텐션 서버로 LaunchRequest가 오는지, 익스텐션의 응답이 음성으로 나가는지 확인
Appendix.
• Clova 플랫폼 개발자 문서 : https://developers.naver.com/console/clova/guide/
• Design 챕터 / Clova Extensions Kit 챕터 / Clova Developer Console 챕터 참고
• 튜토리얼 및 샘플 코드 참고
• 샘플 코드 Github
• 마법 구슬 : https://github.com/naver/clova-extension-sample-magicball
• 빗소리 : https://github.com/naver/clova-extension-sample-rainsound
• 주사위 놀이 : https://github.com/naver/clova-extension-sample-dice
• 코인 헬퍼 : https://github.com/naver/clova-extension-sample-coinhelper

More Related Content

What's hot

Chatbot Extension 개요 및 사용법
Chatbot Extension 개요 및 사용법Chatbot Extension 개요 및 사용법
Chatbot Extension 개요 및 사용법Clova Platform
 
Python 으로 Slackbot 개발하기
Python 으로 Slackbot 개발하기Python 으로 Slackbot 개발하기
Python 으로 Slackbot 개발하기성일 한
 
iFun Engine plugin 만들기 (for Stingray)
iFun Engine plugin 만들기 (for Stingray) iFun Engine plugin 만들기 (for Stingray)
iFun Engine plugin 만들기 (for Stingray) iFunFactory Inc.
 
iFunEngine: 30분 만에 게임 서버 만들기
iFunEngine: 30분 만에 게임 서버 만들기iFunEngine: 30분 만에 게임 서버 만들기
iFunEngine: 30분 만에 게임 서버 만들기iFunFactory Inc.
 
[IGC2018] 에이스프로젝트 안현석 - 유니티로 실시간 멀티플레이 게임서버를 만들수 있을까
[IGC2018] 에이스프로젝트 안현석 - 유니티로 실시간 멀티플레이 게임서버를 만들수 있을까[IGC2018] 에이스프로젝트 안현석 - 유니티로 실시간 멀티플레이 게임서버를 만들수 있을까
[IGC2018] 에이스프로젝트 안현석 - 유니티로 실시간 멀티플레이 게임서버를 만들수 있을까영석 양
 
유연하게 확장할 수 있는 PHP 웹 개발 이야기
유연하게 확장할 수 있는 PHP 웹 개발 이야기유연하게 확장할 수 있는 PHP 웹 개발 이야기
유연하게 확장할 수 있는 PHP 웹 개발 이야기Young D
 
[2017 Incognito] Code Clone 기법을 통한 모바일 브라우저 취약점 분석
[2017 Incognito] Code Clone 기법을 통한 모바일 브라우저 취약점 분석[2017 Incognito] Code Clone 기법을 통한 모바일 브라우저 취약점 분석
[2017 Incognito] Code Clone 기법을 통한 모바일 브라우저 취약점 분석NAVER D2
 
Netty 시작하기 (1)
Netty 시작하기 (1)Netty 시작하기 (1)
Netty 시작하기 (1)Daehyun Kim
 
맛만 보자 Undertow
맛만 보자 Undertow맛만 보자 Undertow
맛만 보자 Undertowjbugkorea
 
[아이펀팩토리]2017 NDC 강연 자료_아이펀 엔진 개발 노트
[아이펀팩토리]2017 NDC 강연 자료_아이펀 엔진 개발 노트[아이펀팩토리]2017 NDC 강연 자료_아이펀 엔진 개발 노트
[아이펀팩토리]2017 NDC 강연 자료_아이펀 엔진 개발 노트iFunFactory Inc.
 
PHP로 Slack Bot 만들기
PHP로 Slack Bot 만들기PHP로 Slack Bot 만들기
PHP로 Slack Bot 만들기Changwan Jun
 
[141] 오픈소스를 쓰려는 자, 리베이스의 무게를 견뎌라
[141] 오픈소스를 쓰려는 자, 리베이스의 무게를 견뎌라[141] 오픈소스를 쓰려는 자, 리베이스의 무게를 견뎌라
[141] 오픈소스를 쓰려는 자, 리베이스의 무게를 견뎌라NAVER D2
 
[NDC2017 : 박준철] Python 게임 서버 안녕하십니까 - 몬스터 슈퍼리그 게임 서버
[NDC2017 : 박준철] Python 게임 서버 안녕하십니까 - 몬스터 슈퍼리그 게임 서버[NDC2017 : 박준철] Python 게임 서버 안녕하십니까 - 몬스터 슈퍼리그 게임 서버
[NDC2017 : 박준철] Python 게임 서버 안녕하십니까 - 몬스터 슈퍼리그 게임 서버준철 박
 
NDC14 범용 게임 서버 프레임워크 디자인 및 테크닉
NDC14 범용 게임 서버 프레임워크 디자인 및 테크닉NDC14 범용 게임 서버 프레임워크 디자인 및 테크닉
NDC14 범용 게임 서버 프레임워크 디자인 및 테크닉iFunFactory Inc.
 
서버학개론(백엔드 서버 개발자를 위한)
서버학개론(백엔드 서버 개발자를 위한)서버학개론(백엔드 서버 개발자를 위한)
서버학개론(백엔드 서버 개발자를 위한)수보 김
 

What's hot (16)

Chatbot Extension 개요 및 사용법
Chatbot Extension 개요 및 사용법Chatbot Extension 개요 및 사용법
Chatbot Extension 개요 및 사용법
 
Python 으로 Slackbot 개발하기
Python 으로 Slackbot 개발하기Python 으로 Slackbot 개발하기
Python 으로 Slackbot 개발하기
 
iFun Engine plugin 만들기 (for Stingray)
iFun Engine plugin 만들기 (for Stingray) iFun Engine plugin 만들기 (for Stingray)
iFun Engine plugin 만들기 (for Stingray)
 
iFunEngine: 30분 만에 게임 서버 만들기
iFunEngine: 30분 만에 게임 서버 만들기iFunEngine: 30분 만에 게임 서버 만들기
iFunEngine: 30분 만에 게임 서버 만들기
 
[IGC2018] 에이스프로젝트 안현석 - 유니티로 실시간 멀티플레이 게임서버를 만들수 있을까
[IGC2018] 에이스프로젝트 안현석 - 유니티로 실시간 멀티플레이 게임서버를 만들수 있을까[IGC2018] 에이스프로젝트 안현석 - 유니티로 실시간 멀티플레이 게임서버를 만들수 있을까
[IGC2018] 에이스프로젝트 안현석 - 유니티로 실시간 멀티플레이 게임서버를 만들수 있을까
 
유연하게 확장할 수 있는 PHP 웹 개발 이야기
유연하게 확장할 수 있는 PHP 웹 개발 이야기유연하게 확장할 수 있는 PHP 웹 개발 이야기
유연하게 확장할 수 있는 PHP 웹 개발 이야기
 
[2017 Incognito] Code Clone 기법을 통한 모바일 브라우저 취약점 분석
[2017 Incognito] Code Clone 기법을 통한 모바일 브라우저 취약점 분석[2017 Incognito] Code Clone 기법을 통한 모바일 브라우저 취약점 분석
[2017 Incognito] Code Clone 기법을 통한 모바일 브라우저 취약점 분석
 
Netty 시작하기 (1)
Netty 시작하기 (1)Netty 시작하기 (1)
Netty 시작하기 (1)
 
Modern PHP
Modern PHPModern PHP
Modern PHP
 
맛만 보자 Undertow
맛만 보자 Undertow맛만 보자 Undertow
맛만 보자 Undertow
 
[아이펀팩토리]2017 NDC 강연 자료_아이펀 엔진 개발 노트
[아이펀팩토리]2017 NDC 강연 자료_아이펀 엔진 개발 노트[아이펀팩토리]2017 NDC 강연 자료_아이펀 엔진 개발 노트
[아이펀팩토리]2017 NDC 강연 자료_아이펀 엔진 개발 노트
 
PHP로 Slack Bot 만들기
PHP로 Slack Bot 만들기PHP로 Slack Bot 만들기
PHP로 Slack Bot 만들기
 
[141] 오픈소스를 쓰려는 자, 리베이스의 무게를 견뎌라
[141] 오픈소스를 쓰려는 자, 리베이스의 무게를 견뎌라[141] 오픈소스를 쓰려는 자, 리베이스의 무게를 견뎌라
[141] 오픈소스를 쓰려는 자, 리베이스의 무게를 견뎌라
 
[NDC2017 : 박준철] Python 게임 서버 안녕하십니까 - 몬스터 슈퍼리그 게임 서버
[NDC2017 : 박준철] Python 게임 서버 안녕하십니까 - 몬스터 슈퍼리그 게임 서버[NDC2017 : 박준철] Python 게임 서버 안녕하십니까 - 몬스터 슈퍼리그 게임 서버
[NDC2017 : 박준철] Python 게임 서버 안녕하십니까 - 몬스터 슈퍼리그 게임 서버
 
NDC14 범용 게임 서버 프레임워크 디자인 및 테크닉
NDC14 범용 게임 서버 프레임워크 디자인 및 테크닉NDC14 범용 게임 서버 프레임워크 디자인 및 테크닉
NDC14 범용 게임 서버 프레임워크 디자인 및 테크닉
 
서버학개론(백엔드 서버 개발자를 위한)
서버학개론(백엔드 서버 개발자를 위한)서버학개론(백엔드 서버 개발자를 위한)
서버학개론(백엔드 서버 개발자를 위한)
 

Similar to Clova Extension 음성기반 게임 기획 및 설계 / FaaS를 이용한 개발

Clova 플랫폼을 활용한 인공지능 서비스 개발
Clova 플랫폼을 활용한 인공지능 서비스 개발Clova 플랫폼을 활용한 인공지능 서비스 개발
Clova 플랫폼을 활용한 인공지능 서비스 개발Clova Platform
 
Clova extension에서 OAuth 계정 연동 구현
Clova extension에서 OAuth 계정 연동 구현Clova extension에서 OAuth 계정 연동 구현
Clova extension에서 OAuth 계정 연동 구현Gosu Ok
 
[112]clova platform 인공지능을 엮는 기술
[112]clova platform 인공지능을 엮는 기술[112]clova platform 인공지능을 엮는 기술
[112]clova platform 인공지능을 엮는 기술NAVER D2
 
Dropbox와 같은 시스템은 파일을 어떻게 저장할까?
Dropbox와 같은 시스템은 파일을 어떻게 저장할까?Dropbox와 같은 시스템은 파일을 어떻게 저장할까?
Dropbox와 같은 시스템은 파일을 어떻게 저장할까?nexusz99
 
20180602 BIT computer - AWS를 활용한 클라우드 기반 웹 개발 1주차
20180602 BIT computer - AWS를 활용한 클라우드 기반 웹 개발 1주차20180602 BIT computer - AWS를 활용한 클라우드 기반 웹 개발 1주차
20180602 BIT computer - AWS를 활용한 클라우드 기반 웹 개발 1주차Jongwon Han
 
서버리스(Serverless)를 위한 Zombie Microservices Workshop 실습 가이드 :: 윤석찬 (AWS 테크에반젤...
서버리스(Serverless)를 위한 Zombie Microservices Workshop 실습  가이드 ::  윤석찬 (AWS 테크에반젤...서버리스(Serverless)를 위한 Zombie Microservices Workshop 실습  가이드 ::  윤석찬 (AWS 테크에반젤...
서버리스(Serverless)를 위한 Zombie Microservices Workshop 실습 가이드 :: 윤석찬 (AWS 테크에반젤...Amazon Web Services Korea
 
셸 스크립트를 이용한 클라우드 시스템 운영
셸 스크립트를 이용한 클라우드 시스템 운영셸 스크립트를 이용한 클라우드 시스템 운영
셸 스크립트를 이용한 클라우드 시스템 운영Nalee Jang
 
AWS CLOUD 2018- 관리형 Kubernetes 지원과 새로운 컨테이너 서비스 Amazon Fargate 소개 (정영준 솔루션즈 아...
AWS CLOUD 2018- 관리형 Kubernetes 지원과 새로운 컨테이너 서비스 Amazon Fargate 소개 (정영준 솔루션즈 아...AWS CLOUD 2018- 관리형 Kubernetes 지원과 새로운 컨테이너 서비스 Amazon Fargate 소개 (정영준 솔루션즈 아...
AWS CLOUD 2018- 관리형 Kubernetes 지원과 새로운 컨테이너 서비스 Amazon Fargate 소개 (정영준 솔루션즈 아...Amazon Web Services Korea
 
20170813 django api server unit test and remote debugging
20170813 django api server unit test and remote debugging20170813 django api server unit test and remote debugging
20170813 django api server unit test and remote debuggingJongwon Han
 
20180609 BIT computer - AWS를 활용한 클라우드 기반 웹 개발 2주차
20180609 BIT computer - AWS를 활용한 클라우드 기반 웹 개발 2주차20180609 BIT computer - AWS를 활용한 클라우드 기반 웹 개발 2주차
20180609 BIT computer - AWS를 활용한 클라우드 기반 웹 개발 2주차Jongwon Han
 
Packer, Terraform, Vault를 이용해 만드는 
재현 가능한 게임 인프라
Packer, Terraform, Vault를 이용해 만드는 
재현 가능한 게임 인프라Packer, Terraform, Vault를 이용해 만드는 
재현 가능한 게임 인프라
Packer, Terraform, Vault를 이용해 만드는 
재현 가능한 게임 인프라MinKyu Kim
 
AWS Community Day 2022 - Nitro Enclave를 이용하여 안전하게 고객 정보 다...
AWS Community Day 2022 - Nitro Enclave를 이용하여 안전하게 고객 정보 다...AWS Community Day 2022 - Nitro Enclave를 이용하여 안전하게 고객 정보 다...
AWS Community Day 2022 - Nitro Enclave를 이용하여 안전하게 고객 정보 다...JooHyung Kim
 
모바일 게임 하이브 런칭기 - 최용호
모바일 게임 하이브 런칭기 - 최용호모바일 게임 하이브 런칭기 - 최용호
모바일 게임 하이브 런칭기 - 최용호용호 최
 
Python으로 채팅 구현하기
Python으로 채팅 구현하기Python으로 채팅 구현하기
Python으로 채팅 구현하기Tae Young Lee
 
[NDC18] 만들고 붓고 부수고 - 〈야생의 땅: 듀랑고〉 서버 관리 배포 이야기
[NDC18] 만들고 붓고 부수고 - 〈야생의 땅: 듀랑고〉 서버 관리 배포 이야기[NDC18] 만들고 붓고 부수고 - 〈야생의 땅: 듀랑고〉 서버 관리 배포 이야기
[NDC18] 만들고 붓고 부수고 - 〈야생의 땅: 듀랑고〉 서버 관리 배포 이야기Chanwoong Kim
 
[NDC17] Kubernetes로 개발서버 간단히 찍어내기
[NDC17] Kubernetes로 개발서버 간단히 찍어내기[NDC17] Kubernetes로 개발서버 간단히 찍어내기
[NDC17] Kubernetes로 개발서버 간단히 찍어내기SeungYong Oh
 
AWS Code 서비스 특집 - 아마존 DevOps와 CodeDeploy, CodePipeline (윤석찬)
AWS Code 서비스 특집 - 아마존 DevOps와 CodeDeploy, CodePipeline (윤석찬)AWS Code 서비스 특집 - 아마존 DevOps와 CodeDeploy, CodePipeline (윤석찬)
AWS Code 서비스 특집 - 아마존 DevOps와 CodeDeploy, CodePipeline (윤석찬)Amazon Web Services Korea
 
Elastic beanstalk - 판교 초급자 모임 - 안병학
Elastic beanstalk - 판교 초급자 모임 - 안병학Elastic beanstalk - 판교 초급자 모임 - 안병학
Elastic beanstalk - 판교 초급자 모임 - 안병학Byeong-hak An
 

Similar to Clova Extension 음성기반 게임 기획 및 설계 / FaaS를 이용한 개발 (20)

Clova 플랫폼을 활용한 인공지능 서비스 개발
Clova 플랫폼을 활용한 인공지능 서비스 개발Clova 플랫폼을 활용한 인공지능 서비스 개발
Clova 플랫폼을 활용한 인공지능 서비스 개발
 
Clova extension에서 OAuth 계정 연동 구현
Clova extension에서 OAuth 계정 연동 구현Clova extension에서 OAuth 계정 연동 구현
Clova extension에서 OAuth 계정 연동 구현
 
[112]clova platform 인공지능을 엮는 기술
[112]clova platform 인공지능을 엮는 기술[112]clova platform 인공지능을 엮는 기술
[112]clova platform 인공지능을 엮는 기술
 
Dropbox와 같은 시스템은 파일을 어떻게 저장할까?
Dropbox와 같은 시스템은 파일을 어떻게 저장할까?Dropbox와 같은 시스템은 파일을 어떻게 저장할까?
Dropbox와 같은 시스템은 파일을 어떻게 저장할까?
 
20180602 BIT computer - AWS를 활용한 클라우드 기반 웹 개발 1주차
20180602 BIT computer - AWS를 활용한 클라우드 기반 웹 개발 1주차20180602 BIT computer - AWS를 활용한 클라우드 기반 웹 개발 1주차
20180602 BIT computer - AWS를 활용한 클라우드 기반 웹 개발 1주차
 
서버리스(Serverless)를 위한 Zombie Microservices Workshop 실습 가이드 :: 윤석찬 (AWS 테크에반젤...
서버리스(Serverless)를 위한 Zombie Microservices Workshop 실습  가이드 ::  윤석찬 (AWS 테크에반젤...서버리스(Serverless)를 위한 Zombie Microservices Workshop 실습  가이드 ::  윤석찬 (AWS 테크에반젤...
서버리스(Serverless)를 위한 Zombie Microservices Workshop 실습 가이드 :: 윤석찬 (AWS 테크에반젤...
 
셸 스크립트를 이용한 클라우드 시스템 운영
셸 스크립트를 이용한 클라우드 시스템 운영셸 스크립트를 이용한 클라우드 시스템 운영
셸 스크립트를 이용한 클라우드 시스템 운영
 
AWS CLOUD 2018- 관리형 Kubernetes 지원과 새로운 컨테이너 서비스 Amazon Fargate 소개 (정영준 솔루션즈 아...
AWS CLOUD 2018- 관리형 Kubernetes 지원과 새로운 컨테이너 서비스 Amazon Fargate 소개 (정영준 솔루션즈 아...AWS CLOUD 2018- 관리형 Kubernetes 지원과 새로운 컨테이너 서비스 Amazon Fargate 소개 (정영준 솔루션즈 아...
AWS CLOUD 2018- 관리형 Kubernetes 지원과 새로운 컨테이너 서비스 Amazon Fargate 소개 (정영준 솔루션즈 아...
 
20170813 django api server unit test and remote debugging
20170813 django api server unit test and remote debugging20170813 django api server unit test and remote debugging
20170813 django api server unit test and remote debugging
 
20180609 BIT computer - AWS를 활용한 클라우드 기반 웹 개발 2주차
20180609 BIT computer - AWS를 활용한 클라우드 기반 웹 개발 2주차20180609 BIT computer - AWS를 활용한 클라우드 기반 웹 개발 2주차
20180609 BIT computer - AWS를 활용한 클라우드 기반 웹 개발 2주차
 
Ansible과 CloudFormation을 이용한 배포 자동화
Ansible과 CloudFormation을 이용한 배포 자동화Ansible과 CloudFormation을 이용한 배포 자동화
Ansible과 CloudFormation을 이용한 배포 자동화
 
Packer, Terraform, Vault를 이용해 만드는 
재현 가능한 게임 인프라
Packer, Terraform, Vault를 이용해 만드는 
재현 가능한 게임 인프라Packer, Terraform, Vault를 이용해 만드는 
재현 가능한 게임 인프라
Packer, Terraform, Vault를 이용해 만드는 
재현 가능한 게임 인프라
 
쉽고 빠르게 접하는 오픈스택
쉽고 빠르게 접하는 오픈스택쉽고 빠르게 접하는 오픈스택
쉽고 빠르게 접하는 오픈스택
 
AWS Community Day 2022 - Nitro Enclave를 이용하여 안전하게 고객 정보 다...
AWS Community Day 2022 - Nitro Enclave를 이용하여 안전하게 고객 정보 다...AWS Community Day 2022 - Nitro Enclave를 이용하여 안전하게 고객 정보 다...
AWS Community Day 2022 - Nitro Enclave를 이용하여 안전하게 고객 정보 다...
 
모바일 게임 하이브 런칭기 - 최용호
모바일 게임 하이브 런칭기 - 최용호모바일 게임 하이브 런칭기 - 최용호
모바일 게임 하이브 런칭기 - 최용호
 
Python으로 채팅 구현하기
Python으로 채팅 구현하기Python으로 채팅 구현하기
Python으로 채팅 구현하기
 
[NDC18] 만들고 붓고 부수고 - 〈야생의 땅: 듀랑고〉 서버 관리 배포 이야기
[NDC18] 만들고 붓고 부수고 - 〈야생의 땅: 듀랑고〉 서버 관리 배포 이야기[NDC18] 만들고 붓고 부수고 - 〈야생의 땅: 듀랑고〉 서버 관리 배포 이야기
[NDC18] 만들고 붓고 부수고 - 〈야생의 땅: 듀랑고〉 서버 관리 배포 이야기
 
[NDC17] Kubernetes로 개발서버 간단히 찍어내기
[NDC17] Kubernetes로 개발서버 간단히 찍어내기[NDC17] Kubernetes로 개발서버 간단히 찍어내기
[NDC17] Kubernetes로 개발서버 간단히 찍어내기
 
AWS Code 서비스 특집 - 아마존 DevOps와 CodeDeploy, CodePipeline (윤석찬)
AWS Code 서비스 특집 - 아마존 DevOps와 CodeDeploy, CodePipeline (윤석찬)AWS Code 서비스 특집 - 아마존 DevOps와 CodeDeploy, CodePipeline (윤석찬)
AWS Code 서비스 특집 - 아마존 DevOps와 CodeDeploy, CodePipeline (윤석찬)
 
Elastic beanstalk - 판교 초급자 모임 - 안병학
Elastic beanstalk - 판교 초급자 모임 - 안병학Elastic beanstalk - 판교 초급자 모임 - 안병학
Elastic beanstalk - 판교 초급자 모임 - 안병학
 

More from Clova Platform

Clova ai-business-day-session-3
Clova ai-business-day-session-3Clova ai-business-day-session-3
Clova ai-business-day-session-3Clova Platform
 
Clova ai-business-day-session-4
Clova ai-business-day-session-4Clova ai-business-day-session-4
Clova ai-business-day-session-4Clova Platform
 
Clova ai-business-day-session-2
Clova ai-business-day-session-2Clova ai-business-day-session-2
Clova ai-business-day-session-2Clova Platform
 
Clova ai-business-day-session-1
Clova ai-business-day-session-1Clova ai-business-day-session-1
Clova ai-business-day-session-1Clova Platform
 
Clova Skill 에서 AudioPlayer 구현
Clova Skill 에서 AudioPlayer 구현Clova Skill 에서 AudioPlayer 구현
Clova Skill 에서 AudioPlayer 구현Clova Platform
 
Clova Tech Summit 2: Serverless로 만드는 쉽고 효율적인 Clova Extension 2
Clova Tech Summit 2: Serverless로 만드는 쉽고 효율적인 Clova Extension 2Clova Tech Summit 2: Serverless로 만드는 쉽고 효율적인 Clova Extension 2
Clova Tech Summit 2: Serverless로 만드는 쉽고 효율적인 Clova Extension 2Clova Platform
 
Clova Tech Summit 2: Serverless로 만드는 쉽고 효율적인 Clova Extension 1
Clova Tech Summit 2: Serverless로 만드는 쉽고 효율적인 Clova Extension 1Clova Tech Summit 2: Serverless로 만드는 쉽고 효율적인 Clova Extension 1
Clova Tech Summit 2: Serverless로 만드는 쉽고 효율적인 Clova Extension 1Clova Platform
 
Clova Tech Summit 2: 대화모델 엔진 구조와 Chatbot 개발 최적화 방안
Clova Tech Summit 2: 대화모델 엔진 구조와 Chatbot 개발 최적화 방안Clova Tech Summit 2: 대화모델 엔진 구조와 Chatbot 개발 최적화 방안
Clova Tech Summit 2: 대화모델 엔진 구조와 Chatbot 개발 최적화 방안Clova Platform
 
Clova Tech Summit 2: Interaction Model의 이해 및 설계/제작 노하우
Clova Tech Summit 2: Interaction Model의 이해 및 설계/제작 노하우Clova Tech Summit 2: Interaction Model의 이해 및 설계/제작 노하우
Clova Tech Summit 2: Interaction Model의 이해 및 설계/제작 노하우Clova Platform
 
Clova Tech Summit 세션4 : 우아한형제들 배달의민족 Clova Extension 개발기
Clova Tech Summit 세션4 : 우아한형제들 배달의민족 Clova Extension 개발기Clova Tech Summit 세션4 : 우아한형제들 배달의민족 Clova Extension 개발기
Clova Tech Summit 세션4 : 우아한형제들 배달의민족 Clova Extension 개발기Clova Platform
 
Clova Tech Summit 세션2 : 띵스플로우 라마마 Clova Extension 개발기
Clova Tech Summit 세션2 : 띵스플로우 라마마 Clova Extension 개발기Clova Tech Summit 세션2 : 띵스플로우 라마마 Clova Extension 개발기
Clova Tech Summit 세션2 : 띵스플로우 라마마 Clova Extension 개발기Clova Platform
 

More from Clova Platform (11)

Clova ai-business-day-session-3
Clova ai-business-day-session-3Clova ai-business-day-session-3
Clova ai-business-day-session-3
 
Clova ai-business-day-session-4
Clova ai-business-day-session-4Clova ai-business-day-session-4
Clova ai-business-day-session-4
 
Clova ai-business-day-session-2
Clova ai-business-day-session-2Clova ai-business-day-session-2
Clova ai-business-day-session-2
 
Clova ai-business-day-session-1
Clova ai-business-day-session-1Clova ai-business-day-session-1
Clova ai-business-day-session-1
 
Clova Skill 에서 AudioPlayer 구현
Clova Skill 에서 AudioPlayer 구현Clova Skill 에서 AudioPlayer 구현
Clova Skill 에서 AudioPlayer 구현
 
Clova Tech Summit 2: Serverless로 만드는 쉽고 효율적인 Clova Extension 2
Clova Tech Summit 2: Serverless로 만드는 쉽고 효율적인 Clova Extension 2Clova Tech Summit 2: Serverless로 만드는 쉽고 효율적인 Clova Extension 2
Clova Tech Summit 2: Serverless로 만드는 쉽고 효율적인 Clova Extension 2
 
Clova Tech Summit 2: Serverless로 만드는 쉽고 효율적인 Clova Extension 1
Clova Tech Summit 2: Serverless로 만드는 쉽고 효율적인 Clova Extension 1Clova Tech Summit 2: Serverless로 만드는 쉽고 효율적인 Clova Extension 1
Clova Tech Summit 2: Serverless로 만드는 쉽고 효율적인 Clova Extension 1
 
Clova Tech Summit 2: 대화모델 엔진 구조와 Chatbot 개발 최적화 방안
Clova Tech Summit 2: 대화모델 엔진 구조와 Chatbot 개발 최적화 방안Clova Tech Summit 2: 대화모델 엔진 구조와 Chatbot 개발 최적화 방안
Clova Tech Summit 2: 대화모델 엔진 구조와 Chatbot 개발 최적화 방안
 
Clova Tech Summit 2: Interaction Model의 이해 및 설계/제작 노하우
Clova Tech Summit 2: Interaction Model의 이해 및 설계/제작 노하우Clova Tech Summit 2: Interaction Model의 이해 및 설계/제작 노하우
Clova Tech Summit 2: Interaction Model의 이해 및 설계/제작 노하우
 
Clova Tech Summit 세션4 : 우아한형제들 배달의민족 Clova Extension 개발기
Clova Tech Summit 세션4 : 우아한형제들 배달의민족 Clova Extension 개발기Clova Tech Summit 세션4 : 우아한형제들 배달의민족 Clova Extension 개발기
Clova Tech Summit 세션4 : 우아한형제들 배달의민족 Clova Extension 개발기
 
Clova Tech Summit 세션2 : 띵스플로우 라마마 Clova Extension 개발기
Clova Tech Summit 세션2 : 띵스플로우 라마마 Clova Extension 개발기Clova Tech Summit 세션2 : 띵스플로우 라마마 Clova Extension 개발기
Clova Tech Summit 세션2 : 띵스플로우 라마마 Clova Extension 개발기
 

Clova Extension 음성기반 게임 기획 및 설계 / FaaS를 이용한 개발

  • 1. FaaS를 이용한 Clova Extension 개발 Clova Platform Evangelist 옥상훈 2018-06-28 발표자료: https://www.slideshare.net/ClovaPlatform/ Clova 스피커용 음성게임 예제 – 구구단놀이, 나라수도맞추기, 업다운
  • 2. 목차 • Clova Platform & extension 개요 • Clova extension 개발 준비 개요 • Clova extension 기획 • 인터렉션모델 • 음성기반 게임 예제 – 구구단놀이, 나라수도맞추기, 업다운 • Cloud Function 및 Clova extension 서버 API 개발 • Clova 앱과 스피커에서 익스텐션 호출 테스트
  • 3. Clova Plaform & extension 개요
  • 6. Clova Interface Connect 적용 사례 LG U+ 블루콤 스피커 LG 전자 스마트씽큐 LG전자 가전기기 제어가능IoT 제품 제어가능
  • 7. LG U+ IPTV STB - LG U+ IPTV UHD급 이상의 STB 내 Clova 제공 (2017년 12월 적용) 시청 중, 리모콘 side음성버튼 or (음성) LGU플러스야 로 음성명령 수행 ‘효리네민박 틀어줘’ ‘스릴러영화 추천해줘’전면 검색키> 전체화면모드, 클로바스러운 검색홈으로 제안 Clova Interface Connect 적용 사례
  • 8. Clova Interface Connect 적용 사례 (Friends +) 스피커로 '셋탑을 컨트롤' 할 수 있습니다. 브라운과 샐리에게 "유플티비"라는 호출어로 지시해보세요. "유플티비, 눈물 쏙 빼는 영화 찾아줘" "유플티비, tvN 틀어줘"
  • 10. Clova extension 이란? • Clova 플랫폼에서 작동하는 3rd party 애플리케이션으로서, 예를 들면 음성명령으로 음악을 재생하거나 쇼핑, IoT기기 제어 등이 가능합니다. • 사용자의 의도(예: 음성명령)에 따라 extension이 정확하게 동작할 수 있도록 Clova 플랫폼 내부적으로 음성인식, 대화분석 등 Clova 인공지능 기술이 적용되어 있습니다.
  • 11. extension으로 무엇을 할 수 있나요? • Extension 종류 • (서비스중) Custom extension: 3rd party 서버에서 제공하는 응답(예: 음성, 이미지 등)을 제공할 수 있습니다. • 예) "팟빵에서 뉴스공장 틀어줘" 라고 하면 "팟빵 extension"이 해당 음원을 들려줍니다. • (서비스중) Chatbot extension: 고객이 자주 묻는 질문(FAQ)과 답변을 등록하여 사업자 대신 챗봇이 답변을 하게 하는 extension입니다. • 예) ”네이버고객센터 실행해줘  네이버 쇼핑 가격 비교하는 방법 알려줄래?” • (제휴문의) Clova Home extension: IoT 기기제어가 가능 • 예) "클로바, TV 좀 켜줘" 라고 하면 클로바가 TV를 켭니다
  • 12. Clova extension 사례 – ‘체리쉬’ 모션베드제어 https://www.youtube.com/watch?v=kpkRRLWHySc 대표발화: 1) 체리쉬에게 자자 2) 체리쉬에게 무중력 모드 해줘 3) 체리쉬에게 첫번째 메모리 해줘
  • 13. Clova extension 사례 – ‘배송지킴이’ 택배조회 https://www.youtube.com/watch?v=27NWVG0yhTQ 대표발화: 1) 배송지키미 시작해줘 2) 배송지키미에서 내 택배 조회해줘 3) 배송지키미 내 택배 언제와
  • 14. Clova extension 사례 – ‘라마마’ 연애운 https://www.youtube.com/watch?v=uCqQem8_LyQ 대표발화: 1) 라마마 시작해줘 2) 라마마에게 연애운 물어봐줘 3) 라마마에게 남친 언제생길지 물어봐줘
  • 16. Clova 챗봇 extension 사례 – ‘멍멍이’ 동물소리 번역기 https://www.facebook.com/ClovaAI/photos/a.1639371196371443.1073741828.1637903373184892/17833965653022 38/ 대표발화: 1) 멍멍이 시작해줘
  • 17. Clova extension 개발 준비 개요
  • 18. Clova extension 개발 준비 – 1 (필수) • 익스텐션서버 • REST API 서버로서, Clova platform은 Clova console에 등록한 REST API 서버URL로 응답과 요 청을 주고 받습니다. • Clova platform은 1) 익스텐션 실행 2) 인텐트 실행 3) 익스텐션 종료라는 3가지 type의 요청을 보 내고, 익스텐션 서버는 여기에 맞게 응답을 하면 됩니다. • 익스텐션 서버는 https로 외부망으로 통신할 수 있는 서버이어야 하며, 포트는 80 또는 443로만 통 신합니다.
  • 19. Clova extension 개발 준비 – 1 (필수) • 익스텐션서버
  • 20. Clova extension 개발 준비 – 2 (필수) • 인터렉션 모델 • 일종의 대화시나리오와 비슷합니다만, 기계인 익스텐션 서버가 사람의 대화를 이해하여 작동할 수 있도록 Clova console에 입력하는 문장 및 메타정보들입니다. • 인터렉션 모델에는 사용자로부터 입력될 만한 문장들과 각 문장이 어떤 실행 명령(이를 '인텐트'라 고합니다.)으로 연결될 지를 설정합니다. • 인텐트를 실행할 때 필요한 정보들은 '슬롯'이라는 것으로 정의하여 처리합니다. • 예를 들면, 피자주문하는 익스텐션의 경우 인텐트와 슬롯은 아래와 같습니다. • 예) 사용자의 대화: "페퍼로니 피자 2판 주문해줘" --> 'OrderPizza'라는 이름으로 피자주문 처리용 인텐 트로 정의 • 예) 'OrderPizza'인텐트가 실제 피자를 주문하기 위해 필요한 정보는 '피자명'과 '수량'이며, 이는 각기 'pizzaType', 'pizzaAmount'라는 슬롯으로 정의
  • 21. Clova extension 개발 준비 – 3 (선택) • OAuth 인증 서버 • 만약 익스텐션이 써드파티 계정 인증이 필요하다면 익스텐션 서 버와 함께 OAuth 인증을 구현하 셔야 필요합니다. • OAuth 인증 서버는 Clova console에 등록된 인증정보를 이 용하여 인증을 처리하고, 인증이 완료되면 접근토큰을 반환해야 합니다. • 인증서버 구축 예) 배달의 민족, LG 전자, LGU + 관련 가이드: https://www.slideshare.net/ClovaPlatform/clova-tech-summit-3-clova-extension-oauth-89597569
  • 23. Clova extension 호출명 설정 • 가전기기를 제어하는 Custom extension (이하 '익스텐션') 서비스를 그려 보 도록 하겠습니다. • 먼저 익스텐션 실행할 때 부르는 이름, 즉 '호출명'을 정해야하는데, 몇 가지 제약이 있습니다. • 일반적인 명사는 안됨 (예: 박사 (X) ) • 브랜드나 유니크한 명사가 접목된 단어 가능: (예: 짱구박사(O)) • 혹시나 음성인식이 잘 안되는 경우는 다른 호출명으로 하셔야 할 수 있으니, Clova앱에서 인식이 잘 되는지 확인해보시길 바랍니다.
  • 24. 익스텐션의 작동 시나리오 • 첫번째는 익스텐션에게 바로 질문하고 답을 받는 것입니다. (싱글턴, single- turn) • 사용자: 클로바, 짱구박사에서 거실 전등 켜줘 • 익스텐션: 거실 전등이 켜졌습니다. • 두번째는 익스텐션을 실행한 다음에 질문하고 답을 받는 것입니다. (멀티턴, multi-turn) • 사용자: 클로바, 짱구박사를 시작해줘 • 익스텐션: 안녕하세요. 짱구박사가 시작되었습니다. 제어하고 싶은 가전기기와 동작 방 법을 말씀하세요. • 사용자: 거실 전등 켜줘. • 익스텐션: 거실 전등이 켜졌습니다.
  • 25. 익스텐션 기본 정보 등록하기 • Clova console에 접속해서 'Clova Extensions Kit'을 클릭한 다음 '새로운 익스텐션 만들기'를 누릅니다. • URL: https://developers.naver.com/console/clova/ • 익스텐션 정보 설정 • type은 Custom Extension으로 선택하고, 나머지 값들도 입력합니다. • 오디오플레이어 사용 여부는 '아니오'로 합니다. '예'로 하는 경우는 음원을 재생하는 경우에 사용합니다.
  • 28. 익스텐션 작동 시나리오 고려사항 • 이제 해야할 일은 시나리오가 클로바 플랫폼에서 작동하도록 하는 것인데요. • 문제는 사용자가 같은 말을 물어보더라도, 위에서 정의한 글자그대로 말하지 는 않는다는 점입니다. • 예) 거실 전등 켜줘 • 예) 거실 점등 해줘 • 예) 거실 불켜줘 • 이렇게 같은 의도이지만 다양한 표현을 입력하고 인터렉션 모델에 이러한 여 러 문장 케이스들을 잘 정리해놔야 더 똑똑한 익스텐션을 만들 수 있겠습니다.
  • 29. 인터렉션 모델 등록하기 – 슬롯 등록 • 짱구박사는 집안의 지역 IoT기기를 제어 할 것이므로 인텐트는 하나만 등록하면 되고, 슬롯은 ’집안의 다양한 장소들이'이 되겠습니다. • 슬롯 등록하기 전에 • 슬롯에는 커스텀 슬롯과 빌트인 슬롯 2가 지가 있습니다. • 빌트인 슬롯은 아래와 같이 사람들이 이 미 인지하는 용어들을 모아둔 것으로, 사 용하겠다고 체크하면 편리하게 사용하실 수 있습니다. • 집안의 다양한 장소들은 커스텀 슬 롯으로 등록합니다. • IOT_TYPE • 거실: 리빙룸 • 안방: 침실 • 부억: 키친 • 베란다
  • 30. 인터렉션 모델 등록하기 – 인텐트 등록 • 우측의 '사용중인 Intent' 옆의 + 버튼을 눌러서 ‘turnOnIntent’ 입력하고 '만들기' 버튼을 누릅 니다. • 사용자 표현 리스트에 사용자들이 입력할 것 같은 대화들을 입력하는데, slot과 의도에 해당 하는 문장들은 다양하게 입력합니다. • 문장의 가짓수는 많을 수록 더욱 대화의도 파악은 잘 됩니다. • 거실 전등 켜줘 • 안방 불 켜줘 • 침실 점등 해줘
  • 32. 인터렉션 모델 등록하기 – 인텐트 슬롯 등록 • 사용자 표현 리스트에서 ’거실'이라는 단어를 드래그한 다음 앞에서 입력한 ‘homeSlotType’이란 이름 으로 매핑해줍니다. • 매핑이 완료되면 Slot 에 해당하는 글씨들이 아래와 같이 하이라이트 됩니다.
  • 33. 인터렉션 모델 빌드하기 • ‘저장’ 버튼을 누른 다음 • 우측 상단의 '빌드' 버튼을 눌러 인터렉션 모델을 빌드합니다. 빌드가 완료되면 다시 '빌드'라는 버튼으로 바뀝니다.
  • 34. 인터렉션 모델 테스트 • 체크할 포인트는 인터렉션 모델에 등록한 문장과 비슷한 문장을 입력하더라도 slot과 intent값을 리턴하는지 확인하 는 것입니다. • 예) • 거실 전등 켜줘 (인터렉션 모델에 있는 문장) • 부억 점등 해줘 (인터렉션 모델에 있는 문장과 비슷한 유형이지만, slot 이 다른 문장) • 침실 불 켜줘 (비슷한 문장)
  • 36. 구구단 놀이 • 개요 • 사용자가 구구단 곱셈의 정답을 맞추는 게임 • 실행 방법 • 시작: “구구단 놀이 시작해줘” • 구구단 단수 변경: 다른 단수를 말하면 해당 단수로 변경
  • 37. 구구단놀이 • 인터렉션 모델 • Intent • 게임시작 – gugudanPlay • 사용자 대답 – gugudanAnswer • slot • 숫자 – dan (built-in number slot)
  • 38. 업다운 • 개요 • 사용자가 1~100사이 숫자를 맞추는 게임 • 실행 방법 • 시작: “업다운 시작해줘” • 사용자가 대답한 숫자가 크면 up, 숫자가 작으면 down이라는 힌 트를 줌
  • 39. 업다운 • 인터렉션 모델 • Intent • 게임시작 – playGameIntent • 사용자 대답 - numberAnswerIntent • slot • 숫자 – numberAnswer (built-in number slot)
  • 40. 나라수도맞추기 • 개요 • 사용자가 특정 국가의 수도 도시명을 맞추는 게임 • 실행 방법 • 시작: “나라수도맞추기 시작해줘” • 난이도 조절: 1단계 ~ 3단계로 조정가능 • 1단계는 누구가 잘 아는 나라 • 3단계는 잘 모르는 나라
  • 41. 나라수도맞추기 • 인터렉션 모델 • Intent • 게임시작 – playGameIntent • 사용자 대답 – answerIntent • 점수 확인 - getScoreIntent • slot • 숫자 – city (도시명입력)
  • 43. 서버가 처리해야할 작업 - 1 • Clova 요청 메시지의 request type에 따라 지정된 포맷의 응답 리 턴 • Request type • LaunchRequest : 익스텐션의 시작 (“짱구박사 시작해줘” 했을 경우) • SessionEndedRequest : 익스텐션의 종료 (“종료해줘” ) • IntentRequest • Custom Intent  개발자 콘솔에 입력한 Intent 와 Slot • Built-in Intent  https://developers.naver.com/console/clova/guide/CEK/References/CEK_API.md#cek-api-레퍼 런스
  • 44. 서버가 처리해야할 작업 – 2 https://developers.naver.com/console/clova/ guide/CEK/References/CEK_API.md#cek- api-레퍼런스 응답메시지 구조
  • 45. 서버가 처리해야할 작업 – 3 • 멀티턴 처리 • 응답 메시지의 shouldEndSession은 false • 계속 유지해야 할 값은 sessionAttribute에 담아서 전송 http://stg.developers.naver.com/console/clova/guide/ CEK/Guides/Build_Custom_Extension.md#DoMultiturn Dialog
  • 46. 개발 환경 구성 • 개발 도구 • IntelliJ ( with Java ) • 프로젝트 생성 • Spring Initializr로 프로젝트 생성 • 프로젝트 설정 • pom에 api test (rest-assured)에 필요한 dependency 설정
  • 47. Cloud Functions & CEK 4 / 30 Action (code) 만들기 CEK URL 등록 NCP 회원 가입
  • 48. Microservice on Serverless - UI에서 바로 작성하고 서비스를 배포하는 것이 가능 - 웹 액션으로 만들고 API Gateway를 통해 end-point 설정 및 CEK 연동 Cloud Functions & CEK
  • 49. Microservice on Serverless - UI에서 바로 작성하고 서비스를 배포하는 것이 가능 - 웹 액션으로 만들고 API Gateway를 통해 end-point 설정 및 CEK 연동 Cloud Functions & CEK
  • 50. Cloud Functions & CEK 4 / 30 Action
  • 51. Cloud Functions & CEK 4 / 30 Action create
  • 52. Cloud Functions & CEK Action 실행
  • 53. https://github.com/naver/clova-extension-sample-rainsound/blob/github- public/clova/index.js Cloud Functions & CEK Node.js 수정 1) 1개의 js 파일로 (include제거 및 관련 변수치환) 2) api 처리하는 부분을 main function으로 const uuid = require('uuid').v4 const _ = require('lodash') //const { DOMAIN } = require('../config')
  • 54. Cloud Functions & CEK Node.js 코드 입력 및 Default parameter 수정
  • 55. Default parameter { "version": "0.1.0", "session": { "sessionId": "7b1652d1-5e44-4f4b-9769-ea2f1190cc6f", "user": { "userId": "Gz1xLLqxROGBWE71SDN_gQ", "accessToken": "07c8d684-a2a9-4147-8abc-8a2e2dc50ef0" }, "new": true }, "context": { "System": { "user": { "userId": "Gz1xLLqxROGBWE71SDN_gQ", "accessToken": "07c8d684-a2a9-4147-8abc-8a2e2dc50ef0" }, "device": { "deviceId": "7609cb94-eec5-4728-b07b-271d32e188b0", "display": { "size": "l100", "orientation": "landscape", "dpi": 96, "contentLayer": { "width": 640, "height": 360 } } } } }, "request": { "type": "IntentRequest", "intent": { "name": "PlayLoopIntent", "slots": { "loopCount": { "name": "loopCount", "value": "2" } } } } }
  • 56. clearMultiturn() { this.response.shouldEndSession = true this.sessionAttributes = {} } addDirective(directive) { this.response.directives.push(directive) } setSimpleSpeechText(outputText) { this.response.outputSpeech = { type: "SimpleSpeech", values: { type: "PlainText", lang: "ko", value: outputText, }, } } appendSpeechText(outputText) { const outputSpeech = this.response.outputSpeech if (outputSpeech.type != 'SpeechList') { outputSpeech.type = 'SpeechList' outputSpeech.values = [] } if (typeof(outputText) == 'string') { outputSpeech.values.push({ type: 'PlainText', lang: 'ko', value: outputText, }) } else { outputSpeech.values.push(outputText) } } } function main(params) { const httpReq = {"body": params} cekResponse = new CEKResponse() cekRequest = new CEKRequest(httpReq) cekRequest.do(cekResponse) return cekResponse }; intentRequest(cekResponse) { console.log('intentRequest') console.log(JSON.stringify(this.request)) const intent = this.request.intent.name const slots = this.request.intent.slots switch (intent) { case "PlayIntent": case "PlayLoopIntent": let loopCount const loopCountSlot = slots.loopCount if (intent == "PlayIntent") { loopCount = 1 } else if (slots.length == 0 || !loopCountSlot) { loopCount = 3 } else { loopCount = parseInt(loopCountSlot.value) } if (loopCount == 1) { cekResponse.appendSpeechText("빗소리를 재생합니다.") } else { cekResponse.appendSpeechText(`빗소리를 ${loopCount}번 재생합니다.`) } for (let i = 0; i < loopCount; i++) { cekResponse.addDirective(audioDirective()) } break case "Clova.GuideIntent": cekResponse.appendSpeechText("죄송해요. 이해할 수 없습니다.") cekResponse.appendSpeechText("빗소리 틀어줘, 라고 시도해보세요.") break; } } sessionEndedRequest(cekResponse) { console.log('sessionEndedRequest') cekResponse.setSimpleSpeechText("빗소리 익스텐션을 종료합니다.") cekResponse.clearMultiturn() } } class CEKResponse { constructor () { this.response = { directives: [], shouldEndSession: true, outputSpeech: {}, } this.version = "0.1.0" this.sessionAttributes = {} } setMultiturn(sessionAttributes) { this.response.shouldEndSession = false this.sessionAttributes = _.assign(this.sessionAttributes, sessionAttributes) } const uuid = require('uuid').v4 const _ = require('lodash') //const { DOMAIN } = require('../config') class Directive { constructor({namespace, name, payload}) { this.header = { messageId: uuid(), namespace: namespace, name: name, } this.payload = payload } } function audioDirective() { episodeId = Math.floor(Math.random() * 1000) return new Directive({ namespace: 'AudioPlayer', name: 'Play', payload: { audioItem: { audioItemId: uuid(), stream: { beginAtInMilliseconds: 0, playType: "NONE", token: uuid(), url: `http://**********/rainning_sound.mp3`, urlPlayable: true }, // type: "custom", }, playBehavior: "REPLACE_ALL", source: { logoUrl: `http://**********/img_sound_rain_108.png`, name: "소리 시리즈" } } }) } class CEKRequest { constructor (httpReq) { this.request = httpReq.body.request this.context = httpReq.body.context this.session = httpReq.body.session } do(cekResponse) { switch (this.request.type) { case "LaunchRequest": return this.launchRequest(cekResponse) case "IntentRequest": return this.intentRequest(cekResponse) case "SessionEndedRequest": return this.sessionEndedRequest(cekResponse) } } launchRequest(cekResponse) { console.log('launchRequest') cekResponse.appendSpeechText("빗소리를 재생합니다.") cekResponse.addDirective(audioDirective()) } Node.js 코드 – 빗소리 https://github.com/okgosu/CEK-CloudFunction-Exam
  • 57. Cloud Functions & CEK 액션실행
  • 58. Cloud Function Server 주소 설정
  • 59. Clova 앱과 스피커에서 익스텐션 호출 테스트
  • 60. 테스트 단계 • 개발자 콘솔에 test할 네이버 계정 등록 • 음성 테스트 방법1 – Clova 앱 • Clova 앱에 해당 아이디로 로그인 후 •  “짱구박사 시작해줘” 라고 했을 때 익스텐션 서버로 LaunchRequest가 오는지, 익스텐션의 응답이 음성으로 나가는지 확인 • 음성 테스트 방법2 – Friends 스피커 • 테스터로 등록된 아이디로 Clova앱을 이용해서 스피커 설정 •  “짱구박사 시작해줘” 라고 했을 때 익스텐션 서버로 LaunchRequest가 오는지, 익스텐션의 응답이 음성으로 나가는지 확인
  • 61. Appendix. • Clova 플랫폼 개발자 문서 : https://developers.naver.com/console/clova/guide/ • Design 챕터 / Clova Extensions Kit 챕터 / Clova Developer Console 챕터 참고 • 튜토리얼 및 샘플 코드 참고 • 샘플 코드 Github • 마법 구슬 : https://github.com/naver/clova-extension-sample-magicball • 빗소리 : https://github.com/naver/clova-extension-sample-rainsound • 주사위 놀이 : https://github.com/naver/clova-extension-sample-dice • 코인 헬퍼 : https://github.com/naver/clova-extension-sample-coinhelper