修复跨平台答案混用: 表格优先策略必须检查heading语义相关性
- 表格优先策略: 不再盲目优先含'操作'的表格, 只优先heading与查询有交集的表格 - 表格兜底策略: 同上, 只兜底与查询语义相关的操作/支持表格 - 表格内容奖励: 同上, 3.0x加权只给与查询相关的表格 - 根因: '操作方式'表(交互模式)含'操作'被盲目优先, 覆盖了'权限级别'表 - 测试: '权限级别'→权限级别表格(20.51), '操作方式'→操作方式表格(49.54)
This commit is contained in:
+42
-20
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user