feat(affinity-flow): 优化兴趣度评分和回复决策逻辑

- 降低回复阈值从0.6到0.55以增加回复可能性
- 在最终分数计算中加入标签数量奖励机制,每多匹配一个标签加0.05分,最高加0.3分
- 引入分级相似度匹配系统(高/中/低)并应用不同加成系数
- 增加关键词直接匹配奖励机制,支持完全匹配、包含匹配和部分匹配
- 在计划过滤器中处理回复动作不可用时的自动转换逻辑
- 增加兴趣度阈值80%检查,低于该阈值直接返回no_action
- 优化日志输出和统计信息,提供更详细的匹配分析
This commit is contained in:
Windpicker-owo
2025-09-17 20:50:03 +08:00
parent e1fcdf94ee
commit 9a2320944b
5 changed files with 167 additions and 24 deletions

View File

@@ -38,7 +38,7 @@ class PlanFilter:
)
self.last_obs_time_mark = 0.0
async def filter(self, plan: Plan) -> Plan:
async def filter(self, reply_not_available: bool, plan: Plan) -> Plan:
"""
执行筛选逻辑,并填充 Plan 对象的 decided_actions 字段。
"""
@@ -58,6 +58,16 @@ class PlanFilter:
prased_json = {"action": "no_action", "reason": "返回内容无法解析为JSON"}
logger.debug(f"墨墨在这里加了日志 -> 解析后的 JSON: {parsed_json}")
if "reply" in plan.available_actions and reply_not_available:
# 如果reply动作不可用但llm返回的仍然有reply则改为no_reply
if isinstance(parsed_json, dict) and parsed_json.get("action") == "reply":
parsed_json["action"] = "no_reply"
elif isinstance(parsed_json, list):
for item in parsed_json:
if isinstance(item, dict) and item.get("action") == "reply":
item["action"] = "no_reply"
item["reason"] += " (但由于兴趣度不足reply动作不可用已改为no_reply)"
if isinstance(parsed_json, dict):
parsed_json = [parsed_json]

View File

@@ -104,16 +104,38 @@ class ActionPlanner:
# 3. 根据兴趣度调整可用动作
if interest_scores:
latest_score = max(interest_scores, key=lambda s: s.total_score)
should_reply = self.interest_scoring.should_reply(latest_score)
should_reply, score = self.interest_scoring.should_reply(latest_score)
reply_not_available = False
if not should_reply and "reply" in initial_plan.available_actions:
logger.info(f"消息兴趣度不足({latest_score.total_score:.2f})移除reply动作")
del initial_plan.available_actions["reply"]
self.interest_scoring.record_reply_action(False)
else:
self.interest_scoring.record_reply_action(True)
# 4. 筛选 Plan
filtered_plan = await self.filter.filter(initial_plan)
reply_not_available = True
base_threshold = self.interest_scoring.reply_threshold
# 检查兴趣度是否达到阈值的0.8
threshold_requirement = base_threshold * 0.8
if score < threshold_requirement:
logger.info(f"❌ 兴趣度不足阈值的80%: {score:.3f} < {threshold_requirement:.3f}直接返回no_action")
logger.info(f"📊 最低要求: 阈值({base_threshold:.3f}) × 0.8 = {threshold_requirement:.3f}")
# 直接返回 no_action
no_action = {
"action_type": "no_action",
"reason": f"兴趣度评分 {score:.3f} 未达阈值80% {threshold_requirement:.3f}",
"action_data": {},
"action_message": None,
}
filtered_plan = initial_plan
filtered_plan.decided_actions = [no_action]
else:
# 4. 筛选 Plan
filtered_plan = await self.filter.filter(reply_not_available,initial_plan)
# 检查filtered_plan是否有reply动作以便记录reply action
has_reply_action = False
for decision in filtered_plan.decided_actions:
if decision.action_type == "reply":
has_reply_action = True
self.interest_scoring.record_reply_action(has_reply_action)
# 5. 使用 PlanExecutor 执行 Plan
execution_result = await self.executor.execute(filtered_plan)

View File

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