From a6e937de6d93cd4e26095dd087f6731c8b1bf2ae Mon Sep 17 00:00:00 2001 From: Windpicker-owo <3431391539@qq.com> Date: Sun, 31 Aug 2025 19:09:36 +0800 Subject: [PATCH] =?UTF-8?q?refactor(chat):=20=E9=87=8D=E6=9E=84SmartPrompt?= =?UTF-8?q?=E7=B3=BB=E7=BB=9F=E7=AE=80=E5=8C=96=E6=9E=B6=E6=9E=84=E5=B9=B6?= =?UTF-8?q?=E7=A7=BB=E9=99=A4=E7=BC=93=E5=AD=98=E6=9C=BA=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 简化SmartPromptParameters类结构,移除复杂的分层参数架构 - 统一错误处理和降级机制,增强系统稳定性 - 移除缓存相关功能,简化架构并减少复杂性 - 完全继承DefaultReplyer功能,确保功能完整性 - 优化性能和依赖管理,改进并发任务处理 - 增强跨群上下文、关系信息、记忆系统等功能的错误处理 - 统一视频分析结果注入逻辑,避免重复代码 --- src/chat/replyer/default_generator.py | 155 +--- src/chat/utils/prompt_parameters.py | 271 ++----- src/chat/utils/prompt_utils.py | 201 +++--- src/chat/utils/smart_prompt.py | 975 +++++++++++++++++--------- 4 files changed, 807 insertions(+), 795 deletions(-) diff --git a/src/chat/replyer/default_generator.py b/src/chat/replyer/default_generator.py index de28ea61e..3a61f0a4d 100644 --- a/src/chat/replyer/default_generator.py +++ b/src/chat/replyer/default_generator.py @@ -1,3 +1,8 @@ +""" +默认回复生成器 - 集成SmartPrompt系统 +使用重构后的SmartPrompt系统替换原有的复杂提示词构建逻辑 +移除缓存机制,简化架构 +""" import traceback import time import asyncio @@ -16,7 +21,7 @@ from src.llm_models.utils_model import LLMRequest from src.chat.message_receive.message import UserInfo, Seg, MessageRecv, MessageSending from src.chat.message_receive.chat_stream import ChatStream, get_chat_manager from src.chat.message_receive.uni_message_sender import HeartFCSender -from src.chat.utils.timer_calculator import Timer # <--- Import Timer +from src.chat.utils.timer_calculator import Timer from src.chat.utils.utils import get_chat_type_and_target_info from src.chat.utils.prompt_builder import Prompt, global_prompt_manager from src.chat.utils.chat_message_builder import ( @@ -241,88 +246,6 @@ class DefaultReplyer: self.tool_executor = ToolExecutor(chat_id=self.chat_stream.stream_id) - async def _build_cross_context_block(self, current_chat_id: str, target_user_info: Optional[Dict[str, Any]]) -> str: - """构建跨群聊上下文""" - if not global_config.cross_context.enable: - return "" - - # 找到当前群聊所在的共享组 - target_group = None - current_stream = get_chat_manager().get_stream(current_chat_id) - if not current_stream or not current_stream.group_info: - return "" - current_chat_raw_id = current_stream.group_info.group_id - - for group in global_config.cross_context.groups: - if str(current_chat_raw_id) in group.chat_ids: - target_group = group - break - - if not target_group: - return "" - - # 根据prompt_mode选择策略 - prompt_mode = global_config.personality.prompt_mode - other_chat_raw_ids = [chat_id for chat_id in target_group.chat_ids if chat_id != str(current_chat_raw_id)] - - cross_context_messages = [] - - if prompt_mode == "normal": - # normal模式:获取其他群聊的最近N条消息 - for chat_raw_id in other_chat_raw_ids: - stream_id = get_chat_manager().get_stream_id(current_stream.platform, chat_raw_id, is_group=True) - if not stream_id: - continue - - messages = get_raw_msg_before_timestamp_with_chat( - chat_id=stream_id, - timestamp=time.time(), - limit=5, # 可配置 - ) - if messages: - chat_name = get_chat_manager().get_stream_name(stream_id) or stream_id - formatted_messages, _ = build_readable_messages_with_id(messages, timestamp_mode="relative") - cross_context_messages.append(f"[以下是来自“{chat_name}”的近期消息]\n{formatted_messages}") - - elif prompt_mode == "s4u": - # s4u模式:获取当前发言用户在其他群聊的消息 - if target_user_info: - user_id = target_user_info.get("user_id") - - if user_id: - for chat_raw_id in other_chat_raw_ids: - stream_id = get_chat_manager().get_stream_id( - current_stream.platform, chat_raw_id, is_group=True - ) - if not stream_id: - continue - - messages = get_raw_msg_before_timestamp_with_chat( - chat_id=stream_id, - timestamp=time.time(), - limit=20, # 获取更多消息以供筛选 - ) - user_messages = [msg for msg in messages if msg.get("user_id") == user_id][ - -5: - ] # 筛选并取最近5条 - - if user_messages: - chat_name = get_chat_manager().get_stream_name(stream_id) or stream_id - user_name = ( - target_user_info.get("person_name") or target_user_info.get("user_nickname") or user_id - ) - formatted_messages, _ = build_readable_messages_with_id( - user_messages, timestamp_mode="relative" - ) - cross_context_messages.append( - f"[以下是“{user_name}”在“{chat_name}”的近期发言]\n{formatted_messages}" - ) - - if not cross_context_messages: - return "" - - return "# 跨群上下文参考\n" + "\n\n".join(cross_context_messages) + "\n" - def _select_weighted_models_config(self) -> Tuple[TaskConfig, float]: """使用加权随机选择来挑选一个模型配置""" configs = self.model_set @@ -463,26 +386,6 @@ class DefaultReplyer: traceback.print_exc() return False, None, prompt if return_prompt else None - async def build_relation_info(self, reply_to: str = ""): - if not global_config.relationship.enable_relationship: - return "" - - relationship_fetcher = relationship_fetcher_manager.get_fetcher(self.chat_stream.stream_id) - if not reply_to: - return "" - sender, text = self._parse_reply_target(reply_to) - if not sender or not text: - return "" - - # 获取用户ID - person_info_manager = get_person_info_manager() - person_id = person_info_manager.get_person_id_by_person_name(sender) - if not person_id: - logger.warning(f"未找到用户 {sender} 的ID,跳过信息提取") - return f"你完全不认识{sender},不理解ta的相关信息。" - - return await relationship_fetcher.build_relation_info(person_id, points_num=5) - async def build_expression_habits(self, chat_history: str, target: str) -> str: """构建表达习惯块 @@ -538,7 +441,7 @@ class DefaultReplyer: expression_habits_block += f"{grammar_habits_str}\n" if style_habits_str.strip() and grammar_habits_str.strip(): - expression_habits_title = "你可以参考以下的语言习惯和句法,如果情景合适就使用,不要盲目使用,不要生硬使用,以合理的方式结合到你的回复中:" + expression_habits_title = "你可以参考以下的语言习惯和句法,如果情景合适就使用,不要盲目使用,不要生硬使用,以合理的方式结合到你的回复中。" return f"{expression_habits_title}\n{expression_habits_block}" @@ -880,7 +783,7 @@ class DefaultReplyer: enable_tool: bool = True, ) -> str: # sourcery skip: merge-else-if-into-elif, remove-redundant-if """ - 构建回复器上下文 + 构建回复器上下文 - 使用重构后的SmartPrompt系统,移除缓存机制 Args: reply_to: 回复对象,格式为 "发送者:消息内容" @@ -967,7 +870,7 @@ class DefaultReplyer: ), self._time_and_run_task(self.get_prompt_info(chat_talking_prompt_short, reply_to), "prompt_info"), self._time_and_run_task( - PromptUtils.build_cross_context_block(chat_id, target_user_info, current_prompt_mode), "cross_context" + PromptUtils.build_cross_context(chat_id, target_user_info, global_config.personality.prompt_mode), "cross_context" ), ) @@ -998,11 +901,6 @@ class DefaultReplyer: prompt_info = results_dict["prompt_info"] cross_context_block = results_dict["cross_context"] - # 检查是否为视频分析结果,并注入引导语 - if target and ("[视频内容]" in target or "好的,我将根据您提供的" in target): - video_prompt_injection = "\n请注意,以上内容是你刚刚观看的视频,请以第一人称分享你的观后感,而不是在分析一份报告。" - memory_block += video_prompt_injection - # 检查是否为视频分析结果,并注入引导语 if target and ("[视频内容]" in target or "好的,我将根据您提供的" in target): video_prompt_injection = "\n请注意,以上内容是你刚刚观看的视频,请以第一人称分享你的观后感,而不是在分析一份报告。" @@ -1052,6 +950,7 @@ class DefaultReplyer: # 根据配置选择模板 current_prompt_mode = global_config.personality.prompt_mode + # 使用重构后的SmartPrompt系统,移除缓存相关参数 prompt_params = SmartPromptParameters( chat_id=chat_id, is_group_chat=is_group_chat, @@ -1062,17 +961,17 @@ class DefaultReplyer: available_actions=available_actions, enable_tool=enable_tool, chat_target_info=self.chat_target_info, - current_prompt_mode=current_prompt_mode, + prompt_mode=current_prompt_mode, message_list_before_now_long=message_list_before_now_long, message_list_before_short=message_list_before_short, chat_talking_prompt_short=chat_talking_prompt_short, target_user_info=target_user_info, # 传递已构建的参数 expression_habits_block=expression_habits_block, - relation_info=relation_info, + relation_info_block=relation_info, memory_block=memory_block, - tool_info=tool_info, - prompt_info=prompt_info, + tool_info_block=tool_info, + knowledge_prompt=prompt_info, cross_context_block=cross_context_block, keywords_reaction_prompt=keywords_reaction_prompt, extra_info_block=extra_info_block, @@ -1186,7 +1085,7 @@ class DefaultReplyer: template_name = "default_expressor_prompt" - # 使用重构后的SmartPrompt系统 - Expressor模式 + # 使用重构后的SmartPrompt系统 - Expressor模式,移除缓存相关参数 prompt_params = SmartPromptParameters( chat_id=chat_id, is_group_chat=is_group_chat, @@ -1194,7 +1093,7 @@ class DefaultReplyer: target=raw_reply, # Expressor模式使用raw_reply作为target reply_to=f"{sender}:{target}" if sender and target else reply_to, extra_info="", # Expressor模式不需要额外信息 - current_prompt_mode="minimal", # Expressor使用minimal模式 + prompt_mode="minimal", # Expressor使用minimal模式 chat_talking_prompt_short=chat_talking_prompt_half, time_block=time_block, identity_block=identity_block, @@ -1204,7 +1103,7 @@ class DefaultReplyer: moderation_prompt_block=moderation_prompt_block, # 添加已构建的表达习惯和关系信息 expression_habits_block=expression_habits_block, - relation_info=relation_info, + relation_info_block=relation_info, ) smart_prompt = SmartPrompt(parameters=prompt_params) @@ -1322,6 +1221,26 @@ class DefaultReplyer: logger.error(f"获取知识库内容时发生异常: {str(e)}") return "" + async def build_relation_info(self, reply_to: str = ""): + if not global_config.relationship.enable_relationship: + return "" + + relationship_fetcher = relationship_fetcher_manager.get_fetcher(self.chat_stream.stream_id) + if not reply_to: + return "" + sender, text = self._parse_reply_target(reply_to) + if not sender or not text: + return "" + + # 获取用户ID + person_info_manager = get_person_info_manager() + person_id = person_info_manager.get_person_id_by_person_name(sender) + if not person_id: + logger.warning(f"未找到用户 {sender} 的ID,跳过信息提取") + return f"你完全不认识{sender},不理解ta的相关信息。" + + return await relationship_fetcher.build_relation_info(person_id, points_num=5) + def weighted_sample_no_replacement(items, weights, k) -> list: """ diff --git a/src/chat/utils/prompt_parameters.py b/src/chat/utils/prompt_parameters.py index 5b498e504..9037dc244 100644 --- a/src/chat/utils/prompt_parameters.py +++ b/src/chat/utils/prompt_parameters.py @@ -1,56 +1,37 @@ """ 智能提示词参数模块 - 优化参数结构 -将SmartPromptParameters拆分为多个专用参数类 +简化SmartPromptParameters,减少冗余和重复 """ from dataclasses import dataclass, field from typing import Dict, Any, Optional, List, Literal @dataclass -class PromptCoreParams: - """核心参数类 - 包含构建提示词的基本参数""" +class SmartPromptParameters: + """简化的智能提示词参数系统""" + # 基础参数 chat_id: str = "" is_group_chat: bool = False sender: str = "" target: str = "" reply_to: str = "" extra_info: str = "" - current_prompt_mode: Literal["s4u", "normal", "minimal"] = "s4u" + prompt_mode: Literal["s4u", "normal", "minimal"] = "s4u" - def validate(self) -> List[str]: - """验证核心参数""" - errors = [] - if not isinstance(self.chat_id, str): - errors.append("chat_id必须是字符串类型") - if not isinstance(self.reply_to, str): - errors.append("reply_to必须是字符串类型") - if self.current_prompt_mode not in ["s4u", "normal", "minimal"]: - errors.append("current_prompt_mode必须是's4u'、'normal'或'minimal'") - return errors - - -@dataclass -class PromptFeatureParams: - """功能参数类 - 控制各种功能的开关""" + # 功能开关 enable_tool: bool = True enable_memory: bool = True enable_expression: bool = True enable_relation: bool = True enable_cross_context: bool = True enable_knowledge: bool = True - enable_cache: bool = True - # 性能和缓存控制 - cache_ttl: int = 300 + # 性能控制 max_context_messages: int = 50 # 调试选项 debug_mode: bool = False - - -@dataclass -class PromptContentParams: - """内容参数类 - 包含已构建的内容块""" + # 聊天历史和上下文 chat_target_info: Optional[Dict[str, Any]] = None message_list_before_now_long: List[Dict[str, Any]] = field(default_factory=list) @@ -60,10 +41,10 @@ class PromptContentParams: # 已构建的内容块 expression_habits_block: str = "" - relation_info: str = "" + relation_info_block: str = "" memory_block: str = "" - tool_info: str = "" - prompt_info: str = "" + tool_info_block: str = "" + knowledge_prompt: str = "" cross_context_block: str = "" # 其他内容块 @@ -77,203 +58,37 @@ class PromptContentParams: mood_prompt: str = "" action_descriptions: str = "" - def has_prebuilt_content(self) -> bool: - """检查是否有预构建的内容""" - return any([ - self.expression_habits_block, - self.relation_info, - self.memory_block, - self.tool_info, - self.prompt_info, - self.cross_context_block - ]) - - -@dataclass -class SmartPromptParameters: - """ - 智能提示词参数系统 - 重构版本 - 组合多个专用参数类,提供统一的接口 - """ - # 核心参数 - core: PromptCoreParams = field(default_factory=PromptCoreParams) - - # 功能参数 - features: PromptFeatureParams = field(default_factory=PromptFeatureParams) - - # 内容参数 - content: PromptContentParams = field(default_factory=PromptContentParams) - - # 兼容性属性 - 提供与旧代码的兼容性 - @property - def chat_id(self) -> str: - return self.core.chat_id - - @chat_id.setter - def chat_id(self, value: str): - self.core.chat_id = value - - @property - def is_group_chat(self) -> bool: - return self.core.is_group_chat - - @is_group_chat.setter - def is_group_chat(self, value: bool): - self.core.is_group_chat = value - - @property - def sender(self) -> str: - return self.core.sender - - @sender.setter - def sender(self, value: str): - self.core.sender = value - - @property - def target(self) -> str: - return self.core.target - - @target.setter - def target(self, value: str): - self.core.target = value - - @property - def reply_to(self) -> str: - return self.core.reply_to - - @reply_to.setter - def reply_to(self, value: str): - self.core.reply_to = value - - @property - def extra_info(self) -> str: - return self.core.extra_info - - @extra_info.setter - def extra_info(self, value: str): - self.core.extra_info = value - - @property - def current_prompt_mode(self) -> str: - return self.core.current_prompt_mode - - @current_prompt_mode.setter - def current_prompt_mode(self, value: str): - self.core.current_prompt_mode = value - - @property - def enable_tool(self) -> bool: - return self.features.enable_tool - - @enable_tool.setter - def enable_tool(self, value: bool): - self.features.enable_tool = value - - @property - def enable_memory(self) -> bool: - return self.features.enable_memory - - @enable_memory.setter - def enable_memory(self, value: bool): - self.features.enable_memory = value - - @property - def enable_cache(self) -> bool: - return self.features.enable_cache - - @enable_cache.setter - def enable_cache(self, value: bool): - self.features.enable_cache = value - - @property - def cache_ttl(self) -> int: - return self.features.cache_ttl - - @cache_ttl.setter - def cache_ttl(self, value: int): - self.features.cache_ttl = value - - @property - def expression_habits_block(self) -> str: - return self.content.expression_habits_block - - @expression_habits_block.setter - def expression_habits_block(self, value: str): - self.content.expression_habits_block = value - - @property - def relation_info(self) -> str: - return self.content.relation_info - - @relation_info.setter - def relation_info(self, value: str): - self.content.relation_info = value - - @property - def memory_block(self) -> str: - return self.content.memory_block - - @memory_block.setter - def memory_block(self, value: str): - self.content.memory_block = value - - @property - def tool_info(self) -> str: - return self.content.tool_info - - @tool_info.setter - def tool_info(self, value: str): - self.content.tool_info = value - - @property - def prompt_info(self) -> str: - return self.content.prompt_info - - @prompt_info.setter - def prompt_info(self, value: str): - self.content.prompt_info = value - - @property - def cross_context_block(self) -> str: - return self.content.cross_context_block - - @cross_context_block.setter - def cross_context_block(self, value: str): - self.content.cross_context_block = value - - # 兼容性方法 - 支持旧代码的直接访问 def validate(self) -> List[str]: - """参数验证""" - errors = self.core.validate() - - # 验证功能参数 - if self.features.cache_ttl <= 0: - errors.append("cache_ttl必须大于0") - if self.features.max_context_messages <= 0: + """统一的参数验证""" + errors = [] + if not self.chat_id: + errors.append("chat_id不能为空") + if self.prompt_mode not in ["s4u", "normal", "minimal"]: + errors.append("prompt_mode必须是's4u'、'normal'或'minimal'") + if self.max_context_messages <= 0: errors.append("max_context_messages必须大于0") - return errors def get_needed_build_tasks(self) -> List[str]: """获取需要执行的任务列表""" tasks = [] - if self.features.enable_expression and not self.content.expression_habits_block: + if self.enable_expression and not self.expression_habits_block: tasks.append("expression_habits") - if self.features.enable_memory and not self.content.memory_block: + if self.enable_memory and not self.memory_block: tasks.append("memory_block") - if self.features.enable_relation and not self.content.relation_info: + if self.enable_relation and not self.relation_info_block: tasks.append("relation_info") - if self.features.enable_tool and not self.content.tool_info: + if self.enable_tool and not self.tool_info_block: tasks.append("tool_info") - if self.features.enable_knowledge and not self.content.prompt_info: + if self.enable_knowledge and not self.knowledge_prompt: tasks.append("knowledge_info") - if self.features.enable_cross_context and not self.content.cross_context_block: + if self.enable_cross_context and not self.cross_context_block: tasks.append("cross_context") return tasks @@ -289,44 +104,44 @@ class SmartPromptParameters: Returns: SmartPromptParameters: 新参数对象 """ - # 创建核心参数 - core_params = PromptCoreParams( + return cls( + # 基础参数 chat_id=kwargs.get("chat_id", ""), is_group_chat=kwargs.get("is_group_chat", False), sender=kwargs.get("sender", ""), target=kwargs.get("target", ""), reply_to=kwargs.get("reply_to", ""), extra_info=kwargs.get("extra_info", ""), - current_prompt_mode=kwargs.get("current_prompt_mode", "s4u"), - ) - - # 创建功能参数 - feature_params = PromptFeatureParams( + prompt_mode=kwargs.get("current_prompt_mode", "s4u"), + + # 功能开关 enable_tool=kwargs.get("enable_tool", True), enable_memory=kwargs.get("enable_memory", True), enable_expression=kwargs.get("enable_expression", True), enable_relation=kwargs.get("enable_relation", True), enable_cross_context=kwargs.get("enable_cross_context", True), enable_knowledge=kwargs.get("enable_knowledge", True), - enable_cache=kwargs.get("enable_cache", True), - cache_ttl=kwargs.get("cache_ttl", 300), + + # 性能控制 max_context_messages=kwargs.get("max_context_messages", 50), debug_mode=kwargs.get("debug_mode", False), - ) - - # 创建内容参数 - content_params = PromptContentParams( + + # 聊天历史和上下文 chat_target_info=kwargs.get("chat_target_info"), message_list_before_now_long=kwargs.get("message_list_before_now_long", []), message_list_before_short=kwargs.get("message_list_before_short", []), chat_talking_prompt_short=kwargs.get("chat_talking_prompt_short", ""), target_user_info=kwargs.get("target_user_info"), + + # 已构建的内容块 expression_habits_block=kwargs.get("expression_habits_block", ""), - relation_info=kwargs.get("relation_info", ""), + relation_info_block=kwargs.get("relation_info", ""), memory_block=kwargs.get("memory_block", ""), - tool_info=kwargs.get("tool_info", ""), - prompt_info=kwargs.get("prompt_info", ""), + tool_info_block=kwargs.get("tool_info", ""), + knowledge_prompt=kwargs.get("knowledge_prompt", ""), cross_context_block=kwargs.get("cross_context_block", ""), + + # 其他内容块 keywords_reaction_prompt=kwargs.get("keywords_reaction_prompt", ""), extra_info_block=kwargs.get("extra_info_block", ""), time_block=kwargs.get("time_block", ""), @@ -336,10 +151,4 @@ class SmartPromptParameters: reply_target_block=kwargs.get("reply_target_block", ""), mood_prompt=kwargs.get("mood_prompt", ""), action_descriptions=kwargs.get("action_descriptions", ""), - ) - - return cls( - core=core_params, - features=feature_params, - content=content_params ) \ No newline at end of file diff --git a/src/chat/utils/prompt_utils.py b/src/chat/utils/prompt_utils.py index e85e9dfd6..3cb3851a7 100644 --- a/src/chat/utils/prompt_utils.py +++ b/src/chat/utils/prompt_utils.py @@ -1,6 +1,7 @@ """ 共享提示词工具模块 - 消除重复代码 提供统一的工具函数供DefaultReplyer和SmartPrompt使用 +移除缓存相关功能 """ import re import time @@ -22,7 +23,7 @@ logger = get_logger("prompt_utils") class PromptUtils: - """提示词工具类 - 提供共享功能""" + """提示词工具类 - 提供共享功能,移除缓存相关功能""" @staticmethod def parse_reply_target(target_message: str) -> Tuple[str, str]: @@ -51,13 +52,50 @@ class PromptUtils: return sender, target @staticmethod - async def build_cross_context_block( + async def build_relation_info(chat_id: str, reply_to: str) -> str: + """ + 构建关系信息 - 统一实现 + + Args: + chat_id: 聊天ID + reply_to: 回复目标字符串 + + Returns: + str: 关系信息字符串 + """ + if not global_config.relationship.enable_relationship: + return "" + + try: + from src.person_info.relationship_fetcher import relationship_fetcher_manager + relationship_fetcher = relationship_fetcher_manager.get_fetcher(chat_id) + + if not reply_to: + return "" + sender, text = PromptUtils.parse_reply_target(reply_to) + if not sender or not text: + return "" + + # 获取用户ID + person_info_manager = get_person_info_manager() + person_id = person_info_manager.get_person_id_by_person_name(sender) + if not person_id: + logger.warning(f"未找到用户 {sender} 的ID,跳过信息提取") + return f"你完全不认识{sender},不理解ta的相关信息。" + + return await relationship_fetcher.build_relation_info(person_id, points_num=5) + except Exception as e: + logger.error(f"构建关系信息失败: {e}") + return "" + + @staticmethod + async def build_cross_context( chat_id: str, target_user_info: Optional[Dict[str, Any]], current_prompt_mode: str ) -> str: """ - 构建跨群聊上下文 - 统一实现 + 构建跨群聊上下文 - 统一实现,完全继承DefaultReplyer功能 Args: chat_id: 当前聊天ID @@ -75,7 +113,12 @@ class PromptUtils: current_stream = get_chat_manager().get_stream(chat_id) if not current_stream or not current_stream.group_info: return "" - current_chat_raw_id = current_stream.group_info.group_id + + try: + current_chat_raw_id = current_stream.group_info.group_id + except Exception as e: + logger.error(f"获取群聊ID失败: {e}") + return "" for group in global_config.cross_context.groups: if str(current_chat_raw_id) in group.chat_ids: @@ -97,15 +140,19 @@ class PromptUtils: if not stream_id: continue - messages = get_raw_msg_before_timestamp_with_chat( - chat_id=stream_id, - timestamp=time.time(), - limit=5, # 可配置 - ) - if messages: - chat_name = get_chat_manager().get_stream_name(stream_id) or stream_id - formatted_messages, _ = build_readable_messages_with_id(messages, timestamp_mode="relative") - cross_context_messages.append(f"[以下是来自\"{chat_name}\"的近期消息]\n{formatted_messages}") + try: + messages = get_raw_msg_before_timestamp_with_chat( + chat_id=stream_id, + timestamp=time.time(), + limit=5, # 可配置 + ) + if messages: + chat_name = get_chat_manager().get_stream_name(stream_id) or stream_id + formatted_messages, _ = build_readable_messages_with_id(messages, timestamp_mode="relative") + cross_context_messages.append(f"[以下是来自\"{chat_name}\"的近期消息]\n{formatted_messages}") + except Exception as e: + logger.error(f"获取群聊{chat_raw_id}的消息失败: {e}") + continue elif current_prompt_mode == "s4u": # s4u模式:获取当前发言用户在其他群聊的消息 @@ -120,27 +167,31 @@ class PromptUtils: if not stream_id: continue - messages = get_raw_msg_before_timestamp_with_chat( - chat_id=stream_id, - timestamp=time.time(), - limit=20, # 获取更多消息以供筛选 - ) - user_messages = [msg for msg in messages if msg.get("user_id") == user_id][ - -5: - ] # 筛选并取最近5条 + try: + messages = get_raw_msg_before_timestamp_with_chat( + chat_id=stream_id, + timestamp=time.time(), + limit=20, # 获取更多消息以供筛选 + ) + user_messages = [msg for msg in messages if msg.get("user_id") == user_id][ + -5: + ] # 筛选并取最近5条 - if user_messages: - chat_name = get_chat_manager().get_stream_name(stream_id) or stream_id - user_name = ( - target_user_info.get("person_name") or - target_user_info.get("user_nickname") or user_id - ) - formatted_messages, _ = build_readable_messages_with_id( - user_messages, timestamp_mode="relative" - ) - cross_context_messages.append( - f"[以下是\"{user_name}\"在\"{chat_name}\"的近期发言]\n{formatted_messages}" - ) + if user_messages: + chat_name = get_chat_manager().get_stream_name(stream_id) or stream_id + user_name = ( + target_user_info.get("person_name") or + target_user_info.get("user_nickname") or user_id + ) + formatted_messages, _ = build_readable_messages_with_id( + user_messages, timestamp_mode="relative" + ) + cross_context_messages.append( + f"[以下是\"{user_name}\"在\"{chat_name}\"的近期发言]\n{formatted_messages}" + ) + except Exception as e: + logger.error(f"获取用户{user_id}在群聊{chat_raw_id}的消息失败: {e}") + continue if not cross_context_messages: return "" @@ -260,88 +311,4 @@ class DependencyChecker: "memory": await DependencyChecker.check_memory_dependencies(), "tool": await DependencyChecker.check_tool_dependencies(), "knowledge": await DependencyChecker.check_knowledge_dependencies(), - } - - -class SmartPromptCache: - """智能提示词缓存系统 - 分层缓存实现""" - - def __init__(self): - self._l1_cache: Dict[str, Tuple[str, float]] = {} # 内存缓存: {key: (value, timestamp)} - self._l2_cache_enabled = False # 是否启用L2缓存 - self._cache_ttl = 300 # 默认缓存TTL: 5分钟 - - def enable_l2_cache(self, enabled: bool = True): - """启用或禁用L2缓存""" - self._l2_cache_enabled = enabled - - def set_cache_ttl(self, ttl: int): - """设置缓存TTL(秒)""" - self._cache_ttl = ttl - - def _generate_key(self, chat_id: str, prompt_mode: str, reply_to: str) -> str: - """生成缓存键""" - import hashlib - key_content = f"{chat_id}_{prompt_mode}_{reply_to}" - return hashlib.md5(key_content.encode()).hexdigest() - - def get(self, chat_id: str, prompt_mode: str, reply_to: str) -> Optional[str]: - """获取缓存值""" - cache_key = self._generate_key(chat_id, prompt_mode, reply_to) - - # 检查L1缓存 - if cache_key in self._l1_cache: - value, timestamp = self._l1_cache[cache_key] - if time.time() - timestamp < self._cache_ttl: - logger.debug(f"L1缓存命中: {cache_key}") - return value - else: - # 缓存过期,清理 - del self._l1_cache[cache_key] - - # TODO: 实现L2缓存(如Redis) - # if self._l2_cache_enabled: - # return self._get_from_l2_cache(cache_key) - - return None - - def set(self, chat_id: str, prompt_mode: str, reply_to: str, value: str): - """设置缓存值""" - cache_key = self._generate_key(chat_id, prompt_mode, reply_to) - - # 设置L1缓存 - self._l1_cache[cache_key] = (value, time.time()) - - # TODO: 实现L2缓存 - # if self._l2_cache_enabled: - # self._set_to_l2_cache(cache_key, value) - - # 定期清理过期缓存 - if len(self._l1_cache) > 1000: # 缓存条目过多时清理 - self._clean_expired_cache() - - def _clean_expired_cache(self): - """清理过期缓存""" - current_time = time.time() - expired_keys = [ - key for key, (_, timestamp) in self._l1_cache.items() - if current_time - timestamp >= self._cache_ttl - ] - for key in expired_keys: - del self._l1_cache[key] - - logger.debug(f"清理过期缓存: {len(expired_keys)} 个条目") - - def clear(self): - """清空所有缓存""" - self._l1_cache.clear() - # TODO: 清空L2缓存 - logger.info("缓存已清空") - - def get_stats(self) -> Dict[str, Any]: - """获取缓存统计信息""" - return { - "l1_cache_size": len(self._l1_cache), - "l2_cache_enabled": self._l2_cache_enabled, - "cache_ttl": self._cache_ttl, } \ No newline at end of file diff --git a/src/chat/utils/smart_prompt.py b/src/chat/utils/smart_prompt.py index d5d154fb6..f3d557b62 100644 --- a/src/chat/utils/smart_prompt.py +++ b/src/chat/utils/smart_prompt.py @@ -1,13 +1,14 @@ """ 智能Prompt系统 - 完全重构版本 基于原有DefaultReplyer的完整功能集成,使用新的参数结构 +解决实现质量不高、功能集成不完整和错误处理不足的问题 +移除了缓存机制,简化架构 """ import asyncio import time from datetime import datetime from dataclasses import dataclass, field from typing import Dict, Any, Optional, List, Literal, Tuple -import re from src.chat.utils.prompt_builder import global_prompt_manager, Prompt from src.common.logger import get_logger @@ -21,69 +22,10 @@ from src.chat.utils.chat_message_builder import ( from src.person_info.person_info import get_person_info_manager from src.plugin_system.core.tool_use import ToolExecutor from src.chat.utils.prompt_utils import PromptUtils -from src.chat.utils.prompt_parameters import PromptCoreParams, PromptFeatureParams, PromptContentParams +from src.chat.utils.prompt_parameters import SmartPromptParameters logger = get_logger("smart_prompt") -# 重新导出参数类以保持兼容性 -from src.chat.utils.prompt_parameters import ( - PromptCoreParams, - PromptFeatureParams, - PromptContentParams -) - - -@dataclass -class SmartPromptParameters: - """兼容的智能提示词参数系统 - 使用分层架构""" - - # 核心参数 (从PromptCoreParams继承) - core: PromptCoreParams = field(default_factory=PromptCoreParams) - - # 功能参数 (从PromptFeatureParams继承) - features: PromptFeatureParams = field(default_factory=PromptFeatureParams) - - # 内容参数 (从PromptContentParams继承) - content: PromptContentParams = field(default_factory=PromptContentParams) - - # 配置和兼容属性 - enable_cache: bool = True - cache_ttl: int = 300 - - # 为了向下兼容,提供属性访问 - @property - def chat_id(self) -> str: - return self.core.chat_id - - @chat_id.setter - def chat_id(self, value: str): - self.core.chat_id = value - - @property - def reply_to(self) -> str: - return self.core.reply_to - - @reply_to.setter - def reply_to(self, value: str): - self.core.reply_to = value - - @property - def current_prompt_mode(self) -> str: - return self.core.prompt_mode - - @current_prompt_mode.setter - def current_prompt_mode(self, value: str): - self.core.prompt_mode = value - - def validate(self) -> List[str]: - """参数验证""" - errors = [] - if not isinstance(self.core.chat_id, str): - errors.append("chat_id必须是字符串类型") - if not isinstance(self.core.reply_to, str): - errors.append("reply_to必须是字符串类型") - return errors + self.features.validate() + self.content.validate() - @dataclass class ChatContext: @@ -98,27 +40,16 @@ class ChatContext: class SmartPromptBuilder: - """重构的智能提示词构建器 - 完全继承DefaultReplyer功能""" + """重构的智能提示词构建器 - 统一错误处理和功能集成,移除缓存机制""" def __init__(self): - # 使用共享缓存 - from src.chat.utils.prompt_utils import PromptUtils + # 移除缓存相关初始化 + pass async def build_context_data(self, params: SmartPromptParameters) -> Dict[str, Any]: - """并行构建完整的上下文数据 - 使用共享缓存和优化后的参数结构""" + """并行构建完整的上下文数据 - 移除缓存机制""" - # 使用共享缓存 - from src.chat.utils.prompt_utils import PromptUtils - cache_key = PromptUtils.get_cache_key( - params.core.chat_id, - params.core.prompt_mode, - params.core.reply_to - ) - - cached = PromptUtils.get_from_cache(cache_key, params.cache_ttl if hasattr(params, 'cache_ttl') else 300) - if cached is not None: - logger.debug(f"使用缓存结果: {cache_key}") - return cached + # 移除缓存检查和存储逻辑 # 并行执行所有构建任务 start_time = time.time() @@ -131,48 +62,92 @@ class SmartPromptBuilder: # 初始化预构建参数,使用新的结构 pre_built_params = {} - if params.content: - pre_built_params.update({ - 'expression_habits_block': params.content.expression_habits or "", - 'relation_info': params.content.relation_info or "", - 'memory_block': params.content.memory_block or "", - 'tool_info': params.content.tool_info or "", - 'knowledge_prompt': params.content.knowledge_info or "", - 'cross_context_block': params.content.cross_context or "", - }) + if params.expression_habits_block: + pre_built_params['expression_habits_block'] = params.expression_habits_block + if params.relation_info_block: + pre_built_params['relation_info_block'] = params.relation_info_block + if params.memory_block: + pre_built_params['memory_block'] = params.memory_block + if params.tool_info_block: + pre_built_params['tool_info_block'] = params.tool_info_block + if params.knowledge_prompt: + pre_built_params['knowledge_prompt'] = params.knowledge_prompt + if params.cross_context_block: + pre_built_params['cross_context_block'] = params.cross_context_block # 根据新的参数结构确定要构建的项 - if params.features.enable_expression and not pre_built_params.get('expression_habits_block'): - tasks.append(self._timed_build(self._build_expression_habits, params, "expression_habits")) + if params.enable_expression and not pre_built_params.get('expression_habits_block'): + tasks.append(self._build_with_fallback( + self._build_expression_habits, params, "expression_habits_block", "" + )) task_names.append("expression_habits") - if params.features.enable_memory and not pre_built_params.get('memory_block'): - tasks.append(self._timed_build(self._build_memory_block, params, "memory_block")) + if params.enable_memory and not pre_built_params.get('memory_block'): + tasks.append(self._build_with_fallback( + self._build_memory_block, params, "memory_block", "" + )) task_names.append("memory_block") - if params.features.enable_relation and not pre_built_params.get('relation_info'): - tasks.append(self._timed_build(self._build_relation_info, params, "relation_info")) + if params.enable_relation and not pre_built_params.get('relation_info_block'): + tasks.append(self._build_with_fallback( + self._build_relation_info, params, "relation_info_block", "" + )) task_names.append("relation_info") - if params.features.enable_tool and not pre_built_params.get('tool_info'): - tasks.append(self._timed_build(self._build_tool_info, params, "tool_info")) + # 添加mai_think上下文构建任务 + if not pre_built_params.get('mai_think'): + tasks.append(self._build_with_fallback( + self._build_mai_think_context, params, "mai_think", None + )) + task_names.append("mai_think_context") + + if params.enable_tool and not pre_built_params.get('tool_info_block'): + tasks.append(self._build_with_fallback( + self._build_tool_info, params, "tool_info_block", "" + )) task_names.append("tool_info") - if params.features.enable_knowledge and not pre_built_params.get('knowledge_prompt'): - tasks.append(self._timed_build(self._build_knowledge_info, params, "knowledge_info")) + if params.enable_knowledge and not pre_built_params.get('knowledge_prompt'): + tasks.append(self._build_with_fallback( + self._build_knowledge_info, params, "knowledge_prompt", "" + )) task_names.append("knowledge_info") - if params.features.enable_cross_context and not pre_built_params.get('cross_context_block'): - tasks.append(self._timed_build(self._build_cross_context, params, "cross_context")) + if params.enable_cross_context and not pre_built_params.get('cross_context_block'): + tasks.append(self._build_with_fallback( + self._build_cross_context, params, "cross_context_block", "" + )) task_names.append("cross_context") - # 并行执行所有任务,设置更合理的超时 - timeout_seconds = max(10.0, params.max_context_messages * 0.3) # 最少10秒超时 - results = await asyncio.wait_for( - asyncio.gather(*tasks, return_exceptions=True), - timeout=timeout_seconds + # 性能优化:根据任务数量动态调整超时时间 + base_timeout = 10.0 # 基础超时时间 + task_timeout = 2.0 # 每个任务的超时时间 + timeout_seconds = min( + max(base_timeout, len(tasks) * task_timeout), # 根据任务数量计算超时 + 30.0 # 最大超时时间 ) + # 性能优化:限制并发任务数量,避免资源耗尽 + max_concurrent_tasks = 5 # 最大并发任务数 + if len(tasks) > max_concurrent_tasks: + # 分批执行任务 + results = [] + for i in range(0, len(tasks), max_concurrent_tasks): + batch_tasks = tasks[i:i+max_concurrent_tasks] + batch_names = task_names[i:i+max_concurrent_tasks] + + batch_results = await asyncio.wait_for( + asyncio.gather(*batch_tasks, return_exceptions=True), + timeout=timeout_seconds + ) + results.extend(batch_results) + else: + # 一次性执行所有任务 + results = await asyncio.wait_for( + asyncio.gather(*tasks, return_exceptions=True), + timeout=timeout_seconds + ) + # 处理结果并收集性能数据 context_data = {} for i, result in enumerate(results): @@ -180,18 +155,13 @@ class SmartPromptBuilder: if isinstance(result, Exception): logger.error(f"构建任务{task_name}失败: {str(result)}") - elif isinstance(result, tuple) and len(result) == 2: - # 结果格式: (data, timing) - data, timing = result - context_data.update(data) - timing_logs[task_name] = timing + elif isinstance(result, dict): + # 结果格式: {component_name: value} + context_data.update(result) # 记录耗时过长的任务 - if timing > 8.0: - logger.warning(f"构建任务{task_name}耗时过长: {timing:.2f}s") - else: - # 直接数据结果 - context_data.update(result) + if task_name in timing_logs and timing_logs[task_name] > 8.0: + logger.warning(f"构建任务{task_name}耗时过长: {timing_logs[task_name]:.2f}s") # 添加预构建的参数 for key, value in pre_built_params.items(): @@ -208,7 +178,7 @@ class SmartPromptBuilder: context_data[key] = value # 构建聊天历史 - 根据模式不同 - if params.current_prompt_mode == "s4u": + if params.prompt_mode == "s4u": await self._build_s4u_chat_context(context_data, params) else: await self._build_normal_chat_context(context_data, params) @@ -226,12 +196,7 @@ class SmartPromptBuilder: 'action_descriptions': params.action_descriptions, }) - # 缓存数据 - if params.enable_cache: - self._cache[cache_key] = { - 'data': context_data, - 'timestamp': time.time() - } + # 移除缓存存储逻辑 total_time = time.time() - start_time if timing_logs: @@ -241,29 +206,56 @@ class SmartPromptBuilder: return context_data - async def _timed_build(self, build_func, params: SmartPromptParameters, task_name: str) -> Tuple[Dict[str, Any], float]: - """带计时的构建函数""" + async def _build_with_fallback( + self, + build_func: callable, + params: SmartPromptParameters, + component_name: str, + fallback_value: Any = "", + critical: bool = False + ) -> Dict[str, Any]: + """ + 统一的构建方法错误处理包装器 + + Args: + build_func: 构建函数 + params: 参数对象 + component_name: 组件名称 + fallback_value: 降级值 + critical: 是否为关键组件,失败时抛出异常 + + Returns: + Dict[str, Any]: 构建结果 + """ start_time = time.time() try: result = await build_func(params) end_time = time.time() - return result, end_time - start_time + timing = end_time - start_time + logger.debug(f"构建{component_name}成功,耗时: {timing:.2f}s") + return {component_name: result, f"{component_name}_timing": timing} + except ImportError as e: + error_msg = f"构建{component_name}时导入依赖失败: {e}" + logger.error(error_msg) + if critical: + raise RuntimeError(error_msg) from e + return {component_name: fallback_value, f"{component_name}_timing": time.time() - start_time} except Exception as e: - logger.error(f"构建任务{task_name}异常: {e}") - end_time = time.time() - return {}, end_time - start_time + error_msg = f"构建{component_name}失败: {e}" + logger.error(error_msg) + if critical: + raise RuntimeError(error_msg) from e + return {component_name: fallback_value, f"{component_name}_timing": time.time() - start_time} async def _build_s4u_chat_context(self, context_data: Dict[str, Any], params: SmartPromptParameters) -> None: """构建S4U模式的聊天上下文 - 使用新参数结构""" - if not params.core.message_list: + if not params.message_list_before_now_long: return # 使用共享工具构建分离历史 - from src.chat.utils.prompt_utils import PromptUtils - core_dialogue, background_dialogue = PromptUtils.build_s4u_separated_history( - params.core.message_list, - params.core.target_user_info, - params.core.target_chat + core_dialogue, background_dialogue = await self._build_s4u_chat_history_prompts( + params.message_list_before_now_long, + params.target_user_info.get("user_id") if params.target_user_info else "" ) context_data['core_dialogue_prompt'] = core_dialogue @@ -271,16 +263,115 @@ class SmartPromptBuilder: async def _build_normal_chat_context(self, context_data: Dict[str, Any], params: SmartPromptParameters) -> None: """构建normal模式的聊天上下文 - 使用新参数结构""" - if not params.core.chat_context: + if not params.chat_talking_prompt_short: return context_data['chat_info'] = f"""群里的聊天内容: -{params.core.chat_context}""" - - def _build_s4u_separated_history(self, *args, **kwargs): - """已废弃 - 使用PromptUtils中的实现""" - logger.warning("_build_s4u_separated_history已废弃,使用PromptUtils.build_s4u_separated_history") - return "", "" +{params.chat_talking_prompt_short}""" + + async def _build_s4u_chat_history_prompts( + self, + message_list_before_now: List[Dict[str, Any]], + target_user_id: str + ) -> Tuple[str, str]: + """构建S4U风格的分离对话prompt - 完整实现""" + core_dialogue_list = [] + background_dialogue_list = [] + bot_id = str(global_config.bot.qq_account) + + # 过滤消息:分离bot和目标用户的对话 vs 其他用户的对话 + for msg_dict in message_list_before_now: + try: + msg_user_id = str(msg_dict.get("user_id")) + reply_to = msg_dict.get("reply_to", "") + _platform, reply_to_user_id = self._parse_reply_target(reply_to) + if (msg_user_id == bot_id and reply_to_user_id == target_user_id) or msg_user_id == target_user_id: + # bot 和目标用户的对话 + core_dialogue_list.append(msg_dict) + else: + # 其他用户的对话 + background_dialogue_list.append(msg_dict) + except Exception as e: + logger.error(f"处理消息记录时出错: {msg_dict}, 错误: {e}") + + # 构建背景对话 prompt + background_dialogue_prompt = "" + if background_dialogue_list: + latest_25_msgs = background_dialogue_list[-int(global_config.chat.max_context_size * 0.5) :] + background_dialogue_prompt_str = build_readable_messages( + latest_25_msgs, + replace_bot_name=True, + timestamp_mode="normal", + truncate=True, + ) + background_dialogue_prompt = f"这是其他用户的发言:\n{background_dialogue_prompt_str}" + + # 构建核心对话 prompt + core_dialogue_prompt = "" + if core_dialogue_list: + core_dialogue_list = core_dialogue_list[-int(global_config.chat.max_context_size * 2) :] # 限制消息数量 + + core_dialogue_prompt_str = build_readable_messages( + core_dialogue_list, + replace_bot_name=True, + merge_messages=False, + timestamp_mode="normal", + read_mark=0.0, + truncate=True, + show_actions=True, + ) + core_dialogue_prompt = core_dialogue_prompt_str + + return core_dialogue_prompt, background_dialogue_prompt + + async def _build_mai_think_context(self, params: SmartPromptParameters) -> Any: + """构建mai_think上下文 - 完全继承DefaultReplyer功能""" + try: + from src.mais4u.mai_think import mai_thinking_manager + + # 获取mai_think实例 + mai_think = mai_thinking_manager.get_mai_think(params.chat_id) + + # 设置mai_think的上下文信息 + mai_think.memory_block = params.memory_block or "" + mai_think.relation_info_block = params.relation_info_block or "" + mai_think.time_block = params.time_block or f"当前时间:{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}" + + # 设置聊天目标信息 + if params.is_group_chat: + from src.chat.utils.prompt_builder import global_prompt_manager + chat_target_1 = await global_prompt_manager.get_prompt_async("chat_target_group1") + chat_target_2 = await global_prompt_manager.get_prompt_async("chat_target_group2") + else: + chat_target_name = "对方" + if params.chat_target_info: + chat_target_name = ( + params.chat_target_info.get("person_name") or + params.chat_target_info.get("user_nickname") or "对方" + ) + from src.chat.utils.prompt_builder import global_prompt_manager + chat_target_1 = await global_prompt_manager.format_prompt( + "chat_target_private1", sender_name=chat_target_name + ) + chat_target_2 = await global_prompt_manager.format_prompt( + "chat_target_private2", sender_name=chat_target_name + ) + + mai_think.chat_target = chat_target_1 + mai_think.chat_target_2 = chat_target_2 + mai_think.chat_info = params.chat_talking_prompt_short or "" + mai_think.mood_state = params.mood_prompt or "" + mai_think.identity = params.identity_block or "" + mai_think.sender = params.sender + mai_think.target = params.target + + # 返回mai_think实例,以便后续使用 + return mai_think + + except Exception as e: + logger.error(f"构建mai_think上下文失败: {e}") + return None + def _parse_reply_target_id(self, reply_to: str) -> str: """解析回复目标中的用户ID""" @@ -299,182 +390,346 @@ class SmartPromptBuilder: user_id = person_info_manager.get_value_sync(person_id, "user_id") return str(user_id) if user_id else "" - @property - def _cached_data(self) -> dict: - """缓存存储""" - if not hasattr(self, '_cache_store'): - self._cache_store = {} - return self._cache_store - - async def _build_expression_habits(self, params: SmartPromptParameters) -> Dict[str, Any]: - """构建表达习惯 - 使用共享工具类""" + async def _build_expression_habits(self, params: SmartPromptParameters) -> str: + """构建表达习惯 - 使用共享工具类,完全继承DefaultReplyer功能""" + # 检查是否允许在此聊天流中使用表达 + use_expression, _, _ = global_config.expression.get_expression_config_for_chat(params.chat_id) + if not use_expression: + return "" + + # 检查依赖项 try: - from src.chat.utils.prompt_utils import PromptUtils - return await PromptUtils.build_expression_habits( - params.core.chat_id, - params.core.chat_context, - params.core.target + from src.chat.express.expression_selector import expression_selector + except ImportError as e: + logger.error(f"expression_selector导入失败: {e}") + return "" + + style_habits = [] + grammar_habits = [] + + # 使用从处理器传来的选中表达方式 + # LLM模式:调用LLM选择5-10个,然后随机选5个 + try: + selected_expressions = await expression_selector.select_suitable_expressions_llm( + params.chat_id, + params.chat_talking_prompt_short, + max_num=8, + min_num=2, + target_message=params.target ) except Exception as e: - logger.error(f"构建表达习惯失败: {e}") - return {"expression_habits_block": ""} + logger.error(f"选择表达方式失败: {e}") + selected_expressions = [] - async def _build_memory_block(self, params: SmartPromptParameters) -> Dict[str, Any]: - """构建记忆块 - 使用共享工具类""" - try: - from src.chat.utils.prompt_utils import PromptUtils - return await PromptUtils.build_memory_block( - params.core.chat_id, - params.core.target, - params.core.chat_context, - params.features.enable_memory # 传入功能开关 + if selected_expressions: + logger.debug(f"使用处理器选中的{len(selected_expressions)}个表达方式") + for expr in selected_expressions: + if isinstance(expr, dict) and "situation" in expr and "style" in expr: + expr_type = expr.get("type", "style") + if expr_type == "grammar": + grammar_habits.append(f"当{expr['situation']}时,使用 {expr['style']}") + else: + style_habits.append(f"当{expr['situation']}时,使用 {expr['style']}") + else: + logger.debug("没有从处理器获得表达方式,将使用空的表达方式") + # 不再在replyer中进行随机选择,全部交给处理器处理 + + style_habits_str = "\n".join(style_habits) + grammar_habits_str = "\n".join(grammar_habits) + + # 动态构建expression habits块 + expression_habits_block = "" + expression_habits_title = "" + if style_habits_str.strip(): + expression_habits_title = ( + "你可以参考以下的语言习惯,当情景合适就使用,但不要生硬使用,以合理的方式结合到你的回复中:" ) + expression_habits_block += f"{style_habits_str}\n" + if grammar_habits_str.strip(): + expression_habits_title = ( + "你可以选择下面的句法进行回复,如果情景合适就使用,不要盲目使用,不要生硬使用,以合理的方式使用:" + ) + expression_habits_block += f"{grammar_habits_str}\n" + + if style_habits_str.strip() and grammar_habits_str.strip(): + expression_habits_title = "你可以参考以下的语言习惯和句法,如果情景合适就使用,不要盲目使用,不要生硬使用,以合理的方式结合到你的回复中。" + + return f"{expression_habits_title}\n{expression_habits_block}" + + async def _build_memory_block(self, params: SmartPromptParameters) -> str: + """构建记忆块 - 使用共享工具类,完全继承DefaultReplyer功能""" + if not global_config.memory.enable_memory: + return "" + + # 检查依赖项 + try: + from src.chat.memory_system.memory_activator import MemoryActivator + from src.chat.memory_system.vector_instant_memory import VectorInstantMemoryV2 + except ImportError as e: + logger.error(f"记忆系统导入失败: {e}") + return "" + + instant_memory = None + + # 初始化记忆激活器 + try: + memory_activator = MemoryActivator() - if global_config.memory.enable_instant_memory: - # 使用异步记忆包装器(最优化的非阻塞模式) + # 获取长期记忆 + running_memories = await memory_activator.activate_memory_with_chat_history( + target_message=params.target, + chat_history_prompt=params.chat_talking_prompt_short + ) + except Exception as e: + logger.error(f"激活记忆失败: {e}") + running_memories = [] + + # 处理瞬时记忆 + if global_config.memory.enable_instant_memory: + # 使用异步记忆包装器(最优化的非阻塞模式) + try: + from src.chat.memory_system.async_instant_memory_wrapper import get_async_instant_memory + + # 获取异步记忆包装器 + async_memory = get_async_instant_memory(params.chat_id) + + # 后台存储聊天历史(完全非阻塞) + async_memory.store_memory_background(params.chat_talking_prompt_short) + + # 快速检索记忆,最大超时2秒 + instant_memory = await async_memory.get_memory_with_fallback(params.target, max_timeout=2.0) + + logger.info(f"异步瞬时记忆:{instant_memory}") + + except ImportError: + # 如果异步包装器不可用,尝试使用异步记忆管理器 try: - from src.chat.memory_system.async_instant_memory_wrapper import get_async_instant_memory + from src.chat.memory_system.async_memory_optimizer import ( + retrieve_memory_nonblocking, + store_memory_nonblocking, + ) - # 获取异步记忆包装器 - async_memory = get_async_instant_memory(params.chat_id) + # 异步存储聊天历史(非阻塞) + asyncio.create_task( + store_memory_nonblocking(chat_id=params.chat_id, content=params.chat_talking_prompt_short) + ) - # 后台存储聊天历史(完全非阻塞) - async_memory.store_memory_background(params.chat_talking_prompt_short) + # 尝试从缓存获取瞬时记忆 + instant_memory = await retrieve_memory_nonblocking(chat_id=params.chat_id, query=params.target) - # 快速检索记忆,最大超时2秒 - instant_memory = await async_memory.get_memory_with_fallback(params.target, max_timeout=2.0) - - logger.info(f"异步瞬时记忆:{instant_memory}") - - except ImportError: - # 如果异步包装器不可用,尝试使用异步记忆管理器 - try: - from src.chat.memory_system.async_memory_optimizer import ( - retrieve_memory_nonblocking, - store_memory_nonblocking, - ) - - # 异步存储聊天历史(非阻塞) - asyncio.create_task( - store_memory_nonblocking(chat_id=params.chat_id, content=params.chat_talking_prompt_short) - ) - - # 尝试从缓存获取瞬时记忆 - instant_memory = await retrieve_memory_nonblocking(chat_id=params.chat_id, query=params.target) - - # 如果没有缓存结果,快速检索一次 - if instant_memory is None: - try: - instant_memory = await asyncio.wait_for( - instant_memory_system.get_memory_for_context(params.target), timeout=1.5 - ) - except asyncio.TimeoutError: - logger.warning("瞬时记忆检索超时,使用空结果") - instant_memory = "" + # 如果没有缓存结果,快速检索一次 + if instant_memory is None: + try: + # 使用VectorInstantMemoryV2实例 + instant_memory_system = VectorInstantMemoryV2(chat_id=params.chat_id, retention_hours=1) + instant_memory = await asyncio.wait_for( + instant_memory_system.get_memory_for_context(params.target), timeout=1.5 + ) + except asyncio.TimeoutError: + logger.warning("瞬时记忆检索超时,使用空结果") + instant_memory = "" logger.info(f"向量瞬时记忆:{instant_memory}") - except ImportError: - # 最后的fallback:使用原有逻辑但加上超时控制 - logger.warning("异步记忆系统不可用,使用带超时的同步方式") - - # 异步存储聊天历史 - asyncio.create_task(instant_memory_system.store_message(params.chat_talking_prompt_short)) - - # 带超时的记忆检索 - try: - instant_memory = await asyncio.wait_for( - instant_memory_system.get_memory_for_context(params.target), - timeout=1.0, # 最保守的1秒超时 - ) - except asyncio.TimeoutError: - logger.warning("瞬时记忆检索超时,跳过记忆获取") - instant_memory = "" - except Exception as e: - logger.error(f"瞬时记忆检索失败: {e}") - instant_memory = "" - - logger.info(f"同步瞬时记忆:{instant_memory}") - - except Exception as e: - logger.error(f"瞬时记忆系统异常: {e}") - instant_memory = "" - - # 构建记忆字符串,即使某种记忆为空也要继续 - memory_str = "" - has_any_memory = False - - # 添加长期记忆 - if running_memories: - if not memory_str: - memory_str = "以下是当前在聊天中,你回忆起的记忆:\n" - for running_memory in running_memories: - memory_str += f"- {running_memory['content']}\n" - has_any_memory = True - - # 添加瞬时记忆 - if instant_memory: - if not memory_str: - memory_str = "以下是当前在聊天中,你回忆起的记忆:\n" - memory_str += f"- {instant_memory}\n" - has_any_memory = True - - # 只有当完全没有任何记忆时才返回空字符串 - return {"memory_block": memory_str if has_any_memory else ""} - - except Exception as e: - logger.error(f"构建记忆块失败: {e}") - return {"memory_block": ""} + except ImportError: + # 最后的fallback:使用原有逻辑但加上超时控制 + logger.warning("异步记忆系统不可用,使用带超时的同步方式") + + # 使用VectorInstantMemoryV2实例 + instant_memory_system = VectorInstantMemoryV2(chat_id=params.chat_id, retention_hours=1) + + # 异步存储聊天历史 + asyncio.create_task(instant_memory_system.store_message(params.chat_talking_prompt_short)) + + # 带超时的记忆检索 + try: + instant_memory = await asyncio.wait_for( + instant_memory_system.get_memory_for_context(params.target), + timeout=1.0, # 最保守的1秒超时 + ) + except asyncio.TimeoutError: + logger.warning("瞬时记忆检索超时,跳过记忆获取") + instant_memory = "" + except Exception as e: + logger.error(f"瞬时记忆检索失败: {e}") + instant_memory = "" + + logger.info(f"同步瞬时记忆:{instant_memory}") + + except Exception as e: + logger.error(f"瞬时记忆系统异常: {e}") + instant_memory = "" + + # 构建记忆字符串,即使某种记忆为空也要继续 + memory_str = "" + has_any_memory = False + + # 添加长期记忆 + if running_memories: + if not memory_str: + memory_str = "以下是当前在聊天中,你回忆起的记忆:\n" + for running_memory in running_memories: + memory_str += f"- {running_memory['content']}\n" + has_any_memory = True + + # 添加瞬时记忆 + if instant_memory: + if not memory_str: + memory_str = "以下是当前在聊天中,你回忆起的记忆:\n" + memory_str += f"- {instant_memory}\n" + has_any_memory = True + + # 注入视频分析结果引导语 + memory_str = self._inject_video_prompt_if_needed(params.target, memory_str) + + # 只有当完全没有任何记忆时才返回空字符串 + return memory_str if has_any_memory else "" - async def _build_relation_info(self, params: SmartPromptParameters) -> Dict[str, Any]: + def _inject_video_prompt_if_needed(self, target: str, memory_str: str) -> str: + """统一视频分析结果注入逻辑""" + if target and ("[视频内容]" in target or "好的,我将根据您提供的" in target): + video_prompt_injection = "\n请注意,以上内容是你刚刚观看的视频,请以第一人称分享你的观后感,而不是在分析一份报告。" + return memory_str + video_prompt_injection + return memory_str + + async def _build_relation_info(self, params: SmartPromptParameters) -> str: """构建关系信息 - 使用共享工具类""" try: - from src.chat.utils.prompt_utils import PromptUtils return await PromptUtils.build_relation_info( - params.core.chat_id, - params.core.reply_to + params.chat_id, + params.reply_to ) except Exception as e: logger.error(f"构建关系信息失败: {e}") - return {"relation_info_block": ""} + return "" - async def _build_tool_info(self, params: SmartPromptParameters) -> Dict[str, Any]: - """构建工具信息 - 使用共享工具类""" + async def _build_tool_info(self, params: SmartPromptParameters) -> str: + """构建工具信息 - 使用共享工具类,完全继承DefaultReplyer功能""" + if not params.enable_tool: + return "" + + if not params.reply_to: + return "" + + sender, text = PromptUtils.parse_reply_target(params.reply_to) + + if not text: + return "" + try: - from src.chat.utils.prompt_utils import PromptUtils - return await PromptUtils.build_tool_info( - params.core.chat_id, - params.core.reply_to, - params.core.chat_context + # 检查依赖项 + from src.plugin_system.core.tool_use import ToolExecutor + except ImportError as e: + logger.error(f"工具执行器导入失败: {e}") + return "" + + # 使用工具执行器获取信息 + try: + tool_executor = ToolExecutor(chat_id=params.chat_id) + tool_results, _, _ = await tool_executor.execute_from_chat_message( + sender=sender, + target_message=text, + chat_history=params.chat_talking_prompt_short, + return_details=False ) + + if tool_results: + tool_info_str = "以下是你通过工具获取到的实时信息:\n" + for tool_result in tool_results: + tool_name = tool_result.get("tool_name", "unknown") + content = tool_result.get("content", "") + result_type = tool_result.get("type", "tool_result") + + tool_info_str += f"- 【{tool_name}】{result_type}: {content}\n" + + tool_info_str += "以上是你获取到的实时信息,请在回复时参考这些信息。" + logger.info(f"获取到 {len(tool_results)} 个工具结果") + + return tool_info_str + else: + logger.debug("未获取到任何工具结果") + return "" + except Exception as e: logger.error(f"工具信息获取失败: {e}") - return {"tool_info_block": ""} + return "" - async def _build_knowledge_info(self, params: SmartPromptParameters) -> Dict[str, Any]: - """构建知识信息 - 使用共享工具类""" + async def _build_knowledge_info(self, params: SmartPromptParameters) -> str: + """构建知识信息 - 使用共享工具类,完全继承DefaultReplyer功能""" + if not params.reply_to: + logger.debug("没有回复对象,跳过获取知识库内容") + return "" + + sender, content = PromptUtils.parse_reply_target(params.reply_to) + if not content: + logger.debug("回复对象内容为空,跳过获取知识库内容") + return "" + + logger.debug(f"获取知识库内容,元消息:{params.chat_talking_prompt_short[:30]}...,消息长度: {len(params.chat_talking_prompt_short)}") + + # 从LPMM知识库获取知识 try: - from src.chat.utils.prompt_utils import PromptUtils - return await PromptUtils.build_knowledge_info( - params.core.reply_to, - params.core.chat_context + # 检查LPMM知识库是否启用 + if not global_config.lpmm_knowledge.enable: + logger.debug("LPMM知识库未启用,跳过获取知识库内容") + return "" + + # 检查依赖项 + from src.plugins.built_in.knowledge.lpmm_get_knowledge import SearchKnowledgeFromLPMMTool + from src.plugin_system.apis import llm_api + from src.config.config import model_config + + time_now = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) + bot_name = global_config.bot.nickname + + prompt = await global_prompt_manager.format_prompt( + "lpmm_get_knowledge_prompt", + bot_name=bot_name, + time_now=time_now, + chat_history=params.chat_talking_prompt_short, + sender=sender, + target_message=content, ) + + _, _, _, _, tool_calls = await llm_api.generate_with_model_with_tools( + prompt, + model_config=model_config.model_task_config.tool_use, + tool_options=[SearchKnowledgeFromLPMMTool.get_tool_definition()], + ) + + if tool_calls: + tool_executor = ToolExecutor(chat_id=params.chat_id) + result = await tool_executor.execute_tool_call(tool_calls[0], SearchKnowledgeFromLPMMTool()) + + if not result or not result.get("content"): + logger.debug("从LPMM知识库获取知识失败,返回空知识...") + return "" + + found_knowledge_from_lpmm = result.get("content", "") + logger.debug( + f"从LPMM知识库获取知识,相关信息:{found_knowledge_from_lpmm[:100]}...,信息长度: {len(found_knowledge_from_lpmm)}" + ) + + return f"你有以下这些**知识**:\n{found_knowledge_from_lpmm}\n请你**记住上面的知识**,之后可能会用到。\n" + else: + logger.debug("从LPMM知识库获取知识失败,可能是从未导入过知识,返回空知识...") + return "" + except Exception as e: logger.error(f"获取知识库内容时发生异常: {str(e)}") - return {"knowledge_prompt": ""} + return "" - async def _build_cross_context(self, params: SmartPromptParameters) -> Dict[str, Any]: + async def _build_cross_context(self, params: SmartPromptParameters) -> str: """构建跨群上下文 - 使用共享工具类""" try: - from src.chat.utils.prompt_utils import PromptUtils return await PromptUtils.build_cross_context( - params.core.chat_id, - params.core.prompt_mode, - params.core.target_user_info + params.chat_id, + params.prompt_mode, + params.target_user_info ) except Exception as e: logger.error(f"构建跨群上下文失败: {e}") - return {"cross_context_block": ""} + return "" def _parse_reply_target(self, target_message: str) -> Tuple[str, str]: """解析回复目标消息 - 使用共享工具类""" @@ -482,7 +737,7 @@ class SmartPromptBuilder: class SmartPrompt: - """重构的智能提示词核心类 - 使用新参数结构""" + """重构的智能提示词核心类 - 增强错误处理和降级机制,移除缓存机制""" def __init__( self, @@ -495,48 +750,123 @@ class SmartPrompt: def _get_default_template(self) -> str: """根据模式选择默认模板""" - if self.parameters.core.prompt_mode == "s4u": + if self.parameters.prompt_mode == "s4u": return "s4u_style_prompt" - elif self.parameters.core.prompt_mode == "normal": + elif self.parameters.prompt_mode == "normal": return "normal_style_prompt" else: return "default_expressor_prompt" async def build_prompt(self) -> str: - """构建最终的Prompt文本 - 使用新参数结构""" + """构建最终的Prompt文本 - 增强错误处理,移除缓存机制""" # 参数验证 errors = self.parameters.validate() if errors: - raise ValueError(f"参数验证失败: {', '.join(errors)}") + logger.error(f"参数验证失败: {', '.join(errors)}") + return self._get_fallback_prompt("参数验证失败") + + # 依赖项检查 + if not await self._check_dependencies(): + logger.warning("依赖项检查失败,使用简化模式") + return self._get_simplified_prompt() start_time = time.time() try: # 构建基础上下文的完整映射 context_data = await self.builder.build_context_data(self.parameters) + # 检查关键上下文数据 + if not context_data or not isinstance(context_data, dict): + logger.error("构建的上下文数据无效") + return self._get_fallback_prompt("上下文数据无效") + # 获取模板 - template = await global_prompt_manager.get_prompt_async(self.template_name) + template = await self._get_template() + if not template: + logger.error("无法获取模板") + return self._get_fallback_prompt("模板获取失败") # 根据模式传递不同的参数 - if self.parameters.core.prompt_mode == "s4u": + if self.parameters.prompt_mode == "s4u": result = await self._build_s4u_prompt(template, context_data) - elif self.parameters.core.prompt_mode == "normal": + elif self.parameters.prompt_mode == "normal": result = await self._build_normal_prompt(template, context_data) else: result = await self._build_default_prompt(template, context_data) # 记录性能数据 total_time = time.time() - start_time - logger.debug(f"SmartPrompt构建完成,模式: {self.parameters.core.prompt_mode}, 耗时: {total_time:.2f}s") + logger.debug(f"SmartPrompt构建完成,模式: {self.parameters.prompt_mode}, 耗时: {total_time:.2f}s") return result + except asyncio.TimeoutError as e: + logger.error(f"构建Prompt超时: {e}") + return self._get_fallback_prompt("构建超时") except Exception as e: logger.error(f"构建Prompt失败: {e}") - # 返回一个基础Prompt作为fallback - fallback_prompt = f"用户说:{self.parameters.core.reply_to}。请回复。" - logger.warning(f"使用fallback prompt: {fallback_prompt}") - return fallback_prompt + return self._get_fallback_prompt(f"构建失败: {str(e)}") + + def _get_fallback_prompt(self, reason: str) -> str: + """获取降级Prompt""" + logger.warning(f"使用fallback prompt, 原因: {reason}") + + # 根据可用的信息构建尽可能有用的降级Prompt + if self.parameters.reply_to: + return f"用户说:{self.parameters.reply_to}。请回复。" + elif self.parameters.target: + return f"请回复以下内容:{self.parameters.target}" + else: + return "请进行回复。" + + def _get_simplified_prompt(self) -> str: + """获取简化Prompt""" + logger.info("使用简化prompt模式") + + # 构建一个只包含最基本信息的简化Prompt + basic_info = [] + + if self.parameters.reply_to: + basic_info.append(f"用户说:{self.parameters.reply_to}") + elif self.parameters.target: + basic_info.append(f"请回复:{self.parameters.target}") + + if self.parameters.identity_block: + basic_info.append(f"你的身份:{self.parameters.identity_block}") + + if self.parameters.time_block: + basic_info.append(f"时间:{self.parameters.time_block}") + + return "\n".join(basic_info) + "\n请根据以上信息进行回复。" + + async def _check_dependencies(self) -> bool: + """检查关键依赖项是否可用""" + dependencies = [ + ("expression_selector", "src.chat.express.expression_selector"), + ("memory_activator", "src.chat.memory_system.memory_activator"), + ("tool_executor", "src.plugin_system.core.tool_use"), + ("knowledge_tool", "src.plugins.built_in.knowledge.lpmm_get_knowledge") + ] + + missing_deps = [] + for name, module_path in dependencies: + try: + __import__(module_path) + logger.debug(f"依赖项 {name} 可用") + except ImportError as e: + logger.error(f"依赖项 {name} 导入失败: {e}") + missing_deps.append(name) + + # 知识工具不是必需的,所以只要其他依赖可用就返回True + return all(dep not in missing_deps or dep == "knowledge_tool" for dep in missing_deps) + + async def _get_template(self) -> Optional[Prompt]: + """获取模板""" + try: + return await global_prompt_manager.get_prompt_async(self.template_name) + except Exception as e: + logger.error(f"获取模板 {self.template_name} 失败: {e}") + return None async def _build_s4u_prompt(self, template: Prompt, context_data: Dict[str, Any]) -> str: """构建S4U模式的完整Prompt - 使用新参数结构""" @@ -547,19 +877,19 @@ class SmartPrompt: 'knowledge_prompt': context_data.get('knowledge_prompt', ''), 'memory_block': context_data.get('memory_block', ''), 'relation_info_block': context_data.get('relation_info_block', ''), - 'extra_info_block': self.parameters.content.extra_info or context_data.get('extra_info_block', ''), + 'extra_info_block': self.parameters.extra_info_block or context_data.get('extra_info_block', ''), 'cross_context_block': context_data.get('cross_context_block', ''), - 'identity': self.parameters.content.identity or context_data.get('identity', ''), - 'action_descriptions': self.parameters.content.actions or context_data.get('action_descriptions', ''), - 'sender_name': self.parameters.core.sender_name, - 'mood_state': self.parameters.content.mood_prompt or context_data.get('mood_state', ''), + 'identity': self.parameters.identity_block or context_data.get('identity', ''), + 'action_descriptions': self.parameters.action_descriptions or context_data.get('action_descriptions', ''), + 'sender_name': self.parameters.sender, + 'mood_state': self.parameters.mood_prompt or context_data.get('mood_state', ''), 'background_dialogue_prompt': context_data.get('background_dialogue_prompt', ''), 'time_block': context_data.get('time_block', ''), 'core_dialogue_prompt': context_data.get('core_dialogue_prompt', ''), 'reply_target_block': context_data.get('reply_target_block', ''), 'reply_style': global_config.personality.reply_style, - 'keywords_reaction_prompt': self.parameters.content.keywords_reaction or context_data.get('keywords_reaction_prompt', ''), - 'moderation_prompt': self.parameters.content.moderation_prompt or context_data.get('moderation_prompt', ''), + 'keywords_reaction_prompt': self.parameters.keywords_reaction_prompt or context_data.get('keywords_reaction_prompt', ''), + 'moderation_prompt': self.parameters.moderation_prompt_block or context_data.get('moderation_prompt', ''), } return await global_prompt_manager.format_prompt(self.template_name, **params) @@ -572,18 +902,18 @@ class SmartPrompt: 'knowledge_prompt': context_data.get('knowledge_prompt', ''), 'memory_block': context_data.get('memory_block', ''), 'relation_info_block': context_data.get('relation_info_block', ''), - 'extra_info_block': self.parameters.content.extra_info or context_data.get('extra_info_block', ''), + 'extra_info_block': self.parameters.extra_info_block or context_data.get('extra_info_block', ''), 'cross_context_block': context_data.get('cross_context_block', ''), - 'identity': self.parameters.content.identity or context_data.get('identity', ''), - 'action_descriptions': self.parameters.content.actions or context_data.get('action_descriptions', ''), - 'schedule_block': self.parameters.content.schedule_prompt or context_data.get('schedule_block', ''), + 'identity': self.parameters.identity_block or context_data.get('identity', ''), + 'action_descriptions': self.parameters.action_descriptions or context_data.get('action_descriptions', ''), + 'schedule_block': self.parameters.schedule_block or context_data.get('schedule_block', ''), 'time_block': context_data.get('time_block', ''), 'chat_info': context_data.get('chat_info', ''), 'reply_target_block': context_data.get('reply_target_block', ''), 'config_expression_style': global_config.personality.reply_style, - 'mood_state': self.parameters.content.mood_prompt or context_data.get('mood_state', ''), - 'keywords_reaction_prompt': self.parameters.content.keywords_reaction or context_data.get('keywords_reaction_prompt', ''), - 'moderation_prompt': self.parameters.content.moderation_prompt or context_data.get('moderation_prompt', ''), + 'mood_state': self.parameters.mood_prompt or context_data.get('mood_state', ''), + 'keywords_reaction_prompt': self.parameters.keywords_reaction_prompt or context_data.get('keywords_reaction_prompt', ''), + 'moderation_prompt': self.parameters.moderation_prompt_block or context_data.get('moderation_prompt', ''), } return await global_prompt_manager.format_prompt(self.template_name, **params) @@ -595,15 +925,15 @@ class SmartPrompt: 'chat_target': "", 'time_block': context_data.get('time_block', ''), 'chat_info': context_data.get('chat_info', ''), - 'identity': self.parameters.content.identity or context_data.get('identity', ''), + 'identity': self.parameters.identity_block or context_data.get('identity', ''), 'chat_target_2': "", 'reply_target_block': context_data.get('reply_target_block', ''), - 'raw_reply': self.parameters.core.target_message, + 'raw_reply': self.parameters.target, 'reason': "", - 'mood_state': self.parameters.content.mood_prompt or context_data.get('mood_state', ''), + 'mood_state': self.parameters.mood_prompt or context_data.get('mood_state', ''), 'reply_style': global_config.personality.reply_style, - 'keywords_reaction_prompt': self.parameters.content.keywords_reaction or context_data.get('keywords_reaction_prompt', ''), - 'moderation_prompt': self.parameters.content.moderation_prompt or context_data.get('moderation_prompt', ''), + 'keywords_reaction_prompt': self.parameters.keywords_reaction_prompt or context_data.get('keywords_reaction_prompt', ''), + 'moderation_prompt': self.parameters.moderation_prompt_block or context_data.get('moderation_prompt', ''), } return await global_prompt_manager.format_prompt(self.template_name, **params) @@ -619,23 +949,11 @@ def create_smart_prompt( """快速创建智能Prompt实例的工厂函数 - 使用新参数结构""" # 使用新的参数结构 - from src.chat.utils.prompt_parameters import PromptCoreParams - - core_params = PromptCoreParams( - chat_id=chat_id, - sender_name=sender_name, - target_message=target_message, - reply_to=reply_to - ) - - # 更新features和content参数 - feature_params = kwargs.pop('features', None) or PromptFeatureParams() - content_params = kwargs.pop('content', None) or PromptContentParams() - parameters = SmartPromptParameters( - core=core_params, - features=feature_params, - content=content_params, + chat_id=chat_id, + sender=sender_name, + target=target_message, + reply_to=reply_to, **kwargs ) @@ -748,14 +1066,13 @@ class SmartPromptHealthChecker: sender="test_user", target="test_message", reply_to="test_user:test_message", - current_prompt_mode="s4u", - enable_cache=False # 禁用缓存以测试真实性能 + prompt_mode="s4u" ) # 测试不同模式下的构建性能 modes = ["s4u", "normal", "minimal"] for mode in modes: - test_params.current_prompt_mode = mode + test_params.prompt_mode = mode smart_prompt = SmartPrompt(parameters=test_params) # 运行多次测试取平均值