修复[相关检查]:纯停用词查询模糊子串回退,容忍OCR/输入噪声
- 问题:查询"关于我们儿"匹配到index.md"关于我们"(匹配度8.66)却未通过内容相关性检查,跳过回复。 - 根因:q_mean为空(关于/我们均为停用词)落入纯停用词分支,整串精确子串匹配"关于我们儿" in full失败即拒,多一个"儿"字符无法容忍。 - 修复:精确匹配失败后增加模糊子串回退——按stripped长度从大到小在full中查找连续片段,命中长度≥max(3, len*0.75)放行。 - 测试:单测4/4(案例+回归),真实KB端到端:index 8.66→True,beibao 2.24/sdf1 0.60→False。
This commit is contained in:
+32
-1
@@ -142,7 +142,38 @@ class AutoReply:
|
||||
if len(stripped) >= 2:
|
||||
full = (doc.get("heading", "") + " " + doc.get("title", "")
|
||||
+ " " + (doc.get("content", "") or doc.get("body", ""))).lower()
|
||||
return stripped in full
|
||||
if stripped in full:
|
||||
return True
|
||||
# ⭐ 模糊子串回退(2026-08-19):OCR/输入噪声导致 1~2 字符差异时
|
||||
# 仍应放行。例:查询"关于我们儿" vs 文档标题"关于我们"(多一个"儿")。
|
||||
# 纯停用词查询(q_mean 为空)整串匹配失败后,降级为 LCS 相似度检查——
|
||||
# 只要 stripped 的绝大部分字符能连续出现在 full 中即视为相关。
|
||||
# 复用子串回退思路,但此分支无 meaningful token 可依赖,直接查 LCS。
|
||||
_win = 0
|
||||
_src = stripped
|
||||
_tgt = full
|
||||
# LCS 长度 ≥ min(len(_src), len(_tgt)) * 0.75 且 ≥ 3 时放行
|
||||
# 用窗口滑动近似 LCS:以 stripped 的连续片段(len 从大到小)在 full 中查找
|
||||
for _qlen in range(len(_src), 2, -1):
|
||||
for _start in range(len(_src) - _qlen + 1):
|
||||
_phrase = _src[_start:_start + _qlen]
|
||||
if _phrase in _tgt:
|
||||
_win = _qlen
|
||||
break
|
||||
if _win:
|
||||
break
|
||||
if _win >= max(3, int(len(_src) * 0.75)):
|
||||
logger.debug(
|
||||
f"纯停用词查询模糊子串回退放行: query={query[:30]!r} "
|
||||
f"stripped={stripped[:30]!r} win_len={_win}/{len(_src)} "
|
||||
f"doc_heading={(doc.get('heading') or '')[:30]!r}"
|
||||
)
|
||||
return True
|
||||
logger.debug(
|
||||
f"纯停用词查询无共同子串拒绝: query={query[:30]!r} "
|
||||
f"stripped={stripped[:30]!r} win_len={_win}/{len(_src)} "
|
||||
f"doc_heading={(doc.get('heading') or '')[:30]!r}"
|
||||
)
|
||||
return False
|
||||
|
||||
_link = re.compile(r'\[([^\]]*)\]\([^\)]+\)')
|
||||
|
||||
Reference in New Issue
Block a user