AI 系统设计

RAG 系统架构设计深度解析

从 Chunk 策略、Embedding 模型、向量检索、Hybrid Search 到重排与评估, 全面剖析企业级 RAG 系统的核心架构设计与最佳实践

📅 2026年5月 ⏱️ 约25分钟阅读 👨‍💻 高级架构
目录

概述

Retrieval-Augmented Generation (RAG) 已成为大语言模型应用的核心架构范式。 它通过将外部知识检索与 LLM 生成能力相结合,有效解决了纯 LLM 的知识时效性、 hallucination 以及缺乏垂直领域知识等问题。本文将从资深架构师视角, 系统性地解析 RAG 系统从数据处理到最终输出的完整技术链条。

💡 核心价值

RAG 的本质是 Context Augmentation——通过在推理时动态注入 相关上下文,让 LLM 能够在「看到」最新、最准确信息的前提下生成回答。

系统架构总览

文档上传
文本分割
Embedding
向量数据库
检索引擎
重排
LLM 生成

一个完整的 RAG Pipeline 包含两个核心阶段:

Indexing Pipeline(索引阶段)

负责将原始文档转化为可检索的知识库。这一阶段的质量直接决定了 后续检索阶段的上限。关键步骤包括:文档解析、文本分块 (Chunking)、 向量化 (Embedding) 以及向量存储。

Query Pipeline(查询阶段)

负责将用户问题转化为精准的答案。这一阶段涉及:Query 理解、 向量检索、Hybrid Search(混合检索)、Reranking(重排序)以及 最终的 LLM 生成。

⚠️ 常见误区

许多团队将大量精力投入在 LLM 调优上,却忽视了索引阶段的质量。 实际上,GIGO (Garbage In, Garbage Out) 在 RAG 系统中 表现得尤为明显——糟糕的分块策略和低质量的 Embedding 会导致 即使最先进的 LLM 也无法给出准确的答案。

Chunk 策略

Chunk 策略是 RAG 系统设计中最基础也最关键的决策之一。 它直接影响:检索精度(Chunk 太小导致语义不完整)、上下文利用率 (Chunk 太大导致关键信息被淹没)以及检索延迟与存储成本。

主流分块方法

固定大小分块

  • 实现简单,一致性强
  • 无法考虑语义边界
  • 适合结构化程度低的文本
chunk_size = 512
chunk_overlap = 50

语义分块

  • 基于句子/段落边界切分
  • 保留完整语义单元
  • 需要 NLP 预处理支持

递归字符分块

  • LangChain 默认策略
  • 递归尝试不同分隔符
  • 平衡效果与实现复杂度

领域感知分块

  • 针对代码、表格、公式优化
  • 需要领域知识介入
  • 效果最优但实现成本高

Chunk Size 选择

Chunk Size 的选择需要综合考虑以下因素:

应用场景 推荐 Chunk Size Overlap 说明
通用文档问答 512 tokens 50 tokens 平衡语义完整性与检索精度
代码库问答 256-512 tokens 50-100 tokens 保持函数/类的完整性
长文档摘要 1000+ tokens 100 tokens 保留更多上下文用于生成
表格密集型文档 按表格结构切分 0 表格需整体保留
多语言文档 句子级别 依赖语言特性 不同语言断句规则不同

高级分块策略

父子块分块 (Parent Document Retrieval)

采用两层分块结构:子块(Small Chunk)用于精确检索,父块(Large Chunk) 用于最终上下文注入。检索时先找到相关子块,再召回其所属的父块。

Small Chunk → 精确匹配 → Parent Chunk → 上下文注入

语义分块 (Semantic Chunking)

通过计算相邻句子之间的语义相似度,动态决定断点。当相似度低于阈值时, 触发新的 Chunk。这种方法产生的块大小不均匀,但语义更加连贯。

结构感知分块

利用文档结构信息(Markdown 标题层级、XML 标签、PDF 目录等)指导分块:

Embedding 模型

Embedding 模型是 RAG 系统的核心组件,负责将文本转化为稠密向量。 它的选择直接影响检索质量和最终回答的准确性。

主流 Embedding 模型对比

模型 维度 上下文 特点 场景
text-embedding-3-large 3072/256-3072 8K OpenAI 最新,性能优异 通用场景
Cohere embed-v3 1024/384/256 16K 多语言支持优秀,支持 MATRYOSHKA 多语言、企业
text-embedding-3-small 1536/256-1536 8K 性价比高 成本敏感场景
BGE-M3 1024 8K 开源、多语言能力强 开源部署
GTE-large 1024 8K 开源、中文优化 中文场景
E5-Mistral 1024 4K 高效、微调友好 垂直领域

维度选择与 MATRYOSHKA 表示

传统观点认为更高的Embedding维度能保留更多信息,但对于实际检索任务, 1024 维度通常已足够。Cohere 提出的 MATRYOSHKA 表示法 允许在不同维度下进行检索(如 1024 → 768 → 512 → 256), 大幅降低存储和计算成本,同时保持可接受的精度。

# 使用 MATRYOSHKA 表示降维示例
original_dim = 1024
target_dim = 256  # 75% 存储节省

# 截断前 256 维即可,无需重新计算
embedding = full_embedding[:target_dim]

Embedding 优化策略

批次处理与向量化加速

批量调用 Embedding API 可大幅提升吞吐量。生产环境中, 建议批次大小设置为 100-500,并发请求数根据 API 限流配置。

Query 预处理

领域微调

通用 Embedding 在垂直领域(如医疗、法律、工程)表现可能不佳。 通过对比学习微调领域语料,可以显著提升检索精度。 典型微调数据格式:

{
  "query": "糖尿病的诊断标准是什么?",
  "positive": "根据 WHO 标准,空腹血糖≥7.0mmol/L...",
  "negative": "高血糖的饮食注意事项包括..."
}
✅ 实践建议

对于中文 RAG 系统,推荐优先尝试 BGE-M3(开源)或 Cohere embed-v3(商业),两者在中文场景下表现优异。 若有大量英文文档,text-embedding-3-large 是更稳妥的选择。

向量检索是 RAG 系统的核心引擎,负责在高维向量空间中快速找到与 Query 最相似的 Top-K 文档。向量数据库的选择需要综合考虑精度、性能、成本和运维复杂度。

向量数据库选型

数据库 索引算法 精度 QPS (100万向量) 部署方式 适用场景
Pinecone SOTA 专利算法 极高 1000+ 全托管 企业级 SaaS
Milvus HNSW, IVF, DISKANN 500-1000 自托管/云 大规模自部署
Weaviate HNSW 500-800 自托管/云 GraphQL 生态
Qdrant HNSW, SCAN 600-1000 自托管/云 高性能需求
pgvector IVFFlat, HNSW 中高 100-300 自托管 PG 已有团队
Chroma HNSW 50-100 嵌入式 原型/POC

索引算法深度解析

HNSW (Hierarchical Navigable Small World)

目前最流行的向量索引算法,采用多层图结构实现近似最近邻搜索:

# HNSW 参数配置示例
{
  "ef_construction": 200,  # 范围: 100-400, 越大越精确越慢
  "M": 16,                  # 范围: 4-64, 边数,影响内存和精度
  "ef_search": 100          # 搜索时动态参数,可调
}

IVF (Inverted File Index)

基于聚类的索引方法,将向量空间划分为 K 个聚类中心,搜索时只扫描 最相关的几个聚类。适合内存受限场景。

DISKANN

微软提出的全内存替代方案,基于图索引设计但优化了磁盘访问模式, 适合 billion 级别向量的单机部署。

向量检索质量指标

Top-K 与召回率的平衡

实际生产中,通常设置 top_k 为 50-100,然后在重排阶段 缩减至 5-20 条最终上下文。早期召回更多候选项能显著提升最终精度。

💡 召回率优化

不要将检索的 Top-K 直接送入 LLM。推荐流程: 检索 Top-100 → 重排 → Top-10 → LLM。 重排阶段可以利用更复杂的交互特征,大幅提升最终相关性。

纯向量检索在某些场景下存在明显局限:难以处理精确关键词匹配(如人名、 型号代码)、数值范围查询、以及结构化查询条件。Hybrid Search(混合检索) 通过融合向量检索与关键词检索,实现优势互补。

混合检索架构

User Query
    │
    ├──→ Sparse Retrieval (BM25) ──→ Score₁ (0.0-1.0)
    │
    └──→ Dense Retrieval (Vector) ──→ Score₂ (0.0-1.0)
            │
            ↓
    ┌───────────────────────┐
    │  Score Fusion (RRF)   │  ← Reciprocal Rank Fusion
    └───────────────────────┘
            │
            ↓
    Unified Ranking

稀疏检索:BM25 详解

BM25 (Best Matching 25) 是经典的信息检索算法,基于词频和逆文档频率:

BM25 Score = Σ IDF(t) · (tf(t,d) · (k₁ + 1)) / (tf(t,d) + k₁ · (1 - b + b · |d|/avgdl))

参数:
- k₁: 词频饱和参数 (通常 1.2-2.0)
- b: 文档长度归一化 (通常 0.75)
- IDF: 逆文档频率
- tf: 词频
- |d|: 文档长度
- avgdl: 平均文档长度

分数融合策略

RRF (Reciprocal Rank Fusion)

最常用的融合方法,对不同检索来源的结果按排名进行加权:

RRF(d) = Σ 1 / (k + rank_i(d))

其中 k 通常为 60,rank_i(d) 为文档 d 在第 i 个检索结果中的排名

Score-based 融合

当两个检索来源的分数分布差异较大时,需要先做归一化再融合:

Final Score = α · normalize(BM25_score) + (1-α) · normalize(Vector_score)

α 通常设置为 0.3-0.5,可通过离线评估优化

BM25 与向量的平衡

场景 推荐权重 说明
通用问答 BM25 30%, Vector 70% 向量主导,BM25 补充精确匹配
代码搜索 BM25 50%, Vector 50% API 名称、函数名精确匹配很重要
产品检索 BM25 40%, Vector 60% 型号、规格需要精确匹配
学术论文 BM25 20%, Vector 80% 概念语义理解为主

实现方案

主流向量数据库均已支持 Hybrid Search:

# Weaviate Hybrid Search 示例
{
  "query": "RAG system architecture",
  "vectorizer": "text2vec-transformers",
  "hybrid": {
    "alpha": 0.5,  # 0=纯关键词, 1=纯向量, 0.5=平衡
    "fusionType": "relativeScoreFusion"
  }
}

重排 (Reranking)

Reranking 是 RAG Pipeline 中提升最终效果的关键步骤。 在向量检索(或混合检索)得到候选文档列表后,Reranker 通过更复杂的 交互式语义模型对候选文档与 Query 的相关性进行更精准的排序。

为什么需要 Reranking?

Reranker 模型

模型 类型 特点 延迟
Cross-Encoder (BERT-based) Cross-Encoder 精度最高,需实时计算 高 (50-200ms)
Cohere Rerank 商业 API 易用,效果好 中 (API)
Sentence-transformers Bi-Encoder 轻量,可本地部署
monoBERT Cross-Encoder 专为排序任务优化
LLM-as-Reranker LLM 精度高,成本高 很高

Cross-Encoder vs Bi-Encoder

Bi-Encoder(双塔)

  • Query 和 Document 独立编码
  • 向量预计算,检索快
  • 无法建模交互特征
  • 适合首次粗筛

Cross-Encoder(交联)

  • Query-Document 联合编码
  • 实时计算,精度高
  • 延迟较高,适合精排
  • 适合 Reranking

典型 Reranking Pipeline

Query ──┬──→ Vector Search (Top-100) ──┐
        │                                  │
        └──→ BM25 Search (Top-100) ────────┼──→ RRF Fusion (Top-50) ──→ Cross-Encoder Rerank ──→ Top-10 ──→ LLM
                                           │                        (精排)
                                           └──→ Vector Search (不同 index) ──┘

Reranking 优化技巧

上下文窗口选择

Reranker 输入通常限制在 512 tokens。若 Chunk 超过此长度, 需要策略性截取:

DocBERT 风格交互

将 Query 作为 Document 的特殊段落插入,利用 BERT 的 [CLS] token 输出做排序分数:

[CLS] + Query + [SEP] + Document + [SEP]
              ↓
         BERT Forward
              ↓
    [CLS] Token Output → Sigmoid → Relevance Score

多样性重排 (MMR-style)

除相关性外,还需考虑结果多样性。通过 Max Marginal Relevance 在相关性与多样性间取得平衡:

MMR Score = α · Relevance(Q, D) - (1-α) · max_{D'∈Selected} Similarity(D, D')
⚠️ 性能注意事项

Cross-Encoder 需要对每个 Query-Document Pair 独立前向传播, N 个候选文档意味着 N 次 GPU/CPU 计算。务必控制候选集大小 (通常 50-100),避免 P99 延迟失控。

RAG 评估

RAG 系统的评估是迭代优化的基础。与传统 ML 不同,RAG 评估需要 同时考量 检索质量生成质量 两个维度。

检索评估指标

指标 定义 说明
Precision@K Top-K 中相关文档的比例 高 Precision 意味着少噪音
Recall@K 所有相关文档中被召回的比例 高 Recall 意味着少遗漏
MRR 第一个相关文档的排名倒数均值 关注最优结果位置
NDCG@K 归一化折损累计增益 综合考虑排名和相关性权重
Hit Rate Top-K 包含任意相关文档的比例 快速判断系统可用性

生成评估指标

RAGAS 框架

RAGAS (Retrieval-Augmented Generation Assessment) 是当前最流行的 RAG 评估框架,从三个维度评估生成质量:

# RAGAS 评估指标计算
from ragas import evaluate
from ragas.metrics import faithfulness, answer_relevancy, context_precision

result = evaluate(
    dataset=test_dataset,
    metrics=[faithfulness, answer_relevancy, context_precision]
)

LLM-as-Judge

使用强 LLM(如 GPT-4、Claude-3)对回答质量进行评分。 相比人工评估,成本更低、速度更快,适合迭代测试。

评估 Prompt 示例:
"请评估以下问答对中,AI 助手的回答质量。
考虑因素:
1. 回答是否准确回答了问题
2. 回答是否基于提供的上下文
3. 回答是否完整、无遗漏

评分范围:1-5 分,5 分为最优。

问题:{question}
上下文:{context}
回答:{answer}
评分理由:"

其他生成指标

端到端评估数据集

数据集 规模 特点 适用场景
NQ (Natural Questions) 3.6K Google 真实搜索查询 通用 QA
TriviaQA 95K 百科知识问答 事实性问答
PopQA 14K 长尾知识问答 知识覆盖评估
HotpotQA 113K 多跳推理问答 推理能力
2WikiMultiHopQA 227K 多跳维基百科问答 复杂推理

评估最佳实践

✅ 构建评估体系的建议

1. 分层评估:先评估检索(Recall@K > 0.9),再评估生成
2. Case Analysis:定期抽样式人工审查 Bad Cases
3. A/B Testing:生产环境持续对比不同策略效果
4. 回归测试:每次 Pipeline 修改后运行完整评估套件

生产级实践

企业级 RAG 架构

┌─────────────────────────────────────────────────────────┐
│                    RAG System Architecture                 │
├─────────────────────────────────────────────────────────┤
│                                                          │
│  ┌──────────┐   ┌──────────┐   ┌──────────────────────┐ │
│  │  Ingest  │──▶│  Chunk   │──▶│  Embedding Service   │ │
│  │  Service │   │  Service │   │  (Batch/Stream)      │ │
│  └──────────┘   └──────────┘   └──────────┬───────────┘ │
│                                            │              │
│                                            ▼              │
│                                    ┌──────────────┐       │
│                                    │  Vector DB   │       │
│                                    │  + Metadata  │       │
│                                    └──────┬───────┘       │
│                                           │              │
│  ┌────────────────────────────────────────┼────────────┐ │
│  │              Query Pipeline             │            │ │
│  │  ┌─────────┐   ┌──────────┐   ┌────────▼───────┐    │ │
│  │  │  Query  │──▶│  Router  │──▶│ Hybrid Search   │    │ │
│  │  │Parsing  │   │(Intent)  │   │ BM25 + Vector   │    │ │
│  │  └─────────┘   └──────────┘   └────────┬────────┘    │ │
│  │                                       │              │ │
│  │                              ┌────────▼────────┐     │ │
│  │                              │   Reranker      │     │ │
│  │                              │(Cross-Encoder)  │     │ │
│  │                              └────────┬────────┘     │ │
│  │                                       │              │ │
│  │                              ┌────────▼────────┐     │ │
│  │                              │  Context       │     │ │
│  │                              │  Assembly      │     │ │
│  │                              └────────┬────────┘     │ │
│  └───────────────────────────────────────┼───────────────┘ │
│                                          │                │
│                               ┌──────────▼──────────┐     │
│                               │     LLM Gateway     │     │
│                               │  (Cache/Rate Limit) │     │
│                               └──────────┬──────────┘     │
│                                          │                │
│                                          ▼                │
│                                  ┌──────────────┐        │
│                                  │  Response    │        │
│                                  │  Streaming   │        │
│                                  └──────────────┘        │
└─────────────────────────────────────────────────────────┘

关键工程实践

缓存策略

延迟优化

RAG 系统的端到端延迟通常由以下因素决定:

💡 流式输出

LLM 生成延迟是用户感知最强的环节。务必启用 Streaming 模式, 即使总时间不变,用户感知到的「首字延迟」也会大幅降低。

容错与降级

监控与告警

生产环境必须监控的指标:

多模态 RAG 扩展

当文档包含图片、表格、PDF 扫描件时,需要额外的处理流程:

总结

RAG 系统架构设计的核心在于对每个环节的深入理解和系统性优化:

Chunk 策略

  • 根据文档结构和领域特性选择分块方法
  • Chunk Size 需要在语义完整性和检索精度间平衡
  • 父子块策略可兼顾精确性和上下文完整性

Embedding

  • 选择支持长上下文的现代 Embedding 模型
  • 领域微调可显著提升垂直场景效果
  • MATRYOSHKA 表示可有效降低存储成本

向量检索

  • HNSW 是当前最优的近似最近邻索引
  • Top-K 设置要兼顾召回率和后续处理成本
  • 向量数据库选型需考虑规模、性能和运维成本

Hybrid Search

  • BM25 + Vector 融合可处理精确匹配和语义理解
  • RRF 是鲁棒的分数融合方法
  • 权重参数需根据场景调优

Reranking

  • Cross-Encoder 可显著提升最终相关性排序
  • 候选集大小需在精度和延迟间平衡
  • 多样化重排可提升结果覆盖率

评估

  • 分层评估:先检索后生成
  • RAGAS + LLM-as-Judge 是实用的评估组合
  • 持续评估是系统迭代优化的基础

RAG 不是一个静态的系统,而是一个需要持续优化的数据 Pipeline。 从 Chunk 策略到最终的用户体验,每个环节都有大量的调优空间。 建议从最小可用系统开始,通过数据驱动的方式逐步迭代,最终构建 满足业务需求的 RAG 系统。

✅ 下一步探索

Agentic RAG:让 RAG 系统具备自主规划、工具调用和迭代反思能力
Graph RAG:利用知识图谱增强关系推理和全局理解能力
Self-RAG:通过自适应检索和自我评估提升生成质量