mirror of
https://github.com/langbot-app/LangBot.git
synced 2026-06-09 23:36:02 +00:00
Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3594e64bfc | ||
|
|
c23d114094 | ||
|
|
6cb3fdc7c9 | ||
|
|
c57642bd4e | ||
|
|
891ee0fac8 |
@@ -1,11 +1,12 @@
|
|||||||
# QChatGPT🤖
|
# QChatGPT🤖
|
||||||
|
> 2023/3/3 官方接口疑似被墙,请自行测试,或等待近期敏感时期结束。
|
||||||
> 2023/3/3 现已在主线支持官方ChatGPT接口,使用方法查看[#195](https://github.com/RockChinQ/QChatGPT/issues/195)
|
> 2023/3/3 现已在主线支持官方ChatGPT接口,使用方法查看[#195](https://github.com/RockChinQ/QChatGPT/issues/195)
|
||||||
> 2023/3/2 OpenAI已发布ChatGPT官方接口,我们正在全力接入,预计明日前完成,请查看[此PR](https://github.com/RockChinQ/QChatGPT/pull/194)
|
> 2023/3/2 OpenAI已发布ChatGPT官方接口,我们正在全力接入,预计明日前完成,请查看[此PR](https://github.com/RockChinQ/QChatGPT/pull/194)
|
||||||
> 2023/2/16 现已支持接入ChatGPT网页版,详情请完成部署并查看底部**插件**小节或[此仓库](https://github.com/RockChinQ/revLibs)
|
> 2023/2/16 现已支持接入ChatGPT网页版,详情请完成部署并查看底部**插件**小节或[此仓库](https://github.com/RockChinQ/revLibs)
|
||||||
|
|
||||||
- 到[项目Wiki](https://github.com/RockChinQ/QChatGPT/wiki)可了解项目详细信息
|
- 到[项目Wiki](https://github.com/RockChinQ/QChatGPT/wiki)可了解项目详细信息
|
||||||
- 由bilibili TheLazy制作的[视频教程](https://www.bilibili.com/video/BV15v4y1X7aP)
|
- 由bilibili TheLazy制作的[视频教程](https://www.bilibili.com/video/BV15v4y1X7aP)
|
||||||
- 交流、答疑群: ~~204785790~~(已满)、691226829
|
- 交流、答疑群: ~~204785790~~(已满)、691226829、656285629
|
||||||
- **进群提问前请您`确保`已经找遍文档和issue均无法解决**
|
- **进群提问前请您`确保`已经找遍文档和issue均无法解决**
|
||||||
- **进群提问前请您`确保`已经找遍文档和issue均无法解决**
|
- **进群提问前请您`确保`已经找遍文档和issue均无法解决**
|
||||||
- **进群提问前请您`确保`已经找遍文档和issue均无法解决**
|
- **进群提问前请您`确保`已经找遍文档和issue均无法解决**
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ mirai_http_api_config = {
|
|||||||
|
|
||||||
# [必需] OpenAI的配置
|
# [必需] OpenAI的配置
|
||||||
# api_key: OpenAI的API Key
|
# api_key: OpenAI的API Key
|
||||||
|
# http_proxy: 请求OpenAI时使用的代理,None为不使用,https和socks5暂不能使用
|
||||||
# 若只有一个api-key,请直接修改以下内容中的"openai_api_key"为你的api-key
|
# 若只有一个api-key,请直接修改以下内容中的"openai_api_key"为你的api-key
|
||||||
#
|
#
|
||||||
# 如准备了多个api-key,可以以字典的形式填写,程序会自动选择可用的api-key
|
# 如准备了多个api-key,可以以字典的形式填写,程序会自动选择可用的api-key
|
||||||
@@ -30,11 +31,13 @@ mirai_http_api_config = {
|
|||||||
# "key1": "sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
|
# "key1": "sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
|
||||||
# "key2": "sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
|
# "key2": "sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
|
||||||
# },
|
# },
|
||||||
|
# "http_proxy": "http://127.0.0.1:12345"
|
||||||
# }
|
# }
|
||||||
openai_config = {
|
openai_config = {
|
||||||
"api_key": {
|
"api_key": {
|
||||||
"default": "openai_api_key"
|
"default": "openai_api_key"
|
||||||
},
|
},
|
||||||
|
"http_proxy": None
|
||||||
}
|
}
|
||||||
|
|
||||||
# [必需] 管理员QQ号,用于接收报错等通知及执行管理员级别指令
|
# [必需] 管理员QQ号,用于接收报错等通知及执行管理员级别指令
|
||||||
|
|||||||
@@ -36,7 +36,11 @@ class OpenAIInteract:
|
|||||||
config = pkg.utils.context.get_config()
|
config = pkg.utils.context.get_config()
|
||||||
|
|
||||||
# 根据模型选择使用的接口
|
# 根据模型选择使用的接口
|
||||||
ai: ModelRequest = create_openai_model_request(config.completion_api_params['model'], 'user')
|
ai: ModelRequest = create_openai_model_request(
|
||||||
|
config.completion_api_params['model'],
|
||||||
|
'user',
|
||||||
|
config.openai_config["http_proxy"] if "http_proxy" in config.openai_config else None
|
||||||
|
)
|
||||||
ai.request(
|
ai.request(
|
||||||
prompts,
|
prompts,
|
||||||
**config.completion_api_params
|
**config.completion_api_params
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
# 提供与模型交互的抽象接口
|
# 提供与模型交互的抽象接口
|
||||||
import openai, logging
|
import openai, logging, threading, asyncio
|
||||||
|
|
||||||
COMPLETION_MODELS = {
|
COMPLETION_MODELS = {
|
||||||
'text-davinci-003',
|
'text-davinci-003',
|
||||||
@@ -26,48 +26,75 @@ IMAGE_MODELS = {
|
|||||||
|
|
||||||
|
|
||||||
class ModelRequest():
|
class ModelRequest():
|
||||||
"""模型请求抽象类"""
|
"""GPT父类"""
|
||||||
can_chat = False
|
can_chat = False
|
||||||
|
runtime:threading.Thread = None
|
||||||
|
ret = ""
|
||||||
|
proxy:str = None
|
||||||
|
|
||||||
def __init__(self, model_name, user_name, request_fun):
|
def __init__(self, model_name, user_name, request_fun, http_proxy:str = None):
|
||||||
self.model_name = model_name
|
self.model_name = model_name
|
||||||
self.user_name = user_name
|
self.user_name = user_name
|
||||||
self.request_fun = request_fun
|
self.request_fun = request_fun
|
||||||
|
if http_proxy != None:
|
||||||
|
self.proxy = http_proxy
|
||||||
|
openai.proxy = self.proxy
|
||||||
|
|
||||||
|
async def __a_request__(self, **kwargs):
|
||||||
|
self.ret = await self.request_fun(**kwargs)
|
||||||
|
|
||||||
def request(self, **kwargs):
|
def request(self, **kwargs):
|
||||||
ret = self.request_fun(**kwargs)
|
if self.proxy != None: #异步请求
|
||||||
self.ret = self.ret_handle(ret)
|
loop = asyncio.new_event_loop()
|
||||||
self.message = self.ret["choices"][0]["message"]
|
self.runtime = threading.Thread(
|
||||||
|
target=loop.run_until_complete,
|
||||||
|
args=(self.__a_request__(**kwargs),)
|
||||||
|
)
|
||||||
|
self.runtime.start()
|
||||||
|
else: #同步请求
|
||||||
|
self.ret = self.request_fun(**kwargs)
|
||||||
|
|
||||||
def __msg_handle__(self, msg):
|
def __msg_handle__(self, msg):
|
||||||
"""将prompt dict转换成接口需要的格式"""
|
"""将prompt dict转换成接口需要的格式"""
|
||||||
return msg
|
return msg
|
||||||
|
|
||||||
def ret_handle(self):
|
def ret_handle(self):
|
||||||
|
'''
|
||||||
|
API消息返回处理函数
|
||||||
|
若重写该方法,应检查异步线程状态,或在需要检查处super该方法
|
||||||
|
'''
|
||||||
|
if self.runtime != None and isinstance(self.runtime, threading.Thread):
|
||||||
|
self.runtime.join()
|
||||||
return
|
return
|
||||||
|
|
||||||
def get_total_tokens(self):
|
def get_total_tokens(self):
|
||||||
return self.ret['usage']['total_tokens']
|
try:
|
||||||
|
return self.ret['usage']['total_tokens']
|
||||||
|
except Exception:
|
||||||
|
return 0
|
||||||
|
|
||||||
def get_message(self):
|
def get_message(self):
|
||||||
return self.message
|
return self.message
|
||||||
|
|
||||||
def get_response(self):
|
def get_response(self):
|
||||||
return self.ret
|
return self.ret
|
||||||
|
|
||||||
|
|
||||||
class ChatCompletionModel(ModelRequest):
|
class ChatCompletionModel(ModelRequest):
|
||||||
"""ChatCompletion接口实现"""
|
"""ChatCompletion类模型"""
|
||||||
Chat_role = ['system', 'user', 'assistant']
|
Chat_role = ['system', 'user', 'assistant']
|
||||||
def __init__(self, model_name, user_name):
|
def __init__(self, model_name, user_name, http_proxy:str = None, **kwargs):
|
||||||
request_fun = openai.ChatCompletion.create
|
if http_proxy == None:
|
||||||
|
request_fun = openai.ChatCompletion.create
|
||||||
|
else:
|
||||||
|
request_fun = openai.ChatCompletion.acreate
|
||||||
self.can_chat = True
|
self.can_chat = True
|
||||||
super().__init__(model_name, user_name, request_fun)
|
super().__init__(model_name, user_name, request_fun, http_proxy, **kwargs)
|
||||||
|
|
||||||
def request(self, prompts, **kwargs):
|
def request(self, prompts, **kwargs):
|
||||||
self.ret = self.request_fun(messages = self.__msg_handle__(prompts), **kwargs, user=self.user_name)
|
prompts = self.__msg_handle__(prompts)
|
||||||
|
kwargs['messages'] = prompts
|
||||||
|
super().request(**kwargs)
|
||||||
self.ret_handle()
|
self.ret_handle()
|
||||||
self.message = self.ret["choices"][0]["message"]['content']
|
|
||||||
|
|
||||||
def __msg_handle__(self, msgs):
|
def __msg_handle__(self, msgs):
|
||||||
temp_msgs = []
|
temp_msgs = []
|
||||||
@@ -76,20 +103,24 @@ class ChatCompletionModel(ModelRequest):
|
|||||||
temp_msgs.append(msg.copy())
|
temp_msgs.append(msg.copy())
|
||||||
return temp_msgs
|
return temp_msgs
|
||||||
|
|
||||||
def get_content(self):
|
def get_message(self):
|
||||||
return self.message
|
return self.ret["choices"][0]["message"]['content'] #需要时直接加载加快请求速度,降低内存消耗
|
||||||
|
|
||||||
|
|
||||||
class CompletionModel(ModelRequest):
|
class CompletionModel(ModelRequest):
|
||||||
"""Completion接口实现"""
|
"""Completion类模型"""
|
||||||
def __init__(self, model_name, user_name):
|
def __init__(self, model_name, user_name, http_proxy:str = None, **kwargs):
|
||||||
request_fun = openai.Completion.create
|
if http_proxy == None:
|
||||||
super().__init__(model_name, user_name, request_fun)
|
request_fun = openai.Completion.create
|
||||||
|
else:
|
||||||
|
request_fun = openai.Completion.acreate
|
||||||
|
super().__init__(model_name, user_name, request_fun, http_proxy, **kwargs)
|
||||||
|
|
||||||
def request(self, prompts, **kwargs):
|
def request(self, prompts, **kwargs):
|
||||||
self.ret = self.request_fun(prompt = self.__msg_handle__(prompts), **kwargs)
|
prompts = self.__msg_handle__(prompts)
|
||||||
|
kwargs['prompt'] = prompts
|
||||||
|
super().request(**kwargs)
|
||||||
self.ret_handle()
|
self.ret_handle()
|
||||||
self.message = self.ret["choices"][0]["text"]
|
|
||||||
|
|
||||||
def __msg_handle__(self, msgs):
|
def __msg_handle__(self, msgs):
|
||||||
prompt = ''
|
prompt = ''
|
||||||
@@ -102,17 +133,17 @@ class CompletionModel(ModelRequest):
|
|||||||
# prompt = prompt + "{}:{}\n".format(msg['role'] , msg['content'])
|
# prompt = prompt + "{}:{}\n".format(msg['role'] , msg['content'])
|
||||||
prompt = prompt + "assistant: "
|
prompt = prompt + "assistant: "
|
||||||
return prompt
|
return prompt
|
||||||
|
|
||||||
def get_text(self):
|
|
||||||
return self.message
|
|
||||||
|
|
||||||
|
|
||||||
def create_openai_model_request(model_name: str, user_name: str = 'user') -> ModelRequest:
|
def get_message(self):
|
||||||
|
return self.ret["choices"][0]["text"]
|
||||||
|
|
||||||
|
|
||||||
|
def create_openai_model_request(model_name: str, user_name: str = 'user', http_proxy:str = None) -> ModelRequest:
|
||||||
"""使用给定的模型名称创建模型请求对象"""
|
"""使用给定的模型名称创建模型请求对象"""
|
||||||
if model_name in CHAT_COMPLETION_MODELS:
|
if model_name in CHAT_COMPLETION_MODELS:
|
||||||
model = ChatCompletionModel(model_name, user_name)
|
model = ChatCompletionModel(model_name, user_name, http_proxy)
|
||||||
elif model_name in COMPLETION_MODELS:
|
elif model_name in COMPLETION_MODELS:
|
||||||
model = CompletionModel(model_name, user_name)
|
model = CompletionModel(model_name, user_name, http_proxy)
|
||||||
else :
|
else :
|
||||||
log = "找不到模型[{}],请检查配置文件".format(model_name)
|
log = "找不到模型[{}],请检查配置文件".format(model_name)
|
||||||
logging.error(log)
|
logging.error(log)
|
||||||
|
|||||||
Reference in New Issue
Block a user