ボットアドベントカレンダー2日目です。今日は、前世紀〜今世紀初頭にタイムスリップします。
AIMLの概要
IntentやEntityをある程度大量に機械学習させ、構文の構造から判別したり、学習済みの似た言葉を参考として判別したりするのが、現在(2017年)のチャットボットの主流です。しかし、今回の機械学習ブームが起きる前は、ひたすらルールベースで定義していました。いわゆる、「人工無能」系です。
AIML(Artificial Intelligence Markup Language)は、XMLベースでルールの定義を行うための言語で、カーネギーメロン大学のRichard WallaceやOSSコミュニティが、主に1995年から2000年にかけて開発しました。A.L.I.C.E. (Artificial Linguistic Internet Computer Entity)というボットの定義を記述した言語としても知られています。
現在では、昨日紹介したようなapi.ai、LUIS、Watsonなど、機械学習を交えた意図理解が主流で、わざわざ今からAIMLでルールを定義しようという方はあまり居ないと思います。実際、AIMLやA.L.I.C.E.関連のサイトは、大量にリンク切れを起こしています。しかし一方で、定義した内容以外の要因でボットが動作することはないという利点から、まだまだ需要があるようです。
AIMLで書かれたXMLをパースするライブラリは、C++, Python, Java, Rubyなどの主要言語で、主に個人が作成したものがネット上に公開されています。Pandorabot Playgroundでは、記述したAIMLファイルをアップロードして、ブラウザ上で無料で動作確認できます。
AIMLでのルール記述方法
細かい仕様を挙げればきりがないですが、この記事は入門ということで、重要な要素のみを簡単に紹介します。
<aiml> : まずは、枠だ
どんなXMLにも、root要素は必要です。AIMLでは、<aiml>
です。
<?xml version="1.0" encoding="UTF-8"?>
<aiml version="1.0.1" encoding="UTF-8">
</aiml>
AIMLのバージョンが何を使うかが悩みどころですが、組み込もうとしている言語のライブラリで準拠しているバージョンにするのが無難です。例えば、PyAIMLでは1.0.1準拠となっています。なお、これまでに仕様が公開されたのは、0.9
、1.0
、1.0.1
、(1.1
、)2.0
です。
<category> : Intentのようなもの
さて、枠の中に1個、ルールを入れてみましょう。
<?xml version="1.0" encoding="UTF-8"?>
<aiml version="1.0.1" encoding="UTF-8">
<category>
<pattern>こんにちは</pattern>
<template>ども</template>
</category>
</aiml>
ルールごとに<category>
のブロックを作成します。
<category>
の中には、<pattern>
と<template>
を定義します。<pattern>
がユーザが話した言葉で、<template>
がボットから返す言葉です。
* と _ と <star> : マッチした文字列の参照
patternの文字列には*
と_
が入れられます。しかし、これは正規表現とは全く関係ありません。AIML独自の定義となっています。
*
と_
は、正規表現グループのようなものです。言語仕様上は、どちらの記号を使っても全く同じ効果です。
<?xml version="1.0" encoding="UTF-8"?>
<aiml version="1.0.1" encoding="UTF-8">
<category>
<pattern>こんにちは * です</pattern>
<template>ども</template>
</category>
</aiml>
上記のようにすると、「こんにちは A です」「こんにちは B です」でも、「ども」と返ってくることになります。
多くのAIMLパーサは、単語の間にスペースがある言語を前提としていますので、日本語で利用する場合は、Mecab等であらかじめ分かち書きした状態でAIMLパーサに渡すなどの前処理が必要になります。
せっかく名乗っているのに「ども」とだけ返されるのは塩対応だ、と思ったら、このように変更します。
<?xml version="1.0" encoding="UTF-8"?>
<aiml version="1.0.1" encoding="UTF-8">
<category>
<pattern>こんにちは * です</pattern>
<template><star index="1"/>さん、ども</template>
</category>
</aiml>
これで、「Aさん、ども」「Bさん、ども」と返ってきます。
<srai> : 継承のようなもの
例えば、とりあえず最初でも最後でも真ん中でも、どこかに「こんにちは」と入っていたら「ども」を返したいとします。今まで説明した範囲で書くと、以下のようになります。
<?xml version="1.0" encoding="UTF-8"?>
<aiml version="1.0.1" encoding="UTF-8">
<category>
<pattern>こんにちは</pattern>
<template>ども</template>
</category>
<category>
<pattern>_ こんにちは</pattern>
<template>ども</template>
</category>
<category>
<pattern>こんにちは _</pattern>
<template>ども</template>
</category>
<category>
<pattern>_ こんにちは _</pattern>
<template>ども</template>
</category>
</aiml>
この例では「ども」だけですので、あまりしんどくはないかと思いますが、返す文章が長いとメンテナンスが大変になります。その時に、<srai>
を使うと、多少は楽になります。sraiとは、Stimulus-Response artificial intelligenceの略だそうです。
<?xml version="1.0" encoding="UTF-8"?>
<aiml version="1.0.1" encoding="UTF-8">
<category>
<pattern>こんにちは</pattern>
<template>ども</template>
</category>
<category>
<pattern>_ こんにちは</pattern>
<template><srai>こんにちは</srai></template>
</category>
<category>
<pattern>こんにちは _</pattern>
<template><srai>こんにちは</srai></template>
</category>
<category>
<pattern>_ こんにちは _</pattern>
<template><srai>こんにちは</srai></template>
</category>
</aiml>
<srai>
で他のcategoryのpattern文字列を指定すると、そのpatternのtemplateの文字列に置き換えられます。_
や*
の部分を他のcategoryのtemplate文字列に置き換えることもできます。その場合は、<srai><star /></srai>
とするか、略して<sr />
とするかします。
<?xml version="1.0" encoding="UTF-8"?>
<aiml version="1.0.1" encoding="UTF-8">
<category>
<pattern>AIML</pattern>
<template>チャットボットなどのルール定義に使用するXMLベースの言語</template>
</category>
<category>
<pattern>_ とはなんですか</pattern>
<template><sr />です</template>
</category>
</aiml>
上記の例では、「AIML とはなんですか」という質問に「チャットボットなどのルール定義に使用するXMLベースの言語です」と返します。
参考サイト
上記で紹介したのはほんの一部です。興味があれば、下記のサイトを確認してみてください。
言語仕様
-
0.9と1.0 AIML Reference Manual
-
1.0.1?1.1? Artificial Intelligence Markup Language (AIML) Version 1.0.1
チュートリアル系
本家は上記ですが、普通に「AIML」でググれば、他にも色々見つかります。パーサの実装に依存する処理について書かれているなどして分かりづらいものもあります。
A.L.I.C.E.のAIMLファイル
1.9が最新の模様。
Free A.L.I.C.E. AIML Set