ChatScript在Centos7下使用

发布 : 2017-07-07 分类 : ChatScript 浏览 :

ChatScript是什么

1
ChatScript是一个使用C++语言开发的对话系统,基于一种对话流脚本语言实现对话逻辑

ChatScript在Centos7下使用

To compile CS src, you will need to have Curl installed

1
2
[root@sparsematrix ~]# yum -y install libcurl libcurl-devel
[lmb_bi@lmb-robot-239 ~]$ sudo yum -y install libcurl libcurl-devel

在github上下载ChatScript中文多轮对话Bots

1
https://github.com/candlewill/Bots

在Centos上部署Cmake

1
[root@sparsematrix ~]# yum install -y gcc gcc-c++ make automake
1
2
3
4
5
6
7
8
[root@sparsematrix ~]# wget http://www.cmake.org/files/v2.8/cmake-2.8.10.2.tar.gz
[root@sparsematrix ~]# tar -zxvf cmake-2.8.10.2.tar.gz -C /usr/local
[root@sparsematrix ~]# cd /usr/local/cmake-2.8.10.2/
[root@sparsematrix cmake-2.8.10.2]# ./bootstrap
[root@sparsematrix cmake-2.8.10.2]# gmake
[root@sparsematrix cmake-2.8.10.2]# gmake install
[root@sparsematrix cmake-2.8.10.2]# cmake --version
cmake version 2.8.10.2

解压

1
[root@sparsematrix ~]# unzip Bots-master.zip

编译ChatScript

1
2
cd /usr/local/Bots-master/ChatScript-7.3/SRC
make server

本地运行模式

1
2
3
4
5
6
7
cd /usr/local/Bots-master
chmod 777 start*
mkdir -p LOGS
mkdir -p TOPIC/BUILD1
./start_compile.sh
./start_compile_lib.sh
./start_local.sh

添加主题

1
2
[root@sparsematrix ~]# cd /usr/local/Bots-master/BOTDATA/TEST
[root@sparsematrix TEST]# vi apologize.top
1
2
3
4
5
6
7
8
topic: ~apologize keep repeat ( 不好意思 对不起 sorry 我不是故意的 )

u: (不好意思)
没关系,这是一件小事!
a: (没有)
好吧
a: (有)
遵命

对话脚本编译

1
2
[root@sparsematrix ~]# cd /usr/local/Bots-master
[root@sparsematrix Bots-master]# ./start_local.sh

在终端输入如下命令,先加载公共资源进行编译

1
:build 0

在终端输入如下命令,完成对话脚本的编译

1
:build Test reset
1
程序会去到根目录(Bots-master文件夹)寻找 filesTest.txt 文件,然后加载这个文件中所列出来的所有文件
1
2
3
4
5
6
[root@sparsematrix Bots-master]# cat filesTest.txt 
# multibot
../BOTDATA/TEST/ # tutorial bot data

# load in chatscript quibbles
../BOTDATA/QUIBBLE/

在终端输入如下命令,完成对话脚本的编译

1
:build xiaola reset
1
2
3
[root@sparsematrix Bots-master]# cat filesxiaola.txt
# load in chatscript quibbles
../BOTDATA/XIAOLA/

Preparing for compiling on the Server

1
:clean

Commands affecting the server

1
2
3
4
:show serverlog
:show echoserver
:quit
:crash

以Web的形式获取ChatScript的服务

1
2
3
4
5
[root@sparsematrix ~]# yum install httpd -y
[root@sparsematrix ~]# service httpd start
[root@sparsematrix ~]# chkconfig httpd on
[root@sparsematrix ~]# rpm -ql httpd
[root@sparsematrix ~]# yum install php php-devel -y
1
[root@sparsematrix ChatScript-7.3]# vi WEBINTERFACE/SIMPLE/index.php

index.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
 <?php

// Program: chatScriptClient.php

// Credits: This program is derived from a sample client script by Alejandro Gervasio
// posted here: www dot devshed dot com/c/a/PHP/An-Introduction-to-Sockets-in-PHP/
// Modified 2012 by R. Wade Schuette -- Augmented 2014 by Bruce Wilcox

// Function -- a working skeleton of a client to the ChatScript Server
// NOTES: Be sure to put in your correct host, port, username, and bot name below !

// LEGAL STUFF:
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, or sell
// copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//*********************************************************************************/

// ============= user values ====
$host = "115.28.240.96"; // <<<<<<<<<<<<<<<<< YOUR CHATSCRIPT SERVER IP ADDRESS GOES HERE
$port = 1024; // <<<<<<< your portnumber if different from 1024
$bot = ""; // <<<<<<< desired botname, or "" for default bot
$null = "\x00";
$botprefix = "Bot: ";
$userprefix = "You: ";

//=========================
// Note - the top part (PHP) is skipped on the first display of this form, but fires on each loop after that.
ini_set('display_errors','on');
error_reporting(E_ALL);
if($_POST['send'])
{
// open client connection to TCP server
$userip = ($_SERVER['X_FORWARDED_FOR']) ? $_SERVER['X_FORWARDED_FOR'] : $_SERVER['REMOTE_ADDR']; // get actual ip address of user as his id

$msg=$_POST['message'];
echo '<h2>'.$userprefix.$msg.'</h2>';

// fifth parameter in fsockopen is timeout in seconds
if(!$fp=fsockopen($host,$port,$errstr,$errno,300))
{
trigger_error('Error opening socket',E_USER_ERROR);
}

fputs($fp,$message); // write message to socket server
while (!feof($fp))
{
$ret= fgets($fp, 500);
}

fclose($fp); // close socket connection

# check for out-of-band messages

// echo "Chatbot $bot replied to $user:";
echo '<h2>'.$botprefix.$ret.'</h2>';
}
?>


<!DOCTYPE HTML>
<html>
<head>
<title>
CHATSCRIPT SERVER
</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body onload="document.getElementById('message').focus()">
<form action="<?php echo $_SERVER['PHP_SELF'] ?>" method="post">
<p>
Enter your message below:
</p>
<table>
<tr>
<td>Message:</td>
<td><input type="text" name="message" id="message" size="70" /></td>
</tr>
<tr>
<td colspan="2"><input type="submit" name="send" value="Send Value" /></td>
</tr>
</table>
</form>

</body>
</html>
1
2
3
[root@sparsematrix ChatScript-7.3]# cp WEBINTERFACE/SIMPLE/*.* /var/www/html
or
[root@sparsematrix ChatScript-7.3]# cp WEBINTERFACE/BETTER/*.* /var/www/html
1
2
3
4
5
6
7
8
[root@sparsematrix ~]# systemctl start firewalld
[root@sparsematrix ~]# setsebool -P httpd_can_network_connect on
[root@sparsematrix ~]# netstat -tan
[root@sparsematrix ~]# netstat -tunpl
[root@sparsematrix ~]# firewall-cmd --zone=public --add-port=1024/tcp --permanent
[root@sparsematrix ~]# firewall-cmd --zone=public --add-port=80/tcp --permanent
[root@sparsematrix ~]# firewall-cmd --reload
[root@sparsematrix ~]# netstat -tunlp | grep 1024

Server

第一种Server启动方式

1
2
3
[root@sparsematrix ~]# cd /usr/local/Bots-master
[root@sparsematrix Bots-master]# chmod u+x ChatScript-7.3/BINARIES/LinuxChatScript64
[root@sparsematrix Bots-master]# ./ChatScript-7.3/BINARIES/LinuxChatScript64

第二种Server启动方式

1
[root@sparsematrix Bots-master]# nohup sh start_server_7.52.sh & >/dev/null
1
当用户注销或者网络中断时,终端后收到SIGHUP信号,从而关闭其所有子进程

nohup命令会忽略SIGHUP信号,从而终端退出时不会影响到后台作业

查看后台运行任务

1
2
3
[root@sparsematrix Bots-master]# jobs
[1]+ Running nohup sh start_server_7.52.sh 2>&1 &
[root@sparsematrix Bots-master]# ps -ef

查看监听端口

1
2
3
4
5
netstat -apn | grep 1024
(Not all processes could be identified, non-owned process info
will not be shown, you would have to be root to see it all.)
tcp 0 0 0.0.0.0:1024 0.0.0.0:* LISTEN 570/BINARIES/ChatSc
tcp 0 0 192.168.1.239:1024 192.168.1.249:33256 TIME_WAIT -

kill掉端口服务

1
kill -9 570

第三种Server启动方式

1
./start_server_7.52.sh >/dev/null 2>&1 &

Client

1
在浏览器地址栏中访问,http://115.28.240.96/index.php

Python获取Chatscript服务

pychatscript.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import socket

host = '115.28.240.96'
port = 1024
bufsize = 1024

def send(query,host,port, bot=''):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))
ip = host
text = '%s\x00%s\x00%s\x00' % (ip, bot, query)
s.send(text.encode('utf8'))

data = b''
while 1:
block = s.recv(1024)
if block:
data += block
else:
break
return data.decode('utf8')

if __name__ == '__main__':
while True:
user_input = input('>')
print('bot:',send(user_input,host,port))

查看日志

1
[root@sparsematrix ChatScript-7.3]# tail -f LOGS/serverlog1024.txt

1
日志中没有显示user,只显示IP

难点1

1
2
php下$null以十六进制输出的结果?
\x00是空字符

难点2

1
2
参照ChatScript官方给出的index.php
用户每次输入的query都要建立一次套接字连接

平台交互脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import socket
import sys

reload(sys)
sys.setdefaultencoding('utf-8')

CONNECT_HOST = '192.168.0.25'
CONNECT_PORT = 1024
BUFSIZE = 1024


def send(query, user, bot):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((CONNECT_HOST, CONNECT_PORT))
if user != '':
text = '%s\x00%s\x00%s\x00' % (user, bot, query)
else:
text = '%s\x00%s\x00%s\x00' % (CONNECT_HOST, bot, query)
s.send(text.encode('utf8'))

data = b''
while 1:
block = s.recv(BUFSIZE)
if block:
data += block
else:
break
return data.decode('utf8')


if __name__ == '__main__':
user = raw_input('user>')
if user == '':
user = raw_input('Please input user>')
bot = raw_input('bots>')
# 初始化机器人
query = 'hello'
flag = 'No such bot.' in send(query, user, bot)
if flag:
query = ':build ' + bot
print send(query, user, bot)
flag = False
while not flag:
query = raw_input('query>')
if query == '':
query = raw_input('Please input query>')
data = send(query, user, bot)
flag = 'No such bot.' in data
print 'bot:', data

查看交互日志

1
[root@sparsematrix Bots-master]# tail -f USERS/log*

创建Bots

mkdir BOTDATA/xxx

vi filesxxx.txt

1
2
3
4
5
# multibot
#../BOTDATA/TEST/ # tutorial bot data

# load in chatscript quibbles
../BOTDATA/xxx/
1
:build xxx

ChatScript对话引擎进阶

综述

1
2
注释:用井号(#)作为注释标志,井号和前文内容之间需要用空格隔开
另外,#!,表示 样例输入,用于自动测试

概念

1
2
概念(concept)定义了同义词、抽象语义等内容
定义概念时,可以使用词性信息(POS information)对其修饰
1
2
concept: ~mynouns NOUN NOUN_SINGULAR (boxdead foxtrot)
concept: ~myadjectives ADJECTIVE ADJECTIVE_BASIC (moony dizcious)

话题

1
ChatScript对于每次用户的输入,并不是检查全部规则来找到匹配的,需以~开始
1
2
3
4
topic: ~DEATH [dead corpse death die body] 

t: I don’t want to die
?: (When will you die) I don’t know.

关键词

1
2
3
如果一句话能够触发多个话题,系统选择最可能触发(触发词数 量、触发词长度)的进入。
跳入某个话题之后,然后去寻找规则,看看那个规则能够匹配,
如果这个话题下的所有规则都不能匹配,那么只输出开场白。

规则

1
2
3
一条规则由四部分组成:
规则类型、规则标签、规则模式、规则输出
如,?: MEAT (you like meat) I do
1
2
3
4
5
6
7
8
9
10
规则类型一共有四种:
陈述句(s:)
疑问句(?:)
陈述句或者疑问句(u:)
开场白(gambit, t:)
除此之外,规则还可以以
a:
b:
q:开头,表示二级规则,用来处理分支情况,称为Rejoinders
二级规则不能作为顶级规则,只有当父级规则已经匹配,才会去匹配。

随机开场白

1
2
[root@sparsematrix ~]# cd /usr/local/Bots-master/BOTDATA/XIAOLA
[root@sparsematrix XIAOLA]# vi beach.top
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Topic: ~beach [beach sand ocean sand_castle] 

u: ( ~country) ^refine() # gets any reference to a country
a: (Turkey) I like Turkey
a: (Sweden) I like Sweden

# subtopic about swimming
r: Do you like the ocean?

t: I like swimming in the ocean.

t: I often go to the beach to swim.

# subtopic about sand castles.
r: Have you made sand castles?
a: (~yes) Maybe sometime you can make some that I can go see.
a: (~no) I admire those who make luxury sand castles.

t: I've seen pictures of some really grand sand castles.

1
2
使用宏(Macros)的方式 共享脚本代码。 
宏名和宏参数名需要以^开始,宏定义的结束以文件结束或者新宏定义开始为标志。
本文作者 : Matrix
原文链接 : https://matrixsparse.github.io/2017/07/07/ChatScript在Centos7下使用/
版权声明 : 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处!

知识 & 情怀 | 二者兼得

微信扫一扫, 向我投食

微信扫一扫, 向我投食

支付宝扫一扫, 向我投食

支付宝扫一扫, 向我投食

留下足迹