修订时间戳新鲜度评分逻辑:≥5分直接放行,<5分查DB决定是否补分到5
This commit is contained in:
+81
-10
@@ -595,6 +595,20 @@ class MessageHistory:
|
||||
finally:
|
||||
conn.close()
|
||||
|
||||
def has_ocr_message_record(self, platform: str, content: str) -> bool:
|
||||
"""检查OCR暂存表中是否已存在该消息的记录(用于时间戳新鲜度评分逻辑)"""
|
||||
content_hash = hashlib.md5(content.strip().encode('utf-8')).hexdigest()
|
||||
conn = self._get_conn()
|
||||
try:
|
||||
cursor = conn.execute(
|
||||
"SELECT COUNT(*) FROM ocr_staging WHERE platform=? AND content_hash=?",
|
||||
(platform, content_hash)
|
||||
)
|
||||
count = cursor.fetchone()[0]
|
||||
return count > 0
|
||||
finally:
|
||||
conn.close()
|
||||
|
||||
|
||||
class MessageMonitor:
|
||||
"""多线程消息监控器"""
|
||||
@@ -6747,6 +6761,45 @@ class MessageMonitor:
|
||||
diff = (now - parsed).total_seconds()
|
||||
return max(diff, 0)
|
||||
|
||||
def _timestamp_freshness_score(self, text: str) -> float:
|
||||
"""计算消息的时间戳新鲜度分数。
|
||||
|
||||
以系统当前时间为基准,根据时间戳与当前时间的接近程度给分:
|
||||
- 5分钟内(300秒):+5分
|
||||
- 10分钟内(600秒):+4分
|
||||
- 30分钟内(1800秒):+3分
|
||||
- 1小时内(3600秒):+2分
|
||||
- 2小时内(7200秒):+1分
|
||||
- 超过2小时或无时间戳:+0分
|
||||
|
||||
所有有时间戳的消息都至少+1分(2小时内),确保时间戳新鲜度作为加分项。
|
||||
"""
|
||||
# 从文本中提取时间戳
|
||||
timestamps = re.findall(r'\d{1,2}:\d{1,2}(?::\d{1,2})?', text)
|
||||
if not timestamps:
|
||||
return 0.0
|
||||
|
||||
# 取最后一个时间戳(通常是最新消息的时间戳)
|
||||
ts_str = timestamps[-1]
|
||||
age_seconds = self._timestamp_age_seconds(ts_str)
|
||||
|
||||
if age_seconds is None:
|
||||
return 0.0
|
||||
|
||||
# 根据时间差给分(越接近得分越高)
|
||||
if age_seconds <= 300: # 5分钟内
|
||||
return 5.0
|
||||
elif age_seconds <= 600: # 10分钟内
|
||||
return 4.0
|
||||
elif age_seconds <= 1800: # 30分钟内
|
||||
return 3.0
|
||||
elif age_seconds <= 3600: # 1小时内
|
||||
return 2.0
|
||||
elif age_seconds <= 7200: # 2小时内
|
||||
return 1.0
|
||||
else:
|
||||
return 0.0
|
||||
|
||||
@staticmethod
|
||||
def _is_system_message(text: str) -> bool:
|
||||
"""过滤机器人/系统消息,不作为用户消息处理。"""
|
||||
@@ -9022,10 +9075,16 @@ class MessageMonitor:
|
||||
except Exception as e:
|
||||
logger.error(f"[{platform}] 获取近5分钟回复失败: {e}")
|
||||
new_items = []
|
||||
# ⭐ 时间戳新鲜度评分:在关键词打分和查重之前计算,作为加分项
|
||||
freshness_scores = {} # 存储每条消息的时间戳新鲜度分数
|
||||
for t in texts:
|
||||
ts = t.strip()
|
||||
if not ts:
|
||||
continue
|
||||
# 计算时间戳新鲜度分数(作为后续综合得分的加分项)
|
||||
freshness_score = self._timestamp_freshness_score(ts)
|
||||
# 存储原始文本和新鲜度分数
|
||||
freshness_scores[ts] = freshness_score
|
||||
# === URL-only 兜底:无中文且含 URL → 碎片 ===
|
||||
if not re.search(r'[\u4e00-\u9fff]', ts) and re.search(r'https?\S', ts, re.IGNORECASE):
|
||||
logger.debug(f"[{platform}] Poll过滤: URL-only碎片 ts={ts!r}")
|
||||
@@ -9658,8 +9717,25 @@ class MessageMonitor:
|
||||
continue
|
||||
# ⭐ 添加到候选列表(含质量分)
|
||||
score = self._score_message_quality(cleaned_item)
|
||||
# ⭐ Task #1609: 时间戳新鲜度奖励——优先处理最新消息
|
||||
# 从原始文本中提取时间戳,计算与当前时间的差值
|
||||
# ⭐ 时间戳新鲜度奖励:使用预先计算的freshness_score
|
||||
# 从freshness_scores字典中获取当前消息的时间戳新鲜度分数
|
||||
freshness_score = freshness_scores.get(item, 0.0)
|
||||
# 修订逻辑:≥5分直接放行,<5分查DB决定是否补分到5
|
||||
if freshness_score >= 5:
|
||||
# ≥5分:直接放行,加上5分
|
||||
score += 5.0
|
||||
if freshness_score > 0:
|
||||
logger.info(f"[{platform}] 时间戳新鲜度≥5直接放行(+5): {item[:50]}")
|
||||
else:
|
||||
# <5分:查DB
|
||||
if self._msg_history and self._msg_history.has_ocr_message_record(platform, cleaned_item):
|
||||
# DB有记录:不加分
|
||||
logger.info(f"[{platform}] 时间戳新鲜度<5且DB有记录,不加分: {item[:50]}")
|
||||
else:
|
||||
# DB无记录:补分到5
|
||||
score += 5.0
|
||||
logger.info(f"[{platform}] 时间戳新鲜度<5且DB无记录,补分到5: {item[:50]}")
|
||||
# 保留原有时间戳差值计算(用于排序)
|
||||
_ts_match = re.search(r'(\d{1,2}):(\d{1,2})(?::(\d{1,2}))?', item)
|
||||
if _ts_match:
|
||||
_h, _m = int(_ts_match.group(1)), int(_ts_match.group(2))
|
||||
@@ -9671,14 +9747,9 @@ class MessageMonitor:
|
||||
# 如果差值为负,说明时间戳跨天(如23:59 vs 00:01),视为很旧
|
||||
if _diff < 0:
|
||||
_diff += 86400
|
||||
# 新鲜度奖励:≤300秒+5分,≤600秒+3分,≤1800秒+1分
|
||||
if _diff <= 300:
|
||||
score += 5.0
|
||||
elif _diff <= 600:
|
||||
score += 3.0
|
||||
elif _diff <= 1800:
|
||||
score += 1.0
|
||||
_candidates.append((score, item, cleaned_item, _diff if _ts_match else 86400))
|
||||
else:
|
||||
_diff = 86400 # 无时间戳,视为很旧
|
||||
_candidates.append((score, item, cleaned_item, _diff))
|
||||
|
||||
# ⭐ 同轮择优:只选质量分最高的那条消息触发回复
|
||||
if _candidates:
|
||||
|
||||
Reference in New Issue
Block a user