fix(kb): 子串回退要求至少一个meaningful_token命中,防止通用词泛匹配

问题:添加'服务器'停用词后,player.md的heading/body仍含'服务器'三字,
子串回退检查到'服务器的'(4字子串)命中文档→错误通过相关性检查。

修复:子串回退增加前置条件——必须至少有一个meaningful_token命中文档。
'服务器的'命中但'近期'/'公告'均未命中→拒绝。
'近期公告'命中且含meaningful_token'近期'/'公告'→通过。

效果:查询'服务器的近期公告有哪些?'现在正确匹配到index.md的'## 🔈近期公告'。
This commit is contained in:
youpaishidifu
2026-08-13 13:56:52 +08:00
parent 3e7ecf79a0
commit d0e3950d6c
+8
View File
@@ -208,6 +208,14 @@ class AutoReply:
full = heading_clean + " " + title.lower() + " " + body_clean[:800]
stripped = re.sub(r'[??!!。,,\s]', '', query).lower()
if len(stripped) >= 4:
# ⭐ 修复:子串回退必须同时满足两个条件:
# 1. 有有意义的子串(≥4字)命中文档
# 2. 至少有一个 meaningful_token 命中文档(防止"服务器"等通用词泛匹配)
has_meaningful_hit = bool(q_mean & (set(heading_clean) | set(title.lower()) | set(body_clean[:800])))
if not has_meaningful_hit:
# 没有 meaningful_token 命中,即使有子串匹配也拒绝
logger.debug(f"无有意义token命中拒绝: query={query[:40]!r} doc_heading={heading[:30]!r}")
return False
for qlen in range(min(len(stripped), 6), 3, -1):
for start in range(len(stripped) - qlen + 1):
phrase = stripped[start:start + qlen]