最近OpenAi推出的ChatGPT火出NLP圈子,看到不少人说强人工智能已经出现,于是赶紧来体验感受一下。 该项目计划长期进行维护更新,欢迎star:https://github.com/zstar1003/Qbot
ChatGPT简介 ChatGPT是一个基于GPT-3(通用语言模型)的聊天机器人。它的目的是能够通过自然语言交流与用户进行对话。它能够理解用户的输入,并根据用户的话语生成相应的回复。
这种技术的出现,标志着人工智能在自然语言处理方面取得了新的突破。GPT-3是目前世界上最大规模的语言模型,它被训练在数百万个文本文件上,因此具有非常强大的语言理解能力。通过在GPT-3的基础上构建ChatGPT,我们可以获得一个能够与人进行自然语言对话的机器人,它能够与人类的对话方式非常相似。
ChatGPT的优势在于它能够进行流畅的对话,并能够根据用户的输入自动生成合适的回复。它能够理解语境,因此可以提供更准确、更有帮助的回复。此外,它还具有语言表达能力,可以使用正确的语法和语言风格进行对话。
实际上,上面三段文字完全由ChatGPT自己进行生成,如果你没察觉到异常,说明它已经通过了“图灵测试”。
目前,ChatGPT没有开源,只能通过OpenAi提供的测试界面调试,
ChatGPT官网:https://chat.openai.com/chat 注:2022-12-12 OpenAi增加了5秒的cloudflare并且大幅缩短了token的存活时间(原24小时缩短为2小时),导致目前国内的一些镜像站均无法使用。
ChatGPT原理 目前ChatGPT没有相关的论文和开源代码,具OpenAi官方所述,ChatGPT是在GPT3.5架构的基础上加入了RLHF(Reinforcement Learning from Human Feedback,人类反馈强化学习)。
ChatGPT采用了InstructGPT的框架,InstructGPT的论文:https://arxiv.org/pdf/2203.02155.pdf
整体训练过程分成三个过程:监督学习、训练奖励模型、引入强化学习迭代模型。
ChatGPT部署 1.注册账号 首先需要注册OpenAi的账号,账号注册使用自己的邮箱,境内手机号验证无法通过,可以使用别的接码平台。 这里使用的是sms(https://sms-activate.org/cn/cashBack ),具体操作步骤很多博文都有提到,不做赘述。
2.获取界面信息 进入到会话界面后,按F12打开开发者工具,在此处提取并记录session_token
:
同样的位置提取并记录cf_clearance
:
最后,还需要提取并记录user-agent
,这里随便找一个数据包都能够找到这个值
3.调用测试 ChatGPT官方有提供用于调用的API,不过试用次数很少,后续使用价格昂贵。 官方API文档:https://beta.openai.com/docs/api-reference/completions/create?lang=python
调用需要设置自己的密钥:https://beta.openai.com/account/api-keys
在Github上,有很多开源的项目提供了很多非官方的调用库,我对于Python最为熟悉,因此使用了这个库https://github.com/acheong08/ChatGPT
安装方式:
1 pip3 install revChatGPT --upgrade
安装完之后,通过下面的程序进行测试:
1 2 3 4 5 6 7 8 9 10 11 12 from revChatGPT.revChatGPT import Chatbot config = { "session_token" : "上一步的session_token" , "cf_clearance" : "上一步的cf_clearance" , "user_agent" : "上一步的user_agent" } chatbot = Chatbot(config, conversation_id=None , debug=True ) message = chatbot.get_chat_response('你好' , output="text" )print (message['message' ])
这里的参数修改为上一步获取到的参数。
如果使用正常,会输出如下结果:
4.QQ机器人搭建 首先得有个小号,用于搭建机器人。 其次需要选择QQ机器人的框架,目前Github上也有很多选择,我这里使用go-cqhttp
这个框架。
该框架支持windows和linux,我在本机上进行部署,因此选择了64位windows版本。 下载链接:https://github.com/Mrs4s/go-cqhttp/releases/download/v1.0.0-rc3/go-cqhttp_windows_amd64.exe
双击运行之后,选择3.正向代理
,之后会产生一系列文件。
配置文件config.yml
修改内容如下:
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 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 # go-cqhttp 默认配置文件 account: # 账号相关 uin: QQ小号 # QQ账号 password: '' # QQ密码 encrypt: false # 是否开启密码加密 status: 0 # 在线状态 请参考 https://docs.go-cqhttp.org/guide/config.html#在线状态 relogin: # 重连设置 delay: 3 # 首次重连延迟, 单位秒 interval: 3 # 重连间隔 max-times: 0 # 最大重连次数, 0为无限制 # 是否使用服务器下发的新地址进行重连 # 注意, 此设置可能导致在海外服务器上连接情况更差 use-sso-address: true # 是否允许发送临时会话消息 allow-temp-session: false heartbeat: # 心跳频率, 单位秒 # -1 为关闭心跳 interval: -1 message: # 上报数据类型 # 可选: string,array post-format: string # 是否忽略无效的CQ码, 如果为假将原样发送 ignore-invalid-cqcode: false # 是否强制分片发送消息 # 分片发送将会带来更快的速度 # 但是兼容性会有些问题 force-fragment: false # 是否将url分片发送 fix-url: false # 下载图片等请求网络代理 proxy-rewrite: '' # 是否上报自身消息 report-self-message: false # 移除服务端的Reply附带的At remove-reply-at: false # 为Reply附加更多信息 extra-reply-data: false # 跳过 Mime 扫描, 忽略错误数据 skip-mime-scan: false output: # 日志等级 trace,debug,info,warn,error log-level: warn # 日志时效 单位天. 超过这个时间之前的日志将会被自动删除. 设置为 0 表示永久保留. log-aging: 15 # 是否在每次启动时强制创建全新的文件储存日志. 为 false 的情况下将会在上次启动时创建的日志文件续写 log-force-new: true # 是否启用日志颜色 log-colorful: true # 是否启用 DEBUG debug: false # 开启调试模式 # 默认中间件锚点 default-middlewares: &default # 访问密钥, 强烈推荐在公网的服务器设置 access-token: '' # 事件过滤器文件目录 filter: '' # API限速设置 # 该设置为全局生效 # 原 cqhttp 虽然启用了 rate_limit 后缀, 但是基本没插件适配 # 目前该限速设置为令牌桶算法, 请参考: # https://baike.baidu.com/item/%E4%BB%A4%E7%89%8C%E6%A1%B6%E7%AE%97%E6%B3%95/6597000?fr=aladdin rate-limit: enabled: false # 是否启用限速 frequency: 1 # 令牌回复频率, 单位秒 bucket: 1 # 令牌桶大小 database: # 数据库相关设置 leveldb: # 是否启用内置leveldb数据库 # 启用将会增加10-20MB的内存占用和一定的磁盘空间 # 关闭将无法使用 撤回 回复 get_msg 等上下文相关功能 enable: true # 媒体文件缓存, 删除此项则使用缓存文件(旧版行为) cache: image: data/image.db video: data/video.db # 连接服务列表 servers: # 添加方式,同一连接方式可添加多个,具体配置说明请查看文档 #- http: # http 通信 #- ws: # 正向 Websocket #- ws-reverse: # 反向 Websocket #- pprof: #性能分析服务器 - http: # HTTP 通信设置 address: 0.0.0.0:8700 # HTTP监听地址 timeout: 5 # 反向 HTTP 超时时间, 单位秒,<5 时将被忽略 long-polling: # 长轮询拓展 enabled: false # 是否开启 max-queue-size: 2000 # 消息队列大小,0 表示不限制队列大小,谨慎使用 middlewares: <<: *default # 引用默认中间件 post: # 反向HTTP POST地址列表 #- url: '' # 地址 # secret: '' # 密钥 # max-retries: 3 # 最大重试,0 时禁用 # retries-interval: 1500 # 重试时间,单位毫秒,0 时立即 - url: http://127.0.0.1:7777/ # 地址 secret: '' # 密钥 max-retries: 0 # 最大重试,0 时禁用 retries-interval: 1000 # 重试时间,单位毫秒,0 时立即
其中,QQ账号替换为自己的小号。
设置完后,点击go-cqhttp.bat
,弹出二维码进行扫码登录即可。
5.后端逻辑 在上一步中,设置了QQ机器人监听本机7777
这个端口用来发送信息,8700
这个端口用来接收信息。这一步需要采用一个后端框架来处理和发送信息。这里参考[2]的提供的方案,采用轻量化的Flask作为后端框架。
首先需要安装环境依赖,新建requirements.txt
,输入以下内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 certifi==2022.12 .7 charset-normalizer==2.1 .1 click==8.1 .3 Flask==2.2 .2 idna==3.4 importlib-metadata==5.1 .0 itsdangerous==2.1 .2 Jinja2==3.1 .2 MarkupSafe==2.1 .1 OpenAIAuth==0.0 .3 .1 PyMySQL==1.0 .2 requests==2.28 .1 tls-client==0.1 .5 urllib3==1.26 .13 Werkzeug==2.2 .2 zipp==3.11 .0
在python环境中安装上述依赖:
1 pip install -r requirements.txt
安装后,编写后端程序
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 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 import jsonimport requestsfrom flask import request, Flaskfrom revChatGPT.revChatGPT import Chatbot cqhttp_url = "http://localhost:8700" qq_no = "自己的QQ号" config = { "session_token" : "上一步的session_token" , "cf_clearance" : "上一步的cf_clearance" , "user_agent" : "上一步的user_agent" } server = Flask(__name__) chatbot = Chatbot(config, conversation_id=None )def chat (msg ): try : message = chatbot.get_chat_response(msg)['message' ] print ("ChatGPT返回内容: " ) print (message) return message except Exception as error: return str ('别问了,我得休息一下了' )@server.route('/chat' , methods=['post' ] ) def chatapi (): requestJson = request.get_data() if requestJson is None or requestJson == "" or requestJson == {}: resu = {'code' : 1 , 'msg' : '请求内容不能为空' } return json.dumps(resu, ensure_ascii=False ) data = json.loads(requestJson) print (data) try : msg = chat(data['msg' ]) except Exception as error: print ("接口报错" ) resu = {'code' : 1 , 'msg' : '请求异常: ' + str (error)} return json.dumps(resu, ensure_ascii=False ) else : resu = {'code' : 0 , 'data' : msg} return json.dumps(resu, ensure_ascii=False )@server.route('/' , methods=["GET" ] ) def index (): return f"你好,QQ机器人逻辑处理端已启动<br/>" @server.route('/' , methods=["POST" ] ) def get_message (): if request.get_json().get('message_type' ) == 'private' : uid = request.get_json().get('sender' ).get('user_id' ) message = request.get_json().get('raw_message' ) sender = request.get_json().get('sender' ) print ("收到私聊消息:" ) print (message) msg_text = chat(message) send_private_message(uid, msg_text) if request.get_json().get('message_type' ) == 'group' : gid = request.get_json().get('group_id' ) uid = request.get_json().get('sender' ).get('user_id' ) message = request.get_json().get('raw_message' ) if str ("[CQ:at,qq=%s]" %qq_no) in message: sender = request.get_json().get('sender' ) print ("收到群聊消息:" ) print (message) msg_text = chat(message) msg_text = str ('[CQ:at,qq=%s]\n' %uid) + str (msg_text) send_group_message(gid, msg_text) if request.get_json().get('post_type' ) == 'request' : print ("收到请求消息" ) request_type = request.get_json().get('request_type' ) uid = request.get_json().get('user_id' ) flag = request.get_json().get('flag' ) comment = request.get_json().get('comment' ) if request_type == "friend" : print ("收到加好友申请" ) print ("QQ:" , uid) print ("验证信息" , comment) set_friend_add_request(flag, "false" ) if request_type == "group" : print ("收到群请求" ) sub_type = request.get_json().get('sub_type' ) gid = request.get_json().get('group_id' ) if sub_type == "add" : print ("收到加群申请,不进行处理" ) elif sub_type == "invite" : print ("收到邀请入群申请" ) print ("群号:" , gid) set_group_invite_request(flag, "false" ) return "ok" def send_private_message (uid, message ): try : res = requests.post(url=cqhttp_url + "/send_private_msg" , params={'user_id' : int (uid), 'message' : message}).json() if res["status" ] == "ok" : print ("私聊消息发送成功" ) else : print (res) print ("私聊消息发送失败,错误信息:" + str (res['wording' ])) except : print ("私聊消息发送失败" )def send_group_message (gid, message ): try : res = requests.post(url=cqhttp_url + "/send_group_msg" , params={'group_id' : int (gid), 'message' : message}).json() if res["status" ] == "ok" : print ("群消息发送成功" ) else : print ("群消息发送失败,错误信息:" + str (res['wording' ])) except : print ("群消息发送失败" )def set_friend_add_request (flag, approve ): try : requests.post(url=cqhttp_url + "/set_friend_add_request" , params={'flag' : flag, 'approve' : approve}) print ("处理好友申请成功" ) except : print ("处理好友申请失败" )def set_group_invite_request (flag, approve ): try : requests.post(url=cqhttp_url + "/set_group_add_request" , params={'flag' : flag, 'sub_type' : 'invite' , 'approve' : approve}) print ("处理群申请成功" ) except : print ("处理群申请失败" )if __name__ == '__main__' : server.run(port=7777 , host='0.0.0.0' )
这里的QQ号,config信息替换为自己的内容。
运行之后,就部署完成了。
ChatGPT评价 回到开头的问题,ChatGPT究竟算不算强人工智能?
以往NLP中的模型往往只能处理文本分类、文本续写、文本风格迁移等单一任务,而ChatGPT却能够处理多任务,的确是一大突破。然而,在测试过程中,它仍有一些问题:
使用速度慢 使用速度慢一方面是由于官方服务器同时段并发量大,另一方面是GPT类的模型是一个字一个字的输出,比如在官网上看到的是一个字一个字吐出来,而不是一整句话。如果插入到QQ机器人回复中,需要等待其将所有内容输出完再一并发送。内容越多,等待时间越久。
太过“自信” ChatGPT很像一本百科全书,对于未知的东西,它仍然会“习惯性”地去做解释,甚至,它很容易被一些关键词所误导。比如,下图中群友对它进行的测试:
无法获取最新信息 ChatGPT是通过2021年以前的数据训练而来的,因此它无法获取最新信息,这让它无法取代搜索引擎。
易被催眠 最后这点,不多做解释,在群友的催眠下,它被成功洗脑了。。
TODD 后续计划在此框架下开发更多内容:
config自动设置 目前官方界面的config两小时会失活,后续会想办法自动进行获取设置
加入其它功能 可能考虑添加Ai绘画等功能
后记 — 2023-02-12更
一段时间没关注ChatGPT了,没想到OpenAi和微软合作之后,又掀起了第二波热潮。 于是重新在GitHub上浏览最新消息,发现本已归档的ChatGPT逆向工程项目又开始更新,作者采用了代理池的方式,在此突破了官方的地区的封锁。
于是更新了一下:
1 pip3 install revChatGPT --upgrade
注:该版本需要的谷歌浏览器内核版本需在110以上,使用前需进行更新。
下面是一个新版的调用示例:
1 2 3 4 5 6 7 8 9 from revChatGPT.Unofficial import Chatbot chatbot = Chatbot({ "email" : "自己的账号" , "password" : "自己的密码" }, conversation_id=None , parent_id=None ) response = chatbot.ask("你好" , conversation_id=None , parent_id=None ) print (response)
经实测发现,如果一分钟收到3个请求以上就会被限制一定时间,响应速度也不及GPT3的Api,不过优势在于免费,不限制输入长度,且有上下文记忆(又可以催眠了😄)
— 2023-02-16更
revChatGPT上面的Unofficial版本在第二天的更新中变成了V2,不过仅过了一天,原作者的代理服务器遭到了OpenAi的攻击,导致V2版本直接失效。 作者又紧急升级了V1版本,并绕过了Cloudfare检测,现在无需启动浏览器也能够正常运行。
调用示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 from revChatGPT.V1 import Chatbot chatbot = Chatbot(config={ "email" : "自己的账号" , "password" : "自己的密码" })for data in chatbot.ask( '你好' , conversation_id=chatbot.config.get("conversation" ), parent_id=chatbot.config.get("parent_id" ), ): result = data["message" ] print (result)
后面更新情况不打算在更新了,后续的变化将直接写入仓库中,敬请关注(star)Qbot仓库,地址在文首。
参考 [1]ChatGPT是怎样被训练出来的?https://www.bilibili.com/video/BV1BG4y137SH/ [2]使用Python对接OpenAi APi 实现智能QQ机器人 https://lucent.blog/?p=99