基于AIML2.0写一个机器人

因为本猿自入行以来都有在开发和维护语音识别这类的产品。只不过是基于像科大讯飞,云知声这类语音引擎,所以对语言识别这块比较好奇,因为好奇,所以也很无奈……之前有尝试过正则式匹配,结果你懂的。

去年年底偶尔看到了AIML(全名为Artificial Intelligence Markup Language(人工智能标记语言)),然后翻了两篇入门博客,感觉这是个好东西。然后,下载了别人的例子来运行,这回让我难受了,源码什么都没修改,运行结果尽然和人家博客写的不一致,而且还老挂。又耗了一个星期去查找资料,发现相关博客基本都是基于AliceBot做的Demo,也都有强调Alice不支持中文需要自己修改,而且Alice官网好像也没有了。当然Iveely Liu也写了一个aiml解析,结合Iveely搜索引擎做了个智能问答机器人(http://www.cnblogs.com/liufanping/p/5879822.html),几个工程代码量比较大,对搜索引擎技术又比较陌生;于是,我找了AIML2.0文档,决定尝试自己去写一个AIML解析器。

年前花了半个月的时间,终于把AIML基本的标签解析弄得差不多了。下面简单介绍一些AIML 2.0。

通配符:

AIML1.0提供了*和_,表示“出现一次或者多次”(以下我简称它们为“1+统配符”)

AIML2.0新添加了^和#,表示“出现零次或者多次”(以下我简称它们为“0+统配符”)

它们的优先级关系:# -> _ -> ^ -> *;


<aiml>标签

AIML文件的根标签,包含aiml文件的内容;

集合SET <set>:

AIML2.0在匹配模型中提供了集合元素匹配

<category>

category表示AIML的基本知识单元

<topic>标签

表示基本知识库单元的主题分类

<pattern>标签

描述知识单元匹配模型

<that>标签

描述上一次匹配的知识单元的匹配模型

<template>标签

描述AIML知识单元的响应,最简答的就是直接返回纯文字,但大多数情况以文字与标签结合形式出现。

<random>标签

描述随机响应

<condition>标签

描述条件响应

<li>标签

描述单条响应

<loop>标签

用于处理<li>标签循环响应

<star>标签

用于提取<pattern>中通配符和集合元素的匹配内容

<thatstar>

用于提取<that>中通配符和集合元素的匹配内容

<topicstar>

用于提取<topic>中通配符和集合元素的匹配内容

<set>和<get>标签

这里的<set>标签包含在<template>中,用于设置变量的值,<get>用于获取某些变量的值

<srai>标识

内容会作为输入继续匹配

<sr/>标签

<sr/> = <srai><star /></srai>


好了,先简单的介绍这些简答的标签;下面我们来看看AIML知识库的几个例子:

最简单的问候语知识单元:

        <category>

<pattern>你好</pattern>

<template>你好!</template>

</category>

当输入“你好”时,机器人回应:“你好!”


随机响应:

        <category>

            <pattern>你有钱吗?</pattern>

            <template>

                <random>

                    <li>谈钱伤感情好吗!</li>

                    <li>作为一个码农,我真心是穷!</li>

                    <li>你猜!</li>

                </random>

        </template>

    </category>

    当输入“你有钱吗?”,机器人从给定的响应中随机响应一条。


条件响应:

 <category>

    <pattern>你有*吗</pattern>

    <template>

        <think><set name="star"><star/></set></think>

        <condition name="star">

            <li value="钱"><srai>你有钱吗?</srai></li>

            <li value="money"><srai>你有钱吗?</srai></li>

            <li value="女朋友"><srai>你亲爱的是谁?</srai></li>

            <li value="老婆"><srai>你亲爱的是谁?</srai></li>

            <li>你是在问我有没有<star />吗?</li>

          </condition>

      </template>

</category>

    这里你肯能注意到了,"你有*吗"其实是可以匹配“你有钱吗?”的,那么这里怎么处理,AIML中精确匹配优先模糊匹配。


响应继续输入:

<category>

    <pattern>现在几点钟</pattern>

    <template>

        <date format="hh点mm"></date>

    </template>

</category>

<category>

    <pattern>#现在的时间|#几点了|#现在几点钟了|#现在几点钟#</pattern>

    <template>

        <srai>现在几点钟</srai>

    </template>

</category>

<category>

    <pattern>#现在的时间|#几点了|#现在几点钟了|#现在几点钟#</pattern>

    <that>现在几点钟</that>

    <template>现在<date format="hh点mm"></date>,你刚问过的。</template>

</category>


    以下贴我测试AIML文件内容,因为现在还在优化解析,所有知识库都是随便写的,大家见谅:

test.aiml

<?xml version="1.0" encoding="UTF-8"?>

<aiml>

    <category>

        <pattern>我叫*</pattern>

        <template>你好,<star /></template>

    </category>

    <category>

        <pattern>#骗你的</pattern>

        <template>

            <random>

                <li>你真不是个好人。</li>

                <li>你是个坏人。</li>

            </random>

        </template>

    </category>

    <category>

        <pattern>我叫*</pattern>

        <that>#骗你的</that>

        <template>以后都不敢相信你了</template>

    </category>

    <category>

        <pattern>#你叫什么名字</pattern>

        <template>我叫<bot name="name"/></template>

    </category>

    <category>

        <pattern>透漏点#</pattern>

        <that>你有*吗</that>

        <template>

            <random>

                <li>打死不说!</li>

                <li>无聊吧,你!</li>

                <li>聊点别的吧!</li>

            </random>

    </template>

</category>

<category>

        <pattern>你有*吗</pattern>

        <template>

            <think><set name="star"><star/></set></think>

            <condition name="star">

                <li value="钱"><srai>你有钱吗?</srai></li>

                <li value="money"><srai>你有钱吗?</srai></li>

                <li value="女朋友"><srai>你亲爱的是谁?</srai></li>

                <li value="老婆"><srai>你亲爱的是谁?</srai></li>

                <li>你是在问我有没有<star />吗?</li>

            </condition>

        </template>

    </category>

    <category>

        <pattern>你有钱吗?</pattern>

        <template>

            <random>

                <li>谈钱伤感情好吗!</li>

                <li>作为一个码农,我真心是穷!</li>

                <li>你猜!</li>

            </random>

        </template>

    </category>

    <category>

        <pattern>你亲爱的是谁?</pattern>

        <template>

            <think>

                    <set name="lover"><bot name="lover"/></set>

            </think>

            <condition name="lover">

                <li value="无"> 

                    <random>

                        <li>我是一只单身狗!</li>

                        <li>单身狗只爱自己!</li>

                        <li>没有女朋友,求介绍!</li>

                    </random>

             </li>

            <li><bot name="lover"/>,是我最最亲爱的她!</li>

        </condition>

    </template>

</category>

<category>

        <pattern>你个混蛋!</pattern>

        <template>

            <srai>你好疯!</srai>

        </template>

</category>


<category>

        <pattern>导航去*</pattern>

        <template>不好意思,我还不会!你用百度地图吧,听说很好用?</template>

</category>


<category>

        <pattern>从*导航去*</pattern>

        <template><star index="1"/><star index="2"/>,你用百度地图吧,听说很好用?</template>

</category>


<category>

        <pattern>你好#</pattern>

        <template>

            <think>

                <set name="star"><star /></set>

            </think>

            <condition name="star">

                <li>你好<star/></li>

                <li value="美">

                    <random>

                        <li>谢谢,你也很美哦!</li>

                        <li>是吗?很美吗?</li>

                        <li>来给我拍张照。</li>

                        <li>说得人家都不好意思了~</li>

                </random>

            </li>

            <li value="无耻">信你才怪!</li>

            <li value="帅">知道就可以了,不要说出来。</li>

            <li value="厉害">哈哈,被你发现啦!</li>

        </condition>

    </template>

</category>


<category>

        <pattern>卖萌</pattern>

        <template>

            <random>

                <li>喵喵~</li>

                <li>么么哒~!!</li>

                <li>人家才不要卖萌~!</li>

                <li>给我滚蛋~!</li>

                </random>

            </template>

</category>


<category>

<pattern>你是不是傻</pattern>

<template>你才傻!</template>

</category>

<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>


name.aiml

<?xml version="1.0" encoding="UTF-8"?>

<aiml>

<category>

<pattern>我叫什么名字?</pattern>

<template>

<random>

<li>我能猜的着才怪呢?</li>

<li>我们认识吗?</li>

<li>对不起,我不认识你。</li>

</random>

</template>

</category>

<category>

<pattern>我叫什么名字?</pattern>

<that>我的名字叫*</that>

<template>

<random>

<li>你在考我吗?你叫<thatstar/></li>

<li><thatstar/>你别闹了!</li>

<li><thatstar/>你改名字了吗?!</li>

</random>

</template>

</category>


<category>

<pattern>#我叫*</pattern>

<template>

<srai>我的名字叫<star index="2"/></srai>

</template>

</category>

<category>

<pattern>我的名字叫*</pattern>

<template>

<!-- <think><set name="clientName"><star /></set></think> -->

很高兴认识你,<set name="clientName"><star /></set>

</template>

</category>

</aiml>


time.aiml

<?xml version="1.0" encoding="UTF-8"?>

<aiml>

<!-- 时间 -->

<category>

<pattern>现在几点钟</pattern>

<template>

<date format="hh点mm"></date>

</template>

</category>

<category>

<pattern>#现在的时间|#几点了|#现在几点钟了|#现在几点钟#</pattern>

<template>

<srai>现在几点钟</srai>

</template>

</category>

<category>

<pattern>#现在的时间|#几点了|#现在几点钟了|#现在几点钟#</pattern>

<that>现在几点钟</that>

<template>现在<date format="hh点mm"></date>,你刚问过的。</template>

</category>

<!-- 日期 -->

<category>

<pattern>今天几号</pattern>

<template>今天<date/></template>

</category>

<category>

<pattern>#今天的日期|#今天几月几号|#今天几月几日|今天几号#</pattern>

<template><srai>今天几号</srai></template>

</category>

<category>

<pattern>#今天的日期|#今天几月几号|#今天几月几日|今天几号#</pattern>

<that>今天几号</that>

<template>今天<date/>,今天是不是对你很重要啊?</template>

</category>

</aiml>


    以下是运行的结果:

基于AIML2.0写一个机器人


目前完成的进度感觉已经可以做做一些智能客服了,后续想定义一些自定义标签做意图识别。今天就先这样吧。