feat: 支持官方ChatGPT API

perf: 提高了稳定性
This commit is contained in:
Soulter
2023-03-02 09:34:16 +08:00
parent 5663c1d6b2
commit 4dc214b27e
4 changed files with 72 additions and 42 deletions

View File

@@ -6,19 +6,16 @@ openai:
# 在下方非注释的地方使用以上格式
key:
-
# OpenAI GPT模型参数
chatGPTConfigs:
engine: text-davinci-003
max_tokens: 600
temperature: 0.8
engine: "gpt-3.5-turbo"
max_tokens: 1000
temperature: 0.9
top_p: 1
frequency_penalty: 0.4
presence_penalty: 0.3
total_tokens_limit: 500
# QQ开放平台机器人信息
# https://q.qq.com
frequency_penalty: 0
presence_penalty: 0
total_tokens_limit: 2000
qqbot:
appid:
token:
@@ -26,18 +23,16 @@ qqbot:
# 设置是否一个人一个会话
uniqueSessionMode: false
# QQChannelChatGPTBot版本号不用改
version: 2.33
# QChannelBot 的版本请勿修改此字段否则可能产生一些bug
version: 2.4 RealChatGPT Ver.
# 转储历史记录时间间隔(分钟)
# [Beta] 转储历史记录时间间隔(分钟)
dump_history_interval: 10
# 用户发言频率限制。
# 一个用户只能在time秒内发送count条消息
limit:
time: 60
count: 5
# 公告
notice: "此机器人由Github项目QQChannelChatGPT驱动。"

View File

@@ -17,25 +17,28 @@ class ChatGPT:
with open(abs_path+"configs/config.yaml", 'r', encoding='utf-8') as ymlfile:
cfg = yaml.safe_load(ymlfile)
if cfg['openai']['key'] != '' or cfg['openai']['key'] != '修改我!!':
print("读取ChatGPT Key成功")
print("[System] 读取ChatGPT Key成功")
self.key_list = cfg['openai']['key']
# openai.api_key = cfg['openai']['key']
else:
input("请先去完善ChatGPT的Key。详情请前往https://beta.openai.com/account/api-keys")
input("[System] 请先去完善ChatGPT的Key。详情请前往https://beta.openai.com/account/api-keys")
# init key record
self.init_key_record()
chatGPT_configs = cfg['openai']['chatGPTConfigs']
print(f'加载ChatGPTConfigs: {chatGPT_configs}')
print(f'[System] 加载ChatGPTConfigs: {chatGPT_configs}')
self.chatGPT_configs = chatGPT_configs
self.openai_configs = cfg['openai']
def chat(self, prompt, image_mode = False):
# ChatGPT API 2023/3/2
messages = [{"role": "user", "content": prompt}]
try:
if not image_mode:
response = openai.Completion.create(
prompt=prompt,
response = openai.ChatCompletion.create(
messages=messages,
**self.chatGPT_configs
)
else:
@@ -47,7 +50,7 @@ class ChatGPT:
except Exception as e:
print(e)
if 'You exceeded' in str(e) or 'Billing hard limit has been reached' in str(e) or 'No API key provided.' in str(e):
print("当前Key已超额,正在切换")
print("[System] 当前Key已超额,正在切换")
self.key_stat[openai.api_key]['exceed'] = True
self.save_key_record()
@@ -57,8 +60,8 @@ class ChatGPT:
raise e
else:
if not image_mode:
response = openai.Completion.create(
prompt=prompt,
response = openai.ChatCompletion.create(
messages=messages,
**self.chatGPT_configs
)
else:
@@ -70,30 +73,31 @@ class ChatGPT:
if not image_mode:
self.key_stat[openai.api_key]['used'] += response['usage']['total_tokens']
self.save_key_record()
print("[ChatGPT] "+str(response["choices"][0]["text"]))
return str(response["choices"][0]["text"]).strip(), response['usage']['total_tokens']
print("[ChatGPT] "+str(response["choices"][0]["message"]["content"]))
return str(response["choices"][0]["message"]["content"]).strip(), response['usage']['total_tokens']
else:
return response['data'][0]['url']
def handle_switch_key(self, prompt):
messages = [{"role": "user", "content": prompt}]
while True:
is_all_exceed = True
for key in self.key_stat:
if not self.key_stat[key]['exceed']:
is_all_exceed = False
openai.api_key = key
print(f"切换到Key: {key}, 已使用token: {self.key_stat[key]['used']}")
print(f"[System] 切换到Key: {key}, 已使用token: {self.key_stat[key]['used']}")
if prompt != '':
try:
response = openai.Completion.create(
prompt=prompt,
response = openai.ChatCompletion.create(
messages=messages,
**self.chatGPT_configs
)
return response, True
except Exception as e:
print(e)
if 'You exceeded' in str(e):
print("当前Key已超额,正在切换")
print("[System] 当前Key已超额,正在切换")
self.key_stat[openai.api_key]['exceed'] = True
self.save_key_record()
time.sleep(1)
@@ -101,7 +105,7 @@ class ChatGPT:
else:
return True
if is_all_exceed:
print("所有Key已超额")
print("[System] 所有Key已超额")
return None, False
def getConfigs(self):
@@ -126,9 +130,10 @@ class ChatGPT:
def check_key(self, key):
pre_key = openai.api_key
openai.api_key = key
messages = [{"role": "user", "content": "1"}]
try:
openai.Completion.create(
prompt="1",
response = openai.ChatCompletion.create(
messages=messages,
**self.chatGPT_configs
)
openai.api_key = pre_key

View File

@@ -15,6 +15,7 @@ import os
import sys
from cores.qqbot.personality import personalities
history_dump_interval = 10
# QQBotClient实例
client = ''
@@ -57,6 +58,9 @@ direct_message_mode = True
# 适配pyinstaller
abs_path = os.path.dirname(os.path.realpath(sys.argv[0])) + '/'
# 版本
version = '2.4 RealChatGPT Ver.'
def new_sub_thread(func, args=()):
thread = threading.Thread(target=func, args=args, daemon=True)
thread.start()
@@ -121,7 +125,7 @@ def dump_history():
# 每隔10分钟转储一次
time.sleep(10*history_dump_interval)
# 上传统计信息
# 上传统计信息并检查更新
def upload():
global object_id
while True:
@@ -206,17 +210,20 @@ def initBot(chatgpt_inst):
# 创建上传定时器线程
threading.Thread(target=upload, daemon=True).start()
global config, uniqueSession, history_dump_interval, frequency_count, frequency_time,announcement, direct_message_mode
global config, uniqueSession, history_dump_interval, frequency_count, frequency_time,announcement, direct_message_mode, version
with open(abs_path+"configs/config.yaml", 'r', encoding='utf-8') as ymlfile:
cfg = yaml.safe_load(ymlfile)
config = cfg
# 得到私聊模式配置
if 'direct_message_mode' in cfg:
direct_message_mode = cfg['direct_message_mode']
if direct_message_mode:
print("[System] 私聊功能打开")
else:
print("[System] 私聊功能关闭")
print("[System] 私聊功能: "+str(direct_message_mode))
# 得到版本
if 'version' in cfg:
version = cfg['version']
print("[System] QQChannelChatGPT版本: "+str(version))
# 得到发言频率配置
if 'limit' in cfg:
@@ -245,11 +252,15 @@ def initBot(chatgpt_inst):
print(f"[System] QQ开放平台AppID: {cfg['qqbot']['appid']} 令牌: {cfg['qqbot']['token']}")
print("[System] 如果有任何问题请在https://github.com/Soulter/QQChannelChatGPT上提交issue说明问题或者添加QQ905617992\n")
print("\n[System] 如果有任何问题请在https://github.com/Soulter/QQChannelChatGPT上提交issue说明问题或者添加QQ905617992")
print("[System] 请给https://github.com/Soulter/QQChannelChatGPT点个star!")
print("[System] 请给https://github.com/Soulter/QQChannelChatGPT点个star!")
input("\n仔细阅读完以上信息后,输入任意信息并回车以继续")
try:
run_bot(cfg['qqbot']['appid'], cfg['qqbot']['token'])
except BaseException as e:
input(f"\n[System-Error] 启动QQ机器人时出现错误原因如下{e}\n可能是没有填写QQBOT appid和token请在config中完善你的appid和token\n配置教程https://soulter.top/posts/qpdg.html\n")
'''
启动机器人
@@ -627,7 +638,15 @@ def command_oper(qq_msg, message, session_id, name, user_id, user_name, at):
msg = f"当前会话数: {len(session_dict)}\n共有频道数: {guild_count} \n共有消息数: {guild_msg_count}\n私信数: {guild_direct_msg_count}\n历史会话数: {session_count}"
if qq_msg == "/help":
msg = "[Github项目名: QQChannelChatGPT有问题请前往提交issue欢迎赞助支持我]\n\n指令面板:\n/status 查看机器人key状态\n/count 查看机器人统计信息\n/reset 重置会话\n/his 查看历史记录\n/token 查看会话token数\n/help 查看帮助\n/set 人格指令菜单\n/key 动态添加key"
ol_version = 'Unknown'
try:
global version
res = requests.get("https://soulter.top/channelbot/update.json")
res_obj = json.loads(res.text)
ol_version = res_obj['version']
except BaseException:
pass
msg = f"[Github项目名: QQChannelChatGPT有问题请前往提交issue欢迎Star此项目~]\n\n当前版本:{version}\n最新版本:{str(ol_version)}\n请及时更新!\n\n指令面板:\n/status 查看机器人key状态\n/count 查看机器人统计信息\n/reset 重置会话\n/his 查看历史记录\n/token 查看会话token数\n/help 查看帮助\n/set 人格指令菜单\n/key 动态添加key"
if qq_msg[:4] == "/key":
if len(qq_msg) == 4:

11
util/log.py Normal file
View File

@@ -0,0 +1,11 @@
import logging
from logging.handlers import RotatingFileHandler
import colorlog
logger = logging.getLogger("QQChannelChatGPT")
logger.setLevel(logging.DEBUG)
handler = colorlog.StreamHandler()
fmt = "%(log_color)s[%(name)s] %(message)s"
handler.setFormatter(colorlog.ColoredFormatter(
fmt))
logger.addHandler(handler)