hubotに人工無能Reudy19を設定してみた

LINEで送る
Pocket

がじです。

前回raspberry Pi2にHubotをインストールしてみましたが、まだPing ->PONGの応答しかしてくれなくて寂しいので、人工無能Reudy19を設定して会話っぽいことができるようにしました。

参考にしたのはこちらのページ
ポンダッドの日記:人工無脳ReudyをHubotで動かす。

Reudy19は2003年に東京工業大学ロボット技術研究会に所属していた市川 宙さんが作成した人工無能Reudyをmmasakiさんという方がRuby1.9向けに書き直したものです。

公開先はこちら:https://github.com/mmasaki/Reudy19

最初の参考リンク先にほぼすべての情報が書かれているので私の今回のエントリではできるだけ自分でやった作業についてだけ書くことにしてみます。

ーーースポンサードリンク



ーーースポンサードリンク

まず、Reudy19を普通に立ち上げると

ruby stdio_reudy.rb
/home/gaji/workspace/Reudy19/lib/reudy/message_log.rb:27: warning: IO#lines is deprecated; use #each_line instead
ログロード終了
文尾辞書( public/db)を作成中…
/home/gaji/workspace/Reudy19/lib/reudy/message_log.rb:42: warning: IO#lines is deprecated; use #each_line instead
/home/gaji/workspace/Reudy19/lib/reudy/message_log.rb:42: warning: IO#lines is deprecated; use #each_line instead
/home/gaji/workspace/Reudy19/lib/reudy/message_log.rb:42: warning: IO#lines is deprecated; use #each_line instead
/home/gaji/workspace/Reudy19/lib/reudy/message_log.rb:42: warning: IO#lines is deprecated; use #each_line instead
/home/gaji/workspace/Reudy19/lib/reudy/message_log.rb:42: warning: IO#lines is deprecated; use #each_line instead
/home/gaji/workspace/Reudy19/lib/reudy/message_log.rb:42: warning: IO#lines is deprecated; use #each_line instead
/home/gaji/workspace/Reudy19/lib/reudy/message_log.rb:42: warning: IO#lines is deprecated; use #each_line instead
単語ロード終了

と警告が出ますが、Ruby2.3/2.4系でちゃんと動作します。

この警告気にしなくていいのですが、新しいRubyのバージョンでの推奨メソッドを使えということなので一応書き換えておきます。
lib/reudy/message_log.rb

27行目
- @size = f.lines("\n---").count
+ @size = f.each_line("\n---").count)

42行目
- line = f.lines("\n---").find{ f.lineno > n }
+ line = f.each_line("\n---").find{ f.lineno > n }

66行目
- default = f.lines("\n---").select{|s| YAML.load(s)[:fromNick] == "De fault" }
+ default = f.each_line("\n---").select{|s| YAML.load(s)[:fromNick] == "De fault" }

これで一応警告は激減するはずです。

Reudy19をHubutから呼び出すだけで良いのですが、リンク先の元記事にもあるように文書の形態素解析はmecabを使ったほうが良いです。リンク元記事に従ってmecabを設定しておきます。

Reudy19をmecab付きで動かす準備ができたらHubotに組み込む作業に入っていきます。

hubotディレクトリ直下にscriptsフォルダが配置され、このscriptsフォルダは以下にCoffeeScriptを記述することでhubotは様々な挙動をすることができます。

CoffeeScriptはJavaScriptの使い勝手を向上したものでJavaScriptより簡素に記述することができます。しかし、私はCoffeeScriptもJavaScriptも得意ではないので手抜き対応でごまかしました。

参考リンク先の記事の通りに記述してしまうと、毎回応答してしまうので若干うるさい。

また、参考リンクが更に参照している
口下手なチームメイトを1日で教育した話:http://qiita.com/Ets/items/4a0466843c8d98d74295
の記述をそのまま使ってしまうと、話しかけた時だけ応答するようになります。

Reudy19は会話した内容を学習して会話のパターンを増やしていくので、私個人としてはルームの会話で学習をして欲しいが、応答は呼びかけた時だけにしたい。

そこで下記のようなCoffeeScriptをHubotに追加してみました。
reucy.coffee

child_process = require('child_process')
module.exports = (robot) ->
  robot.hear /^(.*)/i, (msg) ->
    text = msg.message.text.replace(/\n/g, "")
    dirpath = '../Reudy19/'
    cmd = "bash -c 'echo #{text} | ( cd \"#{dirpath}\"; ruby -W0 stdio_reudy.rb -m)'"
    child_process.exec cmd, (error, stdout, stderr) ->
      if text.indexOf("sunbot") >= 0
        msg.reply(stdout)
        return
      else
        return

メッセージの本文はすべてReudy19に渡しています。
ただし、ボットの名称”sunbot”が含まれる時だけreplyしてそれ以外は何もせずreturnします。

これで学習しつつ、呼びだされた時だけ応答するボットが完成しました。

なお、このボットプログラム、自宅導入してもあまり受けなかったのですが、こっそり仕事で使っているChatプログラムの雑談チャネルに入れておいたら、仕事仲間の皆さんにはばかうけでした。

ああ、こんなこと書いて身バレしませんように

ーーースポンサードリンクーーー

LINEで送る
Pocket