mirror of
https://github.com/AstrBotDevs/AstrBot
synced 2026-07-18 02:00:09 +08:00
feat: 支持官方ChatGPT API
perf: 提高了稳定性
This commit is contained in:
@@ -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驱动。"
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
11
util/log.py
Normal file
11
util/log.py
Normal 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)
|
||||
Reference in New Issue
Block a user