40行代码写一个聊天机器人

发布于 2017-06-27 07:17:15

前言

虽说标题取的是40行写一个微信自动回复机器人,但是实际上肯定要比40行多,这只是一个最终的代码行数而已。另外要说的是,这个机器人非第三方接口。时间的话,用了周六、周日两天的时间,主要用来上传语料数据。中文语料总共有50w,还有英文语料。

效果预览

可以点击聊天机器人进入测试以下,效果还是挺好的,试过了才知道。

概述

聊天机器人的话,大家应该听过小黄鸡,小黄鸡是调用的韩国一家公司的API,公司叫做simsimi,然后在人人上迅速的积累了一波人气,大概到2016年小黄鸡的页面已经停止更新了。通过simsimi的网站,我们可以看到他家的语料数据,至少是2000w,另外还有智能化的一些回复功能,比如计算。好了接下来说一下搭建聊天机器人的思路。

上面介绍simisimi其实是跟他家一样的,就是把qa语料对上传到数据库,对qa进行分词,然后,根据q查询,然后随机取一个a结果进行返回。

安装Elasticsearch

这个数据库需要的内存还是挺高的,我的服务器是1g的内存,完全不够用。安装及遇到的一些问题参考 Elasticsearch5.3.2 安装以及遇到的一些问题。 安装完了Elasticsearch以后,要安装分词和x-pack插件,分词用的是IK分词,可以在github上搜索,readme里面有非常详细的安装方法。x-pack安装,直接通过elasticsearch/bin 目录下的plugin那个脚本安装就好了,安装了以后记得修改默认密码,默认密码是changeme,用户名是elastic。 修改密码:curl -XPUT -u elastic 'http://localhost:9200/_xpack/security/user/elastic/_password' -d '{ "password" : "xxxxxxxxxx" }'

创建索引、类型,上传数据

暂略,稍后补充

微信机器人

微信机器人用的是itchat这个包,直接通过pip安装就可以了,通过朋友发过来的信息,把这个信息放到查询接口里面,如果有返回的查询结果,那么从结果里面随机一个,返回给发信息的朋友。如果没有结果,那么给他发送一个“=。=”颜文字。具体代码如下。

import json
import random
from elasticsearch import Elasticsearch
import itchat
from itchat.content import *

USER_CHAT_HISTORY = []

@itchat.msg_register([TEXT, MAP, CARD, NOTE, SHARING])
def auto_reply(msg):
    print(msg['User']['NickName'], ":",msg['Text'])
    if msg['User']['NickName'] in USER_CHAT_HISTORY:
        text = send(msg['Text'])
    else:
        text = "主人不在,我来陪你吧!" 
        USER_CHAT_HISTORY.append(msg['User']['NickName'])
    print("小笨鸡:", text)
    return text

ES = Elasticsearch(
            [''], #IP
            http_auth=('', ''), #账号密码  
        )

def send(q):
    request_body = {
        "query" : {
          "multi_match" : {
          "query":q, 
          "fields": [ "question"] 
          }
        },
    } 

    res = ES.search(index="lifeepoch", doc_type='bot', body=request_body)

    total = res['hits']['total']
    if total > 1:
        hits = res['hits']['hits']
        hit = random.choice(hits)
        return hit['_source']['answer']
    else:
        return "=。="

@itchat.msg_register(TEXT, isGroupChat=True)
def text_reply(msg):
    print(json.dumps(msg, indent=2, ensure_ascii=False))
    if msg['User']['NickName'] in ["飞哥的唐玉来了", "家"]:
        text = "小笨鸡:{0}".format(send(msg['Text']))
        # print('@%s\u2005I received: %s' % (msg.actualNickName, msg.text))
        msg.user.send(text)    

if __name__ == '__main__':
    itchat.auto_login(hotReload=True)
    itchat.run()