From 7dda9561587ac59b726c29b6dbbd7f46b4b74922 Mon Sep 17 00:00:00 2001 From: 114514 <2514624910@qq.com> Date: Sun, 11 May 2025 03:44:30 +0800 Subject: [PATCH 1/5] =?UTF-8?q?=E6=9D=80=E5=A4=9A=E4=BD=99=E6=B3=A8?= =?UTF-8?q?=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/plugins/PFC/reply_checker.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/PFC/reply_checker.py b/src/plugins/PFC/reply_checker.py index 4f4030e6..d5f28a19 100644 --- a/src/plugins/PFC/reply_checker.py +++ b/src/plugins/PFC/reply_checker.py @@ -64,7 +64,7 @@ class ReplyChecker: if sender_id == self.bot_qq_str: historical_message_text = msg_dict.get("processed_plain_text", "") - # <--- 新增详细对比日志 --- START ---> + # 日志 logger.debug( f"[私聊][{self.private_name}] ReplyChecker: 历史记录 #{i} ({global_config.BOT_NICKNAME}): '{historical_message_text}' (长度 {len(historical_message_text)})" ) @@ -75,7 +75,7 @@ class ReplyChecker: ) match_found = True # <--- 标记找到 return (False, "机器人尝试发送重复消息", False) - # <--- 新增详细对比日志 --- END ---> + if not match_found: # <--- 根据标记判断 logger.debug(f"[私聊][{self.private_name}] ReplyChecker: 未找到重复。") # <--- 新增日志 From ad438c946105c933e9e1fb748e7cdfd4e8c3f8b8 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sat, 10 May 2025 19:44:44 +0000 Subject: [PATCH 2/5] =?UTF-8?q?=F0=9F=A4=96=20=E8=87=AA=E5=8A=A8=E6=A0=BC?= =?UTF-8?q?=E5=BC=8F=E5=8C=96=E4=BB=A3=E7=A0=81=20[skip=20ci]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/plugins/PFC/reply_checker.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/plugins/PFC/reply_checker.py b/src/plugins/PFC/reply_checker.py index d5f28a19..1f306c3f 100644 --- a/src/plugins/PFC/reply_checker.py +++ b/src/plugins/PFC/reply_checker.py @@ -75,7 +75,6 @@ class ReplyChecker: ) match_found = True # <--- 标记找到 return (False, "机器人尝试发送重复消息", False) - if not match_found: # <--- 根据标记判断 logger.debug(f"[私聊][{self.private_name}] ReplyChecker: 未找到重复。") # <--- 新增日志 From cb06662eb4d0874302aad0a48fabe8c74f8648b4 Mon Sep 17 00:00:00 2001 From: 114514 <2514624910@qq.com> Date: Sun, 11 May 2025 04:23:04 +0800 Subject: [PATCH 3/5] =?UTF-8?q?=E6=9B=B4=E6=99=BA=E8=83=BD=E7=9A=84checker?= =?UTF-8?q?=EF=BC=8C=E6=8B=A6=E6=88=AA=E4=BC=AA=E5=A4=8D=E8=AF=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/plugins/PFC/reply_checker.py | 76 +++++++++++++++++++------------- 1 file changed, 46 insertions(+), 30 deletions(-) diff --git a/src/plugins/PFC/reply_checker.py b/src/plugins/PFC/reply_checker.py index 1f306c3f..672f8bad 100644 --- a/src/plugins/PFC/reply_checker.py +++ b/src/plugins/PFC/reply_checker.py @@ -2,6 +2,7 @@ from typing import Tuple, List, Dict, Any from src.common.logger import get_module_logger from src.config.config import global_config # 为了获取 BOT_QQ from .chat_observer import ChatObserver +import re logger = get_module_logger("reply_checker") @@ -10,32 +11,39 @@ class ReplyChecker: """回复检查器 - 新版:仅检查机器人自身发言的精确重复""" def __init__(self, stream_id: str, private_name: str): - # self.llm = LLMRequest(...) # <--- 移除 LLM 初始化 self.name = global_config.BOT_NICKNAME self.private_name = private_name self.chat_observer = ChatObserver.get_instance(stream_id, private_name) - # self.max_retries = 3 # 这个 max_retries 属性在当前设计下不再由 checker 控制,而是由 conversation.py 控制 - self.bot_qq_str = str(global_config.BOT_QQ) # 获取机器人QQ号用于识别自身消息 + self.bot_qq_str = str(global_config.BOT_QQ) + + def _normalize_text(self, text: str) -> str: + """ + 规范化文本,去除首尾空格,移除末尾的特定标点符号。 + """ + if not text: + return "" + text = text.strip() # 1. 去除首尾空格 + # 2. 移除末尾的一个或多个特定标点符号 + # 可以根据需要调整正则表达式以包含更多或更少的标点 + text = re.sub(r"[~\s,.!?;;,。]+$", "", text) + # 如果需要忽略大小写,可以取消下面一行的注释 + # text = text.lower() + return text async def check( self, reply: str, - goal: str, + goal: str, # 当前逻辑未使用 chat_history: List[Dict[str, Any]], - chat_history_text: str, - current_time_str: str, - retry_count: int = 0, + chat_history_text: str, # 当前逻辑未使用 + current_time_str: str, # 当前逻辑未使用 + retry_count: int = 0, # 当前逻辑未使用 ) -> Tuple[bool, str, bool]: """检查生成的回复是否与机器人之前的发言完全一致(长度大于4) Args: reply: 待检查的机器人回复内容 - goal: 当前对话目标 (新逻辑中未使用) chat_history: 对话历史记录 (包含用户和机器人的消息字典列表) - chat_history_text: 对话历史记录的文本格式 (新逻辑中未使用) - current_time_str: 当前时间的字符串格式 (新逻辑中未使用) - retry_count: 当前重试次数 (新逻辑中未使用) - Returns: Tuple[bool, str, bool]: (是否合适, 原因, 是否需要重新规划) 对于重复消息: (False, "机器人尝试发送重复消息", False) @@ -46,13 +54,16 @@ class ReplyChecker: f"[私聊][{self.private_name}] ReplyChecker: BOT_QQ 未配置,无法检查{global_config.BOT_NICKNAME}自身消息。" ) return True, "BOT_QQ未配置,跳过重复检查。", False # 无法检查则默认通过 + + # 对当前待发送的回复进行规范化 + normalized_reply = self._normalize_text(reply) - if len(reply) <= 4: + if len(normalized_reply) <= 4: return True, "消息长度小于等于4字符,跳过重复检查。", False try: match_found = False # <--- 用于调试 - for i, msg_dict in enumerate(chat_history): # <--- 添加索引用于日志 + for i, msg_dict in enumerate(reversed(chat_history)): if not isinstance(msg_dict, dict): continue @@ -64,26 +75,31 @@ class ReplyChecker: if sender_id == self.bot_qq_str: historical_message_text = msg_dict.get("processed_plain_text", "") - # 日志 - logger.debug( - f"[私聊][{self.private_name}] ReplyChecker: 历史记录 #{i} ({global_config.BOT_NICKNAME}): '{historical_message_text}' (长度 {len(historical_message_text)})" - ) - if reply == historical_message_text: - logger.warning(f"[私聊][{self.private_name}] ReplyChecker: !!! 精确匹配成功 !!!") - logger.warning( - f"[私聊][{self.private_name}] ReplyChecker 检测到{global_config.BOT_NICKNAME}自身重复消息: '{reply}'" - ) - match_found = True # <--- 标记找到 - return (False, "机器人尝试发送重复消息", False) + # 对历史消息也进行同样的规范化处理 + normalized_historical_text = self._normalize_text(historical_message_text) - if not match_found: # <--- 根据标记判断 - logger.debug(f"[私聊][{self.private_name}] ReplyChecker: 未找到重复。") # <--- 新增日志 - return (True, "消息内容未与机器人历史发言重复。", False) + logger.debug( + f"[私聊][{self.private_name}] ReplyChecker: 历史记录 (反向索引 {i}) ({global_config.BOT_NICKNAME}): " + f"原始='{historical_message_text[:50]}...', 规范化后='{normalized_historical_text[:50]}...'" + ) + if normalized_reply == normalized_historical_text and len(normalized_reply) > 0: # 确保规范化后不为空串才比较 + logger.warning( + f"[私聊][{self.private_name}] ReplyChecker: !!! 成功拦截一次复读 !!!" + ) + logger.warning( + f"[私聊][{self.private_name}] ReplyChecker 检测到{global_config.BOT_NICKNAME}自身重复消息 (规范化后内容相同): '{normalized_reply[:50]}...'" + ) + match_found = True + # 返回: 不合适, 原因, 不需要重规划 (让上层逻辑决定是否重试生成) + return (False, "机器人尝试发送与历史发言相似的消息 (内容规范化后相同)", False) + + if not match_found: + logger.debug(f"[私聊][{self.private_name}] ReplyChecker: 未找到重复内容 (规范化后比较)。") + return (True, "消息内容未与机器人历史发言重复 (规范化后比较)。", False) except Exception as e: import traceback logger.error(f"[私聊][{self.private_name}] ReplyChecker 检查重复时出错: 类型={type(e)}, 值={e}") logger.error(f"[私聊][{self.private_name}]{traceback.format_exc()}") - # 发生未知错误时,为安全起见,默认通过,并记录原因 - return (True, f"检查重复时发生内部错误: {str(e)}", False) + return (True, f"检查重复时发生内部错误 (规范化检查): {str(e)}", False) \ No newline at end of file From 50363d3901f413fec25104f6dc815792df8db621 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sat, 10 May 2025 20:23:19 +0000 Subject: [PATCH 4/5] =?UTF-8?q?=F0=9F=A4=96=20=E8=87=AA=E5=8A=A8=E6=A0=BC?= =?UTF-8?q?=E5=BC=8F=E5=8C=96=E4=BB=A3=E7=A0=81=20[skip=20ci]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/plugins/PFC/reply_checker.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/plugins/PFC/reply_checker.py b/src/plugins/PFC/reply_checker.py index 672f8bad..adfa33a8 100644 --- a/src/plugins/PFC/reply_checker.py +++ b/src/plugins/PFC/reply_checker.py @@ -33,11 +33,11 @@ class ReplyChecker: async def check( self, reply: str, - goal: str, # 当前逻辑未使用 + goal: str, # 当前逻辑未使用 chat_history: List[Dict[str, Any]], - chat_history_text: str, # 当前逻辑未使用 - current_time_str: str, # 当前逻辑未使用 - retry_count: int = 0, # 当前逻辑未使用 + chat_history_text: str, # 当前逻辑未使用 + current_time_str: str, # 当前逻辑未使用 + retry_count: int = 0, # 当前逻辑未使用 ) -> Tuple[bool, str, bool]: """检查生成的回复是否与机器人之前的发言完全一致(长度大于4) @@ -54,7 +54,7 @@ class ReplyChecker: f"[私聊][{self.private_name}] ReplyChecker: BOT_QQ 未配置,无法检查{global_config.BOT_NICKNAME}自身消息。" ) return True, "BOT_QQ未配置,跳过重复检查。", False # 无法检查则默认通过 - + # 对当前待发送的回复进行规范化 normalized_reply = self._normalize_text(reply) @@ -82,10 +82,10 @@ class ReplyChecker: f"[私聊][{self.private_name}] ReplyChecker: 历史记录 (反向索引 {i}) ({global_config.BOT_NICKNAME}): " f"原始='{historical_message_text[:50]}...', 规范化后='{normalized_historical_text[:50]}...'" ) - if normalized_reply == normalized_historical_text and len(normalized_reply) > 0: # 确保规范化后不为空串才比较 - logger.warning( - f"[私聊][{self.private_name}] ReplyChecker: !!! 成功拦截一次复读 !!!" - ) + if ( + normalized_reply == normalized_historical_text and len(normalized_reply) > 0 + ): # 确保规范化后不为空串才比较 + logger.warning(f"[私聊][{self.private_name}] ReplyChecker: !!! 成功拦截一次复读 !!!") logger.warning( f"[私聊][{self.private_name}] ReplyChecker 检测到{global_config.BOT_NICKNAME}自身重复消息 (规范化后内容相同): '{normalized_reply[:50]}...'" ) @@ -102,4 +102,4 @@ class ReplyChecker: logger.error(f"[私聊][{self.private_name}] ReplyChecker 检查重复时出错: 类型={type(e)}, 值={e}") logger.error(f"[私聊][{self.private_name}]{traceback.format_exc()}") - return (True, f"检查重复时发生内部错误 (规范化检查): {str(e)}", False) \ No newline at end of file + return (True, f"检查重复时发生内部错误 (规范化检查): {str(e)}", False) From c412b275076490335864dda94a9360badbdc8749 Mon Sep 17 00:00:00 2001 From: 114514 <2514624910@qq.com> Date: Sun, 11 May 2025 23:01:18 +0800 Subject: [PATCH 5/5] Update sub_mind.py --- src/heart_flow/sub_mind.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/heart_flow/sub_mind.py b/src/heart_flow/sub_mind.py index 0e9cb93d..19af8528 100644 --- a/src/heart_flow/sub_mind.py +++ b/src/heart_flow/sub_mind.py @@ -33,15 +33,17 @@ def init_prompt(): {chat_observe_info} 你现在{mood_info} -请仔细阅读当前群聊内容,分析讨论话题和群成员关系,分析你刚刚发言和别人对你的发言的反应,思考你要不要回复。然后思考你是否需要使用函数工具。 +请仔细阅读当前群聊内容,分析讨论话题和群成员关系,分析你刚刚发言和别人对你的发言的反应,思考你要不要回复或发言。然后思考你是否需要使用函数工具。 思考并输出你的内心想法 输出要求: 1. 根据聊天内容生成你的想法,{hf_do_next} 2. 不要分点、不要使用表情符号 3. 避免多余符号(冒号、引号、括号等) 4. 语言简洁自然,不要浮夸 -5. 如果你刚发言,并且没有人回复你,不要回复 +5. 如果你刚发言,并且没有人回复你,请谨慎考虑要不要继续发消息 6. 不要把注意力放在别人发的表情包上,它们只是一种辅助表达方式 +7. 注意分辨群里谁在跟谁说话,你不一定是当前聊天的主角,消息中的“你”不一定指的是你({bot_name}),也可能是别人 +8. 思考要不要回复或发言,如果要,需要思考一下具体说什么。 工具使用说明: 1. 输出想法后考虑是否需要使用工具 2. 工具可获取信息或执行操作