65.9K
CodeProject 正在变化。 阅读更多。
Home

增强型 Skype 聊天机器人

starIconstarIconstarIconstarIconstarIcon

5.00/5 (11投票s)

2013年8月4日

CPOL

2分钟阅读

viewsIcon

90652

downloadIcon

5844

一个增强的 Skype 聊天机器人,具有友好的用户界面,可编程的知识库,测试界面,以及将知识库导出/导入到文件。

Sample Image

引言

该软件使用户能够拥有一个可编程的聊天机器人。在互联网上流传的大多数教程中,其知识库都是硬编码的(显然是为了演示目的),在这里,我们将看到可以在运行时添加和编辑知识库规则,并且数据库会自动保存到存储中的文件中。

该程序的第二个功能是它不仅仅比较字符串来搜索答案,而是使用不同的策略来计算字符串之间的相似度,这在一定程度上克服了打字错误、拼写错误或短语颠倒的情况。

除了上述功能外,它还具有几个增强用户体验的辅助功能,如测试部分、消息延迟、问候消息以及将数据库加载和备份到文件的能力。

背景

最初,这是我之前为与编程无关的人制作的一个应用程序。我找到了许多例子,这些例子确实说明了应该如何基本完成,但对于我的最终用户来说,需要增强几件事,比如

  • 用户友好的界面
  • 一个通过 GUI 可编辑的知识库
  • 一种克服打字错误、拼写错误等的方法
  • 消息延迟

我将我的工作基于 CodeProject 文章 用 .NET 制作你的 Skype 机器人,因为它很好地展示了 Skype4COM COM 包装器的基本原理,强烈建议您查看它,因为它包含许多本文中未涵盖的定义。

代码解释

字符串比较策略和消息处理

很明显,普通的字符串比较只会逐字逐句地匹配字符串,这在处理由人类输入的邮件时并不十分有效。在这种情况下,字符串通常通过*相似度*进行比较。即,我们将不得不计算一对字符串的相似程度。有许多算法和方法可以进行这样的比较,为了本项目的目的,我们将使用Levenshtein 距离

消息处理总结如下所示

消息处理的实际方法的源代码预览如下

// this method is the core of our message processing
private string ProcessCommand(string msg,bool showSimilarity)
{
	// remove all special characters, punctuation etc ...
	msg = preTreatMessage(msg);

	// we build our answer search query
	string answer="";
	string searchQuery = "";

	// we tokenize the given message
	string[] tokens = msg.Split(' ');
	string oper = "";
	// we search for all rules with the 'receive' that looks like the given message
	foreach (string token in tokens)
	{
		if (token != "")
		{
			searchQuery += oper + " receive LIKE '%" + token + "%' ";
			oper = "OR";
		}
	}
	// we store the results
	DataRow[] results = this.database.Rules.Select
	("active = True AND "+searchQuery);
	// set the minimum wordsMatching score (precision) 
	// messages that are matched below this threshold will be ignored
	double maxScore = this.intelligence;
	List<string> answerlist =new List<string>();
	// we calculate the matching score foreach rule and store the ones
	// with the highest score in the answerlist array
	foreach (DataRow result in results)
	{
		MatchsMaker m = new MatchsMaker(msg, result["receive"].ToString());
		if (m.Score > maxScore)
		{
			answerlist.Clear();
			answerlist.Add(result["send"] + ((showSimilarity)?" 
			(" + m.Score + ")":""));
			this.messageDelay = (int)result["delay"];
			maxScore = m.Score;
		}
		else if (m.Score == maxScore)
		{
			answerlist.Add(result["send"] + 
			((showSimilarity)?" (" + m.Score + ")":""));
			this.messageDelay = (int)result["delay"];
		}
	}
	if (answerlist.Count == 0) // if no rule was found (scored high)
	{
		// we give an empty message
		// OR , you can modify this to be a default message
		// like : "I dont understand !"
		answer = "";
	}else{
		// if there are rules with the same score
		// we just choose a random one
		Random rand = new Random();
		answer = answerlist[rand.Next(0,answerlist.Count)];
	}
	return answer;
}

消息延迟

需要此功能才能使机器人更逼真,每个规则都会分配一个延迟时间;但是,可以采用不同的方式,例如,我们可以计算响应的字符数,以避免每次添加新规则时都设置延迟。

未涵盖的另一件事是让 Skype 在消息延迟期间显示我们当前正在键入消息。

这是用于延迟消息的方法 (Thread) 的预览,它只是休眠消息设置的秒数。

private void SendSkypeMessage(string username, string message)
{
	// the message is not empty
	if (message != "")
	{
		// pause the thread delay the message so it appears as if the bot types the message
		System.Threading.Thread.Sleep(1000*this.messageDelay);
		try
		{
			// send the actual message
			skype.SendMessage(username, message);
		}
		catch { }
	}
}

它在skype_MessageStatus回调方法中被调用

// create a thread to send the message with its delay
System.Threading.Thread t = new System.Threading.Thread(() => 
	SendSkypeMessage(msg.Sender.Handle, send));
t.Start();

历史

  • 2013 年 8 月:发布

相关材料

© . All rights reserved.