せっかくならデキるエンジニアになりたい

SIerになったので、デキる技術者を目指していろいろ試してみたときの備忘録

memorandum

Let's be a good engineer!

Watson AssistantとSlackをNode-REDで連携させた話

なんでSlackと連携?

Watson Conversation-Slack間の連携なんて、正直言ってググれば2016年くらいからいろんな人がやってる記事がめちゃくちゃ出てくるんですけど、如何せんオリジナリティを出せるほどの技術力と知識がないので、参考にできる記事がいっぱいある分野で慣れていこうと言う、そういう魂胆です(*´-`)

ちなみに、この記事の続きです。

moeka-dev.hatenablog.com

どうやって連携させる?

Slackと連携となると、どうやらこの二つを使うのが主流なようです。

比較項目 BotKit Node-RED
概要 チャットボットを作るためのフレームワーク。Slackでの活用実績が異様に多い(個人の所感)。 ブラウザベースのフローエディタツール。IOTアプリやWebアプリがビジュアルプログラミングっぽく作れる。
公式サイト https://www.botkit.ai/ https://nodered.org/
https://nodered.jp/←日本語版
開発元 XOXCO社 英国IBM(Hursley研究所)
必要な環境 Node.js Node.js
IBM Cloudから動かすのであれば特になし
便利そうなサイト Creating a smart ChatBot for Slack←SlackAPI公式チュートリアルから辿れる Node-REDのデザインパターン10選
Watsonに博多弁をしゃべらせてみたIBM公式サイトから辿れる
GitHub https://github.com/howdyai/botkit https://github.com/node-red/node-red

Botkitと(多分)似たようなチャットボット用FWであるHubotもありましたが、これはWatson-Slack間連携においてはそんなに参考になりそうな記事が多くなかったのでパス。

BotKitとNode-REDのどちらを使うかですが、そもそもボットの動作部分はWatson Assistantで前回作ったし、わざわざチャットボットのFWを使うまでもないかなっていうのと、IBM Cloud上で簡単に使えそうってことで、Node-Redを採用することにしました!

Node-REDをIBM Cloudで使う準備

出来るだけ公式ドキュメントを使おうっていうスタンスで頑張っているので、色々と記事はありますが、できる限り公式に沿ってやって行きたいと思います。

というわけでこのページを探し当てました。
Running on IBM Bluemix

ボイラープレートアプリケーション

Node-REDは、IBM Cloud上でボイラープレートアプリケーションとして提供されています。

(´-`).。oO(ボイラープレートってなんだろう)

しばらく調べてようやくそれっぽい記述を見つけました。

ランタイム
アプリケーションの実行に必要な言語環境のことです。JavaやNode.jsなどの言語環境を利用できます。
サービス
アプリケーションが使用する機能を提供する、事前定義済みのミドルウェアやアプリケーションのことです。データベースやモバイルPush通知などがあります。
アドオン
アプリケーション開発や運用を支える機能を提供します。DevOps関連の機能や、負荷に応じて自動的にリソースを拡張するAuto Scalingなどがあります。
ボイラープレート
ランタイムとサービスの典型的な組み合わせを事前に定義したものです。アプリケーションをとにかく作り始めるときに便利です。ボイラープレートから作成した環境に、サービスを追加することも可能です。

BMの次世代クラウド・プラットフォーム "IBM Bluemix"より引用

IBM CloudではなくIBM Bluemix時代の記事ですが、おそらく意味合い的には変わらないと思います。ボイラープレートはつまり、これさえあればすぐにツールが使えるようになるよっていうツールのセット、DockeでいうDockeイメージみたいな立ち位置ってことですかね!(投げやり)

Node-REDの導入

その便利なボイラープレートアプリケーションであるNode-REDを、早速導入していこうと思います。
ダッシュボードがあるページの上メニューの「カタログ」から見つけることができました。 f:id:moeka-dev:20180318201439p:plain

確かにボイラープレートって書いてますね。

Node-REDが利用できるボイラープレートアプリケーションは、「Node-RED Starter」と「Internet of Things Platform Starter」の2つがあるみたいなんですが、後者はWatson IoT Platformのデフォルトフローが入っているようです。
でも特にIoTで使うわけではないので大人しくNode-RED Starterをクリックします。

f:id:moeka-dev:20180318201446p:plain アプリ名とホスト名を入力。下部で月額費用計算してるのがちょっと怖いけどライトプランなら無料なはず。

f:id:moeka-dev:20180318201454p:plain f:id:moeka-dev:20180318201502p:plain

ちょっと下にスクロールしたら、「SDK for Node.js」と「Cloudant NoSQL DB」のプランが別途選べるようになっていました。なるほど、これを一緒に使えるようにしてくれるからボイラープレートなんですね。ランタイムはNode.jsだから必須だとして、きっとDBはIBM Cloudantじゃなくても良いけど、これがおすすめだよってことなのでしょう。

f:id:moeka-dev:20180318201510p:plain 数分待つとアプリケーションが起動するので、https://<yourAppName>.mybluemix.netというURLでNode-REDにアクセスしました。

f:id:moeka-dev:20180318201518p:plain セキュリティの設定などなどを行なうと…

f:id:moeka-dev:20180318201539p:plain はい、英語です。知ってましたのでダメージは軽いです。とりあえずGo to your Node-RED flow editerをクリックしてみます。

f:id:moeka-dev:20180318201547p:plain 導入が簡単すぎる…

Node-REDでフロー作成

Slackノードの追加

デフォルトではSlackノードが左側のパレットにないので、どうやら導入作業が必要らしいです。Slackと連携するためのパッケージは、Node-RED公式サイトのflowから検索できるようなので、Slackというキーワードで検索します。 f:id:moeka-dev:20180318201601p:plain f:id:moeka-dev:20180318201608p:plain

おお、いっぱい出てき...ん?

node-red-contrib-slacker
Node RED Slack integration built on top of botkit from howdy.ai

howdy.aiがbotkitを作ってて、それを元にNode-REDのSlackノードが構築されている…?
howdy.aiとは!?と思ったんですけど、冒頭でbotkitのGithub調べた時のURLがhttps://github.com/howdyai/botkitでした。めちゃくちゃhowdy.aiですね…

というか比較までしたのに結局裏でbotkit使ってるものもあるっていう笑

とりあえず使うノードを決めたいんですが、それっぽいのだけでも結構あります。迷います。
でもnode-red-contrib-slackだけダウンロード数が桁違いなので、これで良さそうな気がします。中身の説明→node-red-contrib-slackを読んでみても、一番説明もしっかりしてるし用途もあってそうです。
ざっくり言うとSlack.comにWebhookでPostを送信するってことですよね。いけそう。

ありがたく使わせていただくことにします。

このありがたいノードを使うには、公式ドキュメントによるとpackage.jsonファイルに依存するパッケージとそのバージョンを記述するらしい(mavenでいうpom.xml的な感じかな?)んですが、わざわざファイルいじらなくてもできるようです。

f:id:moeka-dev:20180318201553p:plain パレットの管理から「ノードの追加」で検索して

f:id:moeka-dev:20180318201616p:plain 追加!

一瞬何も変わらなくて焦りましたが、F5したらちゃんと追加されてました! f:id:moeka-dev:20180318201623p:plain

Nodeを作成

各ノードの役割が、ちゃんと「ノードのヘルプ」と言うところに表示されるので、読んでみます。 f:id:moeka-dev:20180318201627p:plain

slack
msg.payloadをSlackに送ります。Slack Channelに簡単に投稿できる方法です。 msg.channelを設定することで投稿するチャンネルを切り替えることもできます。 msg.attachmentsを追加すると、Slack Attachmentも使えます。

Slack Attachmentっていうのはこれのことですね。

Slack Bot In
Slack Botがメンバーになっている任意のChannelにリスナーを提供します。 着信メッセージをmsg.payloadに格納して出力します。 msg.SlackObjには完全なSlackMessageの詳細が格納されています。 edit dialogueでチャンネルを制限することもできます。

Slack Bot Out
Bot API Tokenに基づいてmsg.payloadをSlackに送ります。 msg.channelを設定することで投稿するチャンネルを切り替えることもできます。

slackとSlack Bot Outの使い分け方がいまいちピンと来なかったので、ノードの中身をみてみることにします。

これがslack f:id:moeka-dev:20180318201634p:plain

これがSlack Bot Out f:id:moeka-dev:20180318201639p:plain

Webhookを使うか、Bot API Tokenを使うかの違いのようです。
正直用途的にはめちゃくちゃどっちでもいい気はするんですが、Slack Bot Inの方がTokenを使うので、出力の方もそれに合わせることにします。

とりあえずざっくりした流れはこんな感じですよね。 f:id:moeka-dev:20180318201653p:plain

Slackの設定

Slackでwatsonという名前のbotを作りました。 f:id:moeka-dev:20180318201643p:plain

API Tokenをコピーして、Node-REDのSlack Bot InとSlack Bot Outのノードに指定します。
(API Tokenの部分を不可視にする画像加工が面倒くさいのでスクショは撮ってないです(*・ω・)ノ)

Watson Conversationの設定

f:id:moeka-dev:20180318201648p:plain 前回作ったWatson AssistantワークスペースのWorkspaceIDとユーザID、パスワードを
Workspaces/(ワークスペース名)/Deploy/Credentialsから取得し、Node-REDのconversationノードに設定します。
(これもスクショなしです)

Nodeを繋げる

このノードたちを繋げていきます。 f:id:moeka-dev:20180318201653p:plain

Slack In - Say Hello間

Slack InはSlackから入力された言葉をそのままmsg.payloadに格納していて、Say Hello(conversation)はmsg.payloadに格納された言葉を分析すると書いているので、とりあえずそのまま繋ぎます。 f:id:moeka-dev:20180318201659p:plain

Say Hello - Slack Out間

Say Hello(conversation)のアウトプットは、

All Results will made available at msg.payload in JSON format.

と書いているので、ちょっと一工夫必要そうな気がします。詳細はConversation API Referenceに書いてあるそうです。 f:id:moeka-dev:20180318201703p:plain

…どこやねん…(´・ω・`)

しばらく探して頑張って見つけました。多分これでしょう!
f:id:moeka-dev:20180318201710p:plain

API Reference > Message > Send Message > RESPONSE
の部分です。ちゃんとJSON形式のレスポンスの例も書いてあるし。
Slackに喋らせたい部分→Slack Outのmsg.payloadに格納しなければならない部分はどうやら

 "output": {
    "text": [
      "Hi! What can I do for you?"
    ],

この部分のようなので、fanctionを追加してみます。
f:id:moeka-dev:20180318201717p:plain こうかな?
全部繋げます。

f:id:moeka-dev:20180318201721p:plain

これでおっけーなはず…!

デプロイ

なんとデプロイボタンを押すだけでデプロイができるらしい。すごい。 ぽち。

Slackでテスト!

さっき作ったSlackBotを、テスト用のチャンネルに招待して話しかけてみます。

f:id:moeka-dev:20180318201725p:plain わーできた!ちょっとWatsonの方を整備していなさすぎてこれくらいの会話しかまだできませんが、とりあえずSlackとの連携は無事行えました〜

まとめ

今まであまり公式サイトやAPIリファレンスなどを読んで何かするってことはそんなになかった(やってみた系の記事ばっかり見てた)んですが、なんだかんだやっぱり公式が情報量多いし正しいし応用も利くしで一番いいですね。

次にやりたいこと

  • Watson Assistantを色々な会話ができるように整備する
  • google Homeと連携させて音声でWatsonとおしゃべりする!

Watson Assistantでチャットボットを作ってみた話

なんでWatson?

大学1年生の頃に、何かの授業でIBM Watsonのプロモーションムービーを見せられたんですよね。
こんな感じの。


IBM Watson: How it Works

近未来感がすごすぎて大興奮したのはいいものの、当時は

(´-`).。oO(いつかWatsonの製品が出たら買おう、そうしよう)

で終わっていました。まだ授業でC言語をちょこっと触ってたくらいで、自分でWatsonを使って何か作るっていう発想自体がなかったのです。

しかし数年後(まだ大学生)、Watsonが無料で使えるという記事を見つけました。APIが提供され始めたという記事です。
ものすごーく興味はあったんですが、ちょっと調べてみてからやめました。英語ばっかりだったからです。

でも今ならいける気がします。就職してから一般的なIT知識もそこそこ分かるようになりましたし、英語もGoogle翻訳さんがいます。最近の和訳の精度恐ろしいですよね。最高です。

ということでめくるめくWatsonの!!世界へ!!!
↓↓↓

watson APIとは?

流石にお仕事上APIってよく聞くんですけど、「アプリケーション・プログラミング・インターフェース」の略だそうです(知らなかった…)。
言葉通りに取ると、アプリケーション(Watson)をプログラミングに組み込む(そして利用する)ためのインターフェース(方法?)てことになります。

こんな分かりやすい記事を見つけました。
自然言語や性格分析も!知っておきたい Watson API まとめ

どうやら、IBM Cloudを利用してAPIを使えるっぽいです。AWSとかMicrosoftAzureとかGoogleCloudのIBM版とみました。
どれも使ったことも触ったこともないので、IBM Cloudが初のクラウドコンピューティングデビュー。どきどきします。正直使いこなせる気はしません。頑張ります。

使うAPIは、Conversation(会話)にします。Watsonと会話。うーん近未来。

IBM Cloud

IDを作る

IBM Cloud アカウントを作る
とりあえずライトプランでアカウントを作りました。

ダッシュボード

f:id:moeka-dev:20180317234200p:plain ちゃんとチュートリアル出してくれるところに優しみを感じる…
リソースっていうのは、きっとこれのことですね↓
地域とロケーション
私が今からいろいろ作業するサーバー(物理)は、米国南部のデータセンターにありますよってことだと思います。なんだかいきなりクラウドコンピューティングって実感が湧いてきました。
サーバー(物理)をどこにするかっていうのも選択できるんですね。通信速度とか、コンプライアンスとかによって変えたりするんでしょうか。とりあえずこのままにしておきます。

Conversationチュートリアル

ダッシュボードからWatsonのConversationのチュートリアルを開いてみると、WatsonAssistantの概説チュートリアルに飛ばされました。
f:id:moeka-dev:20180317234207p:plain なんと全部日本語。Cloudは思ったより優しい世界でした。
とりあえず公式チュートリアルに沿ってやっていけば間違いはないはず。

Watson Assistantで会話をさせてみる!

(´-`).。oO(あれ?Conversationでは?)
と一瞬思いましたが、多分ConversationAPIを使えるツールの名前がWatson Assistant…という関係性なんだと思います。名前がいっぱいあって大変です。

Watson Assistanサービスを追加

f:id:moeka-dev:20180317234214p:plain (´-`).。oO(どこに何を追加するんだ…)
こういうサービスって何も考えなくても使えるのがいいところなんですけど、中で何がおきてるのか知りたい派にとってはたまに辛いです。
とりあえず、私のアカウントにComversationAPIを使うための資格情報を追加するってことですよね。

プロジェクトの作成

とりあえず特定の用途に特化はさせずにいろいろ試してみる予定なので、プロジェクト名は適当につけてライトプランで作成します。 f:id:moeka-dev:20180317234221p:plain f:id:moeka-dev:20180317234229p:plain 作成できました!
ちなみにAPIリファレンスは完全に英語でした。はい。

ツールの起動

ツールの起動をクリックします。別タブが開いてしばらく読み込みマークがぐるぐるします。
全然関係ない話なんですが、デフォルトで別タブ開くのってめちゃくちゃ助かりますよね。わかってらっしゃる。
起動が完了してページが表示…

f:id:moeka-dev:20180317234236p:plain あ〜〜〜英語〜〜〜
IBM CloudのJennyさんからのメッセージはまぁいいとして、後ろにもなんだか英語が見えます。

Jennyさんからのメッセージ

とりあえず英語頑張るって決めたのでJennyさんからのメッセージを読みます。

Introducing Watson Assistant, the new name for Watson Conversation

あれ、ちょっと前に
"多分ConversationAPIを使えるツールの名前がWatson Assistant…という関係性なんだと思います。"
って書いたんですが、どうやら違ったようです。昔は「Watson Comversation」って名前だったけど、「Watson Assistant」という名前に変わったんですね。

This new name better reflects our product direction and vision for how conversational assistants are built.

新しい名前の方がよりJennyさんたちが思い描く方向性やビジョンに合っているそうです。なるほど。

・ Digressions
・ Pre-Built Intents
・ Set Context Variables in Dialog Quickly (vs. JSON updates
・ Dialog Folders
・ Search Intents & Entities
・ Enhanced Analytics Dashboard
・ Separated Log Files with Deployment IDs
・ Dialog Tracing in the Try-It Panel

新しく追加された機能の一覧のようです。ここは潔くGoogle翻訳さんに頼ります。

  • ディグレッション
  • あらかじめ作成されたインテント
  • Dialogでのコンテキスト変数の設定(対JSONアップデート)
  • ダイアログフォルダ
  • 検索インテントとエンティティ
  • 拡張分析ダッシュボード
  • デプロイメントIDを使用したログファイルの分離
  • Try-Itパネルのダイアログトレース

なんだかいろいろ便利機能が追加されたんだなということは何となく伝わってきます(適当)

And in addition to all of this, you can now request access to our BETA program to see where things are headed and to test out features before they're generally available!

さらに、Jennyさんたちが作ったベータプログラムにアクセスリクエストが可能で、新機能が世の中に出る前に試せるらしいです。技術はどんどん公開していくスタンスなんですね。好きです。

Introducing

f:id:moeka-dev:20180317234244p:plain イントロデュースのページには、簡単な概要やWatsonAssistantのコンセプト、ツールの使い方などを説明した動画がたくさん貼り付けてあります。文章じゃなく動画っていうのがいいですね。まあ聞き取れないんですけどね!!!。゚(゚´ω`゚)゚。
流し見て雰囲気だけ感じ取ります。

Watson Assistantを使うための簡単なステップも書いていました。

1. Create intents and entities
2. Build your dialog
3. Test your dialog

  1. Watsonが学ぶことができるような例(インテントとエンティティ)を作る。
  2. 1で作ったインテント・エンティティとアプリケーションのコンテキストを使ってダイアログ(会話)を構築し、仮想アシスタントが適切に応答できるようにする。
  3. 作ったダイアログがちゃんと想定通りに反応するかテスト!

ふむふむなるほど。例を作るのがちょっと大変そうな感じがしますね。

ワークスペースを作成する

f:id:moeka-dev:20180317234253p:plain プロジェクトの中に、さらにワークスペースを作るんですね。
これが成果物のコンテナになるらしいです。1ワークスペースが1会話フローって感じの認識ですかね? f:id:moeka-dev:20180317234301p:plain こんな感じのワークスペースを作りました。天気の話ができたらいいなぁという願望を込めました。 f:id:moeka-dev:20180317234308p:plain できた!
タブが4つあって、インテント、エンティティ、ダイアログ、コンテンツカタログというカテゴリーに分かれています。
さっきステップに出てきた単語ばかりなので何と無く用途はわかりますね。コンテンツカタログはこんな感じでした。 f:id:moeka-dev:20180317234315p:plain

うわ便利〜〜〜〜
これきっと言語を英語とかにしたらもっとあるんだろうなぁ
なんだか便利そうなので、「一般」カテゴリのインテントワークスペースに追加してみました。

Intents

コンテンツカタログにあったものをワークスペースに追加すると、インテントはこんな感じになります。
f:id:moeka-dev:20180317234322p:plain

あ、挨拶がもうすでにある。クリックしてみます。 f:id:moeka-dev:20180317234330p:plain

例がいっぱい並んでいました。

「好ましくないフィードバック」というのもある。 f:id:moeka-dev:20180317234341p:plain

なんか辛辣っすね…(´・ω・)

どうやらインテントというのは、「ユーザーからこんな感じのことを言われたら、それは挨拶だよ!」「これは好ましくないフィードバックだよ!」というのを定義するもののようです。
これがあるから、何か一つのことをしたい時のいろんな表現に対応できるんですね。なるほど。

Entity

を追加するのかなーと思っていたら、チュートリアルにはその項目がなかったので、きっとなくても会話はできるんだと思います。
エンティティは後から触ってみることにします。

Dialog(対話を作成する)

Dialogタブ内で、対話を定義していきます。
とりあえずCreate。 f:id:moeka-dev:20180317234348p:plain こんな画面になりました。なんだこれは。「ようこそ」をクリックしてみます。
f:id:moeka-dev:20180317234355p:plain これみたらなんとなく用途がわかりました。Watsonになんて喋らせたいかを決めるんですね。

Nodeの構成

If bot recognizes:で、会話のトリガーを指定するようです。 f:id:moeka-dev:20180317234402p:plain ここの条件を全部満たせば、後に続くThen respond with:の返答をする、と。
「If」には、intentsやentity、context variables指定でき…context variablesってなんだろう…?  

コンテキスト変数
↑に説明がありました。会話(ノード)をまたいで値を保持する変数ってことですね。Webサービスでいうセッションみたいなイメージ。
せっかくなので、名前を覚えてもらおう!!

コンテキスト変数の設定

Watsonに名前を覚えてもらいたいので、起動させたらまず名前を聞くようにします。 f:id:moeka-dev:20180317234410p:plain 完全にキャラがぶれぶれのやばい奴ですね。

名前を保持するには、「これは名前だ!」というのをWatsonが認識しないといけないので、それをエンティティとして定義しないといけないっぽいのですが、「名前」みたいな一般的な概念は、システムエンティティというのが使えるようです。
有効化〜 f:id:moeka-dev:20180317234417p:plain ない…(´・ω・)

サポートされる言語を調べたらどうやら、現在はsys-personエンティティは英語BETA版でしか扱っていないようです。Jennyが言ってたベータプログラムってここかぁ…そうだよね、名前って難しいもんね。

てわけで自作。 f:id:moeka-dev:20180317234424p:plain うーん適当。Synonmsで同義語を入れられるらしいんですが、そもそも名前だから同義語も何もないですね。そして私の名前しか認識しませんこのWatson。今はこれで許してください。

Dialogに戻って、子ノードを作ります。子ノードってなんじゃ!って方はダイアログのフローをみると大体わかります。

f:id:moeka-dev:20180317234438p:plain こんな感じで作りしました。これできっと覚えてくれるはず…!

そしてそのまま挨拶されるように指定してみる。 f:id:moeka-dev:20180317234447p:plain

テスト!

すぐそこにTry it!っていうのがあって、すぐにテストできるのよいですね。
やってみます。

f:id:moeka-dev:20180317234454p:plain おお!!「もえかだよ〜」って言ったのがジョークだと認識されてるのがちょっと笑えますがうまく行きました( ・∇・)
上の「Manage Context」ってところからコンテキストの現在の状態もみれました。 f:id:moeka-dev:20180317234502p:plain 保存されてる〜〜嬉しい〜〜

まとめ

今回は簡単な会話だけでしたが、IBM Cloud Docsをちょっとみる限り、かなり難しい会話もできそうです! とりあえずJSONを頑張って書こうと思いました笑

次にやりたいこと

  • Slackと連携
  • お天気APIと連携