文章

RAG准确性提高案例

RAG准确性提高案例

RAG准确性提高案例

面向不微调大模型、通过工程手段提升 RAG 准确率的落地复盘。场景为电力规程文档知识库问答,准确率从约 50% 提升至 88%,全程零模型微调。

  • 原文作者:知乎用户
  • 原文链接:https://www.zhihu.com/question/638730143/answer/2041228453932963535
  • 原问题:如何在不微调的情况下提高 RAG 的准确性?

1. 背景与结论

作者团队做 RAG 落地一年多,在无 GPU 微调资源、无标注数据、无充裕时间的前提下,纯靠工程手段将准确率从 50% 提到 88%

核心观点:

  • 这些手段花钱少,多数代码量不大,但效果实打实
  • 别一上来就微调:先把工程优化做完,准确率仍达不到 80% 再考虑微调,大概率够用
  • RAG 的天花板在检索质量,不在大模型——检索不对,GPT-4 也没用(作者另文:为什么做了优化准确率仍上不去)。

2. 优化路径总览

按作者实践中的提升幅度与实施顺序归纳:

1
2
3
4
5
6
7
8
9
10
11
12
13
数据预处理(干净入库)
    ↓
结构化分块(按条款/章节,非硬切 512 字)
    ↓
Query 改写(口语 → 标准术语,召回率大幅提升)
    ↓
分库 / metadata 过滤(降噪声)
    ↓
Rerank(稳态 +7~8 个百分点)
    ↓
混合检索(向量 + BM25,锦上添花)
    ↓
Prompt 工程(压幻觉)

作者串联后的经验路径(各步贡献为作者项目内估算):

步骤手段效果(作者项目)
1数据预处理约 +5%
2按文档结构分块约 +15~20%
3Query 改写召回率约 35% → 80%
4分库召回top-5 命中率约 +15%
5Rerank约 +7~8%
6混合检索约 +3~4%
7Prompt 工程幻觉率约 15% → 5% 以下

3. 数据预处理:最不起眼,ROI 最高

场景:电力规程 PDF,质量参差不齐——排版好的、扫描件都有。

3.1 扫描件与 OCR

OCR 识别率 97% 听起来很高,但一个 512 字 chunk 里平均仍有约 15 个错字。错字向量化后成为噪声特征,检索时「噪声匹配噪声」,准确率难上去。

做法

  • 扫描 PDF 用高精度 OCR 重识别(作者用 PaddleOCR,效果优于 Adobe 自带 OCR);
  • 识别后对关键页人工校验——不必全库校验,只校验含设备参数、操作步骤的页,约占总页数 20%

3.2 表格

PDF 表格经 OCR 常乱序。Camelot 专门抽表格,结构化结果作为独立 chunk 入库;涉及参数查询的准确率「直接拉满」。

3.3 文档去重与版本

同一规程 2024 版与 2025 版同时在库,检索会召回两个版本的同一条款。加版本过滤,只取最新版,准确率再提升约 2 个百分点

3.4 投入

主要是人力时间:约 1000 页文档库,预处理约 2~3 天。作者认为 ROI 最高


4. 分块策略:硬切 vs 按结构切

512 字硬切 vs 按文档结构切,准确率相差 15~20 个百分点(作者实测)。

原因:电力规程按条款组织。第 X 条是一条完整操作流程。硬切可能把一条款切成两半——前半在 chunk A 讲「遇到 XX 应怎么做」,后半在 chunk B 讲「若做了 YY 会怎样」。只召回一半,大模型无法准确作答。

原则

  • 章节标题 → 按标题切;
  • 条款号 → 按条款切(一条一个 chunk,完整、独立、自洽);
  • 操作步骤 → 按步骤切;
  • 无结构纯文本 → 按段落切,段落过长再按句号切。

实测例(query:「变压器瓦斯保护动作后的处理流程」):

分块方式top-5 中相关条数
512 硬切1 条
按条款切4 条

chunk_size 从 128 调到 1024,影响远不如分块策略本身。与其死磕 chunk_size,不如先把文档按结构拆好


5. 问题改写:召回率翻倍

用户问「保护老跳闸」,向量检索往往效果差——文档写的是「继电保护装置频繁动作」,存在术语 gap

方案:用 7B 模型做 query 改写,把口语化、不完整的问题改写成 3 条标准术语检索 query。

Prompt 关键约束:「使用电力行业标准术语,补充隐含的技术细节。」无此约束时,改写过泛、过学术,效果反而更差。

效果例

原始 query改写后(3 条示例)
变压器嗡嗡响① 变压器运行异常声响识别 ② 变压器正常运行声音特征 ③ 变压器异响原因分析及处理方法

召回率:35% → 80%

模型选型Qwen3-4B 即可,延迟 100ms 以内;35B 略好但延迟约 300ms,多数场景不值得。若已有 GPU 跑大模型,额外成本接近零


6. 分库召回:砍掉噪声

做法:按文档类型建不同向量索引,共 6 类——运行规程、检修规程、调度规程、设备说明书、安全规范、项目技术文档。检索前用小模型判断问题类别,定向到对应库检索。

为何混库效果差:不同类型文档词汇重叠大(如「继电保护」在运行规程与检修规程都高频),混检时问运行问题却召回检修文档——语义相关但答非所问

效果:top-5 命中率从约 60% 出头拉到接近 80%(作者表述为噪声大幅减少,而非准确率直接 +15%)。

替代方案:不分库,用 metadata filter(文档类型写入 Milvus / Qdrant 等 metadata,检索时过滤)。实现更简单,效果略逊于分库。


7. Rerank:最稳的一步

作者称 rerank 为最稳的提升,没有之一

  • 模型:bge-reranker-v2-m3
  • 部署:CPU 可跑(只对 top-20 重排,非全库)
  • 延迟:每 query 约 200~300ms
  • 准确率:稳定 +7~8 个百分点

原理简述

阶段类型特点
向量检索Bi-encoder(双编码器)快,但 Q 与文档分别编码再算相似度,精度有限
RerankCross-encoder(交叉编码器)Q 与每个文档拼接后推理,可见交互信息,精度更高

推荐流水线

1
向量检索 top-20 → rerank → 取 top-5 → 送大模型生成
  • top-10 太少,排名第 10~20 的好文档会漏;
  • top-30 太多,噪声跟进来了。

8. 混合检索:锦上添花

向量检索 + BM25,提升不大但稳定、零额外模型成本

  • Milvus、Qdrant 等原生支持混合检索;
  • 作者用 pgvector 时,BM25 部分用 PostgreSQL 全文检索自实现。

分数融合权重需自测(与数据分布强相关)。作者项目在向量和 BM25 各自归一化后加权,向量侧权重约 0.6 量级——勿直接抄数值,应在自有数据上 A/B


9. Prompt 工程:压幻觉

检索到的 5 条文档如何喂给大模型,对效果影响很大。

阶段做法问题
初期简单拼接:「请根据以下参考资料回答问题:[文档1][文档2]…」易幻觉、少引用
改进结构化 prompt:标明来源与编号;要求引用来源;无相关信息时明确说「知识库中没有找到」,禁止编造幻觉率 15% → 5% 以下

小技巧:在 prompt 中加「请优先使用排名靠前的文档中的信息」。Rerank 后 top-1 通常最相关,但大模型有时偏向后面更「通用、好答」的段落。


10. 小结与对照清单

10.1 一句话

零微调把 RAG 从 50% 拉到 88%:先把数据、分块、检索链路做扎实,再靠 query 改写、分库、rerank、混合检索、prompt 逐级加码;检索质量决定上限。

10.2 落地检查清单

检查项是否做到
扫描件高精度 OCR + 关键页抽检
表格独立结构化入库
文档版本去重 / 只保留最新
按条款/章节分块,避免硬切断语义
领域术语 query 改写
分库或 metadata 过滤
top-20 → rerank → top-5
向量 + BM25 混合(可选)
结构化 prompt + 无则拒答 + 优先靠前文档

10.3 延伸阅读

资源说明
原知乎回答本文整理来源
RAG 天花板在检索作者同系列:为何优化后仍上不去
本文由作者按照 CC BY 4.0 进行授权