From 95f3b990646c19de380eb25e61647f229ba63ef0 Mon Sep 17 00:00:00 2001 From: lacerate551 <128470311+lacerate551@users.noreply.github.com> Date: Fri, 19 Jun 2026 14:39:16 +0800 Subject: [PATCH] =?UTF-8?q?fix(rag):=20BM25=20=E5=88=86=E6=AD=A7=E6=95=91?= =?UTF-8?q?=E6=8F=B4=20source=20=E4=B8=80=E8=87=B4=E6=80=A7=E6=A0=A1?= =?UTF-8?q?=E9=AA=8C=20+=20=E6=84=8F=E5=9B=BE=E5=88=86=E6=9E=90=20max=5Fto?= =?UTF-8?q?kens=20=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. _rescue_bm25_divergence 情况 B 注入前校验 source 与 contexts 多数 source 一致, 防止跨文档注入无关切片(如 2.docx 吸烟场所切片混入 1.docx 投放查询) 2. INTENT_MAX_TOKENS 从 2048 提升至 4096,修复 mimo-v2.5 思维链截断导致意图分析偶发失败 评测 R2+ 结果:overall 4.35(基线 4.20),忠实度 +0.24,幻觉率不变 --- api/chat_routes.py | 21 ++++++++++++++++++++- config.py | 2 +- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/api/chat_routes.py b/api/chat_routes.py index 8dec5db..fb7a91b 100644 --- a/api/chat_routes.py +++ b/api/chat_routes.py @@ -534,6 +534,15 @@ def _rescue_bm25_divergence(contexts: List[Dict], search_result: dict, if chunk_id: existing_ids[chunk_id] = i + # 计算 contexts 中的多数 source(用于情况 B 注入校验) + # 防止跨文档注入无关切片(如 q013 场景:2.docx 的吸烟场所切片被注入到 1.docx 的查询中) + source_counter: Dict[str, int] = {} + for ctx in contexts: + src = ctx.get('meta', {}).get('source', '') + if src: + source_counter[src] = source_counter.get(src, 0) + 1 + majority_source = max(source_counter, key=source_counter.get) if source_counter else None + rescued_count = 0 for bm25_item in bm25_top3: @@ -560,8 +569,18 @@ def _rescue_bm25_divergence(contexts: List[Dict], search_result: dict, continue # 情况 B:切片不在 contexts 中(被 rerank 截断或已被过滤) - # 从 _bm25_top3 备份中注入 + # 从 _bm25_top3 备份中注入,但需校验 source 一致性 if bm25_doc and bm25_meta: + bm25_source = bm25_meta.get('source', '') + # source 一致性校验:只注入与 contexts 多数 source 一致的切片 + # 避免跨文档注入无关内容(如 2.docx 的吸烟场所切片混入 1.docx 的投放查询) + if majority_source and bm25_source and bm25_source != majority_source: + logger.debug( + f"BM25 分歧救援 (情况B-跳过): rank={rank}, " + f"source={bm25_source} != majority={majority_source}, " + f"section={bm25_meta.get('section', '')}" + ) + continue injected_ctx = { 'doc': bm25_doc, 'meta': bm25_meta, diff --git a/config.py b/config.py index 68329aa..0457fa1 100644 --- a/config.py +++ b/config.py @@ -101,7 +101,7 @@ LLM_MAX_TOKENS = 3000 # 最大输出 token 数 # ----- 意图分析(轻量、确定性高)----- # INTENT_MODEL 在顶部「一、API 密钥与模型」中统一配置 INTENT_TEMPERATURE = 0.1 -INTENT_MAX_TOKENS = 2048 # 推理模型需要额外 token 用于思维链 +INTENT_MAX_TOKENS = 4096 # 推理模型思维链消耗大量 token,2048 偶发截断导致意图分析失败 INTENT_HISTORY_WINDOW = 6 # 分析时取最近几条历史消息 # ==============================================================================