之前在业务里做 RAG 知识库问答时,我遇到过一个很典型的问题:系统 demo 阶段表现还行,一上真实业务文档,准确率就稳定卡在 60% 左右。用户问 10 道题,总有 3 到 4 道回答得似是而非,甚至直接漏掉关键信息。当时排查了很久,网上资料零散不成体系,很多文章只讲概念不给步骤,照着做完还是原地踏步。
后面我系统性地把 RAG 全链路拆开优化了一遍,把文档解析、切片策略、召回链路、重排序、Prompt 模板逐项打磨,最终把准确率从 60% 拉到了 80% 以上。这篇文就把这套闭环优化方案完整整理出来,包含核心原理、完整代码示例和真实项目中的避坑清单。如果你正好在做 RAG 知识库问答、私有文档问答,或者刚开始接触大模型应用开发,这份实战笔记可以直接拿来复用。
1. 为什么你的 RAG 系统卡在 60% 准确率
1.1 什么是 RAG,它为何会“答非所问”
RAG(Retrieval-Augmented Generation,检索增强生成)是目前大模型落地最常见的架构。它先把外部知识文档切分成片段,通过 Embedding(向量化)写入向量数据库;用户提问时,先从知识库检索出相关片段,再把这些片段连同问题一起交给大模型生成答案。
用一句话概括:RAG 不指望大模型“记”住你的私有知识,而是让大模型在回答时“查”到对应的资料。
这种架构有效解决了大模型无法掌握企业内部知识、容易产生幻觉的问题。但问题也随之而来:RAG 的效果并不是由单一环节决定的。检索环节漏掉了关键段落,后面大模型再聪明也回答不出;检索环节召回了一堆无关文本,大模型就会被噪声信息带偏,给出错误答案。
1.2 60% 准确率瓶颈的三种典型表现
我在多个项目里复盘过 RAG 效果差的情况,发现 60% 附近徘徊的系统,问题高度集中在以下几个方面:
| 现象 | 用户直观感受 | 根因大概率出在 |
|---|---|---|
| 答案和问题不在一个频道上 | “我问的是报销流程,它答的是发票类型” | 检索召回不准,语义匹配没对齐 |
| 答案内容没错,但关键步骤缺失 | “流程只讲了一半,最重要的审批节点没提到” | 切片粒度过大或过小,信息被截断 |
| 答案引用了文档但内容是错的 | “它说根据文档规定,可文档里根本不是这么写的” | Rerank 缺失,噪声上下文干扰生成 |
这些表现并不是相互独立的,很多时候是多个问题叠加出现。所以要提升准确率,不能头痛医头、脚痛医脚,而要把 RAG 当成一条完整的数据管道来优化。
1.3 准确率提升不是单点优化,而是链路优化
我见过很多同学为了提升 RAG 效果,一上来就换更强的 Embedding 模型,或者把大模型从 7B 换成 72B。换完之后确实有提升,但很快又碰到天花板。
原因很简单:大模型端的回答质量上限很高,真正限制 RAG 系统效果的是“喂给大模型的上下文质量”。
我把 RAG 全链路拆成四个核心环节:
- 知识入库:文档解析、清洗、切片、向量化。
- 召回阶段:通过向量检索、关键词检索、混合检索把候选文档捞出来。
- 重排阶段:对召回结果做精细排序,过滤噪声。
- 生成阶段:Prompt 模板、引用溯源、答案约束。
准确率从 60% 到 80%,本质上就是把这四个环节逐个排除短板。下面从评估体系讲起,因为如果没有“尺子”,你根本不知道优化有没有效果。
2. 环境准备与优化前的效果评估
2.1 技术栈说明
RAG 技术栈更新非常快,本文的示例以常见开源方案为主,版本需要根据你的项目实际情况调整,重点关注配置思路:
- 操作系统:Linux / macOS / Windows 均可,示例以本地开发环境为主。
- 编程语言:Python 3.9+。
- 向量数据库:FAISS(本地原型验证)、Milvus 或 Qdrant(生产环境)。
- Embedding 模型:BGE-M3 或 text-embedding 类模型,按你的算力环境选择。
- Rerank 模型:BGE-Reranker 系列。
- LLM:OpenAI 兼容接口或本地部署模型(例如 Ollama 加载的开源模型)。
- 编排框架:LangChain 或 LlamaIndex,也可以用原生 Python 实现核心链路。
这里要强调:框架只是工具,不要被框架绑定。理解每个环节在做什么,比会调某一个 API 更重要。
2.2 先建立评测集,否则一切优化都是“拍脑袋”
RAG 准确率优化最大的坑,就是没有量化指标就盲目调参。
我强烈建议在动手优化之前,先做一个评测集。评测集不需要太大,但必须覆盖你的核心业务场景:
- 从真实用户问题中挑 30 到 50 条高频问题。
- 为每个问题标注标准答案。
- 标注答案来源文档片段(可用于评估检索命中情况)。
- 覆盖不同类型的问题:事实查询、流程查询、对比查询、开放问答。
评测集建好之后,后续每次修改索引策略、调整切片参数、更换模型,都要在同一个评测集上跑一遍,用数据说话,而不是靠“感觉变好了”。
2.3 评测指标:Recall、Precision、Answer Correctness
RAG 系统建议关注以下三类指标:
| 指标 | 英文名称 | 含义 | 说明 |
|---|---|---|---|
| 召回率 | Recall | 正确的文档片段是否被检索出来 | RAG 的上限 |
| 精确率 | Precision | 检索结果中有多少是和问题相关的 | 影响上下文质量 |
| 答案正确率 | Answer Correctness | 最终生成答案是否准确完整 | 关注语义层面的正确性 |
检索环节重点看 Recall 和 Precision,生成环节重点看 Answer Correctness。从 60% 到 80% 的优化过程,就是这几个指标全面提升的过程。
最简单的方式是请业务方或者自己人工打分:每次跑完评测集,对每条答案打“正确 / 部分正确 / 错误”,计算正确率。虽然人工评估有一定主观性,但这是成本最低、最容易落地的评估方式。
3. 检索链路优化:让正确的文档进到上下文
3.1 文档解析:切块之前先做好清洗
很多 RAG 项目在文档解析阶段就出了问题。比如直接把 PDF 里的文本抽出来就往向量库里存,结果包含大量页眉页脚、目录信息、换行符错乱,这些噪声在后续切片和检索时都会被当成知识内容参与计算,干扰语义匹配。
文档解析阶段要做的三件事:
- 去除噪声:页眉、页脚、页码、脚注、目录页,在抽取文本时需要识别并过滤。
- 保留结构:标题层级、表格结构、列表序号要尽量保留,这些信息有助于后续切片时保持语义完整。
- 处理表格:普通文本抽取会破坏表格的对应关系,建议将表格转成 Markdown 格式或键值对文本,避免语义丢失。
如果是扫描版 PDF,还需要接入 OCR 能力,把图片中的文字抽出来。这个环节没有调好的话,后面所有优化都会受影响。
3.2 分段策略:chunk_size 和 overlap 怎么调
文档切片是 RAG 优化中最容易见效也最容易翻车的地方。切片参数主要有两个:
chunk_size:每个切片的文本长度(按字符或 token 计算)。chunk_overlap:相邻切片之间重叠的长度。
切片太大会导致一个 chunk 里混合多个主题,向量化后语义被稀释,检索时“看似相关其实混沌”;切片太小则会导致信息碎片化,一个完整的知识点被切成好几段,检索时只命中其中一部分,大模型得到的上下文不完整。
从我的经验来看,切片的理想状态是“一个 chunk 只讲一个完整主题”。可以参考以下策略:
- 先按文档结构切,优先保留 Markdown 标题、PDF 章节标题的层级关系。
- 以 300 到 500 个 token 为一个基础块,设置 50 到 100 个 token 的重叠。
- 对常见 QA 文档、操作手册这类结构化的内容,可以按条切分,每条一个 chunk。
- 对于长表格或代码块,切成独立 chunk,不要和正文混在一起。
3.3 Embedding 选型与向量化参数
Embedding 模型负责把文本转换为向量。向量之间的余弦相似度,决定了检索结果的相关性。
选 Embedding 模型时主要看三个方面:
- 语义能力:对中文长文本、专业术语的理解能力。
- 向量维度与索引开销:维度越高,占用存储和计算资源越大。
- 是否支持领域微调:垂直领域如果通用模型效果不好,可以考虑基于领域语料微调。
实际项目中,我建议至少准备两个 Embedding 模型做对比评测,在评测集上分别跑召回率,选效果更好的那个。不要只看宣传参数,实测数据最可靠。
还有一个细节:Embedding 模型在索引和查询阶段必须保持一致。很多项目上线后发新版时换了 Embedding 模型,但旧向量库没有重新构建,导致检索一致性崩溃,这属于非常隐蔽的坑。
4. 混合检索与重排序:从 60% 到 70% 的关键
4.1 为什么“纯向量检索”不够用
纯向量检索基于语义相似度,也叫稠密向量检索(Dense Vector Search)。它的优势是能理解同义改写,比如“怎么报销”和“费用报销流程”在语义上是相近的。
但它有几个明显弱点:
- 对专有名词、精确 ID、型号、规则编号不敏感。比如用户问“BG-2024-001 号文件”,向量检索可能匹配到语义相近但完全不同的内容。
- 对否定关系、条件限定容易理解错。比如“不包含 X 的操作步骤”,向量检索可能把包含 X 的文档也召回。
解决思路是引入混合检索(Hybrid Search):把向量检索和关键词检索(BM25)的结果融合在一起,兼顾语义理解和精确匹配。
4.2 重排序(Rerank)解决“召回多但排序乱”的问题
混合检索会把候选结果从几十条集合到一起,但排序效果不一定理想。向量检索返回的 Top 3 不一定是最相关的 3 条,BM25 召回的结果也可能混杂大量无关内容。
重排序(Rerank)的作用,就是用一个专门的交叉编码器模型,把“问题和候选文档”一起输入模型,重新计算每一条的相关性分数,然后保留最相关的 Top K 条。
Rerank 为什么比向量检索的相似度排序更准?
因为向量检索先要把问题和文档分别编码成向量,再进行相似度计算,这个过程是有信息损失的。而 Rerank 模型把问题和文档拼接在一起送入模型,可以做深层次的交互式匹配,精度更高,但速度也相对更慢。
正确的实践是:召回阶段用混合检索多召回一些候选(比如 Top 20),重排阶段用 Rerank 精确排序,只把 Top 3 到 Top 5 送给大模型。这样既保证了召回率,又控制了上下文质量。
4.3 示例代码:混合检索加 Rerank 的实现思路
下面给出示例代码思路,需要放入你的项目文件中,具体模型路径和 API 地址按实际环境替换。
# 文件路径:retrieval/retriever.py # 说明:该示例展示混合检索 + Rerank 的组合流程 # 依赖:pip install pymilvus rank_bm25 # 注意:此处以伪代码形式演示核心链路,需按实际版本调整 from pymilvus import MilvusClient from rank_bm25 import BM25Okapi class HybridRetriever: def __init__(self, collection_name, embed_func, milvus_uri="http://localhost:19530"): # embed_func: 统一的 embedding 函数,向量化 query 或 document self.client = MilvusClient(uri=milvus_uri) self.collection_name = collection_name self.embed_func = embed_func def bm25_search(self, query, tokenized_docs, top_k=20): # 先用简单分词构建 BM25 索引(生产环境建议使用 jieba 等分词器) bm25 = BM25Okapi(tokenized_docs) scores = bm25.get_scores(query.split()) top_indices = sorted(range(len(scores)), key=lambda i: scores[i], reverse=True)[:top_k] return top_indices, scores def vector_search(self, query, top_k=20): query_vector = self.embed_func(query) res = self.client.search( collection_name=self.collection_name, data=[query_vector], limit=top_k, output_fields=["text", "doc_id"], ) return res[0] def hybrid_search(self, query, tokenized_docs, top_k=20): # 向量召回 vector_results = self.vector_search(query, top_k=top_k) # 关键词召回(这里简化为按索引返回,实际需要存储原文) bm25_top_ids, bm25_scores = self.bm25_search(query, tokenized_docs, top_k=top_k) # 合并结果并去重 candidate_map = {} for item in vector_results: doc_id = item["entity"]["doc_id"] candidate_map[doc_id] = item["entity"]["text"] for doc_id in bm25_top_ids: # 如果关键词命中的 doc 不在向量结果里,补充进来 if doc_id not in candidate_map: candidate_map[doc_id] = tokenized_docs[doc_id] return list(candidate_map.items())上面的代码展示了混合检索的基本思路:向量检索结果和 BM25 关键词检索结果合并去重,形成候选集。在实际项目中,建议把候选集大小设为 20 左右,再交给 Rerank。
# 文件路径:retrieval/reranker.py # 说明:使用 BGE-Reranker 对候选文档重排序 # 依赖:pip install FlagEmbedding from FlagEmbedding import FlagReranker class ReRanker: def __init__(self, model_path="BAAI/bge-reranker-v2-m3"): # 模型可以离线下载后放入本地路径,避免每次启动时联网加载 self.reranker = FlagReranker(model_path, use_fp16=True) def rerank(self, query, candidates, top_k=5): # candidates 为 [(doc_id, text), ...] pairs = [[query, text] for _, text in candidates] scores = self.reranker.compute_score(pairs, normalize=True) # 按分数降序排列 scored = sorted(zip(candidates, scores), key=lambda x: x[1], reverse=True) return scored[:top_k]Rerank 结果里包含了最终要送给大模型的 Top K 条文档,这些文档的相关性已经经过精排,上下文质量会比纯向量检索高一个档次。
5. Prompt 与生成链路优化:把答案的最后一公里走好
5.1 Prompt 模板如何影响准确率
检索做好的前提下,Prompt 模板决定了生成效果的上限。很多 RAG 项目检索结果没问题,但 Prompt 写得过于简单,比如只有一句“请根据上下文回答问题”,导致大模型自由发挥,输出不可控。
一个合格的 RAG Prompt 至少应该包含四部分:
- 角色设定:告诉模型它是“企业内部知识库问答助手”。
- 上下文输入:把检索到的文档片段按引用编号排列。
- 回答要求:只基于给定上下文回答、不要编造、无法回答时明确说明。
- 输出格式:需要时要求结构化输出,标注引用来源。
示例 Prompt 模板:
# 文件路径:prompt/template.py RAG_PROMPT_TEMPLATE = """你是一个严谨的企业知识库问答助手。 请仅根据以下【参考文档】内容回答问题,不要使用你记忆中可能存在的常识进行推测。 【参考文档】 {documents} 【用户问题】 {question} 回答要求: 1. 如果参考文档中没有足够信息,请直接回复“当前知识库中未找到相关答案”。 2. 回答时请条理清晰,分点列出关键步骤或结论。 3. 在答案末尾,标注你引用的文档编号,例如:来源:[1][3]。 4. 禁止编造参考文档中不存在的流程、数字或结论。 """5.2 引用溯源:降低幻觉的强制手段
要求模型输出时标注引用来源,不仅能提升答案可信度,还能显著约束模型“乱编”的倾向。当模型被要求“每个结论都要有出处”时,它会更加依赖上下文中已有的内容。
实现上,你在把文档片段放入 Prompt 时,给每个片段分配一个编号:
[1] 来源:《报销管理制度》第3章:报销流程... [2] 来源:《差旅管理规范》第2节:住宿标准...模型在回答时就会自然引用[1]、[2]这样的编号。这样一方面方便用户核对原始文档,另一方面也方便你做溯源分析和错误定位。
5.3 多轮对话与 Query 改写
如果你做的是对话式 RAG,还有一个容易被忽略的问题:用户后续问题往往是省略主语或指代上文的,例如第一轮问“怎么申请报销”,第二轮问“需要什么材料”,如果直接把第二轮的原始问题拿去检索,召回效果通常很差。
解决方法是引入Query 改写:把对话历史交给大模型,生成一个“独立化”的检索问题,再拿改写后的问题去检索。
示例思路:
# 文件路径:prompt/query_rewrite.py QUERY_REWRITE_PROMPT = """请将用户的当前问题改写为一个独立、完整、适合检索知识库的检索式问题。 要求: 1. 保留原问题中的所有关键条件。 2. 把代称、省略成分补充完整。 3. 不要输出多余解释,只输出改写后的问题。 【对话历史】 {history} 【当前问题】 {current_question} 改写结果: """Query 改写是 RAG 多轮对话场景准确率提升的重要抓手,在很多垂直场景里能让检索命中率提升 10 个百分点以上。
6. 完整实战案例:RAG 准确率优化前后对比
6.1 项目结构
这一节用一个简化但完整的小项目来串联全部优化点。项目结构如下:
rag_optimize_demo/ ├── data/ │ └── 企业制度文档.md # 原始知识文档 ├── retriever/ │ ├── hybrid_retriever.py # 混合检索 │ └── reranker.py # 重排序 ├── prompt/ │ ├── template.py # RAG Prompt 模板 │ └── query_rewrite.py # Query 改写 ├── indexer.py # 文档入库 ├── query_pipeline.py # 查询链路主流程 └── eval.py # 评测脚本6.2 优化前的“朴素 RAG”实现
优化前的实现非常简单:读取文档,直接按固定长度切块,向量化入库,查询时计算向量相似度取 Top 5,拼接后交给大模型。
# 文件路径:indexer.py(优化前版本) # 说明:固定长度切块的简化实现 def naive_chunk_text(text, chunk_size=400, overlap=50): chunks = [] start = 0 while start < len(text): chunks.append(text[start:start + chunk_size]) start += chunk_size - overlap return chunks这种实现有两个明显问题:
- 切块没有考虑文档结构,可能把一个完整段落从中间切断。
- 检索只用向量相似度,没有混合检索,也没有 Rerank。
这就是准确率卡在 60% 的典型结构。
6.3 优化后的完整检索链路
优化后的流程如下:
- 文档入库时按结构切分,保留标题信息。
- 查询阶段先做向量检索 + BM25 混合召回 Top 20。
- 用 Rerank 对 Top 20 精排,取 Top 4。
- 将 Top 4 片段按引用编号填入 Prompt。
- 要求大模型输出答案并标注引用。
6.4 查询主流程代码
# 文件路径:query_pipeline.py # 说明:优化后的查询主流程 from retriever.hybrid_retriever import HybridRetriever from retriever.reranker import ReRanker from prompt.template import RAG_PROMPT_TEMPLATE class RAGPipeline: def __init__(self, retriever, reranker, llm_func): self.retriever = retriever self.reranker = reranker self.llm_func = llm_func # 大模型调用函数,支持 OpenAI 兼容接口或本地模型 def answer(self, question): # 1. 混合召回 20 条候选 candidates = self.retriever.hybrid_search(question, top_k=20) # 2. Rerank 精排取前 4 条 top_docs = self.reranker.rerank(question, candidates, top_k=4) # 3. 构造带引用编号的文档块 document_text = "" for idx, (doc_id, text) in enumerate(top_docs, start=1): document_text += f"[{idx}] {text}\n\n" # 4. 填充 Prompt prompt = RAG_PROMPT_TEMPLATE.format(documents=document_text, question=question) # 5. 调用大模型生成 answer = self.llm_func(prompt) return answer每一次检索都经过了“宽召回 + 精重排”两步,既保证相关文档大概率被召回,又保证最终送到大模型手里的上下文是质量最高的那几条。
6.5 运行与结果对比
我在一组企业制度文档问答评测集上记录了优化前后的效果:
| 优化阶段 | 测试问题数 | 正确率 | 关键变化 |
|---|---|---|---|
| 朴素 RAG | 50 | 60% | 固定切块、纯向量检索 |
| 增加混合检索 | 50 | 68% | BM25 + 向量召回,宽召回 |
| 增加 Rerank | 50 | 76% | 精排过滤噪声上下文 |
| 优化 Prompt + Query 改写 | 50 | 82% | 输出约束 + 多轮改写 |
注意:这里的数字来自我实测的一个业务场景,不代表所有项目都能获得完全一致的提升幅度。但它反映了一个规律:准确率提升通常是多个环节叠加积累的结果,不是某一个“神技”单独带来的。
7. 常见问题与排查思路
RAG 优化过程总会遇到各种问题。我把高频问题整理成一张排查表:
| 问题现象 | 常见原因 | 解决思路 |
|---|---|---|
| 检索不到相关文档 | 切块过大导致主题混合;Embedding 模型语义能力不足 | 按结构切块,缩短 chunk_size;对比测试替换 Embedding 模型 |
| 召回了很多无关内容 | 纯向量检索对精确词不敏感;没有 Rerank 过滤 | 引入 BM25 混合检索;增加 Rerank 精排 |
| 答案引用了错误文档 | Rerank 排序不准确;Prompt 未要求引用溯源 | 检查 Rerank 模型效果;在 Prompt 中强制标注引用编号 |
| 多轮对话答非所问 | 未做 Query 改写,检索用的原始问题信息不完整 | 增加 Query 改写模块,把代称补全 |
| 同一问题答案不稳定 | 大模型采样参数设置不当;检索结果不稳定 | 降低 temperature;固定 Rerank Top K 数量 |
| 向量库更新后效果变差 | 新旧 Embedding 模型不一致;向量库未全量重建 | 统一 Embedding 模型;索引更新后重建向量库 |
下面挑两个出现频率最高的问题详细展开。
问题 1:为什么 Rerank 加了之后反而变慢了,甚至超时?
Rerank 需要对每一条候选文档执行一次模型推理,候选数量越大,耗时越长。有些团队把 Top 20 的候选全部 Rerank 后再取 Top 5,这在文档量很大的时候性能会明显下降。
优化方式是控制 Rerank 的输入规模。召回阶段取 Top 20,Rerank 只对 Top 20 精排,最终取 Top 4 或 Top 5。如果仍然超时,可以考虑把 Rerank 模型切成小模型,或者用异步批处理。
问题 2:怎么判断是检索问题还是生成问题?
这是非常关键的定位步骤。我推荐的判断方法是:把检索出来的 Top K 文档直接打印出来人工看一遍。
- 如果文档本身就文不对题,说明问题出在检索或切片。
- 如果文档相关但答案错误,说明问题出在 Prompt 或大模型生成。
- 如果文档只有一部分相关,说明切片粒度过大,混入了不相关内容。
先把问题定位到具体环节再动手修改,可以避免盲目调参浪费时间。
8. 最佳实践与工程建议
8.1 数据侧:知识库质量决定天花板
RAG 系统的天花板不是由大模型决定的,而是由知识库质量决定的。
入库之前要对文档做版本管理,确定哪些文档是“有效知识”,哪些是过时文档。一条过时的流程信息一旦进入知识库,就会不断被检索到并生成错误答案。建议在文档元数据中加入生效日期、失效日期、文档版本号,检索和生成时可以通过元数据过滤掉失效文档。
另外不要忽视文档去重。多个相似文件同时入库后,检索时会出现多条重复上下文,既浪费 token 又可能造成信息冲突。
8.2 索引侧:版本管理与重建策略
向量索引需要和 Embedding 模型强绑定。每次升级 Embedding 模型后,旧向量库里的向量已经无法和新模型产出的向量直接比较,必须全量重建索引。
生产环境建议:
- Embedding 模型变更走发布流程,先在小范围评测集上验证。
- 新向量库构建完成后,通过开关灰度切流,而不是一次性替换。
- 保留上一版本索引,方便快速回滚。
8.3 安全边界:权限过滤必须有
企业知识库往往包含不同密级的内容。RAG 系统上线时,必须考虑一个问题:用户 A 的提问,会不会检索出用户 B 无权查看的文档?
在召回和重排阶段,都需要按用户权限过滤文档。推荐的做法是在文档入库时给每个 chunk 打上权限标签,在检索条件中强制加上权限过滤,避免敏感信息泄露。
8.4 评估侧:把评测集纳入 CI/CD
评测集不是一次性工具,而是持续维护的资产。建议把评测集纳入 CI 流程中,每次修改 Prompt、升级模型、调整切片参数后,自动跑一轮评测,对比准确率变化。
这样可以避免“优化了 A 类问题,结果 B 类问题回归”的情况。RAG 链路涉及模块很多,手工回归成本极高,自动化评测是长期维护的必选项。
8.5 性能侧:缓存与并发策略
RAG 链路包含向量检索、Rerank 模型推理、大模型生成,单次请求耗时比普通 API 长很多。生产环境建议:
- 对高频问题做精确匹配缓存,命中缓存直接返回。
- 对向量检索和 Rerank 结果做短时缓存,同一问题重复提问时避免重复计算。
- 大模型生成使用流式输出,降低用户等待感知。
- 如果 QPS 较高,Rerank 和大模型需要做异步化或独立部署,避免相互影响。
9. 总结:准确率优化是一套体系化工程
从 60% 到 80%,每一个百分点的提升背后几乎都是几个环节的协同改进。结合这篇文的实践,你可以按下面顺序逐一排查自己的 RAG 系统:
- 先建立评测集,量化当前准确率。
- 检查文档解析和切片策略,确保知识入库阶段没有丢失信息。
- 对比不同的 Embedding 模型,选在评测集上召回率最高的配置。
- 引入混合检索,弥补纯向量检索在精确匹配上的短板。
- 加入 Rerank 精排,过滤噪声上下文。
- 优化 Prompt 模板,加入引用溯源和“不知道就说不知道”的约束。
- 如果有多轮对话场景,补上 Query 改写模块。
RAG 优化的空间通常还很大:你可以继续深入 Agentic RAG,让大模型根据问题自主决定是否需要检索、检索多次甚至调用外部工具;也可以基于领域数据微调 Embedding 模型和 Rerank 模型,让系统更贴合自己的业务场景。
至少现在,你已经有了一个明确的优化地图。下一步,拿起自己的知识库文档,按这个流程跑一遍评测集,看看准确率能有多少提升。