Watson์œผ๋กœ ์‰ฝ๊ฒŒ ๋งŒ๋“œ๋Š” ์นด์นด์˜คํ†ก ChatBot

์ด ํฌ์ŠคํŒ…์€ 1. Watson Conversation ์„œ๋น„์Šค๋กœ ๋Œ€ํ™” ์„œ๋น„์Šค ๋งŒ๋“ค๊ธฐ์™€ ์ด์–ด์ง€๋Š” ํฌ์ŠคํŒ…์ž…๋‹ˆ๋‹ค. ์ด ๋‹จ๊ณ„์—์„œ๋Š” ์ด์ „์— ๋งŒ๋“  ๋Œ€ํ™” ์„œ๋น„์Šค๋ฅผ ์•ฑ์—์„œ ํ™œ์šฉํ•˜๊ณ  ๋ชฉ์ ์— ๋งž๊ฒŒ ์ˆ˜์ •ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ฐฐ์šธ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

< ์ด ํฌ์ŠคํŒ…๊ณผ ์—ฐ๊ฒฐ๋œ ๊ธ€ ๋ชฉ๋ก >

2. ๋‚ด๊ฐ€ ๋งŒ๋“  ์ฑ„ํŒ… ์„œ๋น„์Šค๋ฅผ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์œผ๋กœ ๋…ธ์ถœํ•˜๊ธฐ

2.1 Github์—์„œ ์ƒ˜ํ”Œ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋‹ค์šด๋กœ๋“œ

์ด ํŠœํ† ๋ฆฌ์–ผ์€ Github๋ฅผ ํ†ตํ•ด ๊ณต์œ ๋˜๊ณ  ์žˆ๋Š” Conversation Simple repository๋ฅผ ๊ธฐ๋ณธ์œผ๋กœ ์ž‘์„ฑ ์ž‘์„ฑ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ด ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์€ ๋ธ”๋ฃจ๋ฏน์Šค์— ์˜ฌ๋ผ๊ฐ€ ์žˆ์œผ๋ฏ€๋กœ ํ…Œ์ŠคํŠธํ•ด ๋ณด์‹œ๊ณ  ํ–ฅํ›„ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ฐœ๋ฐœ์— ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

1) Node.js ์™€ Bluemix CLI ์„ค์น˜
์ด ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์€ Node.js ๊ธฐ๋ฐ˜์ž…๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ด ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋กœ์ปฌ์—์„œ ์‹คํ–‰ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” Node.js๋ฅผ ์„ค์น˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋ธ”๋ฃจ๋ฏน์Šค ํ™˜๊ฒฝ์—์„œ ์‹คํ–‰ํ•˜์—ฌ Public์— ๋…ธ์ถœํ•˜๋ ค๋ฉด Cloud Foundary CLI๋ฅผ ์„ค์น˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์— ๋งž๋Š” ํŒŒ์ผ์„ ๋‹ค์šด๋กœ๋“œ ํ•˜์—ฌ ์„ค์น˜ํ•˜์‹ญ์‹œ์˜ค. Node.js๋‚˜ CLI ์„ค์น˜ ํ›„์—๋Š” ๋ช…๋ น ํ”„๋กฌํฌํŠธ ์ฐฝ์„ ๋‹ซ์€ ํ›„ ๋‹ค์‹œ ์—ฌ์‹ญ์‹œ์˜ค. Node.js๋Š” npm -version, Cloud Foundary CLI๋Š” cf โ€“version ๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์„ค์น˜๋ฅผ ํ™•์ธํ•˜์‹ญ์‹œ์˜ค.

git์ด ์„ค์น˜๋˜์–ด ์žˆ์ง€ ์•Š์€ ๊ฒฝ์šฐ git๋„ ์„ค์น˜ํ•˜์‹ญ์‹œ์˜ค.

2) Repository Folk and Clone
Chatbot-tutorial๋ฅผ Folk ํ›„ Cloneํ•˜๊ฑฐ๋‚˜ ๋ฐ”๋กœ Cloneํ•ฉ๋‹ˆ๋‹ค.

git clone https://github.com/hjjo/chatbot-tutorial.git

tutorial2 branch๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค.

git checkout tutorial2

2.2 ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜๊ณผ ๋‚ด Watson Conversation ์—ฐ๊ฒฐ

๋จผ์ € ํ™˜๊ฒฝ๋ณ€์ˆ˜๋ฅผ ์ˆ˜์ •ํ•˜์—ฌ ๋‚ด ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ๋‚ด Conversation Service์˜ Workspace๋ฅผ ๋ฐ”๋ผ๋ณผ ์ˆ˜ ์žˆ๋„๋ก ์ˆ˜์ •ํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์šด๋กœ๋“œํ•œ ์†Œ์Šค์˜ ์ตœ์ƒ์œ„ ํด๋”์— .env.example ํŒŒ์ผ์ด ์žˆ์Šต๋‹ˆ๋‹ค. OS์— ๋”ฐ๋ผ์„œ ์ˆจ๊น€ ํŒŒ์ผ ๋ณด๊ธฐ๋ฅผ ํ•ด์•ผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ํŒŒ์ผ์„ ๋ณต์‚ฌํ•˜์—ฌ ๊ฐ์ž์˜ ๋‚ด์šฉ์— ๋งž๊ฒŒ ์ˆ˜์ •ํ•œ ํ›„ .env๋กœ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค. ํ–ฅํ›„ ์ด .env์— ๋“ฑ๋กํ•œ ํ™˜๊ฒฝ๋ณ€์ˆ˜๋Š” process.env.xxx์˜ ํ˜•ํƒœ๋กœ ์ฝ”๋“œ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  # Conversation
  WORKSPACE_ID= [workspace-id]
  CONVERSATION_USERNAME= [conversation-username]
  CONVERSATION_PASSWORD= [conversation-password]

ํ™˜๊ฒฝ๋ณ€์ˆ˜๋กœ 3๊ฐœ์˜ ๊ฐ’์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ์ด ์ •๋ณด๋Š” Bluemix > Watson Conversation ์„œ๋น„์Šค >์‹ ์ž… ์ •๋ณด ๋ณด๊ธฐ, Watson Conversation Tool > Workspaces > View Detail์„ ํ†ตํ•ด ํ™•์ธ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

์•„๋ž˜ ์Šคํฌ๋ฆฐ์ƒท์„ ์ฐธ์กฐํ•˜์—ฌ ํ•„์š”ํ•œ ์ •๋ณด๋ฅผ ์–ป์œผ์‹ญ์‹œ์˜ค.

credential2

credential3

์ •๋ณด๋ฅผ ์ฐธ์กฐํ•˜์—ฌ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ˆ˜์ •ํ•ฉ๋‹ˆ๋‹ค.

  # Conversation
  WORKSPACE_ID=8dd88a9c-83ac-40f1-bd08-47b319cXXXXX
  CONVERSATION_USERNAME=da3ff9bf-5098-42c2-b2fa-47d1XXXXXX
  CONVERSATION_PASSWORD=tBIuHHpXXXXX

2.3 Watson Conversation SDK ๋ชจ๋“ˆ ์„ค์น˜

Command์ฐฝ์„ ์—ด์–ด chatbot-tutorial ํ”„๋กœ์ ํŠธ์˜ ์ตœ์ƒ์œ„ ํด๋”๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค.

์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์— ์ •์˜๋œ dependency๊ฐ€ ์žˆ๋Š” node module์„ ๋กœ์ปฌ Node.js ๋Ÿฐํƒ€์ž„์— ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค.

  npm install

Watson Conversation SDK ๋ชจ๋“ˆ์„ ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค. –save ์˜ต์…˜์€ insatll ํ›„์— ํ•ด๋‹น ๋ชจ๋“ˆ์„ package.json์— ์ž๋™์œผ๋กœ ๋“ฑ๋กํ•ด์ค๋‹ˆ๋‹ค.

  npm install watson-developer-cloud --save

2.4 ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ตฌ์กฐ ์ดํ•ดํ•˜๊ธฐ

์ด ์Šคํ…์—์„œ๋Š” /api/message api๋ฅผ ์™„์„ฑํ•˜์—ฌ ์›น ํด๋ผ์ด์–ธํŠธ๋ฅผ ํ†ตํ•ด Conversation ์„œ๋น„์Šค๋ฅผ ๋…ธ์ถœํ•ฉ๋‹ˆ๋‹ค. ์›น ํด๋ผ์ด์–ธํŠธ๋Š” ./public์— ์ด๋ฏธ ๊ฐœ๋ฐœ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

๋‹ค์Œ์€ app.js์˜ ์ฝ”๋“œ์ž…๋‹ˆ๋‹ค. ์ด ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์€ ./public ํด๋”๋ฅผ ui๋กœ ์‚ฌ์šฉํ•˜๊ณ  ./api ๋ฐ‘์— REST API๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ๋…ธ์ถœํ•˜๋Š” ๊ตฌ์กฐ๋กœ ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

'use strict';

var express = require('express'); // app server
var bodyParser = require('body-parser'); // parser for post requests

var api = require('./api');
var app = express();

// Bootstrap application settings
app.use(express.static('./public')); // load UI from public folder
app.use(bodyParser.json());
api.initialize(app);
module.exports = app;

./api/index.js๋Š” ./api ํ•˜์œ„์˜ api ๋ชฉ๋ก์„ ๊ด€๋ฆฌํ•˜๊ณ  ์ดˆ๊ธฐํ™”ํ•˜๊ธฐ ์œ„ํ•œ index ํŒŒ์ผ์ž…๋‹ˆ๋‹ค.

./api/message.js๋Š” /api/message api๋ฅผ ๋…ธ์ถœํ•จ๊ณผ ๋™์‹œ์— Conversation API๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๋ชจ๋“ˆ์ž…๋‹ˆ๋‹ค.

./api/message.js ์ƒ๋‹จ์„ ๋ณด๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด conversation ๋ชจ๋“ˆ๊ณผ config ๋ชจ๋“ˆ์„ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.

const Conversation = require('watson-developer-cloud/conversation/v1'); // watson sdk
const config = require('../util/config');

config.json์— ์…‹ํŒ…ํ•œ ๊ฐ’์„ ๋ฐ”ํƒ•์œผ๋กœ Conversation Service Wrapper๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

// Create a Service Wrapper
let conversation = new Conversation(config.conversation);

getConversationResponse ํ•จ์ˆ˜๋Š” ์‚ฌ์šฉ์ž์˜ message์™€ context ์˜ค๋ธŒ์ ํŠธ๋ฅผ input์œผ๋กœ ๋ฐ›์•„ Conversation API๋ฅผ ํ˜ธ์ถœํ•˜๊ณ  Promise ๊ฐ์ฒด๋ฅผ ๋ฆฌํ„ดํ•ฉ๋‹ˆ๋‹ค. Conversation API๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๋ถ€๋ถ„์€ // TODO๋กœ ๊ตฌํ˜„๋˜์ง€ ์•Š์€ ์ƒํƒœ์ž…๋‹ˆ๋‹ค.

let getConversationResponse = (message, context) => {
  let payload = {
    workspace_id: process.env.WORKSPACE_ID,
    context: context || {},
    input: message || {}
  };

  payload = preProcess(payload);

  return new Promise((resolved, rejected) => {
    // Send the input to the conversation service
    // TODO : To be implemented
  })
}

postMessage() ํ•จ์ˆ˜๋Š” /api/message api๋กœ ๋…ธ์ถœ์‹œํ‚ค๊ธฐ ์œ„ํ•œ ํ•จ์ˆ˜๋กœ http request๋ฅผ ๋ฐ›์•„ getConversationResponse()๋ฅผ ํ†ตํ•ด Watson์˜ ์‘๋‹ต์„ ๋ฐ›์œผ๋ฉด http response๋กœ ๋ฆฌํ„ดํ•ฉ๋‹ˆ๋‹ค.

preProcess() ํ•จ์ˆ˜์™€ postProcess() ํ•จ์ˆ˜๋Š” ๊ฐ๊ฐ ์‚ฌ์šฉ์ž์˜ Input์„ ์ „์ฒ˜๋ฆฌ, Watson์˜ ์‘๋‹ต์„ ํ›„์ฒ˜๋ฆฌ ํ•˜๊ธฐ ์œ„ํ•œ ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค.

doAction() ํ•จ์ˆ˜๋Š” ๋Œ€ํ™” ๋„์ค‘ ์‹œ์Šคํ…œ์ด ์ˆ˜ํ–‰ํ•ด์•ผ ํ•˜๋Š” Action์ด ์žˆ๋Š” ๊ฒฝ์šฐ ์ด๋ฅผ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

2.5 Watson Conversation API ํ˜ธ์ถœํ•˜๋Š” ์ฝ”๋“œ ์ž‘์„ฑํ•˜๊ธฐ

./api/message.js๋ฅผ ์—ด์–ด getConversationResponse() ํ•จ์ˆ˜๋ฅผ ์ˆ˜์ •ํ•ฉ๋‹ˆ๋‹ค.
getConversationResponse ํ•จ์ˆ˜์˜ return ๋ฌธ์„ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ณ€๊ฒฝํ•ฉ๋‹ˆ๋‹ค. Conversation SDK๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ API๋ฅผ ํ˜ธ์ถœํ•œ ํ›„์— err๊ฐ€ ๋ฐœ์ƒํ•œ ๊ฒฝ์šฐ reject ์˜ค๋ธŒ์ ํŠธ๋ฅผ, ์ •์ƒ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•œ ๊ฒฝ์šฐ resolved ์˜ค๋ธŒ์ ํŠธ๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ์ฝ”๋“œ์ž…๋‹ˆ๋‹ค.

return new Promise((resolved, rejected) => {
    // Send the input to the conversation service
    conversation.message(payload, function(err, data) {
      if (err) {
        rejected(err);
      }
      resolved(postProcess(data));
    });
  })

2.6 ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ ํ…Œ์ŠคํŠธ

์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ๊ตฌ๋™์ค‘์ด๋ผ๋ฉด Ctrl + C๋ฅผ ๋ˆŒ๋Ÿฌ ์ข…๋ฃŒํ•ฉ๋‹ˆ๋‹ค.

์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

  npm start

์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์ž‘๋™๋˜๋ฉด localhost:3000 ์— ์ ‘์†ํ•˜์—ฌ ์•„๋ž˜์ฒ˜๋Ÿผ ๋Œ€ํ™”ํ•ฉ๋‹ˆ๋‹ค.

test2

Command์ฐฝ์„ ๋ณด๋ฉด Watson Conversation๊ณผ ๋Œ€ํ™”ํ•  ๋•Œ๋งˆ๋‹ค ๋กœ๊ทธ๊ฐ€ ์ฐํžˆ๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

2.7 ๋‚ด ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ธ”๋ฃจ๋ฏน์Šค์— ์˜ฌ๋ ค๋ณด์ž !

ํ”„๋กœ์ ํŠธ์˜ Root ๋””๋ ‰ํ† ๋ฆฌ์—์„œ manifest.yml ํŒŒ์ผ์„ ์˜คํ”ˆํ•ฉ๋‹ˆ๋‹ค. ๋ธ”๋ฃจ๋ฏน์Šค๋Š” ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์˜ฌ๋ฆด ๋•Œ ํ™˜๊ฒฝ์„ ์„ค์ •ํ•˜๊ธฐ ์œ„ํ•ด yml ํŒŒ์ผ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

manifest.yml ํŒŒ์ผ์— applications ์„น์…˜๊ณผ services ์„น์…˜์ด ์žˆ์Šต๋‹ˆ๋‹ค.
applications ์„น์…˜์—๋Š” ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ด๋ฆ„์„ Unique ํ•˜๊ฒŒ ์ง€์ •ํ•˜์‹ญ์‹œ์˜ค. ์„œ๋น„์Šค ์„น์…˜์—์„œ๋Š” ๊ฐ์ž ์ƒ์„ฑํ•œ ์„œ๋น„์Šค ์ธ์Šคํ„ด์Šค์˜ ์„œ๋น„์Šค ์ด๋ฆ„์œผ๋กœ ๋ณ€๊ฒฝํ•ฉ๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ๋“ค๋ฉด ์•„๋ž˜์ฒ˜๋Ÿผ ์ˆ˜์ •ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

  โ€” 
declared-services:
my-conversation-service:
label: conversation
plan: free
applications:
- name: meetingroom-reservation-with-camomile
command: npm start
path: .
memory: 256M
instances: 1
services:
- Conversation-vp
env:
NPM_CONFIG_PRODUCTION: false

์ด์ œ ๋ธ”๋ฃจ๋ฏน์Šค ๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋ฐฐํฌํ•ฉ๋‹ˆ๋‹ค. ๋จผ์ € ๋ธ”๋ฃจ๋ฏน์Šค์— ๋กœ๊ทธ์ธ ํ•ฉ๋‹ˆ๋‹ค.

  cf login

์ปค๋งจ๋“œ ์ฐฝ์— ๋‚˜ํƒ€๋‚˜๋Š” ์š”๊ตฌ์‚ฌํ•ญ์— ๋”ฐ๋ผ ๋กœ๊ทธ์ธ ์ •๋ณด๋ฅผ ์ž…๋ ฅํ•ฉ๋‹ˆ๋‹ค.

  API endpoint > https://api.eu-gb.bluemix.net

API endpoint๋Š” ์‚ฌ์šฉํ•˜๊ณ  ๊ณ„์‹  ๋ฐ์ดํ„ฐ์„ผํ„ฐ ์ง€์—ญ์— ๋”ฐ๋ผ ๋‹ค๋ฅด๊ฒŒ ์ž…๋ ฅํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ๋ฏธ๊ตญ ๋‚จ๋ถ€์ด๋ฉด https://api.ng.bluemix.net ๋ฅผ, ์‹œ๋“œ๋‹ˆ์ด๋ฉด https://api.au-syd.bluemix.net ์„ ์ž…๋ ฅํ•ฉ๋‹ˆ๋‹ค.

๋‹ค์Œ์œผ๋กœ ๋ธ”๋ฃจ๋ฏน์Šค ๊ณ„์ •์„ ์ž…๋ ฅํ•ฉ๋‹ˆ๋‹ค.

  Email > hjjo@kr.ibm.com 
Password > ***

๋ธ”๋ฃจ๋ฏน์Šค ๋‚ด์— ๊ฐ–๊ณ  ๊ณ„์‹  Organization๊ณผ Watson์„ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.

  Org> hjjo@kr.ibm.com 
Space > watson

๋กœ๊ทธ์ธ๊นŒ์ง€ ์™„๋ฃŒ๋˜์—ˆ์œผ๋ฉด ์ด์ œ ๋‹ค์Œ ๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋ฐฐํฌํ•ฉ๋‹ˆ๋‹ค.

  cf push

๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•œ๊ฒฝ์šฐ ์•„๋ž˜ ๋ช…๋ น์–ด๋ฅผ ํ†ตํ•ด ๋กœ๊ทธ๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  cf logs [application name] โ€“recent

์ด์–ด์ง€๋Š” ํฌ์ŠคํŒ…์€

Watson์œผ๋กœ ์‰ฝ๊ฒŒ ๋งŒ๋“œ๋Š” ์นด์นด์˜คํ†ก ChatBot 3. ๋Œ€ํ™” ๋‚ด์šฉ์œผ๋กœ ํšŒ์˜์‹ค ์˜ˆ์•ฝํ•˜๊ธฐ

์ž…๋‹ˆ๋‹ค.