修复跨平台答案混用: 表格优先策略必须检查heading语义相关性

- 表格优先策略: 不再盲目优先含'操作'的表格, 只优先heading与查询有交集的表格
- 表格兜底策略: 同上, 只兜底与查询语义相关的操作/支持表格
- 表格内容奖励: 同上, 3.0x加权只给与查询相关的表格
- 根因: '操作方式'表(交互模式)含'操作'被盲目优先, 覆盖了'权限级别'表
- 测试: '权限级别'→权限级别表格(20.51), '操作方式'→操作方式表格(49.54)
This commit is contained in:
youpaishidifu
2026-08-05 15:01:00 +08:00
parent 49a95fb808
commit d8c0e62a2d
+42 -20
View File
@@ -493,14 +493,20 @@ class KnowledgeBase:
else:
combined_scores[i] *= 0.3 # 不包含核心名词 → 大幅惩罚
# ⭐ 表格内容奖励:当查询关于"支持/操作/方法/方式"时,包含表格的 section 巨幅加分
# ⭐ 表格内容奖励:当查询关于"支持/操作/方法/方式"时,与查询相关的表格 section 巨幅加分
# 防止"领地保护支持哪些操作"匹配到不含表格的"我的领地" section
# ⚠ 修复:只奖励与查询语义相关的表格,避免"操作方式"表覆盖"权限级别"表
table_query_tokens = {'支持', '操作', '方法', '方式', '功能', '可以', '能够'}
if table_query_tokens & query_tokens_set:
# 检查 body 是否是 Markdown 表格(以 | 开头)
body_stripped = body.strip()
if body_stripped.startswith('|') and '|' in body_stripped[1:]:
combined_scores[i] *= 3.0 # 表格内容 → 巨幅奖励
# 检查heading是否与查询语义相关
h_tokens = set(t for t in jieba.cut(heading) if len(t) >= 2)
heading_relevant = bool(query_tokens_set & h_tokens)
# 或body中含查询核心名词
body_relevant = any(n in body_stripped for n in query_tokens_set if len(n) >= 2)
if heading_relevant or body_relevant:
combined_scores[i] *= 3.0 # 相关表格 → 巨幅奖励
# 短查询惩罚:分词数 ≤2 的短查询(如图标残片/短词)得分大幅降权
# 防止 OCR 碎片中的高 IDF 词(如"下载")获得超过真实用户消息的分数
@@ -635,27 +641,36 @@ class KnowledgeBase:
doc_sections.append((i, doc, combined_scores[i]))
doc_sections.sort(key=lambda x: x[2], reverse=True)
# ⭐ 表格兜底策略:当最佳文档包含操作/支持相关表格时,强制加入并给超高分
# ⭐ 表格兜底策略:当最佳文档包含与查询相关的操作/支持表格时,强制加入并给超高分
# 防止"领地保护"因表格TF-IDF=0而丢失正确答案(表格是答案但不含查询词)
# 关键:给足够高的基础分,即使reranking bonus=0也能保持第一
# ⚠ 修复:只优先与查询语义相关的表格,避免"操作方式"表覆盖"权限级别"表
if len(doc_sections) > 0:
# 检查文档是否已有包含"操作"或"支持"的表格section
has_action_table = False
# 检查文档是否已有与查询相关的表格section
has_relevant_table = False
for idx, _, _ in doc_sections:
body = self.docs[idx].get("body", "").strip()
heading = self.docs[idx].get("heading", "")
if body.startswith('|') and ('操作' in body or '支持' in body):
has_action_table = True
break
if not has_action_table:
# 强制加入操作/支持相关表格section
h_tokens = set(t for t in jieba.cut(heading) if len(t) >= 2)
if query_tokens_set & h_tokens:
has_relevant_table = True
break
if not has_relevant_table:
# 强制加入与查询相关的操作/支持表格section
for i, doc in enumerate(self.docs):
if doc["title"] == doc_title:
body = doc.get("body", "").strip()
heading = doc.get("heading", "")
if body.startswith('|') and '|' in body[1:] and ('操作' in body or '支持' in body):
# 给表格section超高分(最高分×2),确保reranking后仍排第一
max_score = max(s for _, _, s in doc_sections) if doc_sections else min_score
doc_sections.append((i, doc, max_score * 2))
break
# 检查heading是否与查询语义相关
h_tokens = set(t for t in jieba.cut(heading) if len(t) >= 2)
heading_relevant = bool(query_tokens_set & h_tokens)
body_relevant = any(n in body for n in query_tokens_set if len(n) >= 2)
if heading_relevant or body_relevant:
# 给表格section超高分(最高分×2),确保reranking后仍排第一
max_score = max(s for _, _, s in doc_sections) if doc_sections else min_score
doc_sections.append((i, doc, max_score * 2))
break
doc_sections.sort(key=lambda x: x[2], reverse=True)
if not doc_sections:
@@ -706,17 +721,24 @@ class KnowledgeBase:
reranked.sort(key=lambda x: x[2], reverse=True)
doc_sections = reranked
# ⭐ 表格优先策略(reranking后):无条件优先返回包含"操作/支持"的表格section
# ⭐ 表格优先策略(reranking后):条件优先返回与查询语义相关的表格section
# 防止reranking后表格被其他section超越(表格是答案但不含查询词)
# ⚠ 修复:不能盲目优先含"操作"的表格——"操作方式"表(交互模式)会覆盖"权限级别"表
# 只有当表格section的heading与查询关键词有交集时才优先
if len(doc_sections) > 1:
# 找到包含表格的section(body以|开头且含"操作"或"支持")
for i in range(len(doc_sections)):
idx = doc_sections[i][0]
body = self.docs[idx].get("body", "").strip()
heading = self.docs[idx].get("heading", "")
if body.startswith('|') and ('操作' in body or '支持' in body):
# 表格section,移到第一位
doc_sections.insert(0, doc_sections.pop(i))
break
# 检查heading是否与查询语义相关(heading含查询词 或 查询词含heading关键词)
h_tokens = set(t for t in jieba.cut(heading) if len(t) >= 2)
heading_relevant = bool(query_tokens & h_tokens)
# 也检查body中是否有查询核心名词
body_relevant = any(n in body for n in query_tokens if len(n) >= 2)
if heading_relevant or body_relevant:
doc_sections.insert(0, doc_sections.pop(i))
break
if has_action and len(doc_sections) > 1:
# 动作查询:提取动词+对象,精准匹配 section