feat(affinity-flow): 优化提及检测逻辑和阈值配置

- 简化提及检测逻辑,移除冗余的私聊检查变量
- 使用配置项 mention_bot_adjustment_threshold 替换硬编码的50%阈值
- 在消息处理中清除开头可能存在的空行
- 增加首次认识用户的信息存储方法,避免未知用户处理逻辑
- 调整消息管理器检查间隔从2秒到5秒,减少系统负载
- 修复计划执行器中用户ID比较逻辑,防止自我回复死循环
This commit is contained in:
Windpicker-owo
2025-09-21 18:01:38 +08:00
parent df3c616d09
commit ad729d74c8
6 changed files with 35 additions and 15 deletions

View File

@@ -270,14 +270,9 @@ class InterestScoringSystem:
# 检查是否被提及 # 检查是否被提及
is_mentioned = msg.is_mentioned or (bot_nickname and bot_nickname in msg.processed_plain_text) is_mentioned = msg.is_mentioned or (bot_nickname and bot_nickname in msg.processed_plain_text)
# 检查是否为私聊group_info为None表示私聊
is_private_chat = msg.group_info is None
# 如果被提及或是私聊都视为提及了bot # 如果被提及或是私聊都视为提及了bot
if is_mentioned or is_private_chat:
logger.debug(f"🔍 提及检测 - 被提及: {is_mentioned}, 私聊: {is_private_chat}") if is_mentioned or not hasattr(msg, "chat_info_group_id"):
if is_private_chat and not is_mentioned:
logger.debug("💬 私聊消息自动视为提及bot")
return global_config.affinity_flow.mention_bot_interest_score return global_config.affinity_flow.mention_bot_interest_score
return 0.0 return 0.0
@@ -297,7 +292,7 @@ class InterestScoringSystem:
# 如果被提及,降低阈值 # 如果被提及,降低阈值
if ( if (
score.mentioned_score >= global_config.affinity_flow.mention_bot_interest_score * 0.5 score.mentioned_score >= global_config.affinity_flow.mention_bot_adjustment_threshold
): # 使用提及bot兴趣分的一半作为判断阈值 ): # 使用提及bot兴趣分的一半作为判断阈值
base_threshold = self.mention_threshold base_threshold = self.mention_threshold
logger.debug(f"📣 消息提及了机器人,使用降低阈值: {base_threshold:.3f}") logger.debug(f"📣 消息提及了机器人,使用降低阈值: {base_threshold:.3f}")

View File

@@ -22,7 +22,7 @@ logger = get_logger("message_manager")
class MessageManager: class MessageManager:
"""消息管理器""" """消息管理器"""
def __init__(self, check_interval: float = 2.0): def __init__(self, check_interval: float = 5.0):
self.stream_contexts: Dict[str, StreamContext] = {} self.stream_contexts: Dict[str, StreamContext] = {}
self.check_interval = check_interval # 检查间隔(秒) self.check_interval = check_interval # 检查间隔(秒)
self.is_running = False self.is_running = False

View File

@@ -126,7 +126,7 @@ class PlanExecutor:
try: try:
logger.info(f"执行回复动作: {action_info.action_type}, 原因: {action_info.reasoning}") logger.info(f"执行回复动作: {action_info.action_type}, 原因: {action_info.reasoning}")
if action_info.action_message.user_info.user_id == str(global_config.bot.qq_account): if action_info.action_message.get("user_id", "") == str(global_config.bot.qq_account):
logger.warning("尝试回复自己,跳过此动作以防止死循环。") logger.warning("尝试回复自己,跳过此动作以防止死循环。")
return { return {
"action_type": action_info.action_type, "action_type": action_info.action_type,

View File

@@ -1051,10 +1051,12 @@ class DefaultReplyer:
# 如果person_name为None使用fallback值 # 如果person_name为None使用fallback值
if person_name is None: if person_name is None:
# 尝试从reply_message获取用户名 # 尝试从reply_message获取用户名
fallback_name = reply_message.get("user_nickname") or reply_message.get("user_id", "未知用户") await person_info_manager.first_knowing_some_one(
logger.warning(f"未知用户,将存储用户信息:{fallback_name}") platform, # type: ignore
person_name = str(fallback_name) reply_message.get("user_id"), # type: ignore
person_info_manager.set_value(person_id, "person_name", fallback_name) reply_message.get("user_nickname"),
reply_message.get("user_cardname")
)
# 检查是否是bot自己的名字如果是则替换为"(你)" # 检查是否是bot自己的名字如果是则替换为"(你)"
bot_user_id = str(global_config.bot.qq_account) bot_user_id = str(global_config.bot.qq_account)

View File

@@ -352,6 +352,8 @@ def process_llm_response(text: str, enable_splitter: bool = True, enable_chinese
sentences = [] sentences = []
for sentence in split_sentences: for sentence in split_sentences:
# 清除开头可能存在的空行
sentence = sentence.lstrip("\n").rstrip()
if global_config.chinese_typo.enable and enable_chinese_typo: if global_config.chinese_typo.enable and enable_chinese_typo:
typoed_text, typo_corrections = typo_generator.create_typo_sentence(sentence) typoed_text, typo_corrections = typo_generator.create_typo_sentence(sentence)
sentences.append(typoed_text) sentences.append(typoed_text)

View File

@@ -499,6 +499,27 @@ class PersonInfoManager:
logger.error(f"根据用户名 {person_name} 获取用户ID时出错 (SQLAlchemy): {e}") logger.error(f"根据用户名 {person_name} 获取用户ID时出错 (SQLAlchemy): {e}")
return "" return ""
@staticmethod
async def first_knowing_some_one(platform: str, user_id: str, user_nickname: str, user_cardname: str):
"""判断是否认识某人"""
person_id = PersonInfoManager.get_person_id(platform, user_id)
# 生成唯一的 person_name
person_info_manager = get_person_info_manager()
unique_nickname = await person_info_manager._generate_unique_person_name(user_nickname)
data = {
"platform": platform,
"user_id": user_id,
"nickname": user_nickname,
"konw_time": int(time.time()),
"person_name": unique_nickname, # 使用唯一的 person_name
}
# 先创建用户基本信息,使用安全创建方法避免竞态条件
await person_info_manager._safe_create_person_info(person_id=person_id, data=data)
# 更新昵称
await person_info_manager.update_one_field(
person_id=person_id, field_name="nickname", value=user_nickname, data=data
)
@staticmethod @staticmethod
async def create_person_info(person_id: str, data: Optional[dict] = None): async def create_person_info(person_id: str, data: Optional[dict] = None):
"""创建一个项""" """创建一个项"""