目录
1. AIML简介 2. AIML的安装 3. AIML的使用 4. AIML语法简介 5. 添加多个AIML文件 6. 加速AIML的载入 7. 会话和谓词
AIML简介
AIML,全名为Artificial Intelligence Markup Language(人工智能标记语言),是一种创建自然语言软件代理的XML语言,是由Richard Wallace和世界各地的自由软件社区在1995年至2002年发明的。Richard Wallace设计了一个名为 A.L.I.C.E.(Artificial Linguistics Internet Computer Entity人工语言网计算机实体)的机器人,并获得了多项人工智能大奖。AIML定语基于规则的聊天机器人的响应。
AIML的安装
AIML原本不支持中文,程序员yaleimeng(https://github.com/yaleimeng)移植到中文语境上。可以直接到他的仓库(https://github.com/yaleimeng/py3Aiml_Chinese)里git下来,该项目运行于python3环境。不需要安装,把源码放到项目目录下即可运行。
AIML一开始是基于python的,后来被移植到各个平台,对于C#如何使用AIML,请参阅博客:https://blog.csdn.net/u010019717/article/details/53791579。
AIML的使用
作者给了一个示例放在Example文件夹里:
# -*- coding: utf-8 -*- ''' @author: yaleimeng@sina.com @license: (C) Copyright 2017 @desc: python3 版本中文Alice,暂时简单添加空格 @DateTime: Created on 2017/11/15,at 10:20 ''' import Kernel alice = Kernel.Kernel() alice.learn("cn-test.aiml") while True: print(alice.respond(input('Alice请您提问...>>')))
将该源文件与aiml源码放在一起运行,结果如下:
从运行结果可知该程序对于你的输入并不能全部响应,而是输出WARNING:No match found for input,这是因为你没有定义对应的模板或者说规则。该程序的模板被定义在cn-test.aiml文件中,打开该文件你就能看到里面是类似xml的文件。下面说明aiml文件元素的意义。
AIML语法简介
AIML的通配符
AIML1.0提供了*和_,表示“出现一次或者多次”;
AIML2.0新添加了^和#,表示“出现零次或者多次”,本文档所用的aiml解析器暂未支持aiml2.0
aiml元素
aiml文件的根标签,包含aiml文件的内容。
category元素
category是AIML库中的基本单位,每个category元素都至少包含两个子元素:pattern和template元素。下面是个简单的例子:
<category> <pattern>WHAT IS YOUR NAME</pattern> <template>My name is Leo.</template> </category>
当这个AIML库被加载之后,你问机器人“WHAT IS YOUR NAME”,机器人便会回答“My name is Leo.”。
Pattern元素
Pattern主要用来匹配用户输入,在原生的英文AIML语法中Pattern支持 _ 和 * 的模糊匹配。例如:
<category> <pattern>WHAT IS YOUR *</pattern> <template>My name is Leo.</template> </category>
只要用户的输入是以“WHAT IS YOUR ”开头,机器人就会回复“My name is Leo.”。
Template元素
很明显Template元素是机器人的对用户提问的回答,当用户的输入和同一个category下的Pattern相匹配是,就会将此category元素下的Template输出。
That元素
机器人之所以有思考功能,主要就是that元素的作用。例如:
<category A> <pattern>是的</pattern> <that>你是程序员吗?</that> <template>你最擅长的编程语言是什么?</template> </category> <category B> <pattern>是的</pattern> <that>你是学生吗?</that> <template> 你是哪个学校的</template> </category>
机器人首先通过pattern匹配,匹配到了“是的”但是机器人的数据库中对应“是的”的回答必然非常多,比方有下面A和B两个categories。于是机器人便去匹配that标签,也就是机器人自己上句说过的话,即“你是程序员吗?”这样它就可以确定应该匹配category A了,最后给出正确的回应“你最擅长的编程语言是什么?”
Random元素
在某个匹配的很多回答中随机选取一个
<category> <pattern>ONE TIME I *</pattern> <template> <random> <li>Go on.</li> <li>How old are you?</li> <li>Be more specific.</li> <li>I did not know that.</li> <li>Are you telling the truth?</li> <li>I don't know what that means.</li> <li>Try to tell me that another way.</li> <li>Are you talking about an animal, vegetable or mineral?</li> <li>What is it?</li> </random> </template> </category>
li元素
表示单条响应
star元素
匹配pattern标签中的*通配符,示例如下:
<category> <pattern> A * is a *. </pattern> <template> When a <star index = "1"/> is not a <star index = "2"/>? </template> </category>
如果用户输入: "A mango is a fruit." 机器人会回答: "When a mango is not a fruit?",其中index属性描述通配符的位置
topic元素
<topic>标记在AIML中用于存储上下文,以便以后的对话可以基于该上下文完成。通常,<topic>标签用于是/否类型对话。它有助于AIML搜索在主题上下文中编写的类别。使用如下:
使用<set>标签定义主题
<template> <set name = "topic"> topic-name </set> </template> 使用<topic>标记定义类别 <topic name = "topic-name"> <category> ... </category> </topic>
在这里,机器人以“电影”为主题进行回应。
<?xml version = "1.0" encoding = "UTF-8"?> <aiml version = "1.0" encoding = "UTF-8"?> <category> <pattern>LET DISCUSS MOVIES</pattern> <template>Yes <set name = "topic">movies</set></template> </category> <topic name = "movies"> <category> <pattern> * </pattern> <template>Watching good movie refreshes our minds.</template> </category> <category> <pattern> I LIKE WATCHING COMEDY! </pattern> <template>I like comedy movies too.</template> </category> </topic> </aiml>
结果输出:
Human: let discuss movies Robot: Yes movies Human: Comedy movies are nice to watch Robot: Watching good movie refreshes our minds. Human: I like watching comedy Robot: I like watching comedy too.
condition元素
<condition>标签类似于编程语言中的switch语句。它有助于ALICE响应匹配的输入。使用:
<category> <pattern> HOW ARE YOU FEELING TODAY </pattern> <template> <think><set name = "state"> happy</set></think> <condition name = "state" value = "happy"> I am happy! </condition> <condition name = "state" value = "sad"> I am sad! </condition> </template> </category>
结果:
Human: How are you feeling today Robot: I am happy!
srai元素
内容会作为输入继续匹配,该标签可以为同一个回答匹配多个问句。主要的功能是:简化模式、分而治之、同义词解析、关键词检测。示例如下:
<category> <pattern>现在几点钟</pattern> <template> <date format="hh点mm"></date> </template> </category> <category> <pattern>几点了</pattern> <template> <srai>现在几点钟</srai> </template> </category>
运行结果:
>>几点了 Sun Feb 17 16:45:56 2019
<set>和<get>
这里的<set>标签包含在<template>中,用于设置变量的值,<get>用于获取某些变量的值。举例如下:
<?xml version = "1.0" encoding = "UTF-8"?> <aiml version = "1.0.1" encoding = "UTF-8"?> <category> <pattern>I am *</pattern> <template> Hello <set name = "username"> <star/>! </set> </template> </category> <category> <pattern>Good Night</pattern> <template> Hi <get name = "username"/> Thanks for the conversation! </template> </category> </aiml>
输出:
Human: I am Mahesh Robot: Hello Mahesh! Human: Good Night Robot: Good Night Mahesh! Thanks for the conversation!
Learn元素
描述aiml文件
Thank元素
<think>标签在AIML中用于存储变量而不通知用户。使用<think>标记存储值:
<think> <set name = "variable-name"> variable-value </set> </think>
使用:
<category> <pattern>My name is *</pattern> <template> Hello!<think><set name = "username"> <star/></set></think> </template> </category> <category> <pattern>Byeee</pattern> <template> Hi <get name = "username"/> Thanks for the conversation! </template> </category>
结果:
Human: My name is Mahesh Robot: Hello! Human: Byeee Robot: Hi Mahesh Thanks for the conversation!
添加多个aiml文件
当我们的模板很多的时候,一个aiml文件是不够的,我们可以通过以下方式添加多个aiml文件。标准的做法是,创建一个名为std-startup.xml的启动文件,作为加载AIML文件的主入口点。
<?xml version="1.0" encoding="UTF-8"?> <aiml version="1.0"> <meta name="author" content="Yalei"/> <meta name="language" content="zh"/> <!-- std-startup.xml --> <category> <pattern>LOAD AIML</pattern> <template> <learn>template1.aiml</learn> </template> </category> </aiml>
Template1.aiml的内容为:
<?xml version="1.0" encoding="UTF-8"?> <aiml version="1.0"> <!-- Free software (c) 2017 yalei --> <!-- This program is open source code released under --> <!-- the terms of the GNU General Public License --> <!-- as published by the Free Software Foundation. --> <meta name="author" content="Yalei"/> <meta name="language" content="zh"/> <category> <pattern>* 再见</pattern> <template> <random> <li>再见,<get name="name"/>.</li> <li>好的,有空再聊, <get name="name"/>.</li> <li>下次见, <get name="name"/>.</li> <li>谢谢你陪我聊天, <get name="name"/>.</li> <li>改天见, <get name="name"/>.</li> </random> </template> </category> </aiml>
源代码内容为:
# -*- coding: utf-8 -*- import Kernel import sys import os bot = Kernel.Kernel() bot.learn("std-startup.aiml") bot.respond('LOAD AIML') while True: print(bot.respond(input('>>')))
当程序运行时,先载入启动文件,然后再载入其它aiml文件,启动文件只是入口,
Template1.aiml才是真正描述规则的地方。
加速AIML载入
随机aiml文件的增多,程序的学习的时间会长很多,这时候我们需要用大脑文件加速这个过程。在机器人学习完所有 AIML 文件后,它可以直接以文件形式存储大脑,再次运行时可以大大提升载入时间。程序如下:
# -*- coding: utf-8 -*- import Kernel import sys import os bot = Kernel.Kernel() fileName='bot_brain.brn' if(os.path.isfile(fileName)): bot.bootstrap(brainFile=fileName) else: bot.bootstrap(learnFiles='std-startup.aiml',commands='LOAD AIML') bot.saveBrain(fileName) while True: print(bot.respond(input('>>')))
会话和谓词(Predicates)
通过指定会话,AIML 能根据不同对话者随机应变。举个例子,如果某人告诉机器人他们叫 Alice,另一个人则告诉机器人它叫 Bob,机器人可以分清他们。指定你需要的会话,将它作为第二个参数传递给 respond()。
sessionId = 12345 kernel.respond(raw_input(">>>"), sessionId)
和每个客户都能有个性化的对话——这棒极了。你不得不生成你特有的会话ID并追踪。记住保存大脑文件不要保存所有的会话值。
sessionId = 12345 # 将会话信息作为字典 # 包含输入输出的历史像已知谓词那样 sessionData = kernel.getSessionData(sessionId) # 每个会话ID需要一个唯一的值 # 用会话中机器人已知的人或事给谓词命名 # 机器人已经知道你叫"Billy"而你的狗叫"Brandy" kernel.setPredicate("dog", "Brandy", sessionId) clients_dogs_name = kernel.getPredicate("dog", sessionId) kernel.setBotPredicate("hometown", "127.0.0.1") bot_hometown = kernel.getBotPredicate("hometown") 在AIML中,我们可以在 项中设置谓词。
aiml文件:
<aiml version="1.0" encoding="UTF-8"> <category> <pattern>MY DOGS NAME IS *</pattern> <template> That is interesting that you have a dog named <set name="dog"><star/></set> </template> </category> <category> <pattern>WHAT IS MY DOGS NAME</pattern> <template> Your dog's name is <get name="dog"/>. </template> </category> </aiml>
通过以上 AIML 你可以告诉机器人:My dogs name is Max
机器人会回答:That is interesting that you have a dog named Max
另外如果问机器人:What is my dogs name?
机器人会这么回应你:Your dog's name is Max.
待续(累死了)。。。
参考文献
[1]百度百科.aiml. https://baike.baidu.com/item/aiml/202958?fr=aladdin
[2]CSDN博客:丶尛宝.基于AIML2.0写一个机器人.https://blog.csdn.net/qin8752/article/details/79386121.2018-02-27
[3]CSDN博客:张 良 玉.AIML学习 (一).https://blog.csdn.net/qq_35315454/article/details/82711138.2018-09-15
[4]tutorialspoint. https://www.tutorialspoint.com/aiml/aiml_star_tag.htm.