Appearance
RAG 工作机制详解
一、总体介绍
RAG(Retrieval-Augmented Generation,检索增强生成) 是一种将**"检索"与"生成"结合的 AI 架构:在让 LLM 回答之前,先从外部知识库检索相关文档片段,把它们作为上下文喂给 LLM,再由其生成**答案。
为什么需要 RAG?
LLM 本身存在三大短板,RAG 恰好补上:
- 知识滞后:模型训练后世界在变,它不知道最新信息。
- 知识私有:企业内部的文档、数据库它没见过。
- 幻觉:模型可能一本正经地编造答案。
RAG 让答案**"有据可依"**——引用真实检索到的资料,显著提升准确性与可溯源。
典型使用场景
| 场景 | 说明 |
|---|---|
| 企业知识库问答 | 内部制度、FAQ、产品文档的智能客服 |
| 私域文档检索 | 合同、研报、论文的问答与摘要 |
| 客服/助手 | 基于帮助文档回答用户问题 |
| 代码助手 | 检索内部代码库/API 文档辅助编程 |
| 实时信息 | 结合联网检索回答最新事件 |
大致流程(一句话版)
离线:文档 → 分片 → 向量化 → 建索引(存入向量库)
在线:提问 → 向量化 → 召回 → 重排 → 拼上下文 → LLM 生成答案二、逐步拆解:五个核心环节
下面按"数据从原始文档到最终答案"的顺序,拆解 分片 → 索引 → 召回 → 重排 → 生成。
1. 分片(Chunking)
- 做什么:把长文档切成一个个较小的文本块(Chunk),便于精确检索与向量化。
- 为什么:LLM 上下文窗口有限;整篇文档向量化会丢失细节,且检索粒度太粗。
- 常见策略:
- 固定长度切分:按字符/Token 数(如 512 Token)硬切,简单但可能切断语义。
- 语义切分:按段落、标题、句子边界切分,保留语义完整。
- 递归切分:优先在段落/换行处切,退而求其次再按句子、词切。
- 重叠(Overlap):相邻块保留一定重叠,避免信息被切断在边界上。
- 关键权衡:块太小→检索精准但缺上下文;块太大→有上下文但噪声多、向量变模糊。
2. 索引(Indexing)
- 做什么:把每个 Chunk 向量化(Embedding),并建立可快速检索的索引,存入向量数据库。
- 向量化:用 Embedding 模型(如 OpenAI text-embedding、BGE、百川等)把文本转成高维向量,语义相近的文本向量也相近。
- 存储:写入向量数据库(如 Milvus、Qdrant、pgvector、Faiss、Chroma)。
- 索引结构:常用 ANN(近似最近邻) 索引(如 HNSW、IVF),在速度与精度间权衡,支持海量向量下的毫秒级检索。
- 补充索引:除向量外,常同时存原文、元数据(来源、时间、标题),便于回带与过滤。
3. 召回(Retrieval / Recall)
- 做什么:用户提问时,把问题也向量化,去向量库里找最相似的 Top-K 个 Chunk。
- 相似度度量:余弦相似度(Cosine)、内积(Dot Product)、欧氏距离。
- 召回特点:宁多勿漏——尽可能把可能相关的都捞回来(如 Top 20~50),后续交给重排精筛。
- 增强手段:
- 混合检索(Hybrid):向量检索(语义)+ 关键词检索(BM25,精确词匹配)融合,兼顾语义与字面。
- 元数据过滤:先按时间/来源/权限筛掉无关文档,再向量检索。
4. 重排(Reranking)
- 做什么:对召回的候选 Chunk 用更精细的模型重新打分排序,挑出最相关的一小部分(如 Top 3~5)给 LLM。
- 为什么需要:召回阶段为了快用了轻量 ANN,精度有限;重排用 Cross-Encoder 类模型同时看"问题+文档" pair,排序质量更高。
- 常见做法:
- Reranker 模型(如 BGE-Reranker、Cohere Rerank):对(query, doc)打分,相关性判断更准。
- 规则融合:RRF(Reciprocal Rank Fusion)把多路召回结果按排名融合。
- 价值:大幅提升送入 LLM 的上下文质量,直接改善最终答案准确率。
5. 生成(Generation)
- 做什么:把重排后的相关 Chunk + 用户问题拼成 Prompt,交给 LLM 生成最终回答。
- Prompt 构造:通常形如
你是一个严谨的助手,仅根据下面的【参考资料】回答, 若资料中没有答案就说"不知道",不要编造。 【参考资料】 {检索到的 Chunk 1} {检索到的 Chunk 2} ... 【问题】{用户提问} - 关键点:
- 约束生成:要求模型"基于资料作答、注明出处、不知道就说不知道",抑制幻觉。
- 引用溯源:让答案附带引用块编号,方便用户核对。
- 上下文压缩:若 Chunk 仍过长,可先做摘要再送入,省 Token。
三、全链路回顾
RAG 链路分为两段:提问前(离线 / 索引链路) 与 提问后(在线 / 查询链路)。
提问前链路(离线,一次性建设)
目标:把知识库变成"可被检索的向量索引"。
原始文档(PDF/网页/数据库)
│ ① 加载 / 解析(抽取纯文本)
▼
文档清洗(去噪、去重、统一格式)
│ ② 分片(Chunking)
▼
文本块 Chunk
│ ③ 向量化(Embedding)
▼
向量 + 原文 + 元数据
│ ④ 写索引(存入向量库 ANN 索引)
▼
向量数据库(知识底座,长期可用)此阶段与用户提问无关,可在系统上线前批量完成;文档更新时需增量重建对应 Chunk 的索引。
提问后链路(在线,每次提问触发)
目标:根据用户问题实时检索并生成答案。
用户提问
│ ⑤ 问题向量化(同一 Embedding 模型)
▼
向量库检索
│ ⑥ 召回 Top-K 候选 Chunk(ANN + 可选 BM25 混合)
▼
候选 Chunk 集合
│ ⑦ 重排(Reranker 精筛 Top-N)
▼
精选相关片段
│ ⑧ 拼接 Prompt(资料 + 问题)
▼
LLM 生成
│ ⑨ 输出答案(+ 引用溯源)
▼
返回给用户两段链路对照
| 阶段 | 触发时机 | 核心动作 | 关键组件 |
|---|---|---|---|
| 提问前(离线) | 建库/更新时 | 加载→分片→向量化→建索引 | 解析器、Embedding、向量库 |
| 提问后(在线) | 每次提问 | 向量化→召回→重排→生成 | Embedding、向量库、Reranker、LLM |
四、核心概念对照表
| 环节 | 一句话 | 关键产出 |
|---|---|---|
| 分片 | 把文档切成合适大小的块 | Chunk 列表 |
| 索引 | 把块向量化并建立可检索结构 | 向量库索引 |
| 召回 | 按语义捞出可能相关的候选 | Top-K Chunk |
| 重排 | 对候选精筛出最相关的少数 | Top-N Chunk |
| 生成 | 结合资料让 LLM 作答 | 带出处的最终答案 |
记忆口诀:离线"切→嵌→存",在线"问→捞→筛→答";分片定粒度,索引供检索,召回求全,重排求准,生成求稳。
常见优化方向
- 分片策略:语义切分 + 合理 Overlap,提升检索粒度。
- 混合检索:向量 + BM25 融合,弥补纯向量对专有名词/编号的弱点。
- 重排必做:加 Reranker 通常能显著提升效果。
- 元数据过滤:先过滤再检索,降本增效。
- Query 改写:把口语化问题改写成更适合检索的查询(如 Hypothetical Document Embeddings)。
- 父子分块:用小块检索、用大块(父块)喂给 LLM,兼顾精度与上下文。