修复EasyOCR超时导致消息丢失:增大外层超时到50s,混合消息检测改为提取最后一条消息
This commit is contained in:
@@ -1043,6 +1043,29 @@ class MsgBotApp(ctk.CTk):
|
||||
# 原来只选第一个通过的,导致 protect"温馨提示"(score高但内容浅)压过 sdf1_login"2.1下载"(score略低但内容深)
|
||||
chosen = None
|
||||
if self.ar.enabled:
|
||||
# 提取query的核心词(复用auto_reply的逻辑)
|
||||
q_tokens = AutoReply._meaningful_tokens(cleaned_msg)
|
||||
# 非核心词(复制自auto_reply.py)
|
||||
non_core_kw = {
|
||||
'多少', '哪些', '哪个', '什么', '怎么', '如何', '吗', '呢', '吧',
|
||||
'备用', '深险', '端的', '那', '这', '些', '个', '种', '类',
|
||||
'最近', '近期', '刚才', '现在', '当前', '刚刚', '以前', '之后', '当天',
|
||||
'第一', '最新', '全部', '所有', '一起', '各种', '各种各样',
|
||||
'哪些', '哪个', '什么', '怎么', '如何', '多少',
|
||||
'相关联', '相关', '有关', '以及', '以及',
|
||||
'问问', '问一嘴', '打听一下', '能够', '可以到',
|
||||
'有个', '问题', '常用', '他们', '各位', '大家', '小伙伴',
|
||||
'知道', '想知道',
|
||||
'下载', '下到', '哪下', '在哪下', '怎么下',
|
||||
'信息', '内容', '详情', '情况', '介绍',
|
||||
'一句', '问一句', '再问',
|
||||
'有人',
|
||||
'一嘴',
|
||||
'那家', '那价',
|
||||
}
|
||||
core_kw = q_tokens - non_core_kw
|
||||
# OCR碎片过滤
|
||||
core_kw = {kw for kw in core_kw if not (kw.isascii() and len(kw) <= 2)}
|
||||
# 收集所有通过相关性检查的候选
|
||||
relevant_candidates = []
|
||||
for idx, (doc, sc) in enumerate(results):
|
||||
@@ -1078,7 +1101,13 @@ class MsgBotApp(ctk.CTk):
|
||||
else:
|
||||
quality_score = sc + body_len / 100.0
|
||||
else:
|
||||
quality_score = sc + body_len / 100.0 # 其他查询,body长度加权
|
||||
# 计算heading核心词命中奖励
|
||||
heading_text = (doc.get('heading') or '').lower()
|
||||
heading_hits = sum(1 for kw in core_kw if kw in heading_text)
|
||||
heading_bonus = heading_hits * 10.0 # 每个核心词命中heading加10分
|
||||
# 表格body加分(非下载查询也适用)
|
||||
table_bonus = 5.0 if is_table_body else 0.0
|
||||
quality_score = sc + body_len / 100.0 + heading_bonus + table_bonus
|
||||
relevant_candidates.append((quality_score, sc, doc))
|
||||
|
||||
if relevant_candidates:
|
||||
|
||||
+17
-4
@@ -2625,7 +2625,7 @@ class MessageMonitor:
|
||||
pass
|
||||
# 其他异常静默处理
|
||||
|
||||
_OCR_TIMEOUT = 10.0 # 总超时秒数(单次OCR请求)- 必须在 _easy_worker 之前定义
|
||||
_OCR_TIMEOUT = 50.0 # 总超时秒数(单次OCR请求)- 必须在 _easy_worker 之前定义
|
||||
|
||||
def _easy_worker():
|
||||
if not _HAS_EASYOCR or self._easyocr_broken:
|
||||
@@ -2675,13 +2675,26 @@ class MessageMonitor:
|
||||
et = easy_text[0]
|
||||
|
||||
# ⭐ EasyOCR超时+Windows OCR混合消息检测:当EasyOCR超时且Windows OCR结果包含
|
||||
# 多个时间戳(表明是多条消息混合),返回空结果,避免消息搅和
|
||||
# 多个时间戳(表明是多条消息混合),提取最后一条消息而非丢弃整个结果
|
||||
if not et and wt:
|
||||
timestamps = re.findall(r'\d{1,2}:\d{1,2}', wt)
|
||||
if len(timestamps) >= 2:
|
||||
logger.warning(f"[{platform}] EasyOCR超时+Windows OCR检测到{len(timestamps)}个时间戳"
|
||||
f"({timestamps[:3]}...),疑似消息混合,跳过本轮避免搅和")
|
||||
return ("", "")
|
||||
f"({timestamps[:3]}...),提取最后一条消息避免搅和")
|
||||
# 提取最后一条消息:找到最后一个时间戳的位置,截取其后内容
|
||||
last_ts_pos = -1
|
||||
for m in re.finditer(r'\d{1,2}:\d{1,2}', wt):
|
||||
last_ts_pos = m.start()
|
||||
if last_ts_pos >= 0:
|
||||
# 截取从最后一个时间戳到末尾的文本
|
||||
extracted = wt[last_ts_pos:].strip()
|
||||
if extracted:
|
||||
wt = extracted
|
||||
logger.info(f"[{platform}] 提取最后一条消息: {wt[:100]!r}")
|
||||
else:
|
||||
logger.warning(f"[{platform}] 提取最后一条消息为空,保留原文本")
|
||||
else:
|
||||
logger.warning(f"[{platform}] 未找到时间戳位置,保留原文本")
|
||||
|
||||
# 日志(原始输出逐行记录,用於長期對比兩引擎能力)
|
||||
if wt:
|
||||
|
||||
Reference in New Issue
Block a user