9 种 RAG 架构深度解析:从入门到生产,每个 AI 开发者都该知道的选型指南
今天在掘金热榜看到一篇"9种RAG架构必学"的文章,阅读量涨得很快。正好最近我在几个项目里踩了不少坑,干脆结合自己的实战经验,把这9种架构逐一拆解一遍,希望对你有用。
引言:为什么 RAG 不是"一招鲜"
很多人第一次接触 RAG(Retrieval-Augmented Generation),往往只知道最简单的那种:向量化文档 → 相似度检索 → 塞进 Prompt → 丢给 LLM。这固然没错,但在生产中你会发现:
- 检索精度上不去,问个细节问题答非所问
- 上下文超长,Token 费用飙升
- 多跳推理(Multi-hop)场景完全撑不住
- 数据库里有图/表,纯文本 Embedding 搞不定
本文按照从简单到复杂的顺序,系统梳理9种主流RAG架构,每种都附上我认为最适合的应用场景和关键代码片段。
架构一:Naive RAG(朴素 RAG)
适合场景:FAQ 问答、入门原型、文档不超过几十篇
最经典的三步走:
python
from langchain.embeddings import OpenAIEmbeddings
from langchain.vectorstores import FAISS
from langchain.chains import RetrievalQA
from langchain.chat_models import ChatOpenAI
# 1. 构建向量库
embeddings = OpenAIEmbeddings()
vectorstore = FAISS.from_documents(docs, embeddings)
# 2. 创建检索器
retriever = vectorstore.as_retriever(search_kwargs={"k": 4})
# 3. 组装 QA 链
qa = RetrievalQA.from_chain_type(
llm=ChatOpenAI(model="gpt-4o"),
retriever=retriever
)
result = qa.run("什么是向量数据库?")
核心缺陷:检索的是字面相似,不是语义关联。用户问"苹果手机怎么样",可能召回一堆关于苹果公司财报的文档。
架构二:Advanced RAG(高级 RAG)
适合场景:精度要求较高的知识库问答
在 Naive RAG 基础上,增加了两个关键优化:
1. 查询改写(Query Rewriting)
python
from langchain.prompts import PromptTemplate
from langchain.chains import LLMChain
rewrite_prompt = PromptTemplate(
input_variables=["question"],
template="""请将以下用户问题改写为更适合向量检索的形式,
去除口语化表达,增加关键术语:
原始问题:{question}
改写后:"""
)
rewrite_chain = LLMChain(llm=llm, prompt=rewrite_prompt)
better_query = rewrite_chain.run(question=user_question)
2. 重排序(Reranking)
python
from sentence_transformers import CrossEncoder
reranker = CrossEncoder("BAAI/bge-reranker-base")
# 先召回多一些候选
candidates = retriever.get_relevant_documents(better_query, k=20)
# 用 CrossEncoder 重排,取 Top 4
scores = reranker.predict([(better_query, doc.page_content) for doc in candidates])
ranked = sorted(zip(scores, candidates), key=lambda x: x[0], reverse=True)
top_docs = [doc for _, doc in ranked[:4]]
我在实际项目中用 BGE-Reranker 后,答案准确率提升了约 25%,强烈建议每个项目都加上这一步。
架构三:Modular RAG(模块化 RAG)
适合场景:复杂业务系统,需要灵活拼装各个组件
把 RAG 流程拆成可插拔的模块:
css
用户问题
↓
[查询分析模块] → 判断意图、提取实体
↓
[路由模块] → 选择知识库(产品文档/技术文档/FAQ)
↓
[检索模块] → 向量/关键词/混合检索
↓
[融合模块] → 多路结果合并去重
↓
[生成模块] → 带引用的答案生成
这种架构的好处是:各模块可以独立迭代,不影响整体流程。生产级系统必备。
架构四:RAG Fusion(融合检索)
适合场景:单一查询命中率低,需要多角度召回
核心思路:用 LLM 生成多个相关查询,分别检索后用 RRF(Reciprocal Rank Fusion)合并排序。
python
def generate_queries(question: str, n: int = 4) -> list[str]:
"""生成多个角度的查询"""
prompt = f"""为以下问题生成{n}个不同角度的检索查询,每行一个:
问题:{question}
查询列表:"""
response = llm.predict(prompt)
return [q.strip() for q in response.split('\n') if q.strip()]
def rrf_score(rankings: list[list], k: int = 60) -> dict:
"""Reciprocal Rank Fusion 打分"""
scores = {}
for ranking in rankings:
for rank, doc_id in enumerate(ranking, 1):
scores[doc_id] = scores.get(doc_id, 0) + 1 / (k + rank)
return sorted(scores.items(), key=lambda x: x[1], reverse=True)
# 执行
queries = generate_queries(user_question)
all_results = [retriever.get_relevant_documents(q) for q in queries]
fused_docs = rrf_score([[doc.metadata['id'] for doc in r] for r in all_results])
亲测:在"多义词"和"模糊意图"场景下,RAG Fusion 的召回率比 Naive RAG 高出 40% 左右。
架构五:Self-RAG(自反思 RAG)
适合场景:答案质量要求极高,允许有额外延迟
Self-RAG 让模型在生成时自我评判是否需要检索,以及检索结果是否有用:
python
def self_rag_generate(question: str) -> str:
# Step 1: 判断是否需要检索
need_retrieval = llm.predict(
f"问题:{question}\n是否需要检索外部知识才能回答?(是/否)"
)
if "是" in need_retrieval:
docs = retriever.get_relevant_documents(question)
# Step 2: 评估每个文档的相关性
relevant_docs = []
for doc in docs:
relevance = llm.predict(
f"文档:{doc.page_content}\n问题:{question}\n该文档与问题相关吗?(相关/不相关)"
)
if "相关" in relevance:
relevant_docs.append(doc)
# Step 3: 生成答案并自我评估
context = "\n".join([d.page_content for d in relevant_docs])
answer = llm.predict(f"基于以下内容回答问题:\n{context}\n\n问题:{question}")
# Step 4: 验证答案是否有幻觉
is_grounded = llm.predict(
f"答案:{answer}\n来源:{context}\n答案是否完全基于来源,没有虚构内容?(是/否)"
)
return answer if "是" in is_grounded else "无法基于现有知识库回答此问题"
else:
return llm.predict(question)
代价:每次查询要多调用 3-5 次 LLM,延迟和成本显著增加。仅在高价值场景(如医疗、法律)中使用。
架构六:CRAG(Corrective RAG,纠错 RAG)
适合场景:文档质量参差不齐,需要动态纠错
CRAG 在 Self-RAG 基础上增加了纠错能力:当检索到的文档相关性低时,自动通过 Web Search 补充信息。
python
def crag_pipeline(question: str) -> str:
docs = retriever.get_relevant_documents(question)
# 评估相关性
relevance_scores = [evaluate_relevance(doc, question) for doc in docs]
avg_score = sum(relevance_scores) / len(relevance_scores)
if avg_score > 0.7:
# 文档质量高,直接用
context = "\n".join([d.page_content for d in docs])
elif avg_score > 0.3:
# 质量中等,混合使用本地+网络
web_results = web_search(question)
context = "\n".join([d.page_content for d in docs] + web_results)
else:
# 质量太低,完全依赖网络搜索
context = "\n".join(web_search(question))
return llm.predict(f"基于以下内容回答:\n{context}\n\n问题:{question}")
架构七:Graph RAG(知识图谱 RAG)
适合场景:实体关系推理、企业知识图谱、复杂依赖查询
普通向量检索找的是"相似内容",Graph RAG 找的是"关联实体":
python
from neo4j import GraphDatabase
class GraphRAG:
def __init__(self, uri, user, password):
self.driver = GraphDatabase.driver(uri, auth=(user, password))
def query_entity_context(self, entity: str, depth: int = 2) -> str:
"""查询实体及其N跳关系的上下文"""
with self.driver.session() as session:
result = session.run("""
MATCH path = (n {name: $entity})-[*1..%d]-(m)
RETURN path
LIMIT 50
""" % depth, entity=entity)
context_parts = []
for record in result:
path = record["path"]
# 将路径转换为自然语言描述
context_parts.append(path_to_text(path))
return "\n".join(context_parts)
def answer(self, question: str) -> str:
entities = extract_entities(question) # NER 提取实体
context = "\n".join([self.query_entity_context(e) for e in entities])
return llm.predict(f"已知信息:\n{context}\n\n回答:{question}")
微软 GraphRAG 是这个方向目前最成熟的开源实现,在复杂报告分析场景下比向量 RAG 强很多。
架构八:Agentic RAG(Agent 式 RAG)
适合场景:需要多步推理、工具调用、动态决策
Agentic RAG 不再是"检索 → 生成"的线性流程,而是让 Agent 自主决定何时检索、检索什么、是否需要多次迭代:
python
from langchain.agents import AgentExecutor, create_react_agent
from langchain.tools import Tool
# 定义可用工具
tools = [
Tool(
name="knowledge_base_search",
func=lambda q: retriever.get_relevant_documents(q),
description="搜索内部知识库,适合查找产品文档、技术规范"
),
Tool(
name="web_search",
func=lambda q: search_web(q),
description="搜索互联网,适合获取最新信息"
),
Tool(
name="calculator",
func=lambda expr: eval(expr),
description="计算数学表达式"
),
Tool(
name="code_executor",
func=lambda code: exec_python(code),
description="执行Python代码来验证某些假设"
)
]
# 创建 ReAct Agent
agent = create_react_agent(llm, tools, react_prompt)
executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
result = executor.invoke({"input": user_question})
我的实战观察 :Agentic RAG 适合"深度问答",但对于"快速问答"来说太重了。建议设置 max_iterations=5 防止无限循环。
架构九:Multimodal RAG(多模态 RAG)
适合场景:文档包含图表、PDF 表格、流程图
纯文本 Embedding 无法处理图像中的信息,多模态 RAG 的做法是:
python
from transformers import CLIPProcessor, CLIPModel
from PIL import Image
import torch
class MultimodalRAG:
def __init__(self):
self.clip_model = CLIPModel.from_pretrained("openai/clip-vit-base-patch32")
self.clip_processor = CLIPProcessor.from_pretrained("openai/clip-vit-base-patch32")
def embed_image(self, image_path: str) -> torch.Tensor:
"""生成图片的 CLIP Embedding"""
image = Image.open(image_path)
inputs = self.clip_processor(images=image, return_tensors="pt")
with torch.no_grad():
features = self.clip_model.get_image_features(**inputs)
return features / features.norm(dim=-1, keepdim=True)
def embed_text(self, text: str) -> torch.Tensor:
"""生成文本的 CLIP Embedding(与图片在同一语义空间)"""
inputs = self.clip_processor(text=[text], return_tensors="pt", padding=True)
with torch.no_grad():
features = self.clip_model.get_text_features(**inputs)
return features / features.norm(dim=-1, keepdim=True)
def retrieve(self, question: str, image_pool: list) -> list:
"""用文本查询找相关图片"""
query_emb = self.embed_text(question)
scores = []
for img_path in image_pool:
img_emb = self.embed_image(img_path)
score = (query_emb @ img_emb.T).item()
scores.append((score, img_path))
return sorted(scores, reverse=True)[:3]
然后用 GPT-4o 或 Claude 3.5 这类视觉模型同时处理文本 + 图片,生成最终答案。
如何选择?一张对比表
| 架构 | 复杂度 | 延迟 | 成本 | 推荐场景 |
|---|---|---|---|---|
| Naive RAG | ⭐ | 低 | 低 | 快速原型 |
| Advanced RAG | ⭐⭐ | 中 | 中 | 大多数业务场景 |
| Modular RAG | ⭐⭐⭐ | 中 | 中 | 复杂生产系统 |
| RAG Fusion | ⭐⭐ | 中高 | 中 | 多义词/模糊查询 |
| Self-RAG | ⭐⭐⭐⭐ | 高 | 高 | 高精度场景 |
| CRAG | ⭐⭐⭐ | 中高 | 中高 | 文档质量不稳定 |
| Graph RAG | ⭐⭐⭐⭐ | 中 | 高 | 实体关系推理 |
| Agentic RAG | ⭐⭐⭐⭐⭐ | 高 | 高 | 多步复杂推理 |
| Multimodal RAG | ⭐⭐⭐ | 中 | 高 | 含图表文档 |
总结
RAG 不是一个架构,而是一个架构家族。我的选型建议:
- 新项目先用 Advanced RAG:基础向量检索 + 查询改写 + BGE-Reranker,80% 的业务场景够用了
- 遇到多跳推理才上 Graph RAG:别过早引入知识图谱的维护成本
- 高价值场景才用 Self-RAG / CRAG:多余的 LLM 调用成本很高
- Agentic RAG 是终态,但不是起点:从简单架构迭代上去,别一上来就全套 Agent
最后说一句实战心得:Reranker 永远值得加。不管用哪种架构,在最后检索结果送入 LLM 之前加一个 BGE-Reranker,几乎对所有场景都有正向收益,投入产出比极高。
如果你在 RAG 实战中踩过坑,或者有其他架构经验,欢迎评论区交流 🙌