From 3a7a05f97390cf836578e3c8147b934d500ca81a Mon Sep 17 00:00:00 2001 From: youpaishidifu Date: Mon, 27 Jul 2026 21:48:44 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=EF=BC=9AOCR=E5=85=A8=E8=A7=92?= =?UTF-8?q?=E6=8B=AC=E5=8F=B7md=E7=A2=8E=E7=89=87=E5=AF=BC=E8=87=B4KB?= =?UTF-8?q?=E6=AD=BB=E5=BE=AA=E7=8E=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 问题:OCR将英文括号识别为全角(()形式,[官方下载](?https... 此类碎片漏过 _is_markdown_document 检测,进入KB匹配触发回复。 修复: 1. _is_markdown_document: 新增 ]( 和 [text]( 检测(全角括号md链接) 2. OCR行级过滤: 新增 ]( 碎片丢弃 3. _extract_user_text_from_md_fragment: 新增全角括号md标记分割 4. KB scoring: 短查询(≤3分词)降权,防碎片得分反超真实消息 --- knowledge_base.py | 8 ++++++++ monitor.py | 17 ++++++++++++++++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/knowledge_base.py b/knowledge_base.py index cd3080a..c45a6f8 100644 --- a/knowledge_base.py +++ b/knowledge_base.py @@ -269,6 +269,14 @@ class KnowledgeBase: combined_scores = 0.7 * tfidf_scores + 0.3 * keyword_scores + # 短查询惩罚:分词数 ≤2 的短查询(如图标残片/短词)得分大幅降权 + # 防止 OCR 碎片中的高 IDF 词(如"下载")获得超过真实用户消息的分数 + n_tokens = len(tokens) + if n_tokens <= 2: + combined_scores *= 0.3 + elif n_tokens <= 3: + combined_scores *= 0.6 + # 按文档聚合:取各文档下的最高 section 分作为文档分 # 同时统计匹配 section 数量,用于后续排序(section 多的文档更可能是主文档) doc_best = {} diff --git a/monitor.py b/monitor.py index 36ae8bc..a4ea15f 100644 --- a/monitor.py +++ b/monitor.py @@ -1073,6 +1073,10 @@ class MessageMonitor: if len(re.findall(r'\[\s*[VXvx√✗]\s*\]', line)) >= 2: logger.debug(f"[{platform}] OCR 过滤: 多checkbox碎片 line={line!r}") continue + # 全角括号 md 链接碎片:`[text](url` 或 `](` — md 链接 OCR 全角退化 + if re.search(r'\](', line): + logger.debug(f"[{platform}] OCR 过滤: 全角括号碎片 line={line!r}") + continue if re.match(r'^\d{1,2}[::\s]\d{1,2}', line): continue if re.match(r'^\d{4}[/-]\d{1,2}', line): @@ -1431,6 +1435,11 @@ class MessageMonitor: # # 行首标题:短文本也检测(OCR 把 ##协议修 切成 5 字符片段) if re.match(r'^#{1,6}(?:\s|\[|[\u4e00-\u9fff])', text): return True + # 全角括号退化 md 链接:短文本也检测 + if re.search(r'\](', text): + return True + if re.search(r'\[.+?\](', text): + return True if len(text) < 10: return False # ##直接跟汉字(OCR 丢失 ##后空格时常见:##文档导航) @@ -1475,6 +1484,9 @@ class MessageMonitor: # ── 整段以 ## 开头 → 无用户文本(无空格 ##中文 也捕获)── if re.match(r'^#{1,6}(?:\s|\[|[\u4e00-\u9fff])', text): return [] + # 整段以 [text]( 开头 → 全角括号 md 链接碎片,无用户文本 + if re.match(r'^\[.+?\](', text): + return [] # ── 找第一个 markdown 起始标记的位置 ── # 标记:## 标题、[text](url)、.md)、| 表格分隔、``` 代码块 @@ -1485,8 +1497,11 @@ class MessageMonitor: if m and m.start() < md_start: md_start = m.start() - # [text](url) 链接 + # [text](url) 链接(含全角括号退化 [text](url)) m = re.search(r'(?<=\S)\s*\[.+?\]\(.+?\)', text) + if m and m.start() < md_start: + md_start = m.start() + m = re.search(r'(?<=\S)\s*\[.+?\](.+?)', text) if m and m.start() < md_start: md_start = m.start()