feat(chat): 优化提及检测并精简兴趣度评分日志
增强了机器人提及检测逻辑,使其能够识别配置文件中设置的所有别名(alias_names),而不仅仅是主昵称。这提高了交互的灵活性和准确性。 此外,还对兴趣度评分和匹配系统的日志输出进行了大幅重构: - 将多条评分计算日志合并为一条包含核心指标的摘要日志,使输出更简洁。 - 调整了部分日志级别,将非关键信息移至 DEBUG 级别,以减少日志噪音。 - 在关键日志中增加了消息内容预览,以便于快速上下文定位和调试。
This commit is contained in:
@@ -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
|
||||||
|
|
||||||
# 如果被提及,降低阈值
|
# 如果被提及,降低阈值
|
||||||
|
|||||||
@@ -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)} 个标签命中 | "
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
Reference in New Issue
Block a user