mirror of https://github.com/Mai-with-u/MaiBot.git
feat:添加黑话收集器
parent
03e06c282c
commit
5bde31e512
|
|
@ -639,6 +639,83 @@ class DefaultReplyer:
|
|||
prompt_personality = f"{prompt_personality};"
|
||||
return f"你的名字是{bot_name}{bot_nickname},你{prompt_personality}"
|
||||
|
||||
def _parse_chat_prompt_config_to_chat_id(self, chat_prompt_str: str) -> Optional[tuple[str, str]]:
|
||||
"""
|
||||
解析聊天prompt配置字符串并生成对应的 chat_id 和 prompt内容
|
||||
|
||||
Args:
|
||||
chat_prompt_str: 格式为 "platform:id:type:prompt内容" 的字符串
|
||||
|
||||
Returns:
|
||||
tuple: (chat_id, prompt_content),如果解析失败则返回 None
|
||||
"""
|
||||
try:
|
||||
# 使用 split 分割,但限制分割次数为3,因为prompt内容可能包含冒号
|
||||
parts = chat_prompt_str.split(":", 3)
|
||||
if len(parts) != 4:
|
||||
return None
|
||||
|
||||
platform = parts[0]
|
||||
id_str = parts[1]
|
||||
stream_type = parts[2]
|
||||
prompt_content = parts[3]
|
||||
|
||||
# 判断是否为群聊
|
||||
is_group = stream_type == "group"
|
||||
|
||||
# 使用与 ChatStream.get_stream_id 相同的逻辑生成 chat_id
|
||||
import hashlib
|
||||
|
||||
if is_group:
|
||||
components = [platform, str(id_str)]
|
||||
else:
|
||||
components = [platform, str(id_str), "private"]
|
||||
key = "_".join(components)
|
||||
chat_id = hashlib.md5(key.encode()).hexdigest()
|
||||
|
||||
return chat_id, prompt_content
|
||||
|
||||
except (ValueError, IndexError):
|
||||
return None
|
||||
|
||||
def get_chat_prompt_for_chat(self, chat_id: str) -> str:
|
||||
"""
|
||||
根据聊天流ID获取匹配的额外prompt(仅匹配group类型)
|
||||
|
||||
Args:
|
||||
chat_id: 聊天流ID(哈希值)
|
||||
|
||||
Returns:
|
||||
str: 匹配的额外prompt内容,如果没有匹配则返回空字符串
|
||||
"""
|
||||
if not global_config.experimental.chat_prompts:
|
||||
return ""
|
||||
|
||||
for chat_prompt_str in global_config.experimental.chat_prompts:
|
||||
if not isinstance(chat_prompt_str, str):
|
||||
continue
|
||||
|
||||
# 解析配置字符串,检查类型是否为group
|
||||
parts = chat_prompt_str.split(":", 3)
|
||||
if len(parts) != 4:
|
||||
continue
|
||||
|
||||
stream_type = parts[2]
|
||||
# 只匹配group类型
|
||||
if stream_type != "group":
|
||||
continue
|
||||
|
||||
result = self._parse_chat_prompt_config_to_chat_id(chat_prompt_str)
|
||||
if result is None:
|
||||
continue
|
||||
|
||||
config_chat_id, prompt_content = result
|
||||
if config_chat_id == chat_id:
|
||||
logger.debug(f"匹配到群聊prompt配置,chat_id: {chat_id}, prompt: {prompt_content[:50]}...")
|
||||
return prompt_content
|
||||
|
||||
return ""
|
||||
|
||||
async def build_prompt_reply_context(
|
||||
self,
|
||||
reply_message: Optional[DatabaseMessages] = None,
|
||||
|
|
@ -820,6 +897,11 @@ class DefaultReplyer:
|
|||
# 构建分离的对话 prompt
|
||||
dialogue_prompt = self.build_chat_history_prompts(message_list_before_now_long, user_id, sender)
|
||||
|
||||
# 获取匹配的额外prompt
|
||||
chat_prompt_content = self.get_chat_prompt_for_chat(chat_id)
|
||||
chat_prompt_block = f"{chat_prompt_content}\n" if chat_prompt_content else ""
|
||||
|
||||
# 固定使用群聊回复模板
|
||||
return await global_prompt_manager.format_prompt(
|
||||
"replyer_prompt",
|
||||
expression_habits_block=expression_habits_block,
|
||||
|
|
@ -840,6 +922,7 @@ class DefaultReplyer:
|
|||
keywords_reaction_prompt=keywords_reaction_prompt,
|
||||
moderation_prompt=moderation_prompt_block,
|
||||
question_block=question_block,
|
||||
chat_prompt=chat_prompt_block,
|
||||
), selected_expressions
|
||||
|
||||
async def build_prompt_rewrite_context(
|
||||
|
|
|
|||
|
|
@ -536,6 +536,83 @@ class PrivateReplyer:
|
|||
prompt_personality = f"{prompt_personality};"
|
||||
return f"你的名字是{bot_name}{bot_nickname},你{prompt_personality}"
|
||||
|
||||
def _parse_chat_prompt_config_to_chat_id(self, chat_prompt_str: str) -> Optional[tuple[str, str]]:
|
||||
"""
|
||||
解析聊天prompt配置字符串并生成对应的 chat_id 和 prompt内容
|
||||
|
||||
Args:
|
||||
chat_prompt_str: 格式为 "platform:id:type:prompt内容" 的字符串
|
||||
|
||||
Returns:
|
||||
tuple: (chat_id, prompt_content),如果解析失败则返回 None
|
||||
"""
|
||||
try:
|
||||
# 使用 split 分割,但限制分割次数为3,因为prompt内容可能包含冒号
|
||||
parts = chat_prompt_str.split(":", 3)
|
||||
if len(parts) != 4:
|
||||
return None
|
||||
|
||||
platform = parts[0]
|
||||
id_str = parts[1]
|
||||
stream_type = parts[2]
|
||||
prompt_content = parts[3]
|
||||
|
||||
# 判断是否为群聊
|
||||
is_group = stream_type == "group"
|
||||
|
||||
# 使用与 ChatStream.get_stream_id 相同的逻辑生成 chat_id
|
||||
import hashlib
|
||||
|
||||
if is_group:
|
||||
components = [platform, str(id_str)]
|
||||
else:
|
||||
components = [platform, str(id_str), "private"]
|
||||
key = "_".join(components)
|
||||
chat_id = hashlib.md5(key.encode()).hexdigest()
|
||||
|
||||
return chat_id, prompt_content
|
||||
|
||||
except (ValueError, IndexError):
|
||||
return None
|
||||
|
||||
def get_chat_prompt_for_chat(self, chat_id: str) -> str:
|
||||
"""
|
||||
根据聊天流ID获取匹配的额外prompt(仅匹配private类型)
|
||||
|
||||
Args:
|
||||
chat_id: 聊天流ID(哈希值)
|
||||
|
||||
Returns:
|
||||
str: 匹配的额外prompt内容,如果没有匹配则返回空字符串
|
||||
"""
|
||||
if not global_config.experimental.chat_prompts:
|
||||
return ""
|
||||
|
||||
for chat_prompt_str in global_config.experimental.chat_prompts:
|
||||
if not isinstance(chat_prompt_str, str):
|
||||
continue
|
||||
|
||||
# 解析配置字符串,检查类型是否为private
|
||||
parts = chat_prompt_str.split(":", 3)
|
||||
if len(parts) != 4:
|
||||
continue
|
||||
|
||||
stream_type = parts[2]
|
||||
# 只匹配private类型
|
||||
if stream_type != "private":
|
||||
continue
|
||||
|
||||
result = self._parse_chat_prompt_config_to_chat_id(chat_prompt_str)
|
||||
if result is None:
|
||||
continue
|
||||
|
||||
config_chat_id, prompt_content = result
|
||||
if config_chat_id == chat_id:
|
||||
logger.debug(f"匹配到私聊prompt配置,chat_id: {chat_id}, prompt: {prompt_content[:50]}...")
|
||||
return prompt_content
|
||||
|
||||
return ""
|
||||
|
||||
async def build_prompt_reply_context(
|
||||
self,
|
||||
reply_message: Optional[DatabaseMessages] = None,
|
||||
|
|
@ -718,6 +795,10 @@ class PrivateReplyer:
|
|||
# 其他情况(空内容等)
|
||||
reply_target_block = f"现在对方说的:{target}。引起了你的注意"
|
||||
|
||||
# 获取匹配的额外prompt
|
||||
chat_prompt_content = self.get_chat_prompt_for_chat(chat_id)
|
||||
chat_prompt_block = f"{chat_prompt_content}\n" if chat_prompt_content else ""
|
||||
|
||||
if global_config.bot.qq_account == user_id and platform == global_config.bot.platform:
|
||||
return await global_prompt_manager.format_prompt(
|
||||
"private_replyer_self_prompt",
|
||||
|
|
@ -738,6 +819,7 @@ class PrivateReplyer:
|
|||
reply_style=global_config.personality.reply_style,
|
||||
keywords_reaction_prompt=keywords_reaction_prompt,
|
||||
moderation_prompt=moderation_prompt_block,
|
||||
chat_prompt=chat_prompt_block,
|
||||
), selected_expressions
|
||||
else:
|
||||
return await global_prompt_manager.format_prompt(
|
||||
|
|
@ -758,6 +840,7 @@ class PrivateReplyer:
|
|||
keywords_reaction_prompt=keywords_reaction_prompt,
|
||||
moderation_prompt=moderation_prompt_block,
|
||||
sender_name=sender,
|
||||
chat_prompt=chat_prompt_block,
|
||||
), selected_expressions
|
||||
|
||||
async def build_prompt_rewrite_context(
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ def init_replyer_prompt():
|
|||
|
||||
{reply_target_block}。
|
||||
{identity}
|
||||
你正在群里聊天,现在请你读读之前的聊天记录,然后给出日常且口语化的回复,平淡一些,{mood_state}
|
||||
{chat_prompt}你正在群里聊天,现在请你读读之前的聊天记录,然后给出日常且口语化的回复,平淡一些,{mood_state}
|
||||
尽量简短一些。{keywords_reaction_prompt}请注意把握聊天内容,不要回复的太有条理,可以有个性。
|
||||
{reply_style}
|
||||
请注意不要输出多余内容(包括前后缀,冒号和引号,括号,表情等),只输出一句回复内容就好。
|
||||
|
|
@ -41,7 +41,7 @@ def init_replyer_prompt():
|
|||
|
||||
{reply_target_block}。
|
||||
{identity}
|
||||
你正在和{sender_name}聊天,现在请你读读之前的聊天记录,然后给出日常且口语化的回复,平淡一些,{mood_state}
|
||||
{chat_prompt}你正在和{sender_name}聊天,现在请你读读之前的聊天记录,然后给出日常且口语化的回复,平淡一些,{mood_state}
|
||||
尽量简短一些。{keywords_reaction_prompt}请注意把握聊天内容,不要回复的太有条理,可以有个性。
|
||||
{reply_style}
|
||||
请注意不要输出多余内容(包括前后缀,冒号和引号,括号,表情等),只输出回复内容。
|
||||
|
|
@ -61,7 +61,7 @@ def init_replyer_prompt():
|
|||
你现在想补充说明你刚刚自己的发言内容:{target},原因是{reason}
|
||||
请你根据聊天内容,组织一条新回复。注意,{target} 是刚刚你自己的发言,你要在这基础上进一步发言,请按照你自己的角度来继续进行回复。注意保持上下文的连贯性。{mood_state}
|
||||
{identity}
|
||||
尽量简短一些。{keywords_reaction_prompt}请注意把握聊天内容,不要回复的太有条理,可以有个性。
|
||||
{chat_prompt}尽量简短一些。{keywords_reaction_prompt}请注意把握聊天内容,不要回复的太有条理,可以有个性。
|
||||
{reply_style}
|
||||
请注意不要输出多余内容(包括前后缀,冒号和引号,括号,表情等),只输出回复内容。
|
||||
{moderation_prompt}不要输出多余内容(包括冒号和引号,括号,表情包,at或 @等 )。
|
||||
|
|
|
|||
|
|
@ -656,6 +656,25 @@ class ExperimentalConfig(ConfigBase):
|
|||
enable_friend_chat: bool = False
|
||||
"""是否启用好友聊天"""
|
||||
|
||||
chat_prompts: list[str] = field(default_factory=lambda: [])
|
||||
"""
|
||||
为指定聊天添加额外的prompt配置列表
|
||||
格式: ["platform:id:type:prompt内容", ...]
|
||||
|
||||
示例:
|
||||
[
|
||||
"qq:114514:group:这是一个摄影群,你精通摄影知识",
|
||||
"qq:19198:group:这是一个二次元交流群",
|
||||
"qq:114514:private:这是你与好朋友的私聊"
|
||||
]
|
||||
|
||||
说明:
|
||||
- platform: 平台名称,如 "qq"
|
||||
- id: 群ID或用户ID
|
||||
- type: "group" 或 "private"
|
||||
- prompt内容: 要添加的额外prompt文本
|
||||
"""
|
||||
|
||||
|
||||
@dataclass
|
||||
class MaimMessageConfig(ConfigBase):
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
[inner]
|
||||
version = "6.19.2"
|
||||
version = "6.20.0"
|
||||
|
||||
#----以下是给开发人员阅读的,如果你只是部署了麦麦,不需要阅读----
|
||||
#如果你想要修改配置文件,请递增version的值
|
||||
|
|
@ -241,6 +241,16 @@ enable = true
|
|||
[experimental] #实验性功能
|
||||
none = false # 暂无
|
||||
|
||||
# 为指定聊天添加额外的prompt配置
|
||||
# 格式: ["platform:id:type:prompt内容", ...]
|
||||
# 示例:
|
||||
# chat_prompts = [
|
||||
# "qq:114514:group:这是一个摄影群,你精通摄影知识",
|
||||
# "qq:19198:group:这是一个二次元交流群",
|
||||
# "qq:114514:private:这是你与好朋友的私聊"
|
||||
# ]
|
||||
chat_prompts = []
|
||||
|
||||
|
||||
#此系统暂时移除,无效配置
|
||||
[relationship]
|
||||
|
|
|
|||
Loading…
Reference in New Issue