RAG 系统通常包含文档解析、清洗、切片、索引、存储、召回、排序和生成。可以自行组合这些组件,也可以使用 RAG 框架统一编排。
flowchart LR subgraph BUILD ["离线建库"] A["原始文档"] --> B["解析、清洗与切片"] B --> C["文档 Embedding"] C --> D[("索引与存储")] end subgraph QUERY ["在线问答"] Q["用户问题"] --> QE["Query Embedding"] QE --> D D --> R["Top-N 召回"] R --> RR["Reranker Top-K"] RR --> G["LLM 组织答案"] Q --> G end
使用本目录构建 RAG
本目录中的文档按 RAG 构建流程组织:
| 阶段 | 需要解决的问题 | 对应文档 |
|---|---|---|
| 1. 解析、清洗与切片 | 如何把 PDF 等原始文件转换成可检索的 chunk | 文档清洗与切片 |
| 2. 理解 Embedding | Embedding 输入、输出和检索指令是什么 | Embedding 模型 |
| 3. 选择 Embedding | 如何比较维度、语言、长度、质量和成本 | Embedding 模型 |
| 4. 选择存储和索引 | 向量、Metadata、索引、过滤和图能力如何比较 | 向量数据库 |
| 5. 设计召回 | Dense、Sparse、关键词、混合和结构化召回如何组合 | RAG 召回方式 |
| 6. 精排候选 | 为什么先取 Top-N,再用 Reranker 选 Top-K | Reranker 模型 |
| 7. 生成最终答案 | 为什么检索片段还需要 LLM 重新组织 | 有 Embedding 就是 RAG 吗? |
常见框架和专用库
| 项目 | 范围 |
|---|---|
| LlamaIndex | 文档摄取、Node 切分、索引、Retriever 和 Query Pipeline |
| LangChain | Document Loader、Text Splitter、Retriever、Vector Store 和链 |
| Haystack | 用 Pipeline 组合转换、存储、召回、排序和生成 |
LlamaIndex、LangChain 和 Haystack 可以编排多阶段 RAG 流程。
这些工具主要减少连接不同组件的样板代码,不会自动替业务决定正确的切片大小、召回方式和评测集。简单项目也可以直接调用模型 API 和数据库,不必为了 “标准 RAG 架构” 引入框架。
非 Embedding 方案:PageIndex
PageIndex 是一种 vectorless、reasoning-based RAG 方案。它把长文档组织成层级树,让 LLM 通过推理和树搜索定位相关章节,不依赖 Embedding 相似度和向量数据库。
flowchart LR A["解析后的文档"] A --> V["向量 RAG<br/> 切片 → Embedding → 向量库"] A --> P["PageIndex<br/> 层级树 → 推理检索"] V --> C["候选上下文"] P --> C C --> L["LLM"]
| 对比项 | 向量 RAG | PageIndex |
|---|---|---|
| 索引 | Chunk 向量 | 文档层级树 |
| 查询 | 向量距离或混合召回 | LLM 推理和树搜索 |
| 向量数据库 | 通常需要 | 不需要 |
| 人工切片 | 通常需要 | 主要依赖自然章节结构 |
| 适合场景 | 大规模语料、低延迟、高并发检索 | 结构清晰的长文档、复杂推理和导航 |
PageIndex 不是 Embedding 管道中的切片器,而是另一条检索路线。应使用相同业务问题比较准确率、延迟、调用成本、并发能力和可追溯性,也可以按文档类型在两条路线之间做查询路由。
具体切片方法见 文档清洗与切片,其余阶段的代码见上表对应文档。