RAG概念与16种方案详解 AI应用开发必学万字干货
近两年,凡是涉足 AI 编程领域的人,几乎都听说过一个热门概念——RAG(Retrieval-Augmented Generation,检索增强生成)。
然而,很多开发者对 RAG 的理解仅仅停留在“检索增强生成”这六个字上,面试官多追问几句就容易卡壳。本文旨在进行一次全景式科普,从最基础的 Naive RAG 到当下最主流的 Agentic RAG,系统梳理 16 种主流 RAG 方案,帮你一次性理清脉络。无论未来遇到什么应用场景,你都能选出最适合的 RAG 路线。

干货满满,建议先收藏再慢慢阅读。
什么是 RAG?
AI 大模型存在几个硬伤:知识有截止日期、会一本正经地胡说八道(即“幻觉”)、缺乏企业私有知识。例如,当你问 DeepSeek“程序员鱼皮的最新项目是什么?”它可能回复两年前的老项目,技术栈完全对不上。

RAG 解决这个问题的思路非常直观——先检索,再回答。让大模型在生成答案之前,先去搜索相关的资料,然后基于这些检索到的知识来组织回答。就像考试时悄悄翻书,遇到不会的题目先翻一翻参考书,再根据书里的知识点答题。

同样的问题,如果主动给 AI 提供一些参考资料,它的回答就会准确很多。

听起来思路很简单,但在实际工程中已经演化出各种不同的实现方法,从最初的“切块→搜索→生成”到让 AI Agent 自主决策检索策略的 Agentic RAG,复杂度和能力天差地别。
有人可能会问:现在的大模型不是已经支持百万 token 的上下文窗口了,还需要 RAG 吗?答案是——需要,而且用得比以前更多。把所有文档塞进上下文窗口,既昂贵又不靠谱。上下文越长,token 费用越高,而且大模型普遍存在“Lost in the Middle”问题,对超长上下文中间部分的注意力会明显下降。这就像听别人讲话,开头和结尾印象最深,中间部分容易遗忘。
当然,RAG 和长上下文并不是互斥关系。目前的最佳实践是:先用 RAG 给 AI 提供相对精确的资料,再利用长上下文窗口进行有针对性的分析推理,两者互补。
背景交代完毕,下面正式进入主题。
主流 RAG 方案
标准 RAG 及变体
Naive RAG
Naive RAG 这个名字听起来很厉害,但 Naive 其实是“朴素”的意思,它是最基本的 RAG 实现方案。
假设你有一份 200 页的《员工手册》,如何让 AI 基于里面的内容回答员工提问?最简单粗暴的做法就是把整本手册每次都塞给 AI。但一本手册可能几十万字,全塞进去又贵又慢,而且上下文一长,大模型还容易出现前面提到的“Lost in the Middle”问题。
更合理的思路是:员工问什么,就只把相关的几段内容塞给 AI。问题又来了——怎么定位到相关的那些段落?如果仅靠关键词匹配,容易出现“老板不批假怎么办”和文档里“请假审批流程”对不上的情况。这就需要用到向量了。
所谓向量,就是把一段文字用一串数字表示出来,让计算机可以比较语义上的相似度。语义越接近的句子,向量在数学空间里离得越近。负责把文字转成向量的模型叫 Embedding 模型;存储这些向量并支持快速相似度搜索的数据库叫向量数据库,例如 Milvus、Chroma、Qdrant 等。
理解了向量,Naive RAG 的做法就很好理解了,主要分两步:
第一步是离线索引:
- 把文档切成小块(chunk),每块几百字
- 用 Embedding 模型把每个小块转成向量
- 把向量和对应原文都存进向量数据库

第二步是在线查询问答:
- 把用户问题也用 Embedding 模型转成向量
- 去向量库里搜索最相似的几个文档块(比如 Top 5)
- 把这几个块和用户问题拼成 Prompt,交给大模型生成回答
回到 200 页的员工手册场景,当员工问“年假有多少天?”时,RAG 的流程是这样的:系统把问题转成向量→在向量库中找到最相似的 5 个文档块(例如“入职满一年享有 10 天年假,满三年 15 天…”)→把这 5 个块连同问题交给大模型→大模型回答:“入职满一年享有 10 天年假”。

不过 Naive RAG 也有一些明显的问题:切块方式粗暴,可能把一段完整语义从中间截断;检索质量完全依赖 embedding 模型,搜不到就没辙;搜到了垃圾文档也不管,导致输出错误答案。这些局限正是后面所有进阶方法要解决的目标。
下面用伪代码帮助理解,不熟悉编程的同学可以跳过,不影响后续学习。
离线索引阶段:
# 1. 将文档切分为小块,chunk_size=500 表示每块 500 字,chunk_overlap=50 表示相邻块之间重叠 50 字,避免关键信息被切断
chunks = split_into_chunks(documents, chunk_size=500, chunk_overlap=50)
# 2. 将每个小块编码为向量,连同原文一起存入向量数据库
for each chunk in chunks:
vector = embedding_model.encode(chunk) # 调用 Embedding 模型编码
vector_store.insert(vector, chunk) # 向量和原文一起入库
在线查询阶段:
# 1. 用同一个 Embedding 模型将用户问题也编码为向量
query_vector = embedding_model.encode(user_query)
# 2. 在向量库中搜索最相似的 Top 5 文档块
top_k_chunks = vector_store.search(query_vector, k=5)
# 3. 将检索到的文档块拼进 Prompt,作为参考资料
prompt = "基于以下参考资料回答问题:\n" + join(top_k_chunks) + "\n问题:" + user_query
# 4. 交给大模型生成最终回答
answer = LLM.generate(prompt)
Multi-Query RAG
用户提问的方式千奇百怪。例如,同样想知道公司报销流程,有人问“怎么报销”,有人问“费用审批流程”,还有人问“花了钱怎么找公司要回来”。但文档里可能只写了“报销申请流程”这一种表述。如果用户的措辞和文档差距太大,向量检索就可能搜不到。
Multi-Query 的思路是:既然一种问法搜不全,那就让大模型把原始问题改写成多种不同的表述,分别去搜索,最后合并去重。

代价就是每次提问要多调用一次 LLM 做改写,再多跑 N 次向量检索,延迟和成本都会增加。而且如果 LLM 改写出的问题方向跑偏,会把无关文档也带进来。因此它比较适合面向普通用户的客服、电商等场景——用户表述口语化、与文档术语差距较大,多花这点成本是值得的。但在术语规范的专业领域,Multi-Query 的收益就很有限了。
Multi-Query RAG 的代码实现:
# 1. 让 LLM 将原问题改写为多个不同的表述
queries = LLM.generate("请将以下问题改写成3个不同的表述:" + user_query)
// 例如AI返回: ["报销流程是什么", "费用审批怎么操作", "如何提交报销申请"]
# 2. 每个表述分别走一次向量检索
all_results = []
for each query in queries:
results = vector_store.search(embed(query), k=5)
all_results.append(results)
# 3. 合并去重,得到覆盖面更广的候选文档
merged_chunks = deduplicate(all_results)
# 4. 将合并后的文档 + 原始问题交给大模型生成回答
answer = LLM.generate(merged_chunks + user_query)
HyDE
AI 回复效果不好,可能不是因为用户问法不好,而是用户的问题和文档的语义空间不一致。用户的提问往往很短,比如“KV Cache 是什么?”,就这么几个字。但文档里关于 KV Cache 的描述可能是一大段技术解释。一短一长,在 embedding 空间中可能离得很远,导致检索不到。
HyDE 的做法是让大模型凭空写一个答案(不必完全准确),然后用这段假答案的向量去检索。因为假答案和真实文档的文体更接近,两者在向量空间中离得也更近。
还是上面的例子,用户问:“KV Cache 是什么?”LLM 先编一段假答案:“KV Cache 是一种在 Transformer 推理过程中缓存 Key 和 Value 矩阵的优化技术,可以避免重复计算…”这段假答案虽然不一定完全准确,但它的向量和真实文档里关于 KV Cache 的描述非常接近,所以能精准命中。

不过 HyDE 也有风险:如果 LLM 编的假答案方向完全跑偏(比如把 KV Cache 理解成了 Redis 缓存),那检索结果就会更差。所以它比较适合 LLM 对问题领域有基本认知的场景,冷门领域或企业私有术语慎用。
HyDE 的代码示例:
# 1. 让 LLM 先凭空生成一段“假答案”(不必完全准确)
hypothetical_answer = LLM.generate("请回答:" + user_query)
# 2. 用假答案的向量去检索,因为它的文体更接近真实文档
hyp_vector = embedding_model.encode(hypothetical_answer)
top_k_chunks = vector_store.search(hyp_vector, k=5)
# 3. 将检索到的真实文档 + 原始问题交给大模型生成最终回答
answer = LLM.generate(top_k_chunks + user_query)
上面这三种方法,解决的是“能不能搜到”的问题。但搜到之后,资料的质量好不好呢?这就是下面要处理的了。
提升检索质量
语义分块(Semantic Chunking)
Naive RAG 里最粗暴的一步就是切块,每 500 个字切一刀,不管是不是正好切在一句话中间。比如“员工请假需要提前 3 天申请,超过 5 天需要”在这里被截断,下一块从“部门经理审批”开始,两块单独看都不完整。虽然可以通过 chunk_overlap 设置重复内容,但效果有限。
语义分块的做法是先把文档按句子拆开,计算相邻句子的 embedding 相似度,当相似度突然下降时(说明话题变了),就在这里切一刀,尽量保证每个句子的语义都完整。

代价是:需要为每一句话都计算一次 embedding,成本和耗时比按字数切分高,而且相似度阈值非常难调。所以比较适合结构松散、话题变化快的文档,比如会议纪要、访谈记录。对于本身有清晰章节结构的技术手册、产品说明文档,直接按标题切效果也不差,更便宜。
语义分块的伪代码:
# 1. 将文档拆分为单个句子
sentences = split_into_sentences(document)
chunks = []
current_chunk = [sentences[0]]
# 2. 遍历相邻句子,计算 embedding 相似度
for i from 1 to len(sentences) - 1:
similarity = cosine_similarity(embed(sentences[i-1]), embed(sentences[i]))
# 相似度骤降,表示话题切换
if similarity < threshold:
chunks.append(join(current_chunk))
current_chunk = []
current_chunk.append(sentences[i])
层级索引(Parent-Child Retrieval)
切块这件事有一个天然矛盾:切得小,检索精度高但上下文不足;切得大,上下文丰富但噪声也大。Parent-Child Retrieval 的策略是“两层都要”——先把文档切成大块,再把每个大块细分成小块。检索时用小块匹配,命中后返回它所属的大块。这相当于在书里搜到某一句话时,把所在的整个章节都拿过来看。

学过数据库的应该对这种思路不陌生。这种方案非常适合长文档场景,比如技术手册、法律合同、产品文档等,往往需要连带上下文一起看才能理解。
层级索引的伪代码:
# 1. 离线阶段:文档先切大块,再在大块内切小块
for each document:
parent_chunks = split_into_sections(document)
for each parent in parent_chunks:
child_chunks = split_into_paragraphs(parent)
# 只对小块建向量索引,但保留它属于哪个大块
for each child in child_chunks:
index.insert(embed(child), child, parent_id=parent.id)
# 2. 在线阶段:用小块做精确匹配
matched_children = index.search(embed(query), k=5)
# 3. 但返回的是小块所属的大块,保证上下文完整
parent_ids = unique([child.parent_id for child in matched_children])
context = [get_parent_chunk(pid) for pid in parent_ids]
# 4. 将大块作为上下文交给大模型
answer = LLM.generate(context + query)
Hybrid Search 混合检索
纯向量检索有一个缺点:无法精确术语匹配。比如用户问“ERROR_CODE_4012 是什么意思?”向量检索会去找语义相似的内容,但这种编码本身没什么语义,向量搜索可能找到一堆讲错误处理的段落,就是找不到那个精确提到 4012 的段落。而传统的关键词搜索擅长精确匹配,但不理解语义,比如搜“如何退款”就搜不到写着“退货及返还货款流程”的文档。
Hybrid Search 就是同时使用两种搜索然后合并排序。向量搜索负责语义理解,BM25 负责精确匹配,通过 RRF(Reciprocal Rank Fusion)算法把两边的结果合并成一个排序。

几乎所有生产环境都建议用 Hybrid Search 替代纯向量搜索,尤其是技术文档、医疗、法律等术语密集的领域。
Hybrid Search 的实现代码:
# 1. 同时跑两路检索,各自召回 Top 20
semantic_results = vector_store.search(embed(query), k=20)
keyword_results = bm25_index.search(query, k=20)
# 2. 用 RRF 算法融合两路结果,公式:1 / (60 + 排名),分数越高越相关
for each doc in (semantic_results ∪ keyword_results):
score = 0
if doc in semantic_results: score += 1 / (60 + rank_in_semantic)
if doc in keyword_results: score += 1 / (60 + rank_in_keyword)
# 3. 按融合后的分数排序,取 Top 5 交给大模型
final_results = sort_by_score(all_docs, top_k=5)
answer = LLM.generate(final_results + query)
Reranking 精排
不管是向量搜索还是 Hybrid Search,检索回来的候选文档里总会混着一些看起来相关但实际没用的噪声。Reranking 的做法是在检索和生成之间加一个精排步骤:用 Reranker 模型给每对 (query, doc) 重新打分。前面提到的 embedding 模型是分别给 query 和 doc 算向量再比较距离,快但粗糙;Reranker 是把它们拼在一起送进模型打分,慢但精准。
在实际生产中,如果语料库有十万级以上的 chunk,一般会采用级联检索方案,分层筛选:

为什么要分这么多层?如果粗检索只捞 20 个内容,在大型语料库里很容易漏掉关键文档;但如果一次性捞 150 个,全送进 Cross-Encoder 算力扛不住。分层筛选是在召回率和计算成本之间找平衡。当语料库 chunk 比较多时,Reranking 的效果提升非常显著。可以这样理解:粗检索负责不遗漏,精排负责不掺假,跟推荐系统里的粗排和精排很像。
分层筛选的实现代码:
# 第一层:粗检索,保证召回率
candidates = hybrid_search(query, k=150)
# 第二层:轻量 Reranker 初筛
semi_final = lightweight_reranker.rank(query, candidates, top_k=20)
# 第三层:Cross-Encoder 精排,只处理 20 个
scored = []
for each doc in semi_final:
score = cross_encoder.score(query, doc)
scored.append((doc, score))
top_docs = top_k(scored, k=5)
answer = LLM.generate(top_docs + query)
到这里,已经能搭出一个相当不错的 RAG 系统了。语义分块 + Hybrid Search + Reranking,这三板斧组合起来,就是大多数生产级 RAG 系统的基础配置。
前面的方法都在优化怎么搜得更准,但有一个更根本的问题没解决:如果搜到的全是垃圾,大模型还是会一本正经地基于这些垃圾内容生成答案。这就像开卷考试带错了书,还照着抄了上去……所以接下来要聊一聊,怎么让 RAG 学会自我纠错。
RAG 反思机制
Corrective RAG(CRAG)
不管我们怎么优化检索,总会有搜不到或者搜歪了的情况。这时候大模型如果还硬着头皮拿这些内容去回答,那就避免不了一本正经地胡说八道。CRAG 就是通过“把搜到的资料过滤一遍”来解决这个问题的。
具体做法是在检索和生成之间插入一个质检员,逐个审查检索到的文档是否和问题相关,然后根据审查结果走不同分支:
- 打分高的,说明资料靠谱,直接喂给大模型生成答案
- 打分低的,说明内部知识库里压根没找着相关内容,干脆回退到 Web 搜索兜底
- 打分模糊的,把两边的结果合一起送进去

Corrective RAG 的示例实现:
# 1. 先跑一遍常规检索
docs = retriever.search(query, k=5)
# 2. 逐个让 LLM 判断文档是否与问题相关
relevant_docs = []
for each doc in docs:
score = LLM.judge("这段内容和问题相关吗?", query, doc)
if score > threshold:
relevant_docs.append(doc)
# 3. 根据审查结果走不同分支
if len(relevant_docs) > 0:
answer = LLM.generate(relevant_docs + query)
else:
new_query = LLM.rewrite(query)
web_results = web_search(new_query)
answer = LLM.generate(web_results + query)
最关键的是那个 else 分支:如果内部知识库完全搜不到有用信息,CRAG 会自动回退到 Web 搜索(当然也可以是其他策略)。
Self-RAG
CRAG 在检索阶段做了质检,但生成阶段呢?大模型完全有可能拿到了正确的参考资料,但回答的时候夹带私货,在答案里掺入了参考资料中根本没提到的内容——这就是生成阶段的幻觉。
Self-RAG 的思路是在整个流程中设置四个检查点,每一步都让模型自我审视:
- 这个问题需要检索吗(Retrieve)?
- 检索到的文档相关吗(IsRel)?
- 我的回答有文档支撑吗(IsSup)?
- 这个答案对用户有用吗(IsUse)?

Self-RAG 的示例实现:
# 1. 判断这个问题是否需要检索
need_retrieval = LLM.judge("这个问题需要外部知识吗?", query)
if not need_retrieval:
return LLM.generate(query)
# 2. 检索 + 逐个过滤相关文档
docs = retriever.search(query, k=5)
relevant_docs = filter(docs, where LLM.judge("和问题相关吗?") == true)
# 3. 生成初步答案
answer = LLM.generate(relevant_docs + query)
# 4. 检查答案的每个论断是否都有文档依据
is_supported = LLM.judge("答案中的每个论断都能在文档中找到依据吗?", answer, relevant_docs)
if not is_supported:
answer = LLM.regenerate(relevant_docs + query + "请严格基于参考资料回答")
一般来说第三个检查点的价值相对较高,能在一定程度上避免 AI 的幻觉。
Adaptive RAG
CRAG 和 Self-RAG 都在给 RAG 加流程来解决问题,但这样增加了多次 LLM 调用,提升了成本。如果用户问的是“你好”或者“今天星期几”,还要跑一遍完整的检索+质检+生成流程,有点开着坦克去买菜的意思,纯属浪费。
Adaptive RAG 在最前面加了一个路由器(分类器),先判断问题的复杂度,然后决定走哪条路线:

Adaptive RAG 的实现代码很简单:
complexity = classifier.predict(query)
# 简单问题直接答
if complexity == "simple":
answer = LLM.generate(query)
# 一般问题检索一次
else if complexity == "moderate":
docs = retriever.search(query)
answer = LLM.generate(docs + query)
# 复杂问题采用 CRAG
else:
answer = run_full_crag_pipeline(query)
这个分类器可以是一个微调的小模型,也可以用 LLM 的 few-shot 实现,关键是让简单问题和复杂问题分别处理。这种方案适合流量混杂的场景,比如既有“公司地址在哪”这种一句话能答的问题,又有“对比 A 和 B 两个方案的优缺点”这种需要多文档综合分析的复杂问题。
上面这些方法处理的都是非结构化文本,但如果数据是关系网络或者表格呢?那就需要下面的方法了。
结构化知识增强
GraphRAG
前面这些方法都有一个共同的问题:答案必须落在某一个文档块里。但现实里经常有一类问题——答案散落在多个文档中,需要串起来推理。举个例子,文档 A 写着“张三是 AI 部门的负责人”,文档 B 写着“AI 部门属于技术中心”。用户问:“张三属于哪个中心?”传统向量检索大概率只能搜到文档 A,但要回答这个问题,必须把 A 和 B 连起来推理:张三→AI 部门→技术中心。这种跨文档的多跳推理,纯向量搜索很难搞定。
GraphRAG 就是用来解决这种问题的,这是 Microsoft Research 在 2024 年提出的方法。

它的思路是先把文档变成知识图谱,再基于图谱来检索和推理。具体做法分 3 步:
- 用 LLM 逐篇读文档,抽取里面的实体(人、部门、产品等)和关系,构建成一张图谱
- 用 Leiden 算法对图谱做社区划分,把关联紧密的实体聚成一团,然后让 LLM 为每个社区生成一段摘要
- 提问时先定位到相关实体,沿着关系拿到子图

根据微软的评测,在全局语义理解类问题上,GraphRAG 答案的全面性和多样性显著优于传统向量 RAG。但对于简单的事实查询,两者效果差不多,没必要用。需要注意的是,GraphRAG 要用 LLM 逐篇抽实体关系,图谱构建成本比向量索引高得多,查询延迟也更大,使用之前一定要评估是否必要。
GraphRAG 的伪代码实现:
# 1. 离线阶段:用 LLM 从每篇文档中抽取实体和关系,构建知识图谱
for each document:
entities, relations = LLM.extract("请抽取文中的实体和关系", document)
knowledge_graph.add(entities, relations)
# 2. 用 Leiden 算法做社区划分,并为每个社区生成摘要(用于回答全局性问题)
communities = leiden_algorithm(knowledge_graph)
for each community:
summary = LLM.summarize(community.entities, community.relations)
# 3. 在线阶段:先定位相关实体,沿关系遍历 2 跳获取子图
relevant_entities = knowledge_graph.search("张三")
subgraph = knowledge_graph.traverse(relevant_entities, hops=2)
# 4. 将子图和社区摘要作为上下文交给大模型生成回答
answer = LLM.generate(subgraph + community_summaries + query)
Text-to-SQL RAG
如果数据本身就是结构化的表格(比如销售数据、用户行为日志、财务报表),传统 RAG 就不合适了——对表格数据做 embedding 非常低效。用户问“上个月销售额最高的产品是哪个?”本质上就是一条 SQL,向量搜索对这种聚合、排序、筛选类的需求完全没辙。
Text-to-SQL RAG 的做法是让 LLM 直接把自然语言翻译成 SQL,执行查询,再把查询结果作为上下文来回答。

这个方案适合所有数据分析类需求,比如 BI 看板问答、数据库运维助手、财务报表查询等,本质上是用 LLM 替代了手写 SQL。不过要特别提醒:生产环境中绝对不能让 LLM 生成的 SQL 直接执行,必须配备只读权限控制、SQL 语法审计、沙盒隔离等安全措施,防止 SQL 注入。
Text-to-SQL RAG 的伪代码:
# 1. 准备表结构(schema)作为提示,让 LLM 知道有哪些表、字段
schema = "表 sales: product(产品名), amount(金额), month(月份), region(地区)"
# 2. 让 LLM 将自然语言问题翻译为 SQL
sql = LLM.generate("根据以下表结构,将问题转为 SQL:\n" + schema + "\n问题:" + query)
# 3. 在数据库中执行 SQL,拿到结构化结果
result = database.execute(sql)
# 4. 将查询结果喂给 LLM,让其用自然语言组织成最终回答
answer = LLM.generate("查询结果:" + result + "\n请用自然语言回答:" + query)
到这里已经讲了很多种 RAG 方法。有的小伙伴可能已经注意到:前面大多数方法都是预定义好的 pipeline,流程是死的,不管什么问题进来,处理方式都差不多。但现实世界的问题千变万化——有的需要搜向量库,有的该查数据库,有的应该搜 Web,甚至有的根本不需要检索。有没有一种方法能让系统自己判断该怎么做?
答案就是 Agentic RAG。
智能体驱动 RAG
Agentic RAG
前面每种方法都有自己擅长的场景:Hybrid Search 擅长术语密集的文档,GraphRAG 擅长多跳推理,Text-to-SQL 擅长结构化数据。但在一个真实系统中,这些场景可能同时存在。比如用户问“张三上个月的考勤记录”得查数据库,问“公司的远程办公政策”得搜文档,问“张三属于哪个部门的哪个中心”得走知识图谱。为每种问题硬编码一条 pipeline 太麻烦了。
Agentic RAG 的做法是让一个 AI Agent 来自动调度,根据问题自主决定每一步该怎么做。给这个 Agent 配备一组检索工具,它会先搜搜看→看看结果够不够→不够就换个方式/换个关键词再搜→结果够了就生成回答。

Agentic RAG 虽然灵活,但代码实现的核心是 Agent Loop 循环:
# 1. 给 Agent 配一组工具(向量检索、Web 搜索、SQL 查询、图谱遍历……)
tools = {
"vector_search": query -> vector_store.search(embed(query)),
"web_search": query -> search_engine.search(query),
"sql_query": query -> database.execute(LLM.to_sql(query)),
"graph_traverse": query -> knowledge_graph.traverse(query),
}
# 2. 进入 ReAct 循环:思考 → 行动 → 观察,直到信息足够为止
context = []
while true:
# 让 LLM 基于已知信息,决定下一步用哪个工具,或者直接回答
thought = LLM.reason("问题:" + query + "\n已知信息:" + context + "\n我应该使用哪个工具?还是信息已经足够可以回答了?")
# 如果决定作答,跳出循环
if thought.action == "answer":
return LLM.generate(context + query)
# 否则调用对应工具,把结果追加到上下文,进入下一轮
result = tools[thought.tool](thought.tool_input)
context.append(result)
以前 Agent 概念刚火起来的时候,大家还在争论“Agent 自主决策靠不靠谱”。到了今天,Agentic RAG 已经是比较主流的生产范式了,知名的 AI 编程工具 Cursor 用的就是这种方式——AI 自主决定使用什么方式来搜集信息。

Multi-Agent RAG
单个 Agent 处理复杂任务时,可能有个问题:当它要同时兼顾理解意图、选择策略、验证质量、生成答案时,Prompt 变得又长又复杂,决策质量就会下降。这就像一个人又当程序员、又教人打篮球、又当说唱歌手,忙不过来。
Multi-Agent RAG 的做法是拆分为多个专职 Agent,各自负责一些任务。例如 Router Agent 负责分发、各 RAG Agent 负责对应领域的检索和推理、Verification Agent 负责质检、Generation Agent 负责润色输出。

这种方案适合数据源多、权限复杂、语言多样的企业级知识库。每个环节可以独立优化和扩展,不会牵一发而动全身。
Multi-Agent RAG 的代码示例:
# 1. Router Agent 先识别问题意图,决定分给哪个专职 Agent
intent = router_agent.analyze(query)
# 2. 各领域 Agent 各管一摊,独立完成检索和推理
if intent == "document_qa":
raw_answer = doc_agent.run(query)
else if intent == "data_analysis":
raw_answer = sql_agent.run(query)
else:
raw_answer = graph_agent.run(query)
# 3. Verifier Agent 做质检,发现问题则提出修改建议
verified = verifier_agent.check(query, raw_answer)
if not verified.passed:
raw_answer = verifier_agent.suggest_fix(raw_answer)
# 4. Writer Agent 做最终润色,统一输出风格
final_answer = writer_agent.polish(query, raw_answer)
RAG 能力扩展
多模态 RAG(Multimodal RAG)
传统 RAG 只处理文本,但现实中的企业文档里充斥着大量图表、流程图、架构图、产品照片。如果用纯文本 RAG 处理一份真实文档,那些流程图、架构图里的信息就全丢了。
多模态 RAG 的做法是把图片、表格和文本统一到一个向量空间里,这样检索时就能跨模态匹配。最后一步生成阶段,需要用视觉语言模型来处理混合模态的上下文,因为普通的纯文本 LLM 看不懂图片。

多模态 RAG 的代码实现比较复杂:
// 离线:文本和图片统一编码到同一个向量空间
for each page in document:
text_chunks = extract_text(page)
images = extract_images(page)
tables = extract_tables(page)
for each chunk in text_chunks:
index.insert(text_encoder.encode(chunk), chunk, type="text")
for each image in images:
index.insert(vision_encoder.encode(image), image, type="image")
for each table in tables:
index.insert(table_encoder.encode(table), table, type="table")
// 在线:统一检索,跨模态匹配
results = index.search(text_encoder.encode(query), k=5)
// results 中可能混合了文本块、图片、表格
answer = vision_LLM.generate(results + query)
// 用视觉语言模型处理混合内容
Speculative RAG
普通 RAG 还有一个问题:如果把检索到的所有文档都塞进同一个 Prompt,不仅增加了推理延迟,而且如果某个文档是噪声,整个生成都会被带偏。
Speculative RAG(假设性检索增强生成)借鉴了推测性解码(Speculative Decoding)的思想,核心目标是降低延迟——把检索到的文档分成多个子集,用多个专家小模型从每个子集并行生成候选草稿,最后由一个更强的大模型做一次验证,选出最佳答案。

这就有点像团队共同做个大项目:多位前端和后端开发一起干活和仔细验证,最后产品经理只需要简单验证就好,能大幅缩短工作总时长,有问题也更容易发现。
Speculative RAG 的实现代码:
# 1. 检索阶段召回较多的候选文档
docs = retriever.search(query, k=15)
# 2. 将候选文档拆成 n 个子集,准备并行处理
subsets = split_into_subsets(docs, n=5)
# 3. 多个小模型并行生成候选草稿,每个草稿只看一部分文档
drafts = parallel_run(for each subset in subsets:
draft = small_LM.generate(subset + query)
return { draft, subset, confidence })
# 4. 大模型做一次验证,从多个草稿中选出最佳答案
best = large_LM.verify_and_select(drafts, query)
return best.answer
方法选择
看到这里,你可能已经被这十几种 RAG 方案搞晕了。到底该用哪一种?
下面这张表格可以直接根据项目情况来选:
| 你的情况 | 推荐方案 |
|---|---|
| 标准文本知识库,追求基本可用 | Naive RAG |
| 用户提问风格多变、口语化 | Multi-Query RAG 或 HyDE |
| 生产环境,追求检索质量 | Hybrid Search + Reranking |
| 对准确率要求高,不能容忍幻觉 | Corrective RAG 或 Self-RAG |
| 查询复杂度差异大 | Adaptive RAG 路由 |
| 需要跨文档多跳推理 | GraphRAG |
| 数据以结构化表格为主 | Text-to-SQL RAG |
| 文档包含大量图表/图片 | 多模态 RAG |
| 多数据源、多类型混合 | Agentic RAG / Multi-Agent RAG |
| 延迟敏感 | Speculative RAG |
对于正在动手搭建 RAG 系统的初学者来说,建议从简单开始,逐步完善。先跑通 Naive RAG,发现哪个环节出了问题,就针对性地选用前面的 RAG 方案。千万别一上来就搞 Multi-Agent + GraphRAG + 多模态全家桶,不仅实现成本高,效果也不一定更好。

那么怎么知道 RAG 系统效果好不好呢?这里有一个评估框架 RAGAS,包含四个核心指标:
- 忠实度:回答有没有瞎编
- 答案相关性:答的是不是你问的
- 上下文精确率:搜到的有多少是有用的
- 上下文召回率:该搜到的搜到了吗
这样就能先评估效果再优化,而不是凭感觉调参数。
除此之外,RAG 相关的主流技术还有编排框架 LangChain/LangGraph、LlamaIndex,一体化平台 Dify、RAGFlow,向量数据库 Chroma、Milvus、Qdrant 等。感兴趣的话可以自行学习了解。
OK,这篇文章写了将近 1 万字,把 16 种 RAG 的实现和优化方案都讲完了,希望对大家有所帮助。

游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。
同类文章
Woebot Health聊天式AI提供可及心理健康支持
Woebot Health 产品介绍:AI 聊天式心理健康支持工具谈及心理健康支持,许多人都会遇到相似的困境:预约心理咨询师,等待数周已是常态;保险条款复杂难懂;好不容易排上号,时间和地点又难以配合。这正是 Woebot Health 希望解决的问题——借助基于聊天界面的 AI 工具,让心理健康支持
智谱AutoClaw实测 1分钟部署OpenClaw集成浏览器上网能力
最近,OpenClaw 的热度持续攀升,它正在重新定义我们与AI的协作方式。过去,AI更像一个被动的聊天机器人,而OpenClaw的出现,让它摇身一变,成了一个不知疲倦、全天候待命的“数字员工”。 不妨想象一下这样的场景:当你进入梦乡时,AI正在后台默默搜集资料;当你短暂休息时,AI仍在持续处理任务
英博云EB Cloud专业GPU租用平台
英博云 EB Cloud:崛起中的AI算力服务平台 如果你最近在关注大模型训练和推理的基础设施,应该会注意到一个名字——英博云 EB Cloud。简单来说,这是英博数科(鸿博股份全资子公司)推出的一套AI算力与大模型应用服务平台。其核心定位清晰:为AI大模型提供低成本、高效能、多元化的智算服务。 那
阿里QoderWork实测 打工人零配置桌面AI助手替代OpenClaw
最近,一款名为OpenClaw的“小龙虾”AI工具在科技圈引发广泛关注。看到网友们纷纷展示AI自主操控电脑、编写代码的成果,确实令人心动不已。 然而,心动之后往往要面对现实的挑战。要真正配置好OpenClaw,门槛并不低:你需要熟悉本地环境搭建,驾驭动辄几十GB的庞大语言模型,还得确保电脑24小时在
请提供原始文章标题
Chat2Course是什么 简而言之,这是一款面向在线教育领域的AI课程生成工具,核心用户群体包括教育者、培训师以及企业培训部门。它的主要使命是:帮助你迅速、高效地创建在线课程。你可以将其视为一个“智能课程构建器”——你提出需求,它利用AI技术自动输出课程大纲、互动内容,甚至能为不同学习者量身定制
- 日榜
- 周榜
- 月榜
1
2
3
4
5
6
7
8
9
10
相关攻略
2015-03-10 11:25
2015-03-10 11:05
2021-08-04 13:30
2015-03-10 11:22
2015-03-10 12:39
2022-05-16 18:57
2025-05-23 13:43
2025-05-23 14:01
热门教程
- 游戏攻略
- 安卓教程
- 苹果教程
- 电脑教程
热门话题

