修复OCR残片入库:在基线轮前统一过滤bot回复碎片
问题: - 之前的检测代码在关键词打分循环中,但score=0的残片通过了打分 - 然后进入基线轮判断,被标记为"基线"跳过但仍在new_items中 - 同轮择优时又被选上,导致残片入库 修复: 将碎片检测移至基线轮判断之前(约8261行),对new_items统一过滤 - 计算文本与已回复内容的最长公共子串占比 - 占比≥80%且长度≥3 → 直接丢弃 - 例:"端0(基岩版)" vs 已回复表格"端口(基岩版)" → 相似度85.7% → 拦截
This commit is contained in:
+30
-21
@@ -8212,31 +8212,11 @@ class MessageMonitor:
|
||||
|
||||
# ⭐ Task #1558 新逻辑: 关键词打分前置(所有消息必须先打分)
|
||||
# 流程:
|
||||
# 0. bot回复碎片检测(新增):如果文本与已回复内容高度重叠(相似度≥80%),直接丢弃
|
||||
# 防止OCR把bot回复表格残片(如"端0(基岩版)")当成用户消息处理
|
||||
# 1. 提取OCR时间戳(用于时间比较)
|
||||
# 2. 调用关键词打分器 → ≤1分无条件放行,≥1分时间比较
|
||||
# 3. 时间比较:OCR时间 vs 系统时间(差值≤10秒用OCR,否则用系统时间)
|
||||
# 4. 判断:当前时间 > DB落库时间+5分钟 → 放行,否则拦截
|
||||
|
||||
# ⭐ 新增:bot回复碎片检测(防止OCR残片入库)
|
||||
if self._replied_texts and len(ts) >= 3:
|
||||
import difflib
|
||||
t_norm = self._norm_frag(ts)
|
||||
for r in self._replied_texts:
|
||||
if len(r) < 5:
|
||||
continue
|
||||
r_norm = self._norm_frag(r)
|
||||
if not t_norm or not r_norm:
|
||||
continue
|
||||
# 计算最长公共子串占比
|
||||
sm = difflib.SequenceMatcher(None, t_norm, r_norm)
|
||||
lm = sm.find_longest_match(0, len(t_norm), 0, len(r_norm)).size
|
||||
# 如果最长公共子串占文本≥80%,认为是bot回复残片
|
||||
if lm >= 0.8 * len(t_norm) and lm >= 3:
|
||||
logger.debug(f"[{platform}] OCR过滤: bot回复碎片(相似度≥80%) ts={ts!r}")
|
||||
seen.add(ts)
|
||||
break
|
||||
# (bot回复碎片检测已在上方统一过滤,此处无需重复)
|
||||
ocr_time = None
|
||||
if self._keyword_scorer:
|
||||
# 从文本中提取最近的时间戳(格式如'22:54:16')
|
||||
@@ -8278,6 +8258,35 @@ class MessageMonitor:
|
||||
and not re.match(r'^\d{4}[/-]\d{1,2}', it.strip())
|
||||
]
|
||||
|
||||
# ⭐ 新增:bot回复碎片检测(在基线轮判断之前过滤,防止OCR残片入库)
|
||||
# 如果文本与已回复内容高度重叠(相似度≥80%),直接丢弃
|
||||
# 例:"端0(基岩版)" vs 已回复表格含"端口(基岩版) | 30679" → 相似度≥80% → 拦截
|
||||
if self._replied_texts:
|
||||
import difflib
|
||||
filtered_new_items = []
|
||||
for item in new_items:
|
||||
ts = item.strip()
|
||||
if len(ts) < 3:
|
||||
filtered_new_items.append(item)
|
||||
continue
|
||||
is_fragment = False
|
||||
t_norm = self._norm_frag(ts)
|
||||
for r in self._replied_texts:
|
||||
if len(r) < 5:
|
||||
continue
|
||||
r_norm = self._norm_frag(r)
|
||||
if not t_norm or not r_norm:
|
||||
continue
|
||||
sm = difflib.SequenceMatcher(None, t_norm, r_norm)
|
||||
lm = sm.find_longest_match(0, len(t_norm), 0, len(r_norm)).size
|
||||
if lm >= 0.8 * len(t_norm) and lm >= 3:
|
||||
logger.debug(f"[{platform}] OCR过滤: bot回复碎片(相似度≥80%) ts={ts!r}")
|
||||
is_fragment = True
|
||||
break
|
||||
if not is_fragment:
|
||||
filtered_new_items.append(item)
|
||||
new_items = filtered_new_items
|
||||
|
||||
# ⚠️ 文本处理后再次检查急停:防止急停在过滤阶段触发后仍触发回复
|
||||
if not self._running:
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user