Merge branch 'G-Test' of https://github.com/smartmita/MaiBot into G-Test

pull/937/head
Bakadax 2025-05-12 08:57:39 +08:00
commit b8bfe4e92a
2 changed files with 50 additions and 33 deletions

View File

@ -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. 工具可获取信息或执行操作

View File

@ -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)
@ -47,12 +55,15 @@ class ReplyChecker:
)
return True, "BOT_QQ未配置跳过重复检查。", False # 无法检查则默认通过
if len(reply) <= 4:
# 对当前待发送的回复进行规范化
normalized_reply = self._normalize_text(reply)
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,27 +75,31 @@ 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)})"
)
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)
# <--- 新增详细对比日志 --- END --->
# 对历史消息也进行同样的规范化处理
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)