feat(chat): 优化提及检测并精简兴趣度评分日志

增强了机器人提及检测逻辑,使其能够识别配置文件中设置的所有别名(alias_names),而不仅仅是主昵称。这提高了交互的灵活性和准确性。

此外,还对兴趣度评分和匹配系统的日志输出进行了大幅重构:
- 将多条评分计算日志合并为一条包含核心指标的摘要日志,使输出更简洁。
- 调整了部分日志级别,将非关键信息移至 DEBUG 级别,以减少日志噪音。
- 在关键日志中增加了消息内容预览,以便于快速上下文定位和调试。
This commit is contained in:
tt-P607
2025-09-21 22:58:18 +08:00
parent e0e81b209a
commit bf0d214376
3 changed files with 21 additions and 32 deletions

View File

@@ -49,9 +49,10 @@ class InterestScoringSystem:
self, messages: List[DatabaseMessages], bot_nickname: str self, messages: List[DatabaseMessages], bot_nickname: str
) -> List[InterestScore]: ) -> List[InterestScore]:
"""计算消息的兴趣度评分""" """计算消息的兴趣度评分"""
logger.info(f"开始为 {len(messages)} 条消息计算兴趣度...")
user_messages = [msg for msg in messages if str(msg.user_info.user_id) != str(global_config.bot.qq_account)] user_messages = [msg for msg in messages if str(msg.user_info.user_id) != str(global_config.bot.qq_account)]
logger.info(f"正在处理 {len(user_messages)} 条用户消息。") if not user_messages:
return []
logger.info(f"正在为 {len(user_messages)} 条用户消息计算兴趣度...")
scores = [] scores = []
for i, msg in enumerate(user_messages, 1): for i, msg in enumerate(user_messages, 1):
@@ -59,25 +60,18 @@ class InterestScoringSystem:
score = await self._calculate_single_message_score(msg, bot_nickname) score = await self._calculate_single_message_score(msg, bot_nickname)
scores.append(score) scores.append(score)
logger.info(f"兴趣度计算完成,共生成 {len(scores)} 评分。") logger.info(f" {len(scores)} 条消息生成了兴趣度评分。")
return scores return scores
async def _calculate_single_message_score(self, message: DatabaseMessages, bot_nickname: str) -> InterestScore: async def _calculate_single_message_score(self, message: DatabaseMessages, bot_nickname: str) -> InterestScore:
"""计算单条消息的兴趣度评分""" """计算单条消息的兴趣度评分"""
logger.info(f"计算消息 {message.message_id} 的分数...") message_preview = f"\033[96m{message.processed_plain_text[:30].replace('\n', ' ')}...\033[0m"
logger.debug(f"消息长度: {len(message.processed_plain_text)} 字符") logger.info(f"计算消息 {message.message_id} 的分数 | 内容: {message_preview}")
keywords = self._extract_keywords_from_database(message) keywords = self._extract_keywords_from_database(message)
logger.debug(f"提取到 {len(keywords)} 个关键词。")
interest_match_score = await self._calculate_interest_match_score(message.processed_plain_text, keywords) interest_match_score = await self._calculate_interest_match_score(message.processed_plain_text, keywords)
logger.debug(f"兴趣匹配度: {interest_match_score:.3f}")
relationship_score = self._calculate_relationship_score(message.user_info.user_id) relationship_score = self._calculate_relationship_score(message.user_info.user_id)
logger.debug(f"关系分数: {relationship_score:.3f}")
mentioned_score = self._calculate_mentioned_score(message, bot_nickname) mentioned_score = self._calculate_mentioned_score(message, bot_nickname)
logger.debug(f"提及分数: {mentioned_score:.3f}")
total_score = ( total_score = (
interest_match_score * self.score_weights["interest_match"] interest_match_score * self.score_weights["interest_match"]
@@ -91,9 +85,10 @@ class InterestScoringSystem:
"mentioned": f"提及: {mentioned_score:.3f}", "mentioned": f"提及: {mentioned_score:.3f}",
} }
logger.info(f"消息 {message.message_id} 最终得分: {total_score:.3f}") logger.info(
logger.debug(f"Score weights: {self.score_weights}") f"消息 {message.message_id} 得分: {total_score:.3f} "
logger.debug(f"Score details: {details}") f"(匹配: {interest_match_score:.2f}, 关系: {relationship_score:.2f}, 提及: {mentioned_score:.2f})"
)
return InterestScore( return InterestScore(
message_id=message.message_id, message_id=message.message_id,
@@ -255,18 +250,19 @@ class InterestScoringSystem:
return 0.0 return 0.0
# 检查是否被提及 # 检查是否被提及
is_mentioned = msg.is_mentioned or (bot_nickname and bot_nickname in msg.processed_plain_text) bot_aliases = [bot_nickname] + global_config.bot.alias_names
is_mentioned = msg.is_mentioned or any(alias in msg.processed_plain_text for alias in bot_aliases if alias)
# 如果被提及或是私聊都视为提及了bot # 如果被提及或是私聊都视为提及了bot
if is_mentioned or not hasattr(msg, "chat_info_group_id"): if is_mentioned or not hasattr(msg, "chat_info_group_id"):
return global_config.affinity_flow.mention_bot_interest_score return global_config.affinity_flow.mention_bot_interest_score
return 0.0 return 0.0
def should_reply(self, score: InterestScore) -> bool: def should_reply(self, score: InterestScore, message: "DatabaseMessages") -> bool:
"""判断是否应该回复""" """判断是否应该回复"""
logger.info(f"评估消息 {score.message_id} (得分: {score.total_score:.3f}) 是否回复...") message_preview = f"\033[96m{(message.processed_plain_text or 'N/A')[:50].replace('\n', ' ')}\033[0m"
logger.info(f"评估消息 {score.message_id} (得分: {score.total_score:.3f}) | 内容: '{message_preview}...'")
base_threshold = self.reply_threshold base_threshold = self.reply_threshold
# 如果被提及,降低阈值 # 如果被提及,降低阈值

View File

@@ -404,8 +404,7 @@ class BotInterestManager:
if not self.current_interests or not self._initialized: if not self.current_interests or not self._initialized:
raise RuntimeError("❌ 兴趣标签系统未初始化") raise RuntimeError("❌ 兴趣标签系统未初始化")
logger.info("开始计算兴趣匹配度...") logger.debug(f"开始计算兴趣匹配度: 消息长度={len(message_text)}, 关键词数={len(keywords) if keywords else 0}")
logger.debug(f"消息长度: {len(message_text)}, 关键词: {len(keywords) if keywords else 0}")
message_id = f"msg_{datetime.now().timestamp()}" message_id = f"msg_{datetime.now().timestamp()}"
result = InterestMatchResult(message_id=message_id) result = InterestMatchResult(message_id=message_id)
@@ -415,7 +414,7 @@ class BotInterestManager:
if not active_tags: if not active_tags:
raise RuntimeError("没有检测到活跃的兴趣标签") raise RuntimeError("没有检测到活跃的兴趣标签")
logger.info(f"正在与 {len(active_tags)} 个兴趣标签进行匹配...") logger.debug(f"正在与 {len(active_tags)} 个兴趣标签进行匹配...")
# 生成消息的embedding # 生成消息的embedding
logger.debug("正在生成消息 embedding...") logger.debug("正在生成消息 embedding...")
@@ -450,9 +449,6 @@ class BotInterestManager:
match_count += 1 match_count += 1
high_similarity_count += 1 high_similarity_count += 1
result.add_match(tag.tag_name, enhanced_score, [tag.tag_name]) result.add_match(tag.tag_name, enhanced_score, [tag.tag_name])
logger.debug(
f" 🏷️ '{tag.tag_name}': 相似度={similarity:.3f}, 权重={tag.weight:.2f}, 基础分数={weighted_score:.3f}, 增强分数={enhanced_score:.3f} [高匹配]"
)
elif similarity > medium_threshold: elif similarity > medium_threshold:
# 中相似度:中等加成 # 中相似度:中等加成
@@ -460,9 +456,6 @@ class BotInterestManager:
match_count += 1 match_count += 1
medium_similarity_count += 1 medium_similarity_count += 1
result.add_match(tag.tag_name, enhanced_score, [tag.tag_name]) result.add_match(tag.tag_name, enhanced_score, [tag.tag_name])
logger.debug(
f" 🏷️ '{tag.tag_name}': 相似度={similarity:.3f}, 权重={tag.weight:.2f}, 基础分数={weighted_score:.3f}, 增强分数={enhanced_score:.3f} [中匹配]"
)
elif similarity > low_threshold: elif similarity > low_threshold:
# 低相似度:轻微加成 # 低相似度:轻微加成
@@ -470,9 +463,6 @@ class BotInterestManager:
match_count += 1 match_count += 1
low_similarity_count += 1 low_similarity_count += 1
result.add_match(tag.tag_name, enhanced_score, [tag.tag_name]) result.add_match(tag.tag_name, enhanced_score, [tag.tag_name])
logger.debug(
f" 🏷️ '{tag.tag_name}': 相似度={similarity:.3f}, 权重={tag.weight:.2f}, 基础分数={weighted_score:.3f}, 增强分数={enhanced_score:.3f} [低匹配]"
)
logger.info( logger.info(
f"匹配统计: {match_count}/{len(active_tags)} 个标签命中 | " f"匹配统计: {match_count}/{len(active_tags)} 个标签命中 | "

View File

@@ -124,7 +124,10 @@ class ActionPlanner:
# 3. 根据兴趣度调整可用动作 # 3. 根据兴趣度调整可用动作
if interest_scores: if interest_scores:
latest_score = max(interest_scores, key=lambda s: s.total_score) latest_score = max(interest_scores, key=lambda s: s.total_score)
should_reply, score = self.interest_scoring.should_reply(latest_score) latest_message = next(
(msg for msg in unread_messages if msg.message_id == latest_score.message_id), None
)
should_reply, score = self.interest_scoring.should_reply(latest_score, latest_message)
reply_not_available = False reply_not_available = False
if not should_reply and "reply" in initial_plan.available_actions: if not should_reply and "reply" in initial_plan.available_actions: