diff --git a/configs/config.yaml b/configs/config.yaml index c3817636e..af46adc90 100644 --- a/configs/config.yaml +++ b/configs/config.yaml @@ -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驱动。" diff --git a/cores/openai/core.py b/cores/openai/core.py index 32e638a87..1a5002dc2 100644 --- a/cores/openai/core.py +++ b/cores/openai/core.py @@ -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 diff --git a/cores/qqbot/core.py b/cores/qqbot/core.py index 2958386a0..1d3fdba18 100644 --- a/cores/qqbot/core.py +++ b/cores/qqbot/core.py @@ -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说明问题!或者添加QQ:905617992\n") + print("\n[System] 如果有任何问题,请在https://github.com/Soulter/QQChannelChatGPT上提交issue说明问题!或者添加QQ:905617992") + 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: diff --git a/util/log.py b/util/log.py new file mode 100644 index 000000000..ec19c1144 --- /dev/null +++ b/util/log.py @@ -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) \ No newline at end of file