better:优化prompt和配置和无用代码
This commit is contained in:
@@ -9,7 +9,6 @@
|
|||||||
|
|
||||||
优化和修复:
|
优化和修复:
|
||||||
|
|
||||||
-
|
|
||||||
- 优化no_reply逻辑
|
- 优化no_reply逻辑
|
||||||
- 优化Log显示
|
- 优化Log显示
|
||||||
- 优化关系配置
|
- 优化关系配置
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ def calculate_interest_value_distribution(messages) -> Dict[str, int]:
|
|||||||
}
|
}
|
||||||
|
|
||||||
for msg in messages:
|
for msg in messages:
|
||||||
if msg.interest_value is None:
|
if msg.interest_value is None or msg.interest_value == 0.0:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
value = float(msg.interest_value)
|
value = float(msg.interest_value)
|
||||||
@@ -80,7 +80,7 @@ def calculate_interest_value_distribution(messages) -> Dict[str, int]:
|
|||||||
|
|
||||||
def get_interest_value_stats(messages) -> Dict[str, float]:
|
def get_interest_value_stats(messages) -> Dict[str, float]:
|
||||||
"""Calculate basic statistics for interest_value"""
|
"""Calculate basic statistics for interest_value"""
|
||||||
values = [float(msg.interest_value) for msg in messages if msg.interest_value is not None]
|
values = [float(msg.interest_value) for msg in messages if msg.interest_value is not None and msg.interest_value != 0.0]
|
||||||
|
|
||||||
if not values:
|
if not values:
|
||||||
return {
|
return {
|
||||||
@@ -112,7 +112,8 @@ def get_available_chats() -> List[Tuple[str, str, int]]:
|
|||||||
chat_id = msg.chat_id
|
chat_id = msg.chat_id
|
||||||
count = Messages.select().where(
|
count = Messages.select().where(
|
||||||
(Messages.chat_id == chat_id) &
|
(Messages.chat_id == chat_id) &
|
||||||
(Messages.interest_value.is_null(False))
|
(Messages.interest_value.is_null(False)) &
|
||||||
|
(Messages.interest_value != 0.0)
|
||||||
).count()
|
).count()
|
||||||
if count > 0:
|
if count > 0:
|
||||||
chat_counts[chat_id] = count
|
chat_counts[chat_id] = count
|
||||||
@@ -174,7 +175,10 @@ def analyze_interest_values(chat_id: Optional[str] = None, start_time: Optional[
|
|||||||
"""Analyze interest values with optional filters"""
|
"""Analyze interest values with optional filters"""
|
||||||
|
|
||||||
# 构建查询条件
|
# 构建查询条件
|
||||||
query = Messages.select().where(Messages.interest_value.is_null(False))
|
query = Messages.select().where(
|
||||||
|
(Messages.interest_value.is_null(False)) &
|
||||||
|
(Messages.interest_value != 0.0)
|
||||||
|
)
|
||||||
|
|
||||||
if chat_id:
|
if chat_id:
|
||||||
query = query.where(Messages.chat_id == chat_id)
|
query = query.where(Messages.chat_id == chat_id)
|
||||||
@@ -212,7 +216,7 @@ def analyze_interest_values(chat_id: Optional[str] = None, start_time: Optional[
|
|||||||
print("时间范围: 不限制")
|
print("时间范围: 不限制")
|
||||||
|
|
||||||
print(f"\n基本统计:")
|
print(f"\n基本统计:")
|
||||||
print(f"有效消息数量: {stats['count']}")
|
print(f"有效消息数量: {stats['count']} (排除null和0值)")
|
||||||
print(f"最小值: {stats['min']:.3f}")
|
print(f"最小值: {stats['min']:.3f}")
|
||||||
print(f"最大值: {stats['max']:.3f}")
|
print(f"最大值: {stats['max']:.3f}")
|
||||||
print(f"平均值: {stats['avg']:.3f}")
|
print(f"平均值: {stats['avg']:.3f}")
|
||||||
|
|||||||
@@ -30,9 +30,6 @@ from src.plugin_system.base.component_types import ActionInfo
|
|||||||
|
|
||||||
logger = get_logger("replyer")
|
logger = get_logger("replyer")
|
||||||
|
|
||||||
ENABLE_S2S_MODE = True
|
|
||||||
|
|
||||||
|
|
||||||
def init_prompt():
|
def init_prompt():
|
||||||
Prompt("你正在qq群里聊天,下面是群里在聊的内容:", "chat_target_group1")
|
Prompt("你正在qq群里聊天,下面是群里在聊的内容:", "chat_target_group1")
|
||||||
Prompt("你正在和{sender_name}聊天,这是你们之前聊的内容:", "chat_target_private1")
|
Prompt("你正在和{sender_name}聊天,这是你们之前聊的内容:", "chat_target_private1")
|
||||||
@@ -97,29 +94,29 @@ def init_prompt():
|
|||||||
{relation_info_block}
|
{relation_info_block}
|
||||||
{extra_info_block}
|
{extra_info_block}
|
||||||
|
|
||||||
你是一个AI虚拟主播,正在直播QQ聊天,同时也在直播间回复弹幕,不过回复的时候不用过多提及这点
|
|
||||||
|
|
||||||
{identity}
|
{identity}
|
||||||
|
|
||||||
{action_descriptions}
|
{action_descriptions}
|
||||||
你现在的主要任务是和 {sender_name} 聊天。同时,也有其他用户会参与你们的聊天,你可以参考他们的回复内容,但是你主要还是关注你和{sender_name}的聊天内容。你现在的心情是:{mood_state}
|
你现在的主要任务是和 {sender_name} 聊天。同时,也有其他用户会参与你们的聊天,你可以参考他们的回复内容,但是你主要还是关注你和{sender_name}的聊天内容。
|
||||||
|
|
||||||
{background_dialogue_prompt}
|
{background_dialogue_prompt}
|
||||||
--------------------------------
|
--------------------------------
|
||||||
{time_block}
|
{time_block}
|
||||||
这是你和{sender_name}的对话,你们正在交流中:
|
这是你和{sender_name}的对话,你们正在交流中:
|
||||||
|
|
||||||
{core_dialogue_prompt}
|
{core_dialogue_prompt}
|
||||||
|
|
||||||
{reply_target_block}
|
{reply_target_block}
|
||||||
对方最新发送的内容:{message_txt}
|
对方最新发送的内容:{message_txt}
|
||||||
回复可以简短一些。可以参考贴吧,知乎和微博的回复风格,回复不要浮夸,不要用夸张修辞,平淡一些。
|
你现在的心情是:{mood_state}
|
||||||
{config_expression_style}。注意不要复读你说过的话
|
{config_expression_style}
|
||||||
|
注意不要复读你说过的话
|
||||||
{keywords_reaction_prompt}
|
{keywords_reaction_prompt}
|
||||||
请注意不要输出多余内容(包括前后缀,冒号和引号,at或 @等 )。只输出回复内容。
|
请注意不要输出多余内容(包括前后缀,冒号和引号,at或 @等 )。只输出回复内容。
|
||||||
{moderation_prompt}
|
{moderation_prompt}
|
||||||
不要浮夸,不要夸张修辞,不要输出多余内容(包括前后缀,冒号和引号,括号(),表情包,at或 @等 )。只输出回复内容,现在{sender_name}正在等待你的回复。
|
不要浮夸,不要夸张修辞,不要输出多余内容(包括前后缀,冒号和引号,括号(),表情包,at或 @等 )。只输出一条回复内容就好
|
||||||
你的回复风格不要浮夸,有逻辑和条理,请你继续回复{sender_name}。
|
现在,你说:
|
||||||
你的发言:
|
|
||||||
""",
|
""",
|
||||||
"s4u_style_prompt",
|
"s4u_style_prompt",
|
||||||
)
|
)
|
||||||
@@ -132,7 +129,6 @@ class DefaultReplyer:
|
|||||||
model_configs: Optional[List[Dict[str, Any]]] = None,
|
model_configs: Optional[List[Dict[str, Any]]] = None,
|
||||||
request_type: str = "focus.replyer",
|
request_type: str = "focus.replyer",
|
||||||
):
|
):
|
||||||
self.log_prefix = "replyer"
|
|
||||||
self.request_type = request_type
|
self.request_type = request_type
|
||||||
|
|
||||||
if model_configs:
|
if model_configs:
|
||||||
@@ -196,7 +192,7 @@ class DefaultReplyer:
|
|||||||
}
|
}
|
||||||
for key, value in reply_data.items():
|
for key, value in reply_data.items():
|
||||||
if not value:
|
if not value:
|
||||||
logger.debug(f"{self.log_prefix} 回复数据跳过{key},生成回复时将忽略。")
|
logger.debug(f"回复数据跳过{key},生成回复时将忽略。")
|
||||||
|
|
||||||
# 3. 构建 Prompt
|
# 3. 构建 Prompt
|
||||||
with Timer("构建Prompt", {}): # 内部计时器,可选保留
|
with Timer("构建Prompt", {}): # 内部计时器,可选保留
|
||||||
@@ -217,7 +213,7 @@ class DefaultReplyer:
|
|||||||
# 加权随机选择一个模型配置
|
# 加权随机选择一个模型配置
|
||||||
selected_model_config = self._select_weighted_model_config()
|
selected_model_config = self._select_weighted_model_config()
|
||||||
logger.info(
|
logger.info(
|
||||||
f"{self.log_prefix} 使用模型配置: {selected_model_config.get('name', 'N/A')} (权重: {selected_model_config.get('weight', 1.0)})"
|
f"使用模型生成回复: {selected_model_config.get('name', 'N/A')} (选中概率: {selected_model_config.get('weight', 1.0)})"
|
||||||
)
|
)
|
||||||
|
|
||||||
express_model = LLMRequest(
|
express_model = LLMRequest(
|
||||||
@@ -226,9 +222,9 @@ class DefaultReplyer:
|
|||||||
)
|
)
|
||||||
|
|
||||||
if global_config.debug.show_prompt:
|
if global_config.debug.show_prompt:
|
||||||
logger.info(f"{self.log_prefix}\n{prompt}\n")
|
logger.info(f"\n{prompt}\n")
|
||||||
else:
|
else:
|
||||||
logger.debug(f"{self.log_prefix}\n{prompt}\n")
|
logger.debug(f"\n{prompt}\n")
|
||||||
|
|
||||||
content, (reasoning_content, model_name) = await express_model.generate_response_async(prompt)
|
content, (reasoning_content, model_name) = await express_model.generate_response_async(prompt)
|
||||||
|
|
||||||
@@ -236,13 +232,13 @@ class DefaultReplyer:
|
|||||||
|
|
||||||
except Exception as llm_e:
|
except Exception as llm_e:
|
||||||
# 精简报错信息
|
# 精简报错信息
|
||||||
logger.error(f"{self.log_prefix}LLM 生成失败: {llm_e}")
|
logger.error(f"LLM 生成失败: {llm_e}")
|
||||||
return False, None, prompt # LLM 调用失败则无法生成回复
|
return False, None, prompt # LLM 调用失败则无法生成回复
|
||||||
|
|
||||||
return True, content, prompt
|
return True, content, prompt
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"{self.log_prefix}回复生成意外失败: {e}")
|
logger.error(f"回复生成意外失败: {e}")
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
return False, None, prompt
|
return False, None, prompt
|
||||||
|
|
||||||
@@ -273,7 +269,7 @@ class DefaultReplyer:
|
|||||||
reasoning_content = None
|
reasoning_content = None
|
||||||
model_name = "unknown_model"
|
model_name = "unknown_model"
|
||||||
if not prompt:
|
if not prompt:
|
||||||
logger.error(f"{self.log_prefix}Prompt 构建失败,无法生成回复。")
|
logger.error(f"Prompt 构建失败,无法生成回复。")
|
||||||
return False, None
|
return False, None
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -281,7 +277,7 @@ class DefaultReplyer:
|
|||||||
# 加权随机选择一个模型配置
|
# 加权随机选择一个模型配置
|
||||||
selected_model_config = self._select_weighted_model_config()
|
selected_model_config = self._select_weighted_model_config()
|
||||||
logger.info(
|
logger.info(
|
||||||
f"{self.log_prefix} 使用模型配置进行重写: {selected_model_config.get('name', 'N/A')} (权重: {selected_model_config.get('weight', 1.0)})"
|
f"使用模型重写回复: {selected_model_config.get('name', 'N/A')} (选中概率: {selected_model_config.get('weight', 1.0)})"
|
||||||
)
|
)
|
||||||
|
|
||||||
express_model = LLMRequest(
|
express_model = LLMRequest(
|
||||||
@@ -295,13 +291,13 @@ class DefaultReplyer:
|
|||||||
|
|
||||||
except Exception as llm_e:
|
except Exception as llm_e:
|
||||||
# 精简报错信息
|
# 精简报错信息
|
||||||
logger.error(f"{self.log_prefix}LLM 生成失败: {llm_e}")
|
logger.error(f"LLM 生成失败: {llm_e}")
|
||||||
return False, None # LLM 调用失败则无法生成回复
|
return False, None # LLM 调用失败则无法生成回复
|
||||||
|
|
||||||
return True, content
|
return True, content
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"{self.log_prefix}回复生成意外失败: {e}")
|
logger.error(f"回复生成意外失败: {e}")
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
return False, None
|
return False, None
|
||||||
|
|
||||||
@@ -321,7 +317,7 @@ class DefaultReplyer:
|
|||||||
person_info_manager = get_person_info_manager()
|
person_info_manager = get_person_info_manager()
|
||||||
person_id = person_info_manager.get_person_id_by_person_name(sender)
|
person_id = person_info_manager.get_person_id_by_person_name(sender)
|
||||||
if not person_id:
|
if not person_id:
|
||||||
logger.warning(f"{self.log_prefix} 未找到用户 {sender} 的ID,跳过信息提取")
|
logger.warning(f"未找到用户 {sender} 的ID,跳过信息提取")
|
||||||
return f"你完全不认识{sender},不理解ta的相关信息。"
|
return f"你完全不认识{sender},不理解ta的相关信息。"
|
||||||
|
|
||||||
return await relationship_fetcher.build_relation_info(person_id, points_num=5)
|
return await relationship_fetcher.build_relation_info(person_id, points_num=5)
|
||||||
@@ -340,7 +336,7 @@ class DefaultReplyer:
|
|||||||
)
|
)
|
||||||
|
|
||||||
if selected_expressions:
|
if selected_expressions:
|
||||||
logger.debug(f"{self.log_prefix} 使用处理器选中的{len(selected_expressions)}个表达方式")
|
logger.debug(f"使用处理器选中的{len(selected_expressions)}个表达方式")
|
||||||
for expr in selected_expressions:
|
for expr in selected_expressions:
|
||||||
if isinstance(expr, dict) and "situation" in expr and "style" in expr:
|
if isinstance(expr, dict) and "situation" in expr and "style" in expr:
|
||||||
expr_type = expr.get("type", "style")
|
expr_type = expr.get("type", "style")
|
||||||
@@ -349,7 +345,7 @@ class DefaultReplyer:
|
|||||||
else:
|
else:
|
||||||
style_habits.append(f"当{expr['situation']}时,使用 {expr['style']}")
|
style_habits.append(f"当{expr['situation']}时,使用 {expr['style']}")
|
||||||
else:
|
else:
|
||||||
logger.debug(f"{self.log_prefix} 没有从处理器获得表达方式,将使用空的表达方式")
|
logger.debug(f"没有从处理器获得表达方式,将使用空的表达方式")
|
||||||
# 不再在replyer中进行随机选择,全部交给处理器处理
|
# 不再在replyer中进行随机选择,全部交给处理器处理
|
||||||
|
|
||||||
style_habits_str = "\n".join(style_habits)
|
style_habits_str = "\n".join(style_habits)
|
||||||
@@ -431,14 +427,14 @@ class DefaultReplyer:
|
|||||||
tool_info_str += f"- 【{tool_name}】{result_type}: {content}\n"
|
tool_info_str += f"- 【{tool_name}】{result_type}: {content}\n"
|
||||||
|
|
||||||
tool_info_str += "以上是你获取到的实时信息,请在回复时参考这些信息。"
|
tool_info_str += "以上是你获取到的实时信息,请在回复时参考这些信息。"
|
||||||
logger.info(f"{self.log_prefix} 获取到 {len(tool_results)} 个工具结果")
|
logger.info(f"获取到 {len(tool_results)} 个工具结果")
|
||||||
return tool_info_str
|
return tool_info_str
|
||||||
else:
|
else:
|
||||||
logger.debug(f"{self.log_prefix} 未获取到任何工具结果")
|
logger.debug(f"未获取到任何工具结果")
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"{self.log_prefix} 工具信息获取失败: {e}")
|
logger.error(f"工具信息获取失败: {e}")
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
def _parse_reply_target(self, target_message: str) -> tuple:
|
def _parse_reply_target(self, target_message: str) -> tuple:
|
||||||
@@ -630,31 +626,40 @@ class DefaultReplyer:
|
|||||||
# 并行执行四个构建任务
|
# 并行执行四个构建任务
|
||||||
task_results = await asyncio.gather(
|
task_results = await asyncio.gather(
|
||||||
self._time_and_run_task(
|
self._time_and_run_task(
|
||||||
self.build_expression_habits(chat_talking_prompt_short, target), "build_expression_habits"
|
self.build_expression_habits(chat_talking_prompt_short, target), "expression_habits"
|
||||||
),
|
),
|
||||||
self._time_and_run_task(
|
self._time_and_run_task(
|
||||||
self.build_relation_info(reply_data), "build_relation_info"
|
self.build_relation_info(reply_data), "relation_info"
|
||||||
),
|
),
|
||||||
self._time_and_run_task(self.build_memory_block(chat_talking_prompt_short, target), "build_memory_block"),
|
self._time_and_run_task(self.build_memory_block(chat_talking_prompt_short, target), "memory_block"),
|
||||||
self._time_and_run_task(
|
self._time_and_run_task(
|
||||||
self.build_tool_info(chat_talking_prompt_short, reply_data, enable_tool=enable_tool), "build_tool_info"
|
self.build_tool_info(chat_talking_prompt_short, reply_data, enable_tool=enable_tool), "tool_info"
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# 任务名称中英文映射
|
||||||
|
task_name_mapping = {
|
||||||
|
"expression_habits": "选取表达方式",
|
||||||
|
"relation_info": "感受关系",
|
||||||
|
"memory_block": "回忆",
|
||||||
|
"tool_info": "使用工具"
|
||||||
|
}
|
||||||
|
|
||||||
# 处理结果
|
# 处理结果
|
||||||
timing_logs = []
|
timing_logs = []
|
||||||
results_dict = {}
|
results_dict = {}
|
||||||
for name, result, duration in task_results:
|
for name, result, duration in task_results:
|
||||||
results_dict[name] = result
|
results_dict[name] = result
|
||||||
timing_logs.append(f"{name}: {duration:.4f}s")
|
chinese_name = task_name_mapping.get(name, name)
|
||||||
|
timing_logs.append(f"{chinese_name}: {duration:.1f}s")
|
||||||
if duration > 8:
|
if duration > 8:
|
||||||
logger.warning(f"回复生成前信息获取耗时过长: {name} 耗时: {duration:.4f}s,请使用更快的模型")
|
logger.warning(f"回复生成前信息获取耗时过长: {chinese_name} 耗时: {duration:.1f}s,请使用更快的模型")
|
||||||
logger.info(f"回复生成前信息获取耗时: {'; '.join(timing_logs)}")
|
logger.info(f"在回复前的步骤耗时: {'; '.join(timing_logs)}")
|
||||||
|
|
||||||
expression_habits_block = results_dict["build_expression_habits"]
|
expression_habits_block = results_dict["expression_habits"]
|
||||||
relation_info = results_dict["build_relation_info"]
|
relation_info = results_dict["relation_info"]
|
||||||
memory_block = results_dict["build_memory_block"]
|
memory_block = results_dict["memory_block"]
|
||||||
tool_info = results_dict["build_tool_info"]
|
tool_info = results_dict["tool_info"]
|
||||||
|
|
||||||
keywords_reaction_prompt = await self.build_keywords_reaction_prompt(target)
|
keywords_reaction_prompt = await self.build_keywords_reaction_prompt(target)
|
||||||
|
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ from src.config.official_configs import (
|
|||||||
LPMMKnowledgeConfig,
|
LPMMKnowledgeConfig,
|
||||||
RelationshipConfig,
|
RelationshipConfig,
|
||||||
ToolConfig,
|
ToolConfig,
|
||||||
|
VoiceConfig,
|
||||||
DebugConfig,
|
DebugConfig,
|
||||||
CustomPromptConfig,
|
CustomPromptConfig,
|
||||||
)
|
)
|
||||||
@@ -328,7 +329,7 @@ class Config(ConfigBase):
|
|||||||
tool: ToolConfig
|
tool: ToolConfig
|
||||||
debug: DebugConfig
|
debug: DebugConfig
|
||||||
custom_prompt: CustomPromptConfig
|
custom_prompt: CustomPromptConfig
|
||||||
|
voice: VoiceConfig
|
||||||
|
|
||||||
def load_config(config_path: str) -> Config:
|
def load_config(config_path: str) -> Config:
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -106,9 +106,6 @@ class ChatConfig(ConfigBase):
|
|||||||
focus_value: float = 1.0
|
focus_value: float = 1.0
|
||||||
"""麦麦的专注思考能力,越低越容易专注,消耗token也越多"""
|
"""麦麦的专注思考能力,越低越容易专注,消耗token也越多"""
|
||||||
|
|
||||||
enable_asr: bool = False
|
|
||||||
"""是否启用语音识别"""
|
|
||||||
|
|
||||||
def get_current_talk_frequency(self, chat_stream_id: Optional[str] = None) -> float:
|
def get_current_talk_frequency(self, chat_stream_id: Optional[str] = None) -> float:
|
||||||
"""
|
"""
|
||||||
根据当前时间和聊天流获取对应的 talk_frequency
|
根据当前时间和聊天流获取对应的 talk_frequency
|
||||||
@@ -309,6 +306,13 @@ class ToolConfig(ConfigBase):
|
|||||||
|
|
||||||
enable_in_focus_chat: bool = True
|
enable_in_focus_chat: bool = True
|
||||||
"""是否在专注聊天中启用工具"""
|
"""是否在专注聊天中启用工具"""
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class VoiceConfig(ConfigBase):
|
||||||
|
"""语音识别配置类"""
|
||||||
|
|
||||||
|
enable_asr: bool = False
|
||||||
|
"""是否启用语音识别"""
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
|
|||||||
@@ -10,13 +10,13 @@ from datetime import datetime
|
|||||||
import asyncio
|
import asyncio
|
||||||
from src.mais4u.s4u_config import s4u_config
|
from src.mais4u.s4u_config import s4u_config
|
||||||
from src.chat.message_receive.message import MessageRecvS4U
|
from src.chat.message_receive.message import MessageRecvS4U
|
||||||
from src.person_info.relationship_manager import get_relationship_manager
|
from src.person_info.relationship_fetcher import relationship_fetcher_manager
|
||||||
|
from src.person_info.person_info import PersonInfoManager, get_person_info_manager
|
||||||
from src.chat.message_receive.chat_stream import ChatStream
|
from src.chat.message_receive.chat_stream import ChatStream
|
||||||
from src.mais4u.mais4u_chat.super_chat_manager import get_super_chat_manager
|
from src.mais4u.mais4u_chat.super_chat_manager import get_super_chat_manager
|
||||||
from src.mais4u.mais4u_chat.screen_manager import screen_manager
|
from src.mais4u.mais4u_chat.screen_manager import screen_manager
|
||||||
from src.chat.express.expression_selector import expression_selector
|
from src.chat.express.expression_selector import expression_selector
|
||||||
from .s4u_mood_manager import mood_manager
|
from .s4u_mood_manager import mood_manager
|
||||||
from src.person_info.person_info import PersonInfoManager, get_person_info_manager
|
|
||||||
from src.mais4u.mais4u_chat.internal_manager import internal_manager
|
from src.mais4u.mais4u_chat.internal_manager import internal_manager
|
||||||
logger = get_logger("prompt")
|
logger = get_logger("prompt")
|
||||||
|
|
||||||
@@ -149,9 +149,17 @@ class PromptBuilder:
|
|||||||
|
|
||||||
relation_prompt = ""
|
relation_prompt = ""
|
||||||
if global_config.relationship.enable_relationship and who_chat_in_group:
|
if global_config.relationship.enable_relationship and who_chat_in_group:
|
||||||
relationship_manager = get_relationship_manager()
|
relationship_fetcher = relationship_fetcher_manager.get_fetcher(chat_stream.stream_id)
|
||||||
|
|
||||||
|
# 将 (platform, user_id, nickname) 转换为 person_id
|
||||||
|
person_ids = []
|
||||||
|
for person in who_chat_in_group:
|
||||||
|
person_id = PersonInfoManager.get_person_id(person[0], person[1])
|
||||||
|
person_ids.append(person_id)
|
||||||
|
|
||||||
|
# 使用 RelationshipFetcher 的 build_relation_info 方法,设置 points_num=3 保持与原来相同的行为
|
||||||
relation_info_list = await asyncio.gather(
|
relation_info_list = await asyncio.gather(
|
||||||
*[relationship_manager.build_relationship_info(person) for person in who_chat_in_group]
|
*[relationship_fetcher.build_relation_info(person_id, points_num=3) for person_id in person_ids]
|
||||||
)
|
)
|
||||||
relation_info = "".join(relation_info_list)
|
relation_info = "".join(relation_info_list)
|
||||||
if relation_info:
|
if relation_info:
|
||||||
|
|||||||
@@ -41,8 +41,6 @@ person_info_default = {
|
|||||||
"know_times": 0,
|
"know_times": 0,
|
||||||
"know_since": None,
|
"know_since": None,
|
||||||
"last_know": None,
|
"last_know": None,
|
||||||
# "user_cardname": None, # This field is not in Peewee model PersonInfo
|
|
||||||
# "user_avatar": None, # This field is not in Peewee model PersonInfo
|
|
||||||
"impression": None, # Corrected from person_impression
|
"impression": None, # Corrected from person_impression
|
||||||
"short_impression": None,
|
"short_impression": None,
|
||||||
"info_list": None,
|
"info_list": None,
|
||||||
|
|||||||
@@ -112,15 +112,6 @@ class RelationshipFetcher:
|
|||||||
|
|
||||||
current_points = await person_info_manager.get_value(person_id, "points") or []
|
current_points = await person_info_manager.get_value(person_id, "points") or []
|
||||||
|
|
||||||
if isinstance(current_points, str):
|
|
||||||
try:
|
|
||||||
current_points = json.loads(current_points)
|
|
||||||
except json.JSONDecodeError:
|
|
||||||
logger.error(f"解析points JSON失败: {current_points}")
|
|
||||||
current_points = []
|
|
||||||
elif not isinstance(current_points, list):
|
|
||||||
current_points = []
|
|
||||||
|
|
||||||
# 按时间排序forgotten_points
|
# 按时间排序forgotten_points
|
||||||
current_points.sort(key=lambda x: x[2])
|
current_points.sort(key=lambda x: x[2])
|
||||||
# 按权重加权随机抽取最多3个不重复的points,point[1]的值在1-10之间,权重越高被抽到概率越大
|
# 按权重加权随机抽取最多3个不重复的points,point[1]的值在1-10之间,权重越高被抽到概率越大
|
||||||
@@ -370,60 +361,6 @@ class RelationshipFetcher:
|
|||||||
logger.error(f"{self.log_prefix} 执行信息提取时出错: {e}")
|
logger.error(f"{self.log_prefix} 执行信息提取时出错: {e}")
|
||||||
logger.error(traceback.format_exc())
|
logger.error(traceback.format_exc())
|
||||||
|
|
||||||
def _organize_known_info(self) -> str:
|
|
||||||
"""组织已知的用户信息为字符串
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
str: 格式化的用户信息字符串
|
|
||||||
"""
|
|
||||||
persons_infos_str = ""
|
|
||||||
|
|
||||||
if self.info_fetched_cache:
|
|
||||||
persons_with_known_info = [] # 有已知信息的人员
|
|
||||||
persons_with_unknown_info = [] # 有未知信息的人员
|
|
||||||
|
|
||||||
for person_id in self.info_fetched_cache:
|
|
||||||
person_known_infos = []
|
|
||||||
person_unknown_infos = []
|
|
||||||
person_name = ""
|
|
||||||
|
|
||||||
for info_type in self.info_fetched_cache[person_id]:
|
|
||||||
person_name = self.info_fetched_cache[person_id][info_type]["person_name"]
|
|
||||||
if not self.info_fetched_cache[person_id][info_type]["unknown"]:
|
|
||||||
info_content = self.info_fetched_cache[person_id][info_type]["info"]
|
|
||||||
person_known_infos.append(f"[{info_type}]:{info_content}")
|
|
||||||
else:
|
|
||||||
person_unknown_infos.append(info_type)
|
|
||||||
|
|
||||||
# 如果有已知信息,添加到已知信息列表
|
|
||||||
if person_known_infos:
|
|
||||||
known_info_str = ";".join(person_known_infos) + ";"
|
|
||||||
persons_with_known_info.append((person_name, known_info_str))
|
|
||||||
|
|
||||||
# 如果有未知信息,添加到未知信息列表
|
|
||||||
if person_unknown_infos:
|
|
||||||
persons_with_unknown_info.append((person_name, person_unknown_infos))
|
|
||||||
|
|
||||||
# 先输出有已知信息的人员
|
|
||||||
for person_name, known_info_str in persons_with_known_info:
|
|
||||||
persons_infos_str += f"你对 {person_name} 的了解:{known_info_str}\n"
|
|
||||||
|
|
||||||
# 统一处理未知信息,避免重复的警告文本
|
|
||||||
if persons_with_unknown_info:
|
|
||||||
unknown_persons_details = []
|
|
||||||
for person_name, unknown_types in persons_with_unknown_info:
|
|
||||||
unknown_types_str = "、".join(unknown_types)
|
|
||||||
unknown_persons_details.append(f"{person_name}的[{unknown_types_str}]")
|
|
||||||
|
|
||||||
if len(unknown_persons_details) == 1:
|
|
||||||
persons_infos_str += (
|
|
||||||
f"你不了解{unknown_persons_details[0]}信息,不要胡乱回答,可以直接说不知道或忘记了;\n"
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
unknown_all_str = "、".join(unknown_persons_details)
|
|
||||||
persons_infos_str += f"你不了解{unknown_all_str}等信息,不要胡乱回答,可以直接说不知道或忘记了;\n"
|
|
||||||
|
|
||||||
return persons_infos_str
|
|
||||||
|
|
||||||
async def _save_info_to_cache(self, person_id: str, info_type: str, info_content: str):
|
async def _save_info_to_cache(self, person_id: str, info_type: str, info_content: str):
|
||||||
# sourcery skip: use-next
|
# sourcery skip: use-next
|
||||||
|
|||||||
@@ -55,60 +55,6 @@ class RelationshipManager:
|
|||||||
# person_id=person_id, user_nickname=user_nickname, user_cardname=user_cardname, user_avatar=user_avatar
|
# person_id=person_id, user_nickname=user_nickname, user_cardname=user_cardname, user_avatar=user_avatar
|
||||||
# )
|
# )
|
||||||
|
|
||||||
async def build_relationship_info(self, person, is_id: bool = False) -> str:
|
|
||||||
if is_id:
|
|
||||||
person_id = person
|
|
||||||
else:
|
|
||||||
person_id = PersonInfoManager.get_person_id(person[0], person[1])
|
|
||||||
person_info_manager = get_person_info_manager()
|
|
||||||
person_name = await person_info_manager.get_value(person_id, "person_name")
|
|
||||||
if not person_name or person_name == "none":
|
|
||||||
return ""
|
|
||||||
short_impression = await person_info_manager.get_value(person_id, "short_impression")
|
|
||||||
|
|
||||||
current_points = await person_info_manager.get_value(person_id, "points") or []
|
|
||||||
# print(f"current_points: {current_points}")
|
|
||||||
if isinstance(current_points, str):
|
|
||||||
try:
|
|
||||||
current_points = json.loads(current_points)
|
|
||||||
except json.JSONDecodeError:
|
|
||||||
logger.error(f"解析points JSON失败: {current_points}")
|
|
||||||
current_points = []
|
|
||||||
elif not isinstance(current_points, list):
|
|
||||||
current_points = []
|
|
||||||
|
|
||||||
# 按时间排序forgotten_points
|
|
||||||
current_points.sort(key=lambda x: x[2])
|
|
||||||
# 按权重加权随机抽取3个points,point[1]的值在1-10之间,权重越高被抽到概率越大
|
|
||||||
if len(current_points) > 3:
|
|
||||||
# point[1] 取值范围1-10,直接作为权重
|
|
||||||
weights = [max(1, min(10, int(point[1]))) for point in current_points]
|
|
||||||
points = random.choices(current_points, weights=weights, k=3)
|
|
||||||
else:
|
|
||||||
points = current_points
|
|
||||||
|
|
||||||
# 构建points文本
|
|
||||||
points_text = "\n".join([f"{point[2]}:{point[0]}" for point in points])
|
|
||||||
|
|
||||||
nickname_str = await person_info_manager.get_value(person_id, "nickname")
|
|
||||||
platform = await person_info_manager.get_value(person_id, "platform")
|
|
||||||
|
|
||||||
if person_name == nickname_str and not short_impression:
|
|
||||||
return ""
|
|
||||||
|
|
||||||
if person_name == nickname_str:
|
|
||||||
relation_prompt = f"'{person_name}' :"
|
|
||||||
else:
|
|
||||||
relation_prompt = f"'{person_name}' ,ta在{platform}上的昵称是{nickname_str}。"
|
|
||||||
|
|
||||||
if short_impression:
|
|
||||||
relation_prompt += f"你对ta的印象是:{short_impression}。\n"
|
|
||||||
|
|
||||||
if points_text:
|
|
||||||
relation_prompt += f"你记得ta最近做的事:{points_text}"
|
|
||||||
|
|
||||||
return relation_prompt
|
|
||||||
|
|
||||||
async def update_person_impression(self, person_id, timestamp, bot_engaged_messages: List[Dict[str, Any]]):
|
async def update_person_impression(self, person_id, timestamp, bot_engaged_messages: List[Dict[str, Any]]):
|
||||||
"""更新用户印象
|
"""更新用户印象
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
[inner]
|
[inner]
|
||||||
version = "4.4.6"
|
version = "4.4.7"
|
||||||
|
|
||||||
#----以下是给开发人员阅读的,如果你只是部署了麦麦,不需要阅读----
|
#----以下是给开发人员阅读的,如果你只是部署了麦麦,不需要阅读----
|
||||||
#如果你想要修改配置文件,请在修改后将version的值进行变更
|
#如果你想要修改配置文件,请在修改后将version的值进行变更
|
||||||
@@ -33,7 +33,7 @@ compress_identity = true # 是否压缩身份,压缩后会精简身份信息
|
|||||||
# 表达方式
|
# 表达方式
|
||||||
enable_expression = true # 是否启用表达方式
|
enable_expression = true # 是否启用表达方式
|
||||||
# 描述麦麦说话的表达风格,表达习惯,例如:(请回复的平淡一些,简短一些,说中文,不要刻意突出自身学科背景。)
|
# 描述麦麦说话的表达风格,表达习惯,例如:(请回复的平淡一些,简短一些,说中文,不要刻意突出自身学科背景。)
|
||||||
expression_style = "请回复的平淡些,简短一些,说中文,可以参考贴吧,知乎和微博的回复风格,回复不要浮夸,不要用夸张修辞,不要刻意突出自身学科背景。"
|
expression_style = "回复可以简短一些。可以参考贴吧,知乎和微博的回复风格,回复不要浮夸,不要用夸张修辞,平淡一些。"
|
||||||
enable_expression_learning = false # 是否启用表达学习,麦麦会学习不同群里人类说话风格(群之间不互通)
|
enable_expression_learning = false # 是否启用表达学习,麦麦会学习不同群里人类说话风格(群之间不互通)
|
||||||
learning_interval = 350 # 学习间隔 单位秒
|
learning_interval = 350 # 学习间隔 单位秒
|
||||||
|
|
||||||
@@ -87,8 +87,6 @@ talk_frequency_adjust = [
|
|||||||
# - 时间支持跨天,例如 "00:10,0.3" 表示从凌晨0:10开始使用频率0.3
|
# - 时间支持跨天,例如 "00:10,0.3" 表示从凌晨0:10开始使用频率0.3
|
||||||
# - 系统会自动将 "platform:id:type" 转换为内部的哈希chat_id进行匹配
|
# - 系统会自动将 "platform:id:type" 转换为内部的哈希chat_id进行匹配
|
||||||
|
|
||||||
enable_asr = false # 是否启用语音识别,启用后麦麦可以通过语音输入进行对话,启用该功能需要配置语音识别模型[model.voice]
|
|
||||||
|
|
||||||
[message_receive]
|
[message_receive]
|
||||||
# 以下是消息过滤,可以根据规则过滤特定消息,将不会读取这些消息
|
# 以下是消息过滤,可以根据规则过滤特定消息,将不会读取这些消息
|
||||||
ban_words = [
|
ban_words = [
|
||||||
@@ -144,6 +142,9 @@ enable_instant_memory = false # 是否启用即时记忆,测试功能,可能
|
|||||||
#不希望记忆的词,已经记忆的不会受到影响,需要手动清理
|
#不希望记忆的词,已经记忆的不会受到影响,需要手动清理
|
||||||
memory_ban_words = [ "表情包", "图片", "回复", "聊天记录" ]
|
memory_ban_words = [ "表情包", "图片", "回复", "聊天记录" ]
|
||||||
|
|
||||||
|
[voice]
|
||||||
|
enable_asr = false # 是否启用语音识别,启用后麦麦可以识别语音消息,启用该功能需要配置语音识别模型[model.voice]s
|
||||||
|
|
||||||
[mood]
|
[mood]
|
||||||
enable_mood = true # 是否启用情绪系统
|
enable_mood = true # 是否启用情绪系统
|
||||||
mood_update_interval = 1.0 # 情绪更新间隔 单位秒
|
mood_update_interval = 1.0 # 情绪更新间隔 单位秒
|
||||||
|
|||||||
Reference in New Issue
Block a user