voluntas-bot の歴史を振り返る

voluntas-bot とは?

voluntas-bot (以下bot) とは、 @moriyoshit が開発した pyspa チャットのための bot ツールである。普通のchatbot同様、コマンド入力に応じた動作を行うことができるのが、sayingコマンド(通称「語録」)という非常にユニークな操作ができるのが特徴である。本記事では、主にこのsayingコマンドの進化に絞った形でのbotの発展の歴史を振り返っていく。

sayingコマンド黎明期

初期の saying コマンドの運用は、まさに文字通り、参加者の語録を保存しランダムに表示するためのものとして用いられていた。

例えば、moriyoshi が「いくつになってもsvnを触るとドキドキするもんだよ」とチャットで発言し、これを私がとても面白いと思ったとする。そのとき、私は moriyoshi の発言をヲ語録として登録することができる。

!moriyoshi いくつになってもsvnを触るとドキドキするもんだよ

このように登録された語録は、あとからランダムで一つ取り出すことができるようになる。

!moriyoshi
> いくつになってもsvnを触るとドキドキするもんだよ

また、任意のユーザを追加できることができる。例えば、私の語録を新規に作成したい場合は以下のコマンドを実行すればいい。

!saying create shiumachi

見ての通り、非常に単純なkey-value型のデータストアをベースとしたコマンドであり、仕組み自体はとても簡素なものである。この基本的なアーキテクチャは現在も全く変わっていない。
しかし、たったこれだけの仕組みで非常に多様な表現ができるようになるのである。その変遷をこれから紹介しよう。

「誰」「何」「サ変」の誕生: 文章の自動生成の始まり

複数の語録を連結して表示する機能が追加され、そして文字列リテラルが追加された。
その後、誰かが「誰」「何」という語録を作成した。続いて、「サ変」という語録を作成した。
これにより、以下のようなコマンドが実行できるようになった。

!{誰}が{何}を{サ変}した
> ドラえもんが10万円を確定申告した

このように、名詞とサ変動詞を語録として保存しランダムに取り出すことで、文章の自動生成が可能になったのである。
当初のsayingコマンド開発時の想定から大きく離れた、全く別の活用方法である。

この品詞語録の特徴はあくまで「人力」ということである。
ただ同一品詞の言葉を集めてをDBに追加するだけなら簡単なのだが、重要なのは pyspa チャット参加者が、pyspa チャットの発言を見て面白いと思ったと品詞を追加するというというプロセスである。
これにより、pyspa チャットの人達の琴線に触れる品詞のみが集積されていき、生成される文章が pyspa チャット参加者にとって面白くなる確率を上げているのである。
上記の文章の例は比較的一般の人でも楽しめるようなものを取り上げたが、実際には pyspa チャット内でのみ楽しめるような内輪ネタのような文も多く生成されている。


また、語録を連結したコマンドそのものも語録として登録できるようになった。
これにより、生成パターンそのものをランダムに出力させることができるようになった。
たとえば、以下のように「日記」語録を作成することができる。

!日記 {今日は}{誰}{と}{どこ}{に行って}{どうした}{。by}{誰}
!日記
> 今日は蒼井そらと歓楽街に行って買い取った。by tokibito

モーラ語録の登場と俳句ブーム到来

品詞語録が作れるのであれば、同じモーラ数で集めた語録も作ることができることは明白である。モーラとは、言葉の音の拍子の数のことである。例えば、「バルク」「あの日」「手術」は全て3モーラである。詳細は wikipedia の該当項目を参照してほしい。 https://ja.wikipedia.org/wiki/%E3%83%A2%E3%83%BC%E3%83%A9

これにより、俳句語録を作成することができるようになった。

!俳句 {2}{3}{" "}{5}{2}{" "}{3}{2}
!俳句
> カツ麻薬 ディープキス事故 破壊キス

俳句というにはあまりに風情のない生成文ではあるが、五七五の音を作り出すことができるようになった。

接頭・接尾語録: 俳句 ver.2

あるとき、モーラ語録に登録された言葉を三種類に分類できることに気づいた。

  • 句の頭につけないと意味が通らないもの。例: 「青い」
  • 句の最後につけないと意味が通らないもの。例: 「ゆえに」
  • 句のどこにあっても意味が通るもの。例: 「カレー」

これを元に、従来のモーラ語録から一部の言葉を「接頭」「接尾」語録に振り分けた。たとえば「3」語録なら、「3接頭」「3接尾」というようにである。
これを活用し、俳句語録の改良版である「俳句2」語録を開発した。

!俳句2 {3接頭}{2}{" "}{4}{3接尾}{" "}{5}
!俳句2
> 地味な海 邪気眼匂う 秋深し

この改良により、俳句としての美しさが格段に上がり、より深みのある自動生成俳句を楽しむことができるようになった。

初句・中句・結句: 俳句 ver.3

しかし、俳句2もまだ完璧というわけにはいかない。接頭・接尾のような分離が難しい5・
7語録にも問題が残されている。
例えば先ほど例でとりあげた俳句「地味な海 邪気眼匂う 秋深し」は、本来この「秋深し」は初句(一番最初の五の部分)に来るべき内容であり、結句(一番最後の五の部分)に表示されるのはふさわしくない。
これは短歌にしたときに7語録にも同じ話が言える。下の句である七七のどちらの位置で生成されるのがふさわしいかは内容によって異なるのである。
そこで、「5初句」「5結句」「7中句」「7結句」を作成し、「俳句3」を開発した。

!俳句3 {5初句}{" "}{7中句}{" "}{5結句}
!俳句3
> 寂しさに キングファイルが 救世主

rsub関数、let関数の登場と「伝記」語録の開発

「誰」「サ変」に代表されるに品詞語録によって、簡単な文章の作成は行えるようになった。しかし、長文を生成するとなると、生成された単語を繰り返し使う必要が出てくる。これを実現するには変数束縛の仕組みが必要である。
moriyoshiがいくつかの方式を実装したが、文法がかなり複雑であまり普及しなかった。しかし、rsub関数の登場により変数束縛の時代が訪れることになった。

rsub 関数はpython の re.sub() にインスパイアされた、正規表現マッチングによる置換機能を持つ関数である。
最もシンプルな(そして想定された)使い方は、生成された文章の特定の語を置換することである。

!rsub("[ww]", "笑", がーすー)
> 地獄絵図じゃないっすか笑

しかし、正規表現のグルーピングを利用することで、変数束縛を行うことができる。

!rsub("(.*)::(.*)", "昨日、"{$1}"が"{$2}"に行ったら、"{$1}"の妹に会った。", {random}"::"{どこ})
> 昨日、とんぷーがハト小屋に行ったら、とんぷーの妹に会った。

変数束縛したい言葉を第三引数に記述する。第三引数全体にマッチさせることで第三引数は最終的に生成させず、第二引数に記述された「置換後の文章」が実際に生成される文章のベースとなる。

!伝記 rsub("(.*)::(.*)::(.*)",{"その昔、"}{$1}{"という日本人が"}{$2}{"で活躍したという文献が残っている。
"}{$1}{"は旅の"}{職業}{"だったが実は"}{$3}{"の達人で、秒間"}{nine}{num}{"回も"}{$3}{"することができたため、"}{$2}{"が危機に瀕したときに大いに役立った。
"}{$1}{"の子孫は"}{random}{"という名で、今も日本にその血筋が残っている。"},{random}{"::"}{国}{"::"}{サ変})
!伝記
> その昔、とんぷーという日本人がカザフスタンで活躍したという文献が残っている。
とんぷーは旅のゲームクリエイターだったが実は割り勘の達人で、秒間63回も割り勘することができたため、カザフスタンが危機に瀕したときに大いに役立った。
とんぷーの子孫はaodagという名で、今も日本にその血筋が残っている。


それからしばらくして、let関数が実装された。これによって変数束縛はより容易になった。上記のrsub関数による伝記語録は、以下のは、語録と等価である。

let({"その昔、"}{主人公}{"という日本人が"}{活躍国}{"で活躍したという文献が残っている。
"}{主人公}{"は旅の"}{職業}{"だったが実は"}{スキル}{"の達人で、秒間"}{nine}{num}{"回も"}{スキル}{"することができたため、"}{活躍国}{"が危機に瀕したときに大いに役立った。
"}{主人公}{"の子孫は"}{random}{"という名で、今も日本にその血筋が残っている。"}, 主人公(random), 活躍国(国), スキル(サ変))

まとめと今後の展望

以上、botコマンドのうち特に語録コマンドの発展について説明した。現在よく使われている語録である儀式、自由律俳句などについては文章量の都合上割愛した。
今後の展望としては、botコマンドのオープンソース化が挙げられる。現在、ある事情があってソース公開には至っていない。また、公開のためにはいくつかのハードルがあり、現在のところ解決できていない。pyspaチャット参加者以外の人でbotを使ってみたいという人はもうしばらく待ってほしい。
その他、管理コマンドの追加、特に統計情報の取得・表示などが開発要望として挙げられている。

謝辞

開発者の moriyoshi、私と同じくらいのbotヘビーユーザであるaodag、そしてbotとともに生活する全ての pyspa コミュニティの参加者達に心から感謝いたします。