基于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></category>
<template>听不懂你说什么!</template>
<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>
以下是运行的结果:
目前完成的进度感觉已经可以做做一些智能客服了,后续想定义一些自定义标签做意图识别。今天就先这样吧。