fix: Task #1693 修复新消息被旧消息盖过的两个bug
1. MAX_NEW_ITEMS截帽前按freshness_score降序排列 - 旧消息在OCR中排前面(顶部先读),不排序会把最新消息截掉 - 截帽前排序确保带新鲜时间戳的消息优先保留 2. 第二关DB查询改为查本条消息自身记录 - 旧消息通过get_latest_record_timestamp()搭上新消息的新鲜DB记录 - 导致旧消息time_diff≤300s通关,分数盖过真正的新消息 - 新增get_message_record_timestamp()查询本条消息自身的入库时间
This commit is contained in:
+54
-8
@@ -986,6 +986,44 @@ class MessageHistory:
|
|||||||
finally:
|
finally:
|
||||||
conn.close()
|
conn.close()
|
||||||
|
|
||||||
|
def get_message_record_timestamp(self, platform: str, text: str) -> Optional[datetime]:
|
||||||
|
"""获取特定消息的入库时间(用于第二关判断,防止旧消息搭便车)"""
|
||||||
|
# ⭐ Task #1693: 查询本条消息自身的 created_at,而非全局最新记录
|
||||||
|
self._ensure_user_messages_table()
|
||||||
|
conn = self._get_conn()
|
||||||
|
try:
|
||||||
|
# 使用模糊匹配:消息可能经过 OCR 噪声清理,与入库原文有微小差异
|
||||||
|
# 先尝试精确匹配,失败则用 LIKE 模糊匹配
|
||||||
|
cursor = conn.execute(
|
||||||
|
"SELECT created_at FROM user_messages WHERE platform=? AND content=? ORDER BY created_at DESC LIMIT 1",
|
||||||
|
(platform, text)
|
||||||
|
)
|
||||||
|
row = cursor.fetchone()
|
||||||
|
if row:
|
||||||
|
try:
|
||||||
|
return datetime.strptime(row[0], "%Y-%m-%d %H:%M:%S")
|
||||||
|
except (ValueError, TypeError):
|
||||||
|
return None
|
||||||
|
|
||||||
|
# 精确匹配失败:尝试模糊匹配(CJK 骨架子串)
|
||||||
|
# 提取消息的中文骨架,用 LIKE 查找包含该骨架的最近记录
|
||||||
|
cjk_skeleton = ''.join(c for c in text if '\u4e00' <= c <= '\u9fff')
|
||||||
|
if len(cjk_skeleton) >= 4:
|
||||||
|
cursor = conn.execute(
|
||||||
|
"SELECT created_at FROM user_messages WHERE platform=? AND content LIKE ? ORDER BY created_at DESC LIMIT 1",
|
||||||
|
(platform, f'%{cjk_skeleton}%')
|
||||||
|
)
|
||||||
|
row = cursor.fetchone()
|
||||||
|
if row:
|
||||||
|
try:
|
||||||
|
return datetime.strptime(row[0], "%Y-%m-%d %H:%M:%S")
|
||||||
|
except (ValueError, TypeError):
|
||||||
|
return None
|
||||||
|
|
||||||
|
return None
|
||||||
|
finally:
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
|
||||||
class MessageMonitor:
|
class MessageMonitor:
|
||||||
"""多线程消息监控器"""
|
"""多线程消息监控器"""
|
||||||
@@ -10724,7 +10762,11 @@ class MessageMonitor:
|
|||||||
self._seen_messages = set(list(seen)[-300:])
|
self._seen_messages = set(list(seen)[-300:])
|
||||||
|
|
||||||
# 单次 poll 最多处理 3 条新消息,防止系统消息海量涌入触发回环
|
# 单次 poll 最多处理 3 条新消息,防止系统消息海量涌入触发回环
|
||||||
|
# ⭐ Task #1693: 截帽前按 freshness_score 降序排列,确保带新鲜时间戳的消息
|
||||||
|
# 优先保留。旧消息(freshness<0)在 OCR 中排前面(顶部先读),
|
||||||
|
# 不排序会把最新消息截掉——恰好与预期相反。
|
||||||
MAX_NEW_ITEMS = 3
|
MAX_NEW_ITEMS = 3
|
||||||
|
new_items.sort(key=lambda it: freshness_scores.get(it.strip(), 0), reverse=True)
|
||||||
new_items = new_items[:MAX_NEW_ITEMS]
|
new_items = new_items[:MAX_NEW_ITEMS]
|
||||||
|
|
||||||
# 过滤纯时间/日期文本 → 不应进入 KB 匹配(OCR 时间戳分割遗留的噪音片段)
|
# 过滤纯时间/日期文本 → 不应进入 KB 匹配(OCR 时间戳分割遗留的噪音片段)
|
||||||
@@ -10975,14 +11017,18 @@ class MessageMonitor:
|
|||||||
logger.debug(f"[{platform}] 第一关未通过:无新鲜时间戳(自身),进入第二关: {item[:50]}")
|
logger.debug(f"[{platform}] 第一关未通过:无新鲜时间戳(自身),进入第二关: {item[:50]}")
|
||||||
|
|
||||||
# 第二关:查库判断
|
# 第二关:查库判断
|
||||||
|
# ⭐ Task #1693: 修复旧消息"搭便车"问题
|
||||||
|
# 旧消息通过 get_latest_record_timestamp() 搭上新消息的新鲜DB记录,
|
||||||
|
# 导致 time_diff≤300s → 通关 → 分数从15→20/18→23,盖过真正的新消息。
|
||||||
|
# 修复:改为查询「本条消息自身的 DB 记录」时间戳,而非全局最新记录。
|
||||||
if self._msg_history:
|
if self._msg_history:
|
||||||
latest_ts = self._msg_history.get_latest_record_timestamp(platform)
|
# 查询本条消息自身的入库时间(created_at)
|
||||||
has_record = self._msg_history.has_ocr_message_record(platform, cleaned_item)
|
my_record_ts = self._msg_history.get_message_record_timestamp(platform, cleaned_item)
|
||||||
|
|
||||||
if latest_ts is not None:
|
if my_record_ts is not None:
|
||||||
# 有数据库记录:计算本地时间与记录时间戳的差值
|
# 有本条消息的数据库记录:计算本地时间与记录时间戳的差值
|
||||||
time_diff_seconds = (datetime.now() - latest_ts).total_seconds()
|
time_diff_seconds = (datetime.now() - my_record_ts).total_seconds()
|
||||||
logger.debug(f"[{platform}] 第二关:有DB记录,时间差={time_diff_seconds:.0f}秒: {item[:50]}")
|
logger.debug(f"[{platform}] 第二关:有本条DB记录,时间差={time_diff_seconds:.0f}秒: {item[:50]}")
|
||||||
|
|
||||||
if time_diff_seconds <= 300:
|
if time_diff_seconds <= 300:
|
||||||
# 本地时间 - 记录时间戳 ≤ 300秒:通关
|
# 本地时间 - 记录时间戳 ≤ 300秒:通关
|
||||||
@@ -10994,9 +11040,9 @@ class MessageMonitor:
|
|||||||
score = -100.0
|
score = -100.0
|
||||||
logger.info(f"[{platform}] 第二关拦截:DB记录时间差{time_diff_seconds:.0f}秒>300秒,丢弃: {item[:50]}")
|
logger.info(f"[{platform}] 第二关拦截:DB记录时间差{time_diff_seconds:.0f}秒>300秒,丢弃: {item[:50]}")
|
||||||
else:
|
else:
|
||||||
# 无数据库记录:返团拦截
|
# 无本条消息的数据库记录:返团拦截
|
||||||
score = -100.0
|
score = -100.0
|
||||||
logger.info(f"[{platform}] 第二关拦截:无DB记录,丢弃: {item[:50]}")
|
logger.info(f"[{platform}] 第二关拦截:无本条消息DB记录,丢弃: {item[:50]}")
|
||||||
else:
|
else:
|
||||||
# msg_history不可用:强制丢弃
|
# msg_history不可用:强制丢弃
|
||||||
score = -100.0
|
score = -100.0
|
||||||
|
|||||||
Reference in New Issue
Block a user