RAG 系统架构详解

从 Query 到 Response 的完整 RAG 流水线,以及索引与查询两条主线的设计要点

14 min read Part of RAG · Ch. 2
← 上一层级:学习路径 · Part 02 · RAG 体系化进阶

RAG 系统架构详解

flowchart LR
  subgraph Offline[离线索引]
    D1[原始文档] --> D2[解析 / 清洗]
    D2 --> D3[Chunking]
    D3 --> D4[Embedding]
    D4 --> D5[向量库 / 索引]
  end

  subgraph Online[在线查询]
    Q1[用户问题] --> Q2[Query Processing]
    Q2 --> Q3[Retrieval]
    Q3 --> Q4[Rerank 可选]
    Q4 --> Q5[Context Assembly]
    Q5 --> Q6[LLM Generation]
    Q6 --> Q7[Response]
  end

  D5 --> Q3

理解了 RAG 是什么,下一步就不是再背定义,而是搞清楚:一个完整的 RAG 系统到底怎么运转。在工程里,RAG 从来不是“调一次向量检索 + 调一次 LLM”这么简单,而是一条包含离线索引和在线查询的完整流水线。LlamaIndex 的文档长期把 RAG 拆成 indexing、retrieval、query engine 等模块;LangChain 的 RAG 教程也明确展示了“索引一条线、查询一条线”的结构。(docs.llamaindex.ai) (docs.langchain.com)

这篇文章会讲什么

上一篇讲的是“为什么需要 RAG”,这一篇讲的是“RAG 系统是怎样跑起来的”。这两者差别很大。知道 RAG 的定义,并不等于知道:

  • 文档什么时候被切分、向量化、入库
  • 用户提问时,哪些步骤在线执行,哪些步骤离线完成
  • 为什么有的系统只做一次检索,有的还要做 rerank
  • 为什么 query 处理和文档索引要分成两条主线
  • 为什么很多 RAG 项目失败,不是因为模型不够强,而是流水线里某一段设计错了

所以这篇文章的目标,是把 RAG 拆成一张“系统总图”,帮你建立两个视角:

  1. 离线视角:文档是如何被整理成可检索知识库的
  2. 在线视角:用户问题是如何一步步变成最终回答的

理解这张图以后,你后面再看 chunking、hybrid search、rerank、agentic RAG,就不会觉得它们是零散技巧,而会知道它们在整条流水线里各自解决什么问题。


延伸阅读

  • Lewis et al. 2020 的原始 RAG 论文,为“检索 + 生成”这条路线提供了研究起点。(arxiv.org)
  • LangChain 官方 RAG 教程展示了一个非常典型的模块化 RAG pipeline。(docs.langchain.com)
  • LlamaIndex 文档长期围绕 indexing、retriever、query engine 来组织 RAG 架构。(docs.llamaindex.ai)
  • 2023 年的 RAG Survey 把现代 RAG 范式总结为 Naive RAG、Advanced RAG、Modular RAG 三类,这个分类在今天仍然很有用。(arxiv.org)

先说结论:RAG 其实是两条流水线

很多人第一次做 RAG,会把系统想成先看定义:

用户问题 → 向量检索 → LLM 回答

这当然没有错,但太粗了。真正的 RAG 系统至少有两条主线:

1. 索引流水线(离线)

负责把原始文档变成“可检索知识”。

2. 查询流水线(在线)

负责把用户问题变成“带参考资料的回答”。

这两条线看起来独立,实际上强耦合。 因为在线查询质量,很大程度上取决于离线索引质量。你在线调 top-k、换 rerank、改 prompt,很多时候是在“救”一个本来就没建好的索引。LlamaIndex 文档里把 indexing 和 query engine 明确拆开,就是这个原因。(docs.llamaindex.ai)

所以理解 RAG 架构时,最重要的一句话是:

RAG 不是一个请求时临时发生的动作,而是离线准备 + 在线检索 + 在线生成的组合系统。


一、完整 RAG 流水线

先给出一条足够完整、又适合工程理解的主链路:

Query
→ Query Processing
→ Retrieval
→ Reranking(可选)
→ Context Assembly
→ LLM Generation
→ Response

如果把索引链路也加进去,可以画成两条并行但耦合的流程:

离线索引:
Documents
→ Parsing / Cleaning
→ Chunking
→ Embedding
→ Vector Store / Index

在线查询:
User Query
→ Query Processing
→ Query Embedding / Search
→ Retrieval
→ Reranking
→ Prompt Assembly
→ LLM
→ Response

LangChain 的官方教程本身就是这个思路:一边是 indexing chain,一边是 retrieval-and-generation chain。(docs.langchain.com)


二、索引流水线(离线):先把文档变成“可被查到的知识”

先看定义:索引流水线的任务不是“保存文档”,而是把原始资料转成适合检索的知识单元。离线建得好,在线回答才有上限。

1. Document Ingestion:文档接入

RAG 的起点通常不是 query,而是文档。原始资料可能来自:

  • PDF
  • Word / PPT / Excel
  • Markdown / HTML
  • Wiki / Notion / Confluence
  • 数据库记录
  • 内部 API 返回内容

这一阶段最重要的工作,是把原始格式解析成尽量干净、结构尽量保留的文本。LlamaIndex 也把 document parsing 放在 indexing 模块的前面,因为这是所有后续步骤的前提。(docs.llamaindex.ai)

这里容易被低估的一点是: 文档解析质量会直接决定后续 RAG 效果。

例如:

  • 页眉页脚没清掉
  • 表格结构丢失
  • 标题层级被打乱
  • PDF 解析后句子顺序错乱

这些问题一旦进入索引,后面再强的 embedding 和 rerank 都只能尽量补救。


2. Cleaning / Normalization:清洗与规范化

文档接入后,通常还要做一定清洗:

  • 去掉噪声字符
  • 去掉重复段落
  • 标准化空格和换行
  • 统一标题和段落边界
  • 识别文档来源、章节、时间等 metadata

这一步不是为了“文本更好看”,而是为了后续两件事:

  1. 切分更稳定
  2. 检索结果更可解释

很多失败的 RAG 系统,问题不在检索算法,而在于输入给索引的原文已经脏了。


3. Chunking:把长文切成可检索单元

这是索引流水线里最关键的一步之一。

RAG 很少直接对整篇文档建索引,而是要切成 chunk。原因很简单:

  • 整篇太长,粒度太粗
  • 相关信息通常只在某个局部段落
  • 模型最终也只适合消费小块上下文,而不是整本手册

所以 chunking 的目标不是“机械切段”,而是:

把文档切成既能被检索到、又保留足够语义完整性的知识单元。

这一点非常重要,后面专门一章会展开讲。


4. Embedding:把 chunk 变成向量

chunk 切完之后,通常要送入 embedding 模型,得到向量表示。 这个向量的作用是:让系统后续能根据 query 的语义相似性去找这些 chunk。

这里最关键的工程原则是:

索引时用什么 embedding 模型,查询时通常也必须用同一套 embedding 空间。

否则 query 和 document 的向量空间不一致,相似度就没有意义。这个原则在现代向量检索和 RAG 系统里几乎是基本前提。(docs.langchain.com)


5. Storage / Index:把向量和 metadata 存进可检索系统

最后,chunk 向量和 metadata 会进入:

  • 向量数据库
  • 稀疏索引系统
  • 混合检索系统
  • 或者更广义的检索后端

这里存的不只是 vector,通常还包括:

  • chunk 原文
  • 文档标题
  • 来源 URL / 文件名
  • 章节位置
  • 创建时间 / 更新时间
  • 租户 ID / 权限范围
  • 文档类型

这些 metadata 对后续 filtering、引用展示和多租户隔离都非常重要。


索引流水线的本质

你可以把离线索引理解成:

先把“人能读的资料”,转成“机器能找的知识”。

这一层不直接回答问题,但它决定了:

  • 你能不能找到相关资料
  • 你找到的是不是足够细的片段
  • 结果能不能带来源
  • 后续检索能不能做过滤和扩展

所以索引流水线看似不“智能”,其实它决定了整个 RAG 系统的上限。


三、查询流水线(在线):用户问题是怎样变成最终回答的

先看定义:在线查询的核心,不是“拿问题去搜一下”,而是把原始问题逐步变成模型真正能用的上下文,再让模型输出可读答案。

1. Query Processing:先处理用户问题,不一定直接搜

用户输入的 query 往往不是最适合检索的形式。

例如:

  • 口语化:咋装 Python
  • 含糊:这个接口限流多少
  • 错别字:苹国
  • 省略上下文:那这个能退吗

所以很多 RAG 系统在真正检索前,会先做一层 query processing。常见做法包括:

  • 拼写纠正
  • query rewrite
  • query expansion
  • 意图识别
  • 上下文补全

这一步不是所有系统都必须做,但在复杂场景里很常见。LangChain 和 LlamaIndex 都支持在 retrieval 前插入更多 query handling 逻辑。(docs.langchain.com) (docs.llamaindex.ai)

为什么 query processing 很重要

因为用户提问是“为人类而说”的,不一定是“为检索系统而写”的。 query processing 的本质,是在做一次语义重写:

把用户的自然提问,转成更适合召回知识的检索表达。


2. Retrieval:先广泛找回候选

检索阶段的目标,不是马上找出“最终最优答案片段”,而是先尽量把可能相关的候选找回来。 这一点特别重要,因为很多系统在这里的优化目标是 召回率,不是精度。

常见做法包括:

  • Dense retrieval(向量检索)
  • Sparse retrieval(BM25 等关键词检索)
  • Hybrid retrieval(两者结合)
  • metadata filtering
  • 多路召回后合并

Pinecone 的 RAG 资料也一直强调,retrieval 的任务首先是把可能相关的上下文快速召回,而不是一步完成所有判断。(pinecone.io)

一个非常重要的工程直觉

检索阶段更像“粗筛”,不是“终审”。

它回答的问题是:

哪些片段有可能相关?

而不是:

哪几个片段一定最值得给模型看?

后者通常要交给 rerank。


3. Reranking:把“召回”变成“更准的前几条”

初检常常会把相关内容找回来,但排序未必最好。 这时很多生产级 RAG 系统会加一层 rerank,也就是对 query 和候选文档做更精细的相关性判断,再从候选里挑出真正最值得给模型看的几条。

这一步常见的实现是 cross-encoder 或专门 rerank 模型。 它的典型作用是:

  • 去掉噪声 chunk
  • 提升前几条结果质量
  • 缩小最终进入 prompt 的上下文范围

所以可以把它理解成:

检索负责“找回来”,Rerank 负责“排前面”。

这也是现代 RAG 系统从 naive 走向 advanced 的一个典型标志。RAG Survey 把包含 rerank、query reformulation 等增强机制的系统归入更高级的 RAG 范式。(arxiv.org)


4. Prompt Assembly:把资料“喂给模型”的方式同样重要

很多人做 RAG 时,只关注“检索到了什么”,却低估了另一个关键问题:

怎么把这些资料组织给模型看?

这就是 augmentation,也可以理解为 prompt assembly。

一个最基本的模板通常长这样:

你是一个助手。请基于以下参考资料回答用户问题。
如果资料中没有答案,请明确说明。

参考资料:
[文档1]
[文档2]
...

用户问题:
{query}

但生产里,Prompt Assembly 往往还会处理更多细节:

  • 是否附带文档来源
  • 是否要求引用
  • 是否要求模型只基于资料回答
  • 多个片段之间如何排序
  • 是否按来源分组
  • 是否截断或摘要过长片段

Prompt Assembly 的质量,会显著影响模型是否真正利用检索结果,而不是“看了一眼又开始自由发挥”。


5. Generation:模型基于检索内容生成答案

最后一步才是 LLM 真正生成回答。

这一步看起来最“显眼”,但它其实是建立在前面所有环节之上的:

  • query 没处理好,检索就可能偏
  • 检索没召回来,模型就无料可用
  • rerank 不准,真正关键片段可能没进 prompt
  • prompt assembly 混乱,模型可能抓不住重点

所以最终回答质量,虽然由模型来呈现,但并不只是模型层的问题。


四、把两条主线放在一起看

如果把索引和查询两条线合在一起,你会更清楚一个 RAG 系统的全貌:

                    ┌────────────────────────────────────┐
                    │          索引流水线(离线)          │
                    │ 文档 → 清洗 → 切分 → 向量化 → 入库   │
                    └────────────────────────────────────┘


┌──────────┐   ┌──────────────┐   ┌─────────────┐   ┌──────────────┐
│ User     │──▶│ Query        │──▶│ Retrieval   │──▶│ Reranking    │
│ Query    │   │ Processing   │   │             │   │(可选)       │
└──────────┘   └──────────────┘   └─────────────┘   └──────┬───────┘


┌──────────┐   ┌──────────────┐   ┌─────────────┐   ┌──────────────┐
│ Response │◀──│ LLM          │◀──│ Prompt      │◀──│ Selected     │
│          │   │ Generation   │   │ Assembly    │   │ Context      │
└──────────┘   └──────────────┘   └─────────────┘   └──────────────┘

这个图里有两个特别容易被忽略的事实:

1. 索引流水线决定上限

在线链路再花哨,也救不了一个糟糕的索引。

2. 在线流水线决定体验

索引再好,如果 query 处理差、rerank 差、prompt assembly 差,最终结果仍然会不稳定。

所以真正成熟的 RAG 系统,通常不是某一个环节“神级优化”,而是每个环节都足够靠谱。


五、三种常见 RAG 架构:Naive、Advanced、Modular

先看定义:从 Naive RAG 到 Modular RAG,本质上是从“检索一下就回答”逐步演化到“检索、重排、路由、工具调用都可插拔”。这种分法在近年的 RAG Survey 中已经很常见。(arxiv.org)

1. Naive RAG

最简单的形态:

Query → Retrieval → Prompt → LLM

特点是:

  • 直接检索
  • 不做 query rewrite
  • 不做 rerank
  • 不做复杂路由
  • 结构简单、延迟低、适合原型

它的价值不是“效果最好”,而是让你先把闭环跑通。


2. Advanced RAG

在 naive 的基础上加入:

  • query rewrite
  • hybrid search
  • rerank
  • metadata filtering
  • 更好的 prompt assembly
  • 引用展示或答案约束

这类系统通常更接近生产环境,因为它已经开始认真处理召回率、精排和回答可控性问题。RAG Survey 把这一类增强检索与重排序的系统视为现代 RAG 的核心演进方向。(arxiv.org)


3. Modular RAG

再往上走,会变成“模块可插拔”的系统:

  • 某些 query 走不同检索器
  • 某些场景接工具调用
  • 某些任务需要多跳检索
  • 某些问题先分类再进入特定 query engine
  • 某些回答需要结构化输出或验证

这时 RAG 已经不只是“一个 pipeline”,而更像一套可编排的知识访问架构。LangGraph、LlamaIndex query engine/router 之类能力,通常都在往这个方向走。(docs.langchain.com) (docs.llamaindex.ai)


六、关键设计决策:哪些参数真的会影响系统质量

1. Chunk 大小

选项影响
太小容易丢上下文,检索碎片化
太大容易引入噪声,相关性变模糊
合理大小兼顾语义完整性和检索粒度

chunk 大小没有一刀切答案,它取决于文档类型、领域语言密度、后续模型上下文预算。后面专门一章会详细讲。


2. Top-k

选项影响
太小可能召回不足,漏掉关键证据
太大噪声增加,prompt 变长,rerank 成本更高
常见起点先取一个中等 k,再由 rerank 压缩到更小 n

一个常见工程模式是:

  • retrieval 阶段取较大的 top-k
  • rerank 后再选更小的 top-n 送给模型

3. 是否做 Rerank

这是延迟和准确率最典型的权衡点之一。 如果你只做原型,可能先不加; 如果你要生产质量,很多场景里 rerank 都会显著提升前几条结果质量。RAG Survey 也把 rerank 视为 advanced RAG 的关键组件。(arxiv.org)


4. 检索策略:Dense / Sparse / Hybrid

不同数据集对检索方式的敏感性很高:

  • 关键词非常重要的场景,sparse 往往有优势
  • 语义改写很多的场景,dense 更有价值
  • 企业文档里两者经常互补,hybrid 很常见

所以“默认用向量检索就行”通常只是起点,不是终点。


5. Embedding 模型

embedding 模型不只是影响“语义理解”,还会影响:

  • 多语言效果
  • 领域术语匹配
  • chunk 间距离结构
  • 向量库成本和维度

它往往是整个 RAG 系统最被低估的基础组件之一。


七、延迟与成本:RAG 为什么天然比纯聊天复杂

RAG 多出来的,不只是一个检索步骤,而是一整条前置链路。 因此一次请求的典型耗时通常由这些部分组成:

阶段典型成本来源优化方向
Query Processing额外 LLM 调用或规则处理能省则省,能缓存则缓存
Embedding / Search检索请求和向量检索优化索引、缓存热门 query
RerankCross-encoder 或 rerank API减少候选量、只在必要时用
Prompt Assemblytoken 增长精简上下文、限制 top-n
LLM Generationtoken 输出和模型大小控制回答长度、模型路由

所以从系统视角看,RAG 天然比“直接调模型”更贵、更慢一些。 但换来的,是知识接入、来源可追溯和回答可靠性的提升。


八、错误处理与降级:RAG 不是永远成功的

一个成熟的 RAG 系统,不能假设每次都能顺利命中相关资料。至少要考虑这些失败方式:

1. 检索无结果

可能是知识库里真没有,也可能是 query 表达方式和文档表述差太多。

可选策略:

  • 明确告诉用户“未找到相关资料”
  • 降级到纯 LLM 回答,但要强调不确定性
  • 触发 query rewrite 后重试一次

2. 检索结果相关性差

这时模型很可能会被误导,回答看起来有依据但其实答非所问。

可选策略:

  • 启用 rerank
  • 加 metadata filtering
  • 降低 top-k 噪声
  • 对答案增加“仅基于资料回答”的约束

3. 检索服务或 embedding 服务异常

可选策略:

  • 降级为 BM25 等稀疏检索
  • 走纯 LLM 模式
  • 返回友好错误并记录日志

一个重要的工程原则是:

RAG 不能假设任何单点永远成功,必须设计“失败时怎么活下去”。


九、一个最好记住的原则:RAG 不是“加了检索”,而是“重写了回答路径”

如果你只想记住一句话,那就是:

RAG 的本质,不是在原有 LLM 前面“多加一个搜索框”,而是把“用户问题如何变成答案”这条路径彻底改写了。

在纯 LLM 系统里,路径通常是:

问题 → 模型 → 回答

在 RAG 系统里,路径变成了:

问题 → 检索 → 选择证据 → 组织上下文 → 模型 → 回答

这意味着,RAG 的质量不再只由模型决定,而是由整条流水线共同决定。 这也是为什么 RAG 一定要用“系统架构”的视角来看,而不能只把它当成一个 prompt 技巧。


小结

一个完整的 RAG 系统包含两条主线:

  • 索引流水线(离线):文档解析、清洗、切分、向量化、入库
  • 查询流水线(在线):query 处理、检索、重排、上下文组装、生成回答

从 Naive RAG 到 Advanced RAG 再到 Modular RAG,本质上是让检索更智能、让上下文更可控、让整条链路更模块化。RAG Survey 对这三类范式的总结,也印证了今天工程实践中的典型分层。(arxiv.org)

如果说上一篇解决的是“为什么需要 RAG”,那么这一篇解决的就是:

一个 RAG 系统到底由哪些环节组成,以及这些环节是如何彼此依赖的。

核心概念速查

概念一句话
Indexing Pipeline离线将文档清洗、切分、向量化并存入索引的流程
Query Pipeline在线从 Query 到 Response 的实时链路
Query Processing在检索前对用户问题做纠错、改写、扩展或意图识别
Retrieval从知识库中召回可能相关的候选片段
Reranking对候选结果重新打分,选出更相关的前几条
Prompt Assembly把检索结果组织成模型当前可见的参考上下文
Naive RAG单次检索 + 直接生成的最基础形态
Advanced RAG加入 rerank、hybrid、query rewrite 等增强机制
Modular RAG模块可插拔、可路由、可多跳扩展的 RAG 系统