修复OCR残片入库问题:新增bot回复碎片检测

根因:
- 用户发送"关于我们@游戏专用"后,bot回复表格
- 下一轮OCR再次抓取同屏内容,把表格残片"端0(基岩版)"当成新消息
- 残片通过所有过滤(长度7有括号豁免短句检查,score=2放行)
- 残片入库后占用处理位置,导致真正的"关于我们"被跳过

修复:
在关键词打分前置增加bot回复碎片检测:
- 计算文本与已回复内容的最长公共子串占比
- 占比≥80%且长度≥3 → 判定为bot回复残片,直接丢弃
- 例:"端0(基岩版)" vs 已回复表格含"端口(基岩版) | 30679" → 公共子串相似度≥80% → 拦截
This commit is contained in:
youpaishidifu
2026-08-19 16:11:54 +08:00
parent dd21327806
commit 5982cadad6
+21
View File
@@ -8212,10 +8212,31 @@ 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
ocr_time = None
if self._keyword_scorer:
# 从文本中提取最近的时间戳(格式如'22:54:16')