fix: 修复下载类查询被URL路径误匹配的问题

问题:
- 用户问"那个登录插件去哪下载",beibao.md(背包插件)被错误选中
- 下载意图检查正确拒绝了beibao(因为不含"登录"核心词)
- 但子串回退逻辑却放行了:因为"插件"出现在URL路径 /plugin/ 中

根因:
子串回退检查phrase in full时,没有排除URL路径中的匹配
导致通用词"插件"在URL中出现就误判为相关文档

修复:
1. 下载类查询要求:核心名词短语(如"登录")必须在文档正文中出现
   不能只是"插件"这种通用词在URL路径中命中
2. 如果核心名词未命中,直接拒绝子串回退
3. 额外检查:如果phrase只在URL中出现,也拒绝

测试预期:
- '那个登录插件去哪下载' → beibao拒绝(不含"登录"),sdf1_login通过(含"登录")
- '哪个插件下载' → beibao可能通过(只有"插件"通用词)
This commit is contained in:
youpaishidifu
2026-08-17 09:22:08 +08:00
parent 4acbea8440
commit ecadaaa9ae
+39
View File
@@ -360,10 +360,49 @@ class AutoReply:
# 没有 meaningful_token 命中,即使有子串匹配也拒绝
logger.debug(f"无有意义token命中拒绝: query={query[:40]!r} doc_heading={heading[:30]!r}")
return False
# ⭐ 新增:下载类查询的特殊处理(2026-08-17 修复牛头不对马嘴)
# 如果查询含"下载"且已有明确的"下载意图拒绝"日志,说明核心词检查已通过但语义不匹配
# 此时子串回退不应放行(防止"插件"等通用词在URL中误匹配)
_is_download_query = any(w in query for w in ('下载', '下到', '哪下', '在哪下', '怎么下'))
if _is_download_query:
# 下载类查询要求:子串必须包含查询的核心名词(如"登录插件")
# 不能只是"插件"这种通用词在URL路径中命中
_download_core_phrases = []
for kw in q_mean:
if kw not in {'下载', '下到', '哪下', '在哪下', '怎么下', '哪个', '哪里', '去哪'}:
_download_core_phrases.append(kw)
if _download_core_phrases:
# 检查是否有核心名词短语在文档中完整出现
_has_core_noun_match = any(
phrase in full
for phrase in _download_core_phrases
if len(phrase) >= 2
)
if not _has_core_noun_match:
logger.debug(
f"下载查询子串回退拒绝(核心名词未命中): query={query[:40]!r} "
f"doc_heading={heading[:30]!r} core_nouns={_download_core_phrases!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]
if phrase in full:
# ⭐ 新增:下载类查询跳过URL路径中的匹配
# 防止"插件"在/plugin/路径中误匹配
if _is_download_query and 'http' in full:
# 检查phrase是否在URL路径中(而非正文)
_url_pattern = r'https?://[^\s\)]+'
_urls = re.findall(_url_pattern, full)
_in_url_only = all(phrase in url for url in _urls if phrase in url)
if _in_url_only:
logger.debug(
f"下载查询子串回退拒绝(URL路径匹配): query={query[:40]!r} "
f"phrase={phrase!r} in URL only"
)
continue
logger.debug(
f"子串回退命中: phrase={phrase!r} in doc={doc.get('heading', '')[:30]!r}"
)