Skip to content
🔗 分享本题
查看我的学习进度 →

RAG 效果差时按检索、排序、生成和数据四层定位并用单变量实验验证图

🧠 记忆锚点:先用分层指标和失败切片定位根因,再做单变量实验;不要一看到答案差就同时改切分、召回、重排和 Prompt。

💡 答案要点

效果问题诊断流程:

RAG回答不好
    ├── 检索没找到相关内容(召回问题)
    │       ├── Embedding 模型不够好 → 换 bge-large-zh
    │       ├── Chunk 切分太大/太小 → 调整 chunk_size
    │       ├── 查询和文档表达不一致 → 加 Query 改写
    │       └── 只用向量检索 → 改混合检索(BM25 + 向量)

    ├── 找到了但排序靠后(排序问题)
    │       └── 加 Rerank(BGE-Reranker/Cohere)

    └── 找到了但模型没用上(生成问题)
            ├── Context 太长模型忽略 → 上下文压缩
            ├── Prompt 没引导好 → 优化 Prompt
            └── 模型能力不足 → 换更强模型

四层排查清单(面试高光:按层排故):

面试官问"RAG 回答不准从哪开始排查",按这四层走,覆盖 90% 故障点——最后 10% 才是模型问题:

第一层:Chunk 策略(地基)
  检查:按语义边界切还是固定长度?有重叠窗口吗?关键信息被切断了吗?
  修复:语义边界优先+重叠10-20%+保留元数据(来源文档/页码)
  判断:人肉读 top-3 片段,读不出答案 → 是切分问题,跟模型无关

第二层:检索质量
  检查:top-3 结果真的相关吗?设相似度阈值了吗?混合检索?Rerank?
  修复:相似度阈值过滤+BM25混合+初检top-20再Rerank筛top-3
  关键:相似≠相关(问"GIL是什么"搜到"多线程优化"→高相似度低相关性)

第三层:上下文组装
  检查:上下文太长?片段互相矛盾?prompt 明确"不知道就说不知道"了吗?
  修复:减top-k/摘要压缩;矛盾时标注来源优先采信最新权威;加拒答指令

第四层:用户 Query(最容易被忽略)
  检查:问题本身模糊吗?("这个怎么样""帮我总结一下")
  修复:Query改写(LLM转成明确检索query)+追问机制+拼接历史上下文

核心认知:90% 的 RAG 回答不准不是模型问题,是检索问题。

优化金字塔方法论(从能用到好用):

最顶层 高级优化:多路召回、RAG-Fusion、自我评估(锦上添花)
中间层 召回优化:混合检索、查询改写、Rerank(核心)
最底层 基础优化:文档预处理、合理分块、好的Embedding模型(地基)
        → 80% 的 RAG 问题根源在数据质量

原则:地基没打好,上层再优化也没用。先搞干净数据、分对块、选好Embedding,再谈花活。

RAG 五大常见坑(面试追问点):

表现解法
切分不合理句子中间切断,语义断裂搜不到按语义切分+重叠10-20%
召回太少只Top1-2,相关排在Top3被漏召回Top20再Rerank精选
召回太多几十条全塞给模型,噪音干扰限制K值+上下文压缩
上下文冲突两份文档口径不一致,模型混乱冲突检测+优先级规则+合并策略
相似度陷阱向量距离近≠能回答问题(问安装误召回故障帖)答案相关性过滤+Rerank校准

四步优化组合拳:

python
# Step 1: Query 改写(解决表达不一致)
rewritten_query = await query_rewriter.rewrite(
    query=user_query,
    history=conversation_history
)

# Step 2: 混合检索(提升召回率)
vector_results = vector_db.search(rewritten_query, top_k=20)
bm25_results   = bm25_index.search(rewritten_query, top_k=20)
merged_results = rrf_merge(vector_results, bm25_results)  # RRF 融合

# Step 3: Rerank 精排(提升相关性)
reranked = reranker.rerank(
    query=rewritten_query,
    docs=merged_results,
    top_k=5  # 精选 top5
)

# Step 4: 上下文压缩(避免 Lost in Middle)
compressed = context_compressor.compress(
    query=rewritten_query,
    docs=reranked,
    max_tokens=2000
)

# 生成
answer = await llm.generate(query=user_query, context=compressed)

各优化手段效果量化:

优化手段召回率提升准确率提升成本影响
混合检索(BM25+向量)+20-30%+15%+10%
Query 改写+15-25%+20%+5%
Rerank-+25-35%+15%
上下文压缩-+10-15%-30%
组合使用+40%+50%+0%

面试话术:

"RAG 效果优化我分三层诊断:召回层(混合检索+Query改写)、排序层(BGE-Reranker精排)、生成层(上下文压缩+Prompt优化)。实际项目中组合使用后准确率从 65% 提升到 88%,成本基本持平(压缩节省的抵消了Rerank的开销)。"

📚 参考:RAGAS:RAG 诊断指标(faithfulness/answer relevancy)