RAG 架构总览
从 Naive RAG 到 Modular RAG,全面理解检索增强生成的架构演进与核心流程
RAG 背景与动机
大型语言模型(LLM)在自然语言处理领域取得了突破性进展,但其固有缺陷限制了在真实生产环境中的应用:
- 知识截止:模型训练数据存在时间截断,无法感知训练完成后发布的新知识。例如,基于 2023 年数据训练的模型无法回答 2024 年发生的新闻事件。
- 幻觉问题:LLM 倾向于生成流畅但事实上不正确的回答。研究表明,即使最先进的大模型在面对超出其知识边界的查询时,仍然会产生 15%-30% 的幻觉内容。
- 实时性不足:重新训练或微调模型以注入最新知识的成本极高,无法满足高频更新的业务场景需求。
检索增强生成(Retrieval-Augmented Generation, RAG)通过引入外部知识库检索机制,从根源上解决了上述问题。RAG 不在训练阶段修改模型参数,而是在推理阶段从向量数据库或搜索引擎中检索与用户查询最相关的文档片段,将其作为上下文注入提示词,引导模型生成基于事实的回答。
与传统的纯参数化记忆相比,RAG 将知识存储从模型参数转移到了外部索引,使得知识更新只需更新索引库而无需重新训练模型,大幅降低了知识维护成本。
Naive RAG 基础架构
Naive RAG 是最经典的三阶段流水线架构,也是后续演进的基础范式。
第一阶段:Indexing(索引构建)
索引阶段将原始文档处理为可供向量检索的结构化数据,是整个 RAG 系统的基石。
1. 文档加载与解析:将 PDF、HTML、Markdown、Word 等不同格式的文档统一解析为纯文本。
2. 文本分块(Chunking):将长文本按语义边界或固定长度切分为独立片段。常见策略包括:
- 固定长度分块(如 512 tokens,128 tokens 重叠)
- 递归字符分块(以段落、句子、词语为层级递归拆分)
- 语义分块(基于 embedding 相似度判断分割点)
3. 向量化(Embedding):使用文本嵌入模型(如 text-embedding-3-small、bge-large-zh)将每个 Chunk 转换为固定维度的向量。
4. 存储索引:将向量及其对应的元数据(来源文档、位置、标题等)存入向量数据库(如 Milvus、Pinecone、Weaviate、Qdrant)。第二阶段:Retrieval(检索)
收到用户查询后,系统执行以下检索流程:
# 伪代码示例:向量检索流程
def retrieve(query: str, top_k: int = 5) -> List[Document]:
# 1. 将用户查询向量化
query_vector = embedding_model.encode(query)
# 2. 在向量数据库中执行近似最近邻搜索(ANN)
results = vector_store.similarity_search(
query_vector,
k=top_k,
score_threshold=0.75 # 相似度阈值过滤
)
# 3. 返回与查询最相关的前 k 个文档片段
return results常用检索算法包括余弦相似度、欧几里得距离和点积相似度。现代向量数据库采用 HNSW(Hierarchical Navigable Small World)或 IVF(Inverted File Index)等近似最近邻算法,在十亿级数据规模下仍保持毫秒级延迟。
第三阶段:Generation(生成)
将检索到的文档片段与原始查询拼接为增强提示词,送入 LLM 生成最终回答:
# 伪代码示例:提示词拼接与生成
def generate(query: str, retrieved_docs: List[Document]) -> str:
# 拼接上下文
context = "\n\n".join([
f"[来源 {i+1}] {doc.text}"
for i, doc in enumerate(retrieved_docs)
])
# 构建增强提示词
prompt = f"""请根据以下上下文信息回答用户的问题。
如果上下文中没有相关信息,请明确告知无法回答,不要编造。
上下文信息:
{context}
用户问题:{query}
回答:"""
# 调用 LLM 生成回答
response = llm.chat(prompt)
return responseAdvanced RAG 演进
Naive RAG 在实践中暴露了检索质量不稳定、上下文窗口浪费等问题。Advanced RAG 在上述三阶段基础上引入了精细化优化策略。
Pre-Retrieval 优化
在检索之前对用户查询进行预处理,提升检索命中率:
- 查询重写(Query Rewriting):将模糊或简短的查询改写为更精确的表达。例如,"它的作者是谁"重写为"《三体》的作者刘慈欣是谁"。
- 查询扩展(Query Expansion):使用 LLM 或同义词库生成查询的多个变体,扩大召回覆盖范围。例如,查询"机器学习"可扩展为"机器学习、深度学习、神经网络、监督学习"。
- HyDE(Hypothetical Document Embeddings):先让 LLM 基于查询生成一个假设的理想答案文档,再用该文档的向量去检索真实文档,缩小查询与文档之间的语义鸿沟。
Post-Retrieval 优化
在检索结果返回后、生成之前,对结果进行精炼:
- 重排序(Re-ranking):使用交叉编码器(Cross-encoder)模型对初筛结果逐对打分,重新排序。交叉编码器计算精度高但速度慢,适合对 top-50 或 top-100 的结果进行二次排序,选出 top-5 送入生成阶段。
- 结果过滤(Filtering):基于元数据过滤(如时间范围、文档来源、相关性阈值),剔除低质量或不相关的结果。
- 上下文压缩(Context Compression):对检索到的文档进行摘要或关键句提取,减少冗余信息,降低对 LLM 上下文窗口的占用。
混合检索策略
单一向量检索无法应对所有场景。混合检索(Hybrid Search)将向量搜索与关键词搜索结合,兼顾语义理解与精确匹配:
# 伪代码示例:混合检索
def hybrid_search(query: str, top_k: int = 10) -> List[Document]:
# 向量检索:捕获语义相似
vector_results = vector_store.similarity_search(
embedding_model.encode(query), k=top_k
)
# 关键词检索(BM25):捕获精确匹配
keyword_results = bm25_search(query, k=top_k)
# 融合排序(Reciprocal Rank Fusion)
combined = reciprocal_rank_fusion(
[vector_results, keyword_results],
weights=[0.6, 0.4] # 语义权重略高于关键词
)
return combined[:top_k]BM25 算法擅长处理术语匹配、代码片段、产品编号等精确查询,与语义检索形成互补。
Modular RAG 模块化架构
Modular RAG 将检索生成流程拆解为独立的可组合模块,支持根据不同业务场景灵活编排工作流。
各模块职责说明:
| 模块 | 功能 | 典型实现 |
|---|---|---|
| Search | 从多源数据存储中检索相关文档 | 向量检索、BM25、SQL 查询、图查询 |
| Filter | 对检索结果进行精炼与过滤 | 元数据过滤、去重、重排序、上下文压缩 |
| Memory | 维护对话历史与短期/长期记忆 | 滑动窗口、记忆摘要、结构化记忆 |
| Fusion | 融合多路检索结果 | RRF 融合、加权平均、LLM 排序融合 |
| Route | 根据查询意图路由到不同处理管线 | 意图分类器、LLM 路由决策、规则引擎 |
| Predict | 基于最终上下文生成回答 | LLM 调用、流式输出、结构化输出 |
模块化架构的核心优势在于可组合性。以智能客服场景为例:
# 示例:智能客服场景的工作流编排
pipeline:
- module: Route
params:
classifier: intent_classifier
routes:
order_query: [search_order_db, predict]
product_info: [search_product_index, re_rank, predict]
complaint: [search_order_db, search_qa_db, fusion, predict]
- module: Memory
params:
strategy: sliding_window
window_size: 10
- module: Search
params:
sources:
- type: vector_store
embedding: bge-large-zh
top_k: 3
- type: bm25
top_k: 3
- module: Filter
params:
re_ranker: bge-reranker-large
threshold: 0.8
- module: Fusion
params:
strategy: reciprocal_rank_fusion
- module: Predict
params:
model: gpt-4o
temperature: 0.3RAG vs 微调对比
RAG 与模型微调(Fine-tuning)是两种互补的技术路线,适用于不同场景:
| 对比维度 | RAG | 微调(Fine-tuning) |
|---|---|---|
| 知识更新 | 只需更新索引库,成本低、速度快 | 需要重新训练模型,周期长、成本高 |
| 幻觉控制 | 基于检索事实生成,幻觉率低 | 依赖参数化记忆,高知识密度场景易产生幻觉 |
| 实时性 | 检索结果实时反映最新数据,天然支持实时查询 | 只能反映训练截止前的知识 |
| 长尾知识 | 通过检索覆盖稀缺知识,效果好 | 低频知识难以有效记忆,容易遗忘 |
| 推理成本 | 每次需检索 + 生成,延迟较高 | 仅需推理,延迟低 |
| 模型行为 | 不改变模型参数,行为不变 | 可定制输出风格、格式、领域术语 |
| 数据隐私 | 数据不出本地索引库,隐私保护较好 | 微调数据需传输给模型服务方 |
| 实现复杂度 | 需搭建索引、检索、重排序等基础设施 | 需要准备高质量标注数据集 |
选型建议:需要高频知识更新、强实时性、低幻觉的场景优先选择 RAG;需要定制输出风格、指令遵循能力、领域语言习惯的场景优先选择微调。两者也可结合使用,即微调模型领域能力 + RAG 注入实时知识,兼顾质量与新鲜度。
主流 RAG 框架
以下框架为当前社区最主流的 RAG 开发工具,各有侧重:
- LangChain:最流行的 LLM 应用开发框架,提供了完整的 RAG 组件链,包括文档加载器、文本分割器、向量存储封装、检索器和提示词模板。生态丰富,社区活跃度最高。
- LlamaIndex:专注于数据索引和检索场景,提供了精细化的索引结构设计(树索引、关键词表索引、向量索引)和高级查询引擎,适合对检索粒度有较高要求的场景。
- Haystack:由 deepset 公司开源的端到端 NLP 框架,内置了完整的 RAG 管线,支持多种检索器和阅读器组合,提供友好的 API 接口和可视化 Pipeline 编辑器。
- RAGFlow:基于深度文档理解的 RAG 引擎,在文档解析环节拥有显著优势,能够处理复杂版面(表格、多栏、页眉页脚)的解析,适合企业级文档密集型场景。
- FastGPT:面向知识库问答场景的开源平台,提供了可视化的知识库管理、工作流编排和 API 发布能力,降低了 RAG 应用的上手门槛。
以上框架均支持私有化部署,在数据安全方面有良好保障。实际选型时,建议根据文档复杂度、检索精度要求、开发团队技术栈等因素综合评估。
结语
RAG 架构从 Naive RAG 的三阶段流水线,到 Advanced RAG 的精细化优化,再到 Modular RAG 的模块化编排,其演进路径反映了业界对检索增强生成的理解不断深化。对于希望在生产环境中落地 LLM 应用的团队而言,深入理解 RAG 各层架构的设计取舍和技术细节,是构建可靠、可控、可维护的 AI 应用的基础。