ari3_botの日記
ari3_botというtwitter botを作っています。アリ (@ari3_bot) op Twitter
先週くらいに常用していたセント・ジョーンズ・ワートが切れたせいか、特に自殺とかしなくても自動的に死ぬのではないかというレベルのウツになってて、その異常行動による成果です。(現在は復活しています)
twitter botといえば、n-gramのマルコフ連鎖によってなにかそれっぽい文を生成するか、用意した文章をランダムに流すかが多い気がしますが、このbotはゲームのようにある世界をシミュレートして、その世界にいる一匹のアリが自分のしていることや周りの状況をツイッターで報告するというものです。
基本的な部分は2日で作ったテキトウなものですが、その後毎日更新しまくっています。
README!
http://www.udp.jp/misc/ari3_bot.txt からコピペ。
= @ari3_bot = アリのような外見をした知的な生物をtwitterから観察するためのインターフェースです。 コマンド * putコマンド putコマンドは物質を巣の付近に転送するときに使います。 put 物質名 [type] typeには種類を指定することができます。なにも指定しない場合は食物として転送されます。 typeには次のものが指定できます。(大文字小文字は区別されない) Food : 餌。食料。 Book : 本。読むもの。本でも可。 Video : ビデオ。見るもの。 DVD,アニメでも可。 Game : ゲーム。するもの。ゲームでも可。 例: put いも * いも(食物)を転送する 例: put 人殺しゲーム GAME * 人殺しゲーム(ゲーム)を転送する なお、食物の場合には彼ら全員分程度の量が転送されますが それ以外についてはひとり分しか転送されません。 また当然のことながら食物は転送されてから時間がたつと ダメになり食べることができなくなります。 本は何度か読むと読み終わるでしょうし、ゲームはそのうちにクリアされるでしょう。 * statusコマンド statusコマンドでは、彼らの状態、彼らの所有物を報告したくなる特殊な音波(無害)を送信します。 status [index|名前] [item] 最初の引数は彼らの番号(0から始まる)または名前の部分文字列で、 ふたつ目の引数が報告させる情報の種類です。 引数を指定しない場合は、番号0の状態を報告させます。 ふたつ目の引数にitemという文字列を指定すると、彼らの所有物の情報を報告させます。 例: status * 0の状態を報告させる 例: status 1 * 1の状態を報告させる 例: status 1 item * 1の所有物の情報を報告させる 所有物が多く表示できない場合は適当に省略されます(未確認)。 status アイテム名 最初に引数にアイテム名を渡すと持っている人のアイテムを報告させます。 アイテムには食料(food)は含まれていません。 * 会話 最近開発されたアリ語変換器により会話ができるようになりました。 ただ、まだアリ語の解明も含め研究中なので、そこそこ正しい単純な文でないと通じないかもしれません。 基本的には、主語と述語に注目しているようです。 例: アリはご飯を食べる? アリはかわいい アリはかわいくない アリはご飯を食べるよ 人間は死ぬ 僕は人間である 僕は死ぬ? アリは死なない アリは死なない? アリは昆虫じゃない ねむい だるい おやすみ 格助詞は省略してもある程度は理解しますが あったほうが間違えることが少ないです。 家帰る -> 家に帰る ゴミ捨てる -> ゴミを捨てる アニメ見る?-> アニメを見る? 質問文: アリは昆虫なの アリは昆虫でしょ アリは昆虫だろ アリは怖いね アリは昆虫ですか アリは昆虫? アリは飛ぶ? アリは空を飛ぶのか 昆虫? 飛ぶ? 飛ばない? のような文は質問と認識しているようです。 いまのところ答えがYES/NOになるような質問しか認識できていません。 主語がない文: 昆虫? -> アリさんは昆虫? お腹痛い -> 僕はお腹が痛い(?) のように主語がない質問文はアリさんに係り 主語がない平叙文はしゃべっている人に係ると認識しているようです。 アリさんは知らないことを否定しますが、 正しく教えてあげると否定しなくなります。 アリは穴を掘るよ アリはグッピーを育てます。 僕は真人間である 自分の認識: アリ アリさん アリちゃん おまえ てめえ そち (その他いろいろ) は自分のことだと認識しているようです。 漢字の「蟻」は自分だと認識していないですが、 アリさんは蟻である ということを覚えている場合は、 蟻は穴を掘る アリさんは穴を掘る? にYESと判断するようです。 また、 僕 オレ わたし ウチ われわれ (その他いろいろ) はしゃべっている人のことだと認識しているようです。 アリさんは寝ているときは返信してくれません。 それとは関係なく、たまに返信しないことがあるようです。 * 現在分かっている基本的な行動 - 寝る - 穴を掘る - 餌を探して食べる - 遊ぶ - グッピーを飼育する * 攻略情報 - twitterで発言している彼以外にもアリはいます。 たまに他の人がなにをしているか発言します。 - グッピーの餌は穴掘りで得た金で買っています。 - グッピーは餌をあげないと減ります。時間がたつと分裂します。 - グッピーは彼ら全員で育てています。 -- なにかあれば @ultraistter へ
中身
行動
アリはたぶん階層型の有限状態マシンによるゲームAIで
- 眠くなる
- 寝る
- 寝る準備をする
- 寝る
- 起きる
- 穴を掘る
- 穴掘る
- 誰か遊んでいたら報告する
- 誰かなにか食べていたら報告する
- 餌を探す
- 餌を探す
- なにか見つける
- アイテムなら自分の所有物にする
- 腐っていたら捨てる
- 食べれるなら探すのをやめる
- 食べる
- 料理する
- 食べる
- 感想を言う
- 実は食べれないなら捨てる
- 遊ぶ
- 遊ぶ
- 終わったら(読み終わったり、クリアしたり)捨てる
- グッピーを育てる
(テキトウに書いた)
のような状態をぐるぐる回っています。遷移は、寝る→起きるように決まった行動がいくつかあるのと、それ以外は自分の内部パラメーター(空腹、ストレス、所持金、眠さ、など)から次に遷移する状態の確率を作って、その確率に従うサイコロを振って次の状態を決めています。餌はユーザが置くので、外部からの入力の影響もあります。
アリが育ているグッピーも一匹ずつ単純な有限状態マシンで
- 泳ぐ
- 餌を食べる
- 死ぬ
- 分裂
のような状態を内部パラメーターに従ってぐるぐる回っています。グッピーの餌はアリが与え、アリの行動はユーザの入力に影響を受けているので、グッピーもユーザの影響を受けています。
会話
会話は、CaboChaによる係り受け解析の結果から許容できる文法を抜き出して、それに対して推論したり、事実として認識したりしています。
ちょっと分かりにくいですが、
アリは穴を掘る
のような文を、
- 主語
- アリは
- 述語
- 掘る
- 述語にかかるオプション
- 穴を
に分解した後、
掘る(アリ, 穴)がtrueになるように知識を更新します。
質問は、この逆に、掘る(アリ, 穴)、掘る(人間, nil)、のような関数がtrue/false/nilのいずれかを返すので、それにしたがって日本語での回答を生成して返しています。
アリなのでそんなに賢くない、という言い訳により、あまり深くリンクをたどったりはしていないです。
日本語は品詞ごとに変換用の関数(掘るを否定する→掘らない、眠いを否定する→眠くない、昆虫を否定→昆虫じゃない、など)を作っているので、それらを使って生成しています。
今後
いろいろある。
運用的なこと
ボット同士で無限ループすると困るので、ランダムにに無視していて、botに無視されるとつらいので、最近の会話頻度などから無視するか判断するようにしたい。
会話
行動と同期を取りたい。今は眠い、寝る、○○を食べるなどは、眠い(アリさん, nil)、食べる(アリさん, ○○)などがtrueになるように更新されていますが、全ての行動を知識と同期させたい。
今は知らないことは否定するけど、知らないことは聞き返えして、その答えでうまく知識を更新できるようにしたい。
どうして? ○はなに? ○はどこ? のような聞き出す文に対応したい。
それは違う。のような代名詞の入った文を自分の発言を参照して、再構成してから処理したい。
行動
何日か見てると飽きるので、ウツや風邪、ハイテンションなどなど付加状態を作って、付加状態によって遷移する状態の確率を変えたり、特殊な状態に遷移したりしたい。
なんらかのイベントを適当に発生させて、イベント特有の行動をさせたい。
全部遷移のシナリオを書かないといけないのがダルイというのがありますが、組み合わせでうまく動くようにすれば少数でもそこそこいろいろするのではないか〜と思っています。
よろしく。