修复[知识库搜索]:排除链接文本干扰,防止php.md误匹配sdf1插件内容
- Task #1720: 修复兑换码插件怎么用查询返回php.md而非sdf1.md的问题 - 根因:php.md的链接文本[sdf1插件](sdf1.md)被误判为内容关键词 - 修复:auto_reply.py中排除链接文本进行核心词匹配 - 修复:使用body_no_links替代body_clean进行关键词匹配 - 修复:动作类查询要求标题和正文都包含核心词 - Task #1719: 修复旧消息被环形缓冲区淘汰后重新回复 - 修复:record_user_message()增加跨缓冲区查重 - 修复:第二关增加is_user_message_replied()检查
This commit is contained in:
+16
-5
@@ -196,9 +196,15 @@ class AutoReply:
|
||||
# ⭐ 移除代码块内容:避免配置示例/问答数据等代码块污染相关性检查
|
||||
# 修复"用户组是怎么配置的"被sdf1_game"题目配置格式"(body含代码块)误匹配的问题
|
||||
body_clean = re.sub(r'```.*?```', '', body_clean, flags=re.DOTALL)
|
||||
# ⭐ 移除整个链接(包括链接文本),用于核心词匹配
|
||||
# 防止php.md的"[sdf1插件](sdf1.md)"链接文本被误判为内容关键词
|
||||
# 链接文本是引用,不是真正的内容,不应参与核心词匹配
|
||||
body_no_links = _link.sub('', body).lower()
|
||||
body_no_links = re.sub(r'```.*?```', '', body_no_links, flags=re.DOTALL)
|
||||
|
||||
ht_tokens = AutoReply._meaningful_tokens(heading_clean + " " + title)
|
||||
body_tokens = AutoReply._meaningful_tokens(body_clean[:800])
|
||||
# ⭐ 使用body_no_links计算body_tokens,排除链接文本干扰
|
||||
body_tokens = AutoReply._meaningful_tokens(body_no_links[:800])
|
||||
has_ht = bool(q_mean & ht_tokens)
|
||||
has_body = bool(q_mean & body_tokens)
|
||||
|
||||
@@ -240,7 +246,8 @@ class AutoReply:
|
||||
# 规则:heading主体命中(has_ht) + body是表格(|分隔) + 查询动作词在表格中出现 → 放行
|
||||
_is_table_body = ('|' in (body or '')) or ('-|-' in (body or ''))
|
||||
# 注意:不能用 set(body_clean)——字符集不包含多字符词,须用子串判断
|
||||
_action_hits_body = any(kw in body_clean[:800] for kw in (q_mean & action_kw))
|
||||
# ⭐ 使用body_no_links进行动作词匹配,排除链接文本干扰
|
||||
_action_hits_body = any(kw in body_no_links[:800] for kw in (q_mean & action_kw))
|
||||
if has_ht and _is_table_body and _action_hits_body:
|
||||
logger.debug(
|
||||
f"动作查询表格兜底放行: query={query[:40]!r} "
|
||||
@@ -267,7 +274,8 @@ class AutoReply:
|
||||
has_body = has_body_nonaction
|
||||
|
||||
# ⭐ 后台/前台关键词区分:查询含"后台"但文档不含"后台"→ 不相关
|
||||
full = heading_clean + " " + title.lower() + " " + body_clean[:800]
|
||||
# ⭐ 使用body_no_links进行关键词匹配,排除链接文本干扰
|
||||
full = heading_clean + " " + title.lower() + " " + body_no_links[:800]
|
||||
# 注意:"管理后台"是整体概念,拆分后"后台"可能不在heading中,但"管理员"+"后端"已表达管理意图
|
||||
# 所以当heading含"管理员"或"后端"时,不应因缺"后台"而拒绝
|
||||
if "后台" in query and "后台" not in full:
|
||||
@@ -367,7 +375,9 @@ class AutoReply:
|
||||
# ⭐ OCR碎片过滤:纯ASCII且≤2字符的词(如"丿IJ"切成'ij')是OCR噪声
|
||||
# 不参与核心词覆盖判定——否则垃圾词抬高分母,真核心词反而达不到阈值
|
||||
core_kw = {kw for kw in core_kw if not (kw.isascii() and len(kw) <= 2)}
|
||||
doc_text = heading_clean + " " + title.lower() + " " + body_clean[:800]
|
||||
# ⭐ 使用body_no_links进行核心词匹配,排除链接文本干扰
|
||||
# 防止php.md的"[sdf1插件](sdf1.md)"链接文本被误判为内容关键词
|
||||
doc_text = heading_clean + " " + title.lower() + " " + body_no_links[:800]
|
||||
core_hits = sum(1 for kw in core_kw if kw in doc_text)
|
||||
|
||||
# ⭐ 下载意图检查提前到核心词检查之前
|
||||
@@ -523,7 +533,8 @@ class AutoReply:
|
||||
return True
|
||||
|
||||
# 子串回退:jieba 可能产生碎片 token,导致交集为空但文档确实含查询短语
|
||||
full = heading_clean + " " + title.lower() + " " + body_clean[:800]
|
||||
# ⭐ 使用body_no_links进行子串回退检查,排除链接文本干扰
|
||||
full = heading_clean + " " + title.lower() + " " + body_no_links[:800]
|
||||
stripped = re.sub(r'[??!!。,,\s]', '', query).lower()
|
||||
if len(stripped) >= 4:
|
||||
# ⭐ 修复:子串回退必须同时满足两个条件:
|
||||
|
||||
Reference in New Issue
Block a user