User Localの人工知能ボットAPIを使ってLINEで雑談してみました


先日User Localが[人工知能ボットAPI](http://ai.userlocal.jp/)を公開しました。ボット開発に必要な自然言語処理ライブラリを集約したもので、現時点で以下のような機能が提供されています。

- 全自動会話API
- 氏名自動識別API
- キャラクター会話API
- 形態素解析API

国産のボット作成サービスということで、前々から気になっていたので早速手を出してみました。今回は全自動会話APIを使ってLINEボットを作成しました。

# 機能確認

## 準備

利用するためには[ここ](http://ai.userlocal.jp/)から会員登録が必要で、現在、第2期募集を行っています。自分は第一期に申し込んで、6月15日にAPIキーが届きました。今から申し込んだ場合は、利用できるまでに若干時間がかかるかもしれません。ただし、会員登録しなくても試用する方法は用意されています。


また、今回はBot実装にあたって、Ruby、sinatra、heroku、LINE BOT API等を利用しています。
[参考1](http://www.sakana.tech/entry/2016/04/12/112700) [参考2](http://qiita.com/EastResident/items/d1b572f00c29f907b743)

## 動作検証

Botを作る前にとりあえず通信してみます。自動会話APIを利用するには、パラメータを付与して<https://chatbot-api.userlocal.jp/api/chat>に向けてGETすればいいようです(POSTもできます)。

```
https://chatbot-api.userlocal.jp/api/chat?key=your_api_key&message=こんにちは
```

"key"はUserLocalから提供されるAPIキーです。"message"には話しかけるテキストを入力します。ちなみに、keyに "sample"と入れると、未登録でも利用できます(10回/1hまで)。

それでは試しに通信して、結果を受け取ってみましょう。最初はPOSTで通信しようと思ったのですが、RubyのRestClientではなぜかjsonが渡らなかったので、getでリクエストを送っています。

```rb
require 'json'
require 'rest-client'
require "cgi"

request_content = {'key' => '5d11a37a8e1ff54e86cf', 'message' => CGI.escape('こんにちは')}
request_params = request_content.reduce([]) do |params, (key, value)|
  params << "#{key.to_s}=#{value}"
end
rest = RestClient.get('https://chatbot-api.userlocal.jp/api/chat?' + request_params.join('&').to_s)
result = JSON.parse(rest)
p result
```

上記のコードを実行すると、以下のような結果が出力されました。

```json
{"status"=>"success", "result"=>"おはようございます"}
```

今は朝ではないのですが、あいさつを返してくれました。

# 実装

では実際にLINEボットとして実装していきます。今回は、Ruby、Sinatra、heroku、LINE BOT APIを使用しています。このあたりの詳しい使用方法に関しては先人の方々がまとめてくださっているので、詳しくは割愛します。

[参考1:LINE botでオウム返しをブラウザ上で作る全手順](http://www.sakana.tech/entry/2016/04/12/112700)
[参考2:LINE BOT APIでgoogle検索ボットを作った](http://qiita.com/EastResident/items/d1b572f00c29f907b743)

## ファイル構成
ファイル構成は以下のような感じです。

- working_folder
  - Gemfile
  - config.ru
  - main.rb

## Gemfileの編集

Gemfileを以下のように編集し、'bundle install'を実行します。

```
source "https://rubygems.org"

gem 'sinatra'
gem 'json'
gem 'rest-client'
gem 'sinatra-contrib'
```

## config.ruの編集

config.ruは、以下のように編集します。こちらに処理を書いてもいいのですが、今回はmain.rbのほうに処理を書いていきます。

```rb
require './main.rb'

run Main
```

## 環境変数に追加
API KEYやID等の情報をherokuの環境変数に追加します。
LINE developersで作成したアカウントのBasic informationから、Channel ID、 Channel Secret、 MIDの3つ、herokuのFixieアドオンのproxy_URL、そして人工知能ボットAPIのAPI キーを登録します。

```
heroku config:add LINE_CHANNEL_ID="your_channel_id"
heroku config:add LINE_CHANNEL_SECRET="your_channel_secret"
heroku config:add LINE_CHANNEL_MID="your_channel_mid"
heroku config:add USR_LOCAL_API_KEY="your_api_key"
heroku config:add FIXIE_URL="your_proxy_url"
```

## main.rbの編集

main.rbを以下のように編集します。

```rb
require 'bundler/setup'
require 'sinatra/base'
require 'json'
require 'rest-client'
require "cgi"

class Main < Sinatra::Base

  post '/linebot/callback' do
    @params = JSON.parse(request.body.read)['result'].first

    post_text(get_userlocal_bot)
  end

  private

  def post_text(*post_messages)
    line_pipe = {
      'Content-Type': 'application/json; charset=UTF-8',
      'X-Line-ChannelID': ENV['LINE_CHANNEL_ID'],
      'X-Line-ChannelSecret': ENV['LINE_CHANNEL_SECRET'],
      'X-Line-Trusted-User-With-ACL': ENV['LINE_CHANNEL_MID']
    }

    RestClient.proxy = ENV['FIXIE_URL']
    endpoint_uri = 'https://trialbot-api.line.me/v1/events'

    post_messages.flatten.each do |post_message|
      request_content = {
        to: [@params['content']['from']],
        toChannel: 1383378250,
        eventType: '138311608800106203',
        content: {contentType:1, toType:1, text: post_message }
      }
      content_json = request_content.to_json

      RestClient.post(endpoint_uri, content_json, line_pipe)
    end
  end

  def get_userlocal_bot
    word = @params['content']['text']

    request_content = {'key' =>  ENV['USR_LOCAL_API_KEY'], 'message' => CGI.escape(word), 'user_id' => @params['content']['from']}

    request_params = request_content.reduce([]) do |params, (key, value)|
      params << "#{key}=#{value}"
    end
    rest = RestClient.get('https://chatbot-api.userlocal.jp/api/chat?' + request_params.join('&').to_s)

    result = JSON.parse(rest)
    result['result']
  end
end
```

## 動作確認

LINE上で会話してみました。

![スクリーンショット 2016-06-17 00.01.40.png](https://qiita-image-store.s3.amazonaws.com/0/79302/673fdc7d-5c6e-a611-34e5-2599c74f1c05.png)

# 感想

先日、類似の国産サービスである[BOT TREE for MEDIA](http://zeals.co.jp/bottree/)がリリースされるなど、日本でもチャットボットがより身近になってきているように思います。

今回使用してみた全自動会話APIですが、正直、現状では精度が高いとは言えません。しかし、この部分に関しては公式側で、

>会話の精度については、まだ機械学習の途中であり、今後、会話の質が上がっていく予定です。(初期段階では、学習や調整が進んでいないため会話精度が低いことがあります)

と言及されているため、時間が経つにしたがって、会話精度の向上が見込めるかもしれません。今後も様々な追加機能の提供を控えているようなので、これからの展開に期待です。