本地部署基于Chatgpt的qq机器人

2,051 阅读4分钟

本篇文章主要是分享我个人在本地部署基于Chatgpt的qq机器人的经验,主要分为两大步骤,一、部署qq机器人。二、让这个机器人接上Chatgpt的接口。如果你对于部署qq机器人已经十分熟悉,那么前面一个步骤可以快速掠过。下面进入正文
一、部署QQ机器人
这里运用的是go-cphttp的qq机器人,支持liunx和window,如果和我一样只是用于体验,可只部署在自己的电脑上部署window版本,如果想接入服务器的话,可以使用liunx版本,以下均以window系统为例。
1.下载chatgpt-mirai-qq-bot
下载地github.com/Mrs4s/go-cq…,打开releases版本列表,找到“go-cqhttp_windows_amd64.zip”,下载,并解压。
2.登录
这里选择一个qq小号作为机器人,在解压后的文件夹里,打开go-cqhttp.exe,自动生成对应go-cqhttp.bat,再点击bat,选择HTTP通信会自动生成的配置文件config.yml(这里注意不要急着打开配置文件,如果太快打开后面的内容会生成不完全),config.yml需要修改的的两部分
(1).qq账号,这里填int数据,即不加引号直接输入账号

(2).网络设置,这部分可以照着图设置,timeout可自行设置,我这里设置比较高的原因是openai在文本量大时回复较慢,此处用于监控的5700端口,和用于发送消息的5701端口并无特殊意义,但是要保证这两个端口没有被占用,如果被占用了,可以更换其他端口

2.网络

之后再点击bat文件,此时等待出现二维码之后便可以关闭,此时会出现新文件“device.json”,修改其中的protocol值为2。随后便可正常登陆了
3.简单测试
可以让自己的机器人装个复读功能测试机器人是否能够正常工作此处引用了这篇文章的代码blog.csdn.net/weixin_4776…

import requests
from flask import Flask, request
from gevent import pywsgi
app = Flask(__name__)

@app.route('/', methods=["POST"])
def post_data():
    if request.get_json().get('message_type') == 'private':            
        QQ_id = request.get_json().get('sender').get('user_id')         
        msg = request.get_json().get('raw_message')             
        requests.get("http://127.0.0.1:5700/send_private_msg?user_id={0}&message={1}".format(QQ_id, msg))
    return 'OK,do not say anymore' 

server = pywsgi.WSGIServer(('127.0.0.1', 5701), app)
server.serve_forever()

运行结果如下

二、使用openai的api
1.获取api key
进入网站openai的网站获取api,我将api key注册为了环境变量OPENAI_API_KEY方便后面操作

2.测试是否能调用api,仅做测试,代码如下(如果链接有错误可以尝试将urllib3改为1.25.11版本即可,即在命令行输入pip uninstall urllib3,pip install urllib3==1.25.11)

import openai
import os
openai.api_key = os.environ['OPENAI_API_KEY']
def openai_reply(question) -> str:
    response = openai.Completion.create(
        model="text-davinci-003",
        prompt=question,
        temperature=0.7,
        max_tokens=400,
        top_p=1,
        user='1',
        frequency_penalty=0,
        presence_penalty=0
    )
    choices = response['choices']
    first_item = choices[0]
    return first_item['text']
print(openai_reply("我测你的码"))

如果正确收到输出,说明能够正常调用api
3.链接api和机器人,其实这里的内容比较简单,其实就是两段代码的复制粘贴

import requests
from flask import Flask, request
import os 
import openai
from gevent import pywsgi
def openai_reply(question) -> str:
    response = openai.Completion.create(
        model="text-davinci-003",
        prompt=question,
        temperature=0.7,
        max_tokens=400,
        top_p=1,
        user='1',
        frequency_penalty=0,
        presence_penalty=0
    )
    choices = response['choices']
    first_item = choices[0]
    return first_item['text']
app = Flask(__name__)

@app.route('/', methods=["POST"])
def post_data():
    if request.get_json().get('message_type') == 'private':            
        QQ_id = request.get_json().get('sender').get('user_id')         
        msg = request.get_json().get('raw_message')    
        msg=openai_reply(msg,str(QQ_id))
        requests.get("http://127.0.0.1:5700/send_private_msg?user_id={0}&message={1}".format(QQ_id, msg))
    return 'OK,do not say anymore' 

server = pywsgi.WSGIServer(('127.0.0.1', 5701), app)
server.serve_forever()

三、结尾
以上代码已经实现了主要的功能,其他诸如发送群聊信息,识别@信息等,可以自行添加,篇幅所限,这里不多赘述,值得注意的是,以上代码运用的是单轮输入的达芬奇模型,因此该模型并没有上下文联想功能,如果要加入该功能的话,可以参考这篇文章zhuanlan.zhihu.com/p/614781557

我自己的代码为

import requests
from flask import Flask, request
import os
import openai
import json
from gevent import pywsgi
import re
bot_id='123456789'#自己填写机器人的qq号
app = Flask(__name__)
openai.api_key = os.environ['OPENAI_API_KEY']
msg = [{"role": "system", "content": "你的名字是诺诺."},]
chatlis={}#用于区分不同的用户
total={}#用于计数使用的token数
msgt=msg
def openai_reply(question,id) -> str:
    txt = {"role": "user", "content": str(question)}
    if(id not in chatlis):#初始化一个新聊天会话
        chatlis[id]=msgt.copy()
        total[id]=0
    if total[id]+len(question)>2800:#当会话用的token过多时,自动重置
        chatlis[id]=msgt.copy()
        total[id]=0
        return "单次会话数据过多,已重置。"
    chatlis[id].append(txt)
    response = openai.ChatCompletion.create(
        model="gpt-3.5-turbo",
        #prompt=question,
        temperature=0.7,
        max_tokens=1200,
        top_p=1,
        n = 1,
        user = id,
        frequency_penalty=0,
        presence_penalty=0,
        messages=chatlis[id]
    )
    print('本次消费的token总数量:'+str(response['usage'].total_tokens))
    total[id]=response['usage'].total_tokens
    choices = response['choices']
    first_item = choices[0]
    txt = {"role": "assistant", "content": first_item['message']['content']}
    chatlis[id].append(txt)
    return first_item['message']['content']
@app.route('/', methods=["POST"])
def post_data():
    if request.get_json().get('message_type') == 'private':              
        QQ_id = request.get_json().get('sender').get('user_id')         
        msg = request.get_json().get('raw_message') 
        msg=openai_reply(msg,str(QQ_id))  
        requests.get("http://127.0.0.1:5700/send_private_msg?user_id={}&message={}".format(QQ_id,msg))
    elif request.get_json().get('message_type') == 'group':           
        Qun_id = request.get_json().get('group_id')                         
        QQ_id = request.get_json().get('sender').get('user_id')         
        msg = request.get_json().get('raw_message')          
        if str("[CQ:at,qq=%s]"%bot_id) in msg: 
            msg=Xingxi_text.replace(str("[CQ:at,qq=%s] "%bot_id),"")
            msg=openai_reply(msg,str(QQ_id))
            requests.get("http://127.0.0.1:5700/send_group_msg?group_id={0}&message={1}".format(Qun_id,"[CQ:at,qq=%s]"%QQ_id+msg))
    return 'OK,do not say anymore'  
server = pywsgi.WSGIServer(('127.0.0.1', 5701), app)
server.serve_forever()