diff --git a/knowledge_base.py b/knowledge_base.py index 22ba59d..263523a 100644 --- a/knowledge_base.py +++ b/knowledge_base.py @@ -413,9 +413,16 @@ class KnowledgeBase: heading = doc.get("heading", "") body = doc.get("body", doc.get("content", "")) h_tokens = set(t for t in jieba.cut(heading) if len(t) >= 2) - # heading 包含查询关键词 → bonus + # heading 包含查询关键词 → bonus(5.0 每命中词,足够翻转 TF-IDF 差距) heading_hits = len(query_tokens & h_tokens) - bonus = heading_hits * 2.0 + bonus = heading_hits * 5.0 + # heading 包含查询连续短语 → 额外 bonus(如查询含"奖励配置"且 heading 含"奖励配置") + for qlen in range(min(len(query_stripped), 8), 3, -1): + for start in range(len(query_stripped) - qlen + 1): + phrase = query_stripped[start:start+qlen] + if len(phrase) >= 4 and phrase in heading: + bonus += 8.0 + break # 文档头部惩罚:heading 是单层 # + 文档名(如 "# php管理员后端"),且无 body if heading.startswith("# ") and (not body or len(body) < 50): bonus -= 5.0 diff --git a/monitor.py b/monitor.py index 024fd64..dda67d4 100644 --- a/monitor.py +++ b/monitor.py @@ -3481,9 +3481,14 @@ class MessageMonitor: else: win = None # 惰性创建:OCR 失败后需要 fallback 时再建 - # 3. 读消息 + # 3. 读消息(Windows OCR 同步阻塞,可能耗时 2-5s) texts = self._read_messages(win, platform) + # ⚠️ OCR 返回后立即检查急停标志:急停可能在 OCR 阻塞期间触发, + # Windows OCR 无法被中断,但后续文本处理可以立即跳过。 + if not self._running: + return + if not texts: # 截图未变→不计入空读,不触发清缓存 if self._ocr_unchanged.get(platform): @@ -3691,6 +3696,10 @@ class MessageMonitor: and not re.match(r'^\d{4}[/-]\d{1,2}', it.strip()) ] + # ⚠️ 文本处理后再次检查急停:防止急停在过滤阶段触发后仍触发回复 + if not self._running: + return + # 更新 last_texts 与签名 self._last_texts[platform] = list(texts) self._last_sig[platform] = sig