mirror of
https://github.com/langbot-app/LangBot.git
synced 2025-11-25 11:29:39 +08:00
Merge branch 'master' into json_scenario
This commit is contained in:
36
README.md
36
README.md
@@ -1,16 +1,27 @@
|
||||
# QChatGPT🤖
|
||||
> 2023/3/3 官方接口疑似被墙,可考虑使用网络代理 [#198](https://github.com/RockChinQ/QChatGPT/issues/198)
|
||||
> 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/2/16 现已支持接入ChatGPT网页版,详情请完成部署并查看底部**插件**小节或[此仓库](https://github.com/RockChinQ/revLibs)
|
||||
# QChatGPT🤖完整情景导入版
|
||||
|
||||
- 到[项目Wiki](https://github.com/RockChinQ/QChatGPT/wiki)可了解项目详细信息
|
||||
- 由bilibili TheLazy制作的[视频教程](https://www.bilibili.com/video/BV15v4y1X7aP)
|
||||
- 交流、答疑群: ~~204785790~~(已满)、691226829、656285629
|
||||
- **进群提问前请您`确保`已经找遍文档和issue均无法解决**
|
||||
- QQ频道机器人见[QQChannelChatGPT](https://github.com/Soulter/QQChannelChatGPT)
|
||||
- 2023/3/9 初步追加通过json导入messages数组的方式进行情景预设,
|
||||
参考[api](https://platform.openai.com/docs/guides/chat/introduction),通过该方法能注入gpt本不存在的记忆。neko.json来源于[此](https://gist.github.com/ChenYFan/ffb8390aac6c4aa44869ec10fe4eb9e2)
|
||||
- 2023/3/8 fork from: [RockChinQ/QChatGPT](https://github.com/RockChinQ/QChatGPT)
|
||||
|
||||
通过调用OpenAI的ChatGPT等语言模型来实现一个更加智能的QQ机器人
|
||||
## 改动一览
|
||||
|
||||
### 切换完整情景模式
|
||||
|
||||
- 在`config.py`中,将`preset_mode`更改为`full_scenario`
|
||||
- 将情景json放入`scenario`文件夹中,使用`!reload`和`!reset <无后缀文件名>`指令切换
|
||||
|
||||
### 过滤脱离人设的回复
|
||||
|
||||
- 在`config.py`中将`filter_ai_warning`改为`True`
|
||||
- 在对应情景的json中添加(**注意,使用此过滤会使得机器人无法回复有关过滤词的内容**):
|
||||
|
||||
```json
|
||||
"filter": {
|
||||
"reg": "我的本质|抱歉|AI助手|人工智能|语言模型|无法提供|无法回应|机器人",
|
||||
"replace": "<替换的回复>"
|
||||
},
|
||||
```
|
||||
|
||||
## 🍺模型适配一览
|
||||
|
||||
@@ -227,10 +238,9 @@ python3 main.py
|
||||
- [@hissincn](https://github.com/hissincn) 本项目贡献者
|
||||
- [@LINSTCL](https://github.com/LINSTCL) GPT-3.5官方模型适配贡献者
|
||||
- [@Haibersut](https://github.com/Haibersut) 本项目贡献者
|
||||
- [@万神的星空](https://github.com/qq255204159) 整合包发行
|
||||
|
||||
以及其他所有为本项目提供支持的朋友们。
|
||||
|
||||
## 👍赞赏
|
||||
|
||||
<img alt="赞赏码" src="res/mm_reward_qrcode_1672840549070.png" width="400" height="400"/>
|
||||
<img alt="赞赏码" src="res/mm_reward_qrcode_1672840549070.png" width="400" height="400"/>
|
||||
|
||||
@@ -79,17 +79,11 @@ default_prompt = {
|
||||
"default": "如果我之后想获取帮助,请你说“输入!help获取帮助”",
|
||||
}
|
||||
|
||||
# 实验性设置项
|
||||
# JSON完整情景导入,存放JSON的文件夹
|
||||
full_prompt_dir = "scenario/"
|
||||
|
||||
# 实验性设置项: JSON完整情景导入
|
||||
# 预设prompt模式
|
||||
# 参考值:旧版本方式:default | 完整情景:full_scenario
|
||||
preset_mode = "default"
|
||||
|
||||
# 过滤AI脱离人设的消息
|
||||
# 这类消息在对应情景json中设置,将其替换为自定义消息,以保持人格
|
||||
filter_ai_warning = False
|
||||
|
||||
# 群内响应规则
|
||||
# 符合此消息的群内消息即使不包含at机器人也会响应
|
||||
|
||||
@@ -10,6 +10,10 @@ __prompts_from_files__ = {}
|
||||
"""从文件中读取的情景预设值"""
|
||||
|
||||
|
||||
import json
|
||||
import logging
|
||||
|
||||
|
||||
def read_prompt_from_file() -> str:
|
||||
"""从文件读取预设值"""
|
||||
# 读取prompts/目录下的所有文件,以文件名为键,文件内容为值
|
||||
@@ -66,14 +70,38 @@ def set_to_default():
|
||||
|
||||
|
||||
def get_prompt(name: str = None) -> str:
|
||||
import config
|
||||
preset_mode = config.preset_mode
|
||||
|
||||
"""获取预设值"""
|
||||
if name is None:
|
||||
name = get_current()
|
||||
|
||||
default_dict = get_prompt_dict()
|
||||
# JSON预设方式
|
||||
if preset_mode == 'full_scenario':
|
||||
import os
|
||||
# 整合路径,获取json文件名
|
||||
json_file = os.path.join(os.getcwd(), "scenario", name + '.json')
|
||||
|
||||
for key in default_dict:
|
||||
if key.lower().startswith(name.lower()):
|
||||
return default_dict[key]
|
||||
logging.debug('try to load json: {}'.format(json_file))
|
||||
|
||||
raise KeyError("未找到情景预设: " + name)
|
||||
try:
|
||||
with open(json_file, 'r', encoding ='utf-8') as f:
|
||||
json_content = json.load(f)
|
||||
logging.debug('succeed to load json: {}'.format(json_file))
|
||||
return json_content['prompt']
|
||||
|
||||
except FileNotFoundError:
|
||||
|
||||
raise KeyError("未找到Json情景预设: " + name)
|
||||
|
||||
# 默认预设方式
|
||||
elif preset_mode == 'default':
|
||||
|
||||
default_dict = get_prompt_dict()
|
||||
|
||||
for key in default_dict:
|
||||
if key.lower().startswith(name.lower()):
|
||||
return default_dict[key], None, None
|
||||
|
||||
raise KeyError("未找到默认情景预设: " + name)
|
||||
|
||||
@@ -128,51 +128,15 @@ class Session:
|
||||
logging.debug('{},lock release successfully,{}'.format(self.name, self.response_lock))
|
||||
|
||||
# 从配置文件获取会话预设信息
|
||||
def get_default_prompt(self, use_default: str = None, get_only = False):
|
||||
def get_default_prompt(self, use_default: str = None):
|
||||
config = pkg.utils.context.get_config()
|
||||
|
||||
import pkg.openai.dprompt as dprompt
|
||||
|
||||
if use_default is None:
|
||||
use_default = dprompt.get_current()
|
||||
current_default_prompt = \
|
||||
[
|
||||
{
|
||||
'role': 'user',
|
||||
'content': '如果我之后想获取帮助,请你说“输入!help获取帮助”'
|
||||
}, {
|
||||
'role': 'assistant',
|
||||
'content': 'ok'
|
||||
}
|
||||
]
|
||||
# 根据设置进行prompt预设模式
|
||||
|
||||
if config.preset_mode == "full_scenario":
|
||||
import os
|
||||
##
|
||||
dir = os.path.join(os.getcwd(), config.full_prompt_dir)
|
||||
json_file = os.path.join(dir, use_default) + '.json'
|
||||
|
||||
logging.debug("try to load json: {}".format(json_file))
|
||||
|
||||
try:
|
||||
with open(json_file, 'r', encoding ='utf-8') as f:
|
||||
json_content = json.load(f)
|
||||
current_default_prompt = json_content['prompt']
|
||||
|
||||
if not get_only:
|
||||
self.bot_name = json_content['name'] # 读取机器人名字,用于响应信息
|
||||
self.bot_filter = json_content['filter'] # 过滤掉不符合人格的警告
|
||||
logging.debug("first bot filter: {}".format(self.bot_filter))
|
||||
|
||||
except FileNotFoundError:
|
||||
logging.info("couldn't find file {}".format(json_file))
|
||||
|
||||
# logging.info("json: {}".format(current_default_prompt))
|
||||
##
|
||||
|
||||
else:
|
||||
current_default_prompt = dprompt.get_prompt(use_default)
|
||||
current_default_prompt = dprompt.get_prompt(use_default)
|
||||
|
||||
return current_default_prompt
|
||||
|
||||
@@ -227,7 +191,7 @@ class Session:
|
||||
self.last_interact_timestamp = int(time.time())
|
||||
|
||||
# 触发插件事件
|
||||
if self.prompt == self.get_default_prompt(get_only = True):
|
||||
if self.prompt == self.get_default_prompt():
|
||||
args = {
|
||||
'session_name': self.name,
|
||||
'session': self,
|
||||
@@ -249,25 +213,13 @@ class Session:
|
||||
# 成功获取,处理回复
|
||||
res_test = message
|
||||
res_ans = res_test
|
||||
|
||||
|
||||
# 去除开头可能的提示
|
||||
res_ans_spt = res_test.split("\n\n")
|
||||
if len(res_ans_spt) > 1:
|
||||
del (res_ans_spt[0])
|
||||
res_ans = '\n\n'.join(res_ans_spt)
|
||||
|
||||
|
||||
# 检测是否包含ai人格否定
|
||||
logging.debug('bot_filter: {}'.format(self.bot_filter))
|
||||
if config.filter_ai_warning and self.bot_filter:
|
||||
import re
|
||||
match = re.search(self.bot_filter['reg'], res_ans)
|
||||
logging.debug(self.bot_filter)
|
||||
logging.debug(res_ans)
|
||||
if match:
|
||||
logging.debug('回复:{}, 检测到人格否定,替换中。。'.format(res_ans))
|
||||
res_ans = self.bot_filter['replace']
|
||||
logging.debug('替换为: {}'.format(res_ans))
|
||||
|
||||
|
||||
# 将此次对话的双方内容加入到prompt中
|
||||
@@ -322,7 +274,7 @@ class Session:
|
||||
|
||||
# 持久化session
|
||||
def persistence(self):
|
||||
if self.prompt == self.get_default_prompt(get_only = True):
|
||||
if self.prompt == self.get_default_prompt():
|
||||
return
|
||||
|
||||
db_inst = pkg.utils.context.get_database_manager()
|
||||
|
||||
@@ -27,15 +27,7 @@ def check_response_rule(text: str, event):
|
||||
config = pkg.utils.context.get_config()
|
||||
if not hasattr(config, 'response_rules'):
|
||||
return False, ''
|
||||
|
||||
|
||||
bot_name = pkg.openai.session.get_session('group_{}'.format(event.group.id)).bot_name
|
||||
logging.debug(bot_name)
|
||||
# 检查情景json自带的名字
|
||||
if bot_name:
|
||||
import re
|
||||
if re.search(bot_name, text):
|
||||
return True, text
|
||||
|
||||
rules = config.response_rules
|
||||
# 检查前缀匹配
|
||||
if 'prefix' in rules:
|
||||
|
||||
Reference in New Issue
Block a user