是真人?还是 Chatbot::Eliza?

作者:Mike Diehl

当我们还在大学的时候,我的妻子(当时的女朋友)曾经设置过有史以来最好的答录机问候语。当人们给她打电话时,答录机会回答:“你好?”并等待。通常,来电者会开始说话,好像他们真的接通了真人。他们会谈论上周的作业,或者下周的聚会。然后就会真相大白。答录机接着会说:“哦,对不起。我现在不在。如果您想留言,请等待嘟声!” 然后来电者不得不重新开始,可能感觉有点不好意思。最终,她将留言更改为更传统的说法,可能是迫于朋友和家人的严厉威胁。但在她更改之前,即使有空,她也不会费心接电话;听人们对着机器说话,以为他们在和真人说话,这真是太有趣了。

我深有同感。自从高中以来,我就一直想编写看起来或行为像真人的程序。我记得小时候玩过一个叫做 Eliza 的程序,当时觉得它能运行得这么好真是太神奇了。Eliza 程序会模仿精神科医生,并通过与您进行自然语言对话来尝试“分析”您的“问题”。但是,一旦您意识到它只是在匹配简单的模式,它就会提到您之前说过的一些话,只是为了让您感到困惑。它很原始,但很有效。

当我在大学时,我开始沉迷于玩多人地下城游戏,或 MUD。这些游戏本质上是基于文本的 MMORPG,世界各地的人们可以在其中互相交谈并探索其他玩家创建的地点。这很有趣。然后出现了“机器人”。这变得很有趣,至少对我而言是这样。“机器人”就像 Eliza 这样的程序。事实上,它们中的许多都使用相同的算法来伪装成游戏中的另一个玩家。一些“机器人”伪装成女朋友、酒吧女招待、邮递员,甚至宠物,而不是精神科医生。但有一些新的东西;他们可以响应特定的命令。例如,您可以询问“机器人”如何到达 MUD 中的某个位置,或者某个玩家上次在线的时间。您甚至可以询问他们关于他们自己的事情。除了有趣和有趣之外,它们还变得有用。

那么,一个假装是人类的程序一定很难编写,对吧?实际上,这非常简单,这要归功于 Perl 的 Chatbot::Eliza 模块。让我们来看一个(非常)简单的例子

#!/usr/bin/perl

use Chatbot::Eliza;

$bot = new Chatbot::Eliza("Jill", "");

$bot->command_interface();

没错,只需 4 行代码,无需任何配置!该模块自带一个默认数据库,使其能够延续原始 Eliza 程序的传统。以下是与“Jill”交互的示例。

Jill: 请告诉我什么困扰着您。
你:我很无聊。
Jill: 您喜欢感到无聊吗?
你:不。
Jill: 这让您感到不快乐吗?
你:是的。
Jill: 请继续。
你:我想找点事做。
Jill: 假设您很快就能找到事做。
你:那就太好了!
Jill: 请详细说说。
你:我很无聊。
Jill: 您来找我是因为您感到无聊吗?
你:是的。
Jill: 我明白了。

对于 4 行代码来说还不错,但我们的程序不是很灵活。让我们对程序进行一些更改,以演示如何从我们自己的运行循环中使用该模块

#!/usr/bin/perl

use Chatbot::Eliza;

$bot = new Chatbot::Eliza("Jill", "");

print $bot->{initial}->[0] . "\n";

$true++;

while ($true) {
print "You: ";
$message = <STDIN>;

$message = $bot->transform($message);
print "$message\n";
}

exit;

这个程序的行为几乎与第一个程序完全相同,但它演示了如何将该模块集成到 Jabber 客户端、IRC 客户端或任何其他客户端中。您只需从用户那里获取消息,将其传递给 transform() 方法,并将结果发送回用户。

尽管如此,一个虚假的心理医生有点过时了;让我们看看改变程序的“个性”有多难。根据您的政治倾向,这可能类似于

$bot = new Chatbot::Eliza("Sarah", "palin.txt");
或者
$bot = new Chatbot::Eliza("Barak", "obama.txt");

两者都可能很有趣,但我尽量避免在这里谈论政治。无论如何,既然我们知道如何加载不同的数据库,那么这个数据库是什么样的呢?以下是默认数据库的摘录

key: remember 5
decomp: * i remember *
reasmb: 您经常想到 (2) 吗?
reasmb: 想到 (2) 会让您想起其他事情吗?
reasmb: 您还记得什么?
reasmb: 您为什么现在才想起 (2)?
reasmb: 目前的情况有什么让您想起 (2)?
reasmb: 我和 (2) 之间有什么联系?
reasmb: (2) 还让您想起什么?

其余的模式与此类似,所以让我们讨论一下这是做什么的以及如何做的。key: 行引入一个关键字“remember”并为其分配等级 5。这代表了轻微的性能优化。该模块首先扫描输入消息中的关键字。当找到关键字时,会记录其等级。等级最高的关键字获胜,然后我们继续进入“decomp”部分。“decomp”部分只是一个我们应用于输入句子的模式。星号是通配符,会导致句子的某些部分被存储起来,以便稍后替换到回复中。如果 decomp 匹配,该模块将从 reasmb 选项列表中随机选择。reasmb 或重组模式是模块返回的回复。请注意,括号中的数字对应于 decomp 部分中的星号。例如,(2) 代表 decomp 模式中的第二个星号。

从这里,很容易想象创建一个模仿几乎任何类型个性的数据库。这样的模式可能看起来像

key: like 5

decomp: * like you

reasmb: 很高兴听到您喜欢我 <tab> karma(+1);

然后我们可以实现一个名为 karma() 的子程序,该子程序跟踪一个人有多“好”。我们必须更改主循环,以便当给定变量超过某些阈值时,可以加载新的数据库,从而使“Jill”变得越来越“轻浮”或“巫婆”,这取决于人们如何与她交谈。我们还可以实现与世界其他地方交互的功能。然后我们可以询问“Jill”给定服务器上的负载平均值是多少,或者我们可以向她询问 Google 为给定单词或短语返回的第一个链接。天空才是极限。

现在我并不是认真地建议将 Eliza 机器人作为下一代计算机用户界面。但是,Chatbot::Eliza Perl 模块是一个有趣的玩具,易于使用、简单扩展和集成。玩得开心。

加载 Disqus 评论