但对大部分开发者来说,搭一个RAG不难,怎么把它优化成生产可用的状态最难。
在这个过程中,检索效率、准确性、成本、响应速度,都是重点关注问题。
那么,如何对其进行优化?我们可以逐步对查询、索引、检索器、生成器以及RAG pipeline这五大环节分别进行优化。
接下来,本文将对此进行逐一解读。
以下是太长不看版:
01 查询策略优化
(1)假设性问题生成
做法:先用 LLM 为文档块生成潜在用户问题,RAG 阶段先做 query-to-query 检索,搜索到相关的假设问题,然后再找到对应的文档块,最后生成回答。
优势:query-to-query检索属于对称域内训练,比基于Q-A pair的“跨域(out-of-domain)”相似检索更直观,检索效果提升。
局限:需要额外生成问题,可能有幻觉;建议对此环节离线预处理。
-
-
-
-
-
-
-
-
-
class HypotheticalQuestionGenerator:
def generate_questions(self, document_chunk):
prompt = f"""
基于以下文档内容,生成3-5个用户可能询问的问题:
文档内容:{document_chunk}
问题:
"""
questions = self.llm.generate(prompt)
return self.parse_questions(questions)
(2)HyDE(假设性文档嵌入)
做法:针对用户提问,LLM 先生成一个假答案(fake answer,可能是真,可能是假,但都不重要),再与 query 一起嵌入向量库检索。
优势:同假设性问题生成,answer-to-answer检索属于对称域内训练,可以显著提高缺乏标注数据情况下的检索召回率。
局限:引入生成开销和不确定性。
论文出处:《Precise Zero-Shot Dense Retrieval without Relevance Labels》。
(3)分解子查询
做法:复杂问题拆解为多个子查询,分别检索再综合。
优势:简化查询复杂度,提高检索相关性。
适用:功能对比、组合型问题。
举例:“Milvus和Zilliz Cloud功能差异是什么?"这样的复杂问题,将其分解为:
子查询1:"Milvus的功能特性有哪些?"
子查询2:"Zilliz Cloud的功能特性有哪些?"
然后向量数据库为每个子查询找到Top-K最相关的文档块;LLM使用这些信息生成更准确的综合答案。
(4)创建回退式提示词
做法:将复杂问题转化为更高层、更直观的问题。
优势:提升准确性,适合技术规格、容量边界类问题。
举例:把提问"我有100亿条记录的数据集,想存储在Milvus中进行查询,这可能吗?"这样的复杂查询,改为"Milvus能够处理的数据集规模上限是多少?"
02 索引策略优化
(1)自动合并文档块
做法:索引的创建分为 chunk 级别以及 parent chunk级别,如果召回的Top-K 中,某parent chunk下的子块超过阈值,就直接把parent chunk作为上下文信息提供给LLM。
优势:平衡检索精度与上下文完整性。
关键点:动态阈值调优,上下文不宜过长。
-
-
-
-
-
-
-
-
-
-
class HierarchicalChunkMerger:
def merge_chunks(self, child_chunks, threshold=3):
parent_chunk_count = {}
for chunk in child_chunks:
parent_id = chunk.parent_id
parent_chunk_count[parent_id] = parent_chunk_count.get(parent_id, 0) + 1
# 选择超过阈值的父块
selected_parents = [pid for pid, count in parent_chunk_count.items()
if count >= threshold]
return self.get_parent_chunks(selected_parents)
(2)分层索引构建
做法:为文档建立两级索引:摘要级别索引和文档块级别索引。检索时,先在摘要层级检索,再深入到对应文档块检索。
优势:适合海量数据与分层数据,尤其适合图书馆/知识库类场景。
风险:摘要质量直接影响效果,需要采用专门的摘要生成技术和质量评估机制。
(3)混合检索与重排序
做法:向量检索 + 全文检索,最后 rerank(RRF 或 Cross-Encoder)。具体参考实战Milvus 2.5:语义检索VS全文检索VS混合检索
优势:多路召回更全面,重排提升排序精度。
关键点:合理配置向量与全文检索对应的权重和参数。
03 检索器策略优化
(1)句子窗口检索Sentence Window Retrieval
背景:传统的向量检索通常以段落级或文档级为单位,这会导致:切的太粗,长段落里只有少量句子真正相关,从而引入大量噪声;切分太细,相关内容之间的联系丢失。
做法:以句子为单位检索,同时带前后若干句的上下文窗口。
优势:保证精细匹配,保留上下文,减少碎片化。
挑战:窗口大小需动态调整,避免上下文过长引入噪声,影响输出质量。
-
-
-
-
-
-
-
-
-
-
-
-
class SentenceWindowRetriever:
def retrieve_with_window(self, query, window_size=3):
# 检索核心句子
core_sentences = self.vector_search(query, top_k=5)
# 扩展窗口上下文
expanded_results = []
for sentence in core_sentences:
window_context = self.get_surrounding_sentences(
sentence, window_size
)
expanded_results.append(window_context)
return expanded_results
(2)元数据过滤
做法:做向量检索前,先基于元数据(时间、类别等)过滤。
优势:精准定位,适合金融/医药等领域。比如金融中检索某企业某一年财报中关于资产负债的描述。
难点:先做元数据过滤,再使用图索引算法,会导致图结构基本失联,可采用Alpha 策略、ACORN 、动态选择邻居解决。详情参考Milvus Week | 向量搜索遇上过滤筛选,如何选择最优索引组合?
04 生成器策略优化
(1)LLM提示压缩
背景:大模型提示词越长,对核心内容的权重分配越混乱,压缩上下文,可以帮助大模型更好捕捉重点。
做法:检索结果传给大模型前对上下文进行摘要/关键信息提取。
适用:长上下文/多文档、agent场景。
小tips:训练小模型来进行上下文压缩,压缩的核心技术包括关键信息提取、摘要生成和噪声过滤算法。
-
-
-
-
-
-
-
class PromptCompressor:
def compress_context(self, retrieved_docs, max_length=2000):
# 提取关键信息
key_info = self.extract_key_information(retrieved_docs)
# 生成压缩摘要
compressed = self.summarize_content(key_info, max_length)
return compressed
(2)块顺序优化
背景:基于“Lost in the middle”现象,LLM会给上下文的开头和结尾更高的权重,忽略中间部分内容。
做法:将高置信度内容放在上下文的首尾位置。
05 RAG pipeline整体优化
(1)自反馈机制
做法:第一轮检索不佳时,触发二次检索或推理反思。常见的反思办法有,自然语言推理(NLI)模型或互联网搜索等。
应用:Self-RAG、Corrective RAG、LangGraph 等已有探索。
(2)智能查询路由
做法:在 RAG 之前设置 agent,分析、拆解用户意图,判断是否启用 RAG/子查询/网络搜索。
优势:避免在简单问题上滥用 RAG,提升整体效率和准确性。
06 结论
RAG优化是个系统性工程,通过这些综合优化策略,企业级RAG系统能够在保证高精度的同时,显著提升系统的性能表现和用户体验。

优网科技秉承"专业团队、品质服务" 的经营理念,诚信务实的服务了近万家客户,成为众多世界500强、集团和上市公司的长期合作伙伴!
优网科技成立于2001年,擅长网站建设、网站与各类业务系统深度整合,致力于提供完善的企业互联网解决方案。优网科技提供PC端网站建设(品牌展示型、官方门户型、营销商务型、电子商务型、信息门户型、微信小程序定制开发、移动端应用(手机站、APP开发)、微信定制开发(微信官网、微信商城、企业微信)等一系列互联网应用服务。