RAG系统设计全解析:从架构到多模态的核心知识图谱

# RAG系统设计全解析:从架构到多模态的核心知识图谱

> 一篇带你理清RAG设计的核心脉络:知识存储、向量检索、文档切分、Embedding选型与多模态支持

---

## 一、RAG是什么?为什么要这样设计?

RAG(Retrieval-Augmented Generation,检索增强生成)的核心思想很朴素:

> **在LLM生成答案之前,先从外部知识库中检索相关信息,作为"参考资料"一起送给模型。**

这个设计的本质原因有两个:

1. **LLM的知识是"截断"的**——训练数据截止到某个时间点,之后的新知识它不知道
2. **LLM会产生"幻觉"**——在没有事实依据时,它会"编造"看似合理的答案

RAG通过**检索外部知识**来"锚定"LLM的生成,让答案既有事实依据,又能利用大模型的推理能力。

---

## 二、RAG的三大核心阶段

```
┌─────────────────────────────────────────────────────────────────┐
│                        RAG 系统全景图                          │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  阶段一:知识准备(离线)      阶段二:向量存储(离线)          │
│  ┌──────────────────────┐    ┌──────────────────────────┐      │
│  │  原始文档 / PDF /     │    │   向量数据库              │      │
│  │  Web页面 / 数据库     │───►│   (Milvus/Pinecone/      │      │
│  │        ↓              │    │    Qdrant/Weaviate)      │      │
│  │  文档切分 (Chunking)  │    │                          │      │
│  │        ↓              │    │   ┌──────────────────┐   │      │
│  │  Embedding 向量化     │    │   │ 向量索引 (HNSW)  │   │      │
│  └──────────────────────┘    │   │ 元数据索引 (倒排) │   │      │
│                               │   └──────────────────┘   │      │
│                               └──────────────────────────┘      │
│                                          ↑                      │
│  阶段三:查询与生成(在线)              │                      │
│  ┌──────────────────────┐               │                      │
│  │  用户问题             │               │                      │
│  │        ↓              │               │                      │
│  │  Query改写/扩展       │───────────────┘                      │
│  │        ↓              │                                      │
│  │  向量检索 (ANN)       │                                      │
│  │        ↓              │                                      │
│  │  Reranker 精排        │                                      │
│  │        ↓              │                                      │
│  │  Prompt构建 + LLM生成 │                                      │
│  └──────────────────────┘                                      │
└─────────────────────────────────────────────────────────────────┘
```

### 阶段一:知识准备(离线阶段)

这是RAG系统的"原料准备"环节,处理的是**非结构化数据**:

| 步骤 | 做什么 | 为什么重要 |
|------|--------|-----------|
| **数据采集** | 从PDF、Word、网页、数据库等来源收集文档 | 知识来源的广度决定系统能力上限 |
| **文档解析** | OCR识别、PDF解析、HTML清洗 | 格式多样性是最大的工程挑战 |
| **文本清洗** | 去噪声、去重、归一化 | 脏数据会污染Embedding质量 |
| **文档切分** | 将长文档切分为语义完整的Chunk | 决定了检索粒度 |

### 阶段二:向量存储(离线阶段)

将Chunk转换为向量并建立索引,供在线查询使用:

| 组件 | 功能 | 关键技术 |
|------|------|---------|
| **Embedding模型** | 文本→向量 | BGE/Qwen/OpenAI Embedding |
| **向量数据库** | 存储+高效检索 | Milvus/Qdrant/Pinecone |
| **向量索引** | 加速ANN搜索 | HNSW/IVF/PQ |
| **元数据存储** | 结构化过滤 | 倒排索引/B-Tree |

### 阶段三:查询与生成(在线阶段)

用户提问后的实时处理链路:

| 步骤 | 做什么 | 技术要点 |
|------|--------|---------|
| **Query理解** | 改写、扩展、意图识别 | HyDE/多查询生成 |
| **向量检索** | 从数据库中召回Top-K | ANN搜索 + Metadata过滤 |
| **重排序** | 精排候选文档 | Cross-Encoder/RRF |
| **Prompt构建** | 组装上下文+问题 | 模板工程/指令设计 |
| **LLM生成** | 基于上下文生成答案 | 流式/非流式输出 |

---

## 三、文档怎么切分?(Chunking策略)

切分是RAG最容易被忽视但影响极大的环节。切得好,召回率天然高;切不好,再好的模型也救不回来。

### 常见切分策略对比

| 策略 | 做法 | 优点 | 缺点 | 适用场景 |
|------|------|------|------|---------|
| **固定长度** | 按Token数硬切 | 简单、可控 | 破坏语义边界 | 通用场景 |
| **句子边界** | 按句号/换行切 | 语义相对完整 | 可能过长或过短 | 正式文档 |
| **段落边界** | 按段落切分 | 主题连贯性好 | 段落可能太大 | 书籍/报告 |
| **语义切分** | 用模型判断语义边界 | 语义最完整 | 计算成本高 | 高质量场景 |
| **递归切分** | 多层次:先段落→再句子 | 灵活、多粒度 | 实现复杂 | 生产环境 |

### 生产推荐配置

```text
┌─────────────────────────────────────────────────┐
│          推荐参数(以英文/中文通用场景为例)      │
├─────────────────────────────────────────────────┤
│  Chunk Size:   512 ~ 1024 tokens               │
│  Overlap:      50 ~ 200 tokens                 │
│  分割优先级:   段落 > 句子 > 固定长度           │
│  特殊处理:     表格保留Markdown/HTML格式       │
│                代码块保持语法完整性             │
└─────────────────────────────────────────────────┘
```

### 高级技术:父子块结构(Parent-Child)

```
┌─────────────────────────────────────┐
│        父块 (Parent Chunk)           │
│  完整段落 / 整个章节 (大粒度)        │
│         ↓                           │
│   ┌─────────┐ ┌─────────┐         │
│   │ 子块1    │ │ 子块2    │         │
│   │ 句子级    │ │ 句子级    │         │
│   └─────────┘ └─────────┘         │
│                                     │
│  检索时用子块匹配,用父块送入LLM     │
└─────────────────────────────────────┘
```

**为什么有效**:子块粒度细→匹配精准;父块上下文完整→生成质量高。

---

## 四、Embedding用什么模型?

### 选型决策框架

```text
                    选择Embedding模型
                           │
          ┌────────────────┼────────────────┐
          ▼                ▼                ▼
    语言/领域          性能要求          成本预算
    ├─中文优先         ├─精度优先        ├─开源免费
    │  → BGE-M3       │  → Cohere       │  → BGE系列
    │  → Qwen-Emb     │  → OpenAI v3    │  → BCE
    ├─英文优先         ├─速度优先        ├─商业API
    │  → OpenAI v3    │  → MiniLM-L6    │  → OpenAI
    │  → Cohere       │  → BGE-small    │  → Cohere
    ├─多语言           ├─平衡优先        ├─混合方案
    │  → BGE-M3       │  → BGE-large    │  → 开源+微调
    │  → multilingual │  → Qwen-Emb     │
```

### 主流模型对比

| 模型 | 维度 | 中文能力 | 开源 | 特点 |
|------|------|---------|------|------|
| **BGE-M3** | 1024 | ⭐⭐⭐⭐⭐ | ✅ | 多语言/多粒度/多功能 |
| **Qwen-Embedding** | 1536 | ⭐⭐⭐⭐⭐ | ✅ | 阿里出品,中文优化 |
| **BCE-Embedding** | 768 | ⭐⭐⭐⭐ | ✅ | 字节开源,性价比高 |
| **OpenAI text-embedding-3-small** | 1536 | ⭐⭐⭐⭐ | ❌ | API调用,英文SOTA |
| **OpenAI text-embedding-3-large** | 3072 | ⭐⭐⭐⭐⭐ | ❌ | 最高精度,成本最高 |
| **MiniLM-L6-v2** | 384 | ⭐⭐ | ✅ | 轻量级,速度快 |

### 选型建议

```text
场景1:企业中文RAG(通用)  → BGE-M3 / Qwen-Embedding
场景2:英文SaaS产品文档     → OpenAI text-embedding-3-small
场景3:成本敏感/大规模部署  → BCE-Embedding / BGE-small
场景4:多语言跨国企业       → BGE-M3 / multilingual-e5
场景5:极致精度(金融/医疗)→ Cohere / OpenAI v3-large
```

---

## 五、如何支持多模态Embedding?

### 什么是多模态Embedding?

> 不仅能把**文本**变成向量,还能把**图片、音频、视频**等不同模态的内容统一映射到同一个向量空间。

**核心价值**:实现"用文本搜图片"、"用图片搜文档"等跨模态检索。

```
                   统一向量空间
          ┌────────────┬────────────┬────────────┐
          │            │            │            │
       文本向量     图像向量     音频向量     视频向量
          │            │            │            │
          └────────────┴────────────┴────────────┘
                    ↑ 可直接计算相似度
```

### 主流实现方案

#### 方案一:专用多模态模型

| 模型 | 模态支持 | 特点 |
|------|---------|------|
| **CLIP** | 文本+图像 | OpenAI出品,最经典 |
| **BLIP** | 文本+图像 | 图像理解更强 |
| **SigLIP** | 文本+图像 | CLIP的改进版 |
| **ImageBind** | 6种模态 | Meta出品,多模态统一 |
| **CLAP** | 文本+音频 | 音频理解专用 |

```python
# CLIP 使用示例
from transformers import CLIPProcessor, CLIPModel
import torch

model = CLIPModel.from_pretrained("openai/clip-vit-base-patch32")
processor = CLIPProcessor.from_pretrained("openai/clip-vit-base-patch32")

# 文本和图像统一编码
text_inputs = processor(text=["一张可爱的猫"], return_tensors="pt")
image_inputs = processor(images=image, return_tensors="pt")

text_embeds = model.get_text_features(**text_inputs)
image_embeds = model.get_image_features(**image_inputs)
# 两者可直接计算余弦相似度
```

#### 方案二:多模态向量数据库

| 数据库 | 多模态支持 | 特点 |
|--------|-----------|------|
| **Milvus** | 支持任意向量 | 通用性强,可存多种向量 |
| **Pinecone** | 支持任意向量 | 托管服务,运维简单 |
| **Weaviate** | 原生多模态 | 内置CLIP等模块 |
| **Qdrant** | 支持任意向量 | Rust编写,性能优秀 |

#### 方案三:统一Embedding架构

```text
┌─────────────────────────────────────────────────────────────┐
│                    统一多模态Embedding架构                   │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  文本输入 ──→ Text Encoder ──→ [文本向量]                   │
│                    │                                        │
│  图像输入 ──→ Vision Encoder ──→ [图像向量]                │
│                    │                                        │
│  音频输入 ──→ Audio Encoder ──→ [音频向量]                │
│                    │                                        │
│                    └──→ 投影到同一空间 ←── 对比学习训练     │
│                                                             │
│  检索时:查询向量 → 与所有模态的向量计算相似度              │
└─────────────────────────────────────────────────────────────┘
```

### 多模态RAG典型应用

```text
┌─────────────────────────────────────────────────────────────┐
│                  多模态RAG应用场景                           │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  1. 图文混合问答                                           │
│     "这张X光片显示什么问题?" + 医学报告检索                │
│                                                             │
│  2. 视频内容检索                                           │
│     "找到会议中讨论预算的那段视频"                          │
│                                                             │
│  3. 电商商品搜索                                           │
│     "找一件和这件相似但价格更低的"(用图片搜商品)          │
│                                                             │
│  4. 多模态知识库问答                                       │
│     技术手册含流程图/架构图 + 文本说明 → 统一检索           │
└─────────────────────────────────────────────────────────────┘
```

---

## 六、设计决策总结

| 设计维度 | 关键决策 | 常见选择 |
|---------|---------|---------|
| **知识来源** | 数据从哪里来? | 内部文档/数据库/API/网页爬取 |
| **文档切分** | 粒度和边界如何定? | 512-1024 tokens + 重叠 + 句边界 |
| **Embedding模型** | 用什么编码器? | BGE-M3/Qwen/OpenAI(看语言和预算) |
| **向量数据库** | 用什么存储? | Milvus/Qdrant/Pinecone(看规模和运维) |
| **检索策略** | 用什么方式? | Hybrid Search(BM25+向量) |
| **多模态支持** | 需要跨模态吗? | CLIP/ImageBind + 多模态DB |
| **精排策略** | 如何从粗到精? | Retriever(Top-20) + Reranker(Top-3) |

---

## 七、核心记忆框架

> **一句话记住RAG设计要点:**

```
知识准备 → 分块编码 → 向量存储 → 查询召回 → 精排生成
   ↑          ↑           ↑          ↑          ↑
 数据源     Chunk      Embedding   检索策略     LLM
```

**设计原则**:

1. **分块要完整**——语义边界优先,宁可重叠也不割裂
2. **编码要精准**——选对Embedding模型,中文场景优先国产
3. **存储要高效**——向量索引+元数据索引双管齐下
4. **召回要全面**——混合检索(语义+关键词)+ 适当大的Top-K
5. **生成要有据**——检索结果作为事实锚点,减轻幻觉

posted @ 2026-07-06 23:18  若-飞  阅读(32)  评论(0)    收藏  举报