feat(affinity-flow): 调整回复概率参数和评分计算

- 增加最大不回复次数至15次,降低每次不回复的概率提升至1%
- 在最终评分计算中增加1.15倍系数提升
- 被提及时的基础分数从1.0提升至3.0
- 为兴趣标签保存添加数据库验证机制
- 在消息处理流程中增加数据库存储功能
- 修复JSON解析错误处理,增加异常情况下的默认响应
- 优化数据库会话管理和模型转换的健壮性
This commit is contained in:
Windpicker-owo
2025-09-17 13:37:57 +08:00
committed by Windpicker-owo
parent dcdef633e0
commit e1fcdf94ee
8 changed files with 44 additions and 14 deletions

View File

@@ -35,8 +35,8 @@ class InterestScoringSystem:
# 连续不回复概率提升 # 连续不回复概率提升
self.no_reply_count = 0 self.no_reply_count = 0
self.max_no_reply_count = 5 self.max_no_reply_count = 15
self.probability_boost_per_no_reply = 0.15 # 每次不回复增加15%概率 self.probability_boost_per_no_reply = 0.01 # 每次不回复增加15%概率
# 用户关系数据 # 用户关系数据
self.user_relationships: Dict[str, float] = {} # user_id -> relationship_score self.user_relationships: Dict[str, float] = {} # user_id -> relationship_score
@@ -148,7 +148,7 @@ class InterestScoringSystem:
logger.debug(f" 🔢 匹配详情: {match_result.match_scores}") logger.debug(f" 🔢 匹配详情: {match_result.match_scores}")
# 返回匹配分数,考虑置信度 # 返回匹配分数,考虑置信度
final_score = match_result.overall_score * match_result.confidence final_score = match_result.overall_score * 1.15 * match_result.confidence
logger.debug(f"⚖️ 最终分数(总分×置信度): {final_score:.3f}") logger.debug(f"⚖️ 最终分数(总分×置信度): {final_score:.3f}")
return final_score return final_score
else: else:
@@ -226,7 +226,7 @@ class InterestScoringSystem:
return 0.0 return 0.0
if msg.is_mentioned or (bot_nickname and bot_nickname in msg.processed_plain_text): if msg.is_mentioned or (bot_nickname and bot_nickname in msg.processed_plain_text):
return 1.0 return 3.0
return 0.0 return 0.0
@@ -258,6 +258,7 @@ class InterestScoringSystem:
logger.debug(f" 🎯 有效阈值: {effective_threshold:.3f}") logger.debug(f" 🎯 有效阈值: {effective_threshold:.3f}")
# 做出决策 # 做出决策
score.total_score = score.total_score * 1
should_reply = score.total_score >= effective_threshold should_reply = score.total_score >= effective_threshold
decision = "✅ 应该回复" if should_reply else "❌ 不回复" decision = "✅ 应该回复" if should_reply else "❌ 不回复"

View File

@@ -611,6 +611,19 @@ class BotInterestManager:
logger.info("✅ 兴趣标签已成功保存到数据库") logger.info("✅ 兴趣标签已成功保存到数据库")
# 验证保存是否成功
with get_db_session() as session:
saved_record = session.query(DBBotPersonalityInterests).filter(
DBBotPersonalityInterests.personality_id == interests.personality_id
).first()
session.commit()
if saved_record:
logger.info(f"✅ 验证成功数据库中存在personality_id为 {interests.personality_id} 的记录")
logger.info(f" 版本: {saved_record.version}")
logger.info(f" 最后更新: {saved_record.last_updated}")
else:
logger.error(f"❌ 验证失败数据库中未找到personality_id为 {interests.personality_id} 的记录")
except Exception as e: except Exception as e:
logger.error(f"❌ 保存兴趣标签到数据库失败: {e}") logger.error(f"❌ 保存兴趣标签到数据库失败: {e}")
logger.error("🔍 错误详情:") logger.error("🔍 错误详情:")

View File

@@ -478,7 +478,17 @@ class ChatBot:
template_group_name = None template_group_name = None
async def preprocess(): async def preprocess():
# 使用消息管理器处理消息 # 存储消息到数据库
from .storage import MessageStorage
try:
await MessageStorage.store_message(message, message.chat_stream)
logger.debug(f"消息已存储到数据库: {message.message_info.message_id}")
except Exception as e:
logger.error(f"存储消息到数据库失败: {e}")
traceback.print_exc()
# 使用消息管理器处理消息(保持原有功能)
from src.common.data_models.database_data_model import DatabaseMessages from src.common.data_models.database_data_model import DatabaseMessages
# 创建数据库消息对象 # 创建数据库消息对象

View File

@@ -174,8 +174,6 @@ class MessageStorage:
await session.execute( await session.execute(
update(Messages).where(Messages.id == matched_message.id).values(message_id=qq_message_id) update(Messages).where(Messages.id == matched_message.id).values(message_id=qq_message_id)
) )
await session.commit()
# 会在上下文管理器中自动调用
logger.debug(f"更新消息ID成功: {matched_message.message_id} -> {qq_message_id}") logger.debug(f"更新消息ID成功: {matched_message.message_id} -> {qq_message_id}")
else: else:
logger.warning(f"未找到匹配的消息记录: {mmc_message_id}") logger.warning(f"未找到匹配的消息记录: {mmc_message_id}")
@@ -211,10 +209,7 @@ class MessageStorage:
select(Images).where(Images.description == description).order_by(desc(Images.timestamp)) select(Images).where(Images.description == description).order_by(desc(Images.timestamp))
) )
).scalar() ).scalar()
if image_record: return f"[picid:{image_record.image_id}]" if image_record else match.group(0)
new_text += f"[picid:{image_record.image_id}]"
else:
new_text += match.group(0)
except Exception: except Exception:
new_text += match.group(0) new_text += match.group(0)
last_end = match.end() last_end = match.end()

View File

@@ -51,8 +51,11 @@ class PlanFilter:
llm_content, _ = await self.planner_llm.generate_response_async(prompt=prompt) llm_content, _ = await self.planner_llm.generate_response_async(prompt=prompt)
if llm_content: if llm_content:
logger.info(f"规划器原始返回: {llm_content}") logger.debug(f"墨墨在这里加了日志 -> LLM a原始返回: {llm_content}")
parsed_json = orjson.loads(repair_json(llm_content)) try:
parsed_json = orjson.loads(repair_json(llm_content))
except orjson.JSONDecodeError:
prased_json = {"action": "no_action", "reason": "返回内容无法解析为JSON"}
logger.debug(f"墨墨在这里加了日志 -> 解析后的 JSON: {parsed_json}") logger.debug(f"墨墨在这里加了日志 -> 解析后的 JSON: {parsed_json}")
if isinstance(parsed_json, dict): if isinstance(parsed_json, dict):

View File

@@ -41,6 +41,7 @@ def init_prompts():
4. 如果用户明确要求了某个动作,请务必优先满足。 4. 如果用户明确要求了某个动作,请务必优先满足。
**如果可选动作中没有reply请不要使用** **如果可选动作中没有reply请不要使用**
**反之如果可选动作中有reply应尽量考虑使用不过也要考虑当前情景**
**可用动作:** **可用动作:**
{actions_before_now_block} {actions_before_now_block}

View File

@@ -691,6 +691,7 @@ async def get_db_session() -> AsyncGenerator[AsyncSession, None]:
raise RuntimeError("Database session not initialized") raise RuntimeError("Database session not initialized")
session = SessionLocal() session = SessionLocal()
yield session yield session
#session.commit()
except Exception: except Exception:
if session: if session:
await session.rollback() await session.rollback()

View File

@@ -22,7 +22,12 @@ def _model_to_dict(instance: Base) -> Dict[str, Any]:
""" """
将 SQLAlchemy 模型实例转换为字典。 将 SQLAlchemy 模型实例转换为字典。
""" """
return {col.name: getattr(instance, col.name) for col in instance.__table__.columns} try:
return {col.name: getattr(instance, col.name) for col in instance.__table__.columns}
except Exception as e:
# 如果对象已经脱离会话尝试从instance.__dict__中获取数据
logger.warning(f"从数据库对象获取属性失败尝试使用__dict__: {e}")
return {col.name: instance.__dict__.get(col.name) for col in instance.__table__.columns}
async def find_messages( async def find_messages(
@@ -133,6 +138,7 @@ async def find_messages(
logger.error(f"执行无限制查询失败: {e}") logger.error(f"执行无限制查询失败: {e}")
results = [] results = []
# 在会话内将结果转换为字典,避免会话分离错误
return [_model_to_dict(msg) for msg in results] return [_model_to_dict(msg) for msg in results]
except Exception as e: except Exception as e:
log_message = ( log_message = (