RAG
Indexing
这个阶段在用户提问之前完成,目的是把外部知识库(如公司文档、PDF、网页)加工成机器容易检索的格式。
1. 解析文档(Document Parsing & Chunking)
核心任务:把杂乱无章的原始文件转化成纯文本,并按语义切分成“小段落”。
- 解析:PDF 有表格、图片,Word 有标题层级,网页有 HTML 标签。解析器要提取出真正有效的文字内容,并识别出标题、段落、列表等结构。
- 分块(Chunking):因为大模型的上下文窗口有限,且 Embedding 模型对过长文本的语义捕捉会变差,所以要把长文档切成 200-1000 个 token 的小块。
- 关键技巧:不能硬切(否则会把一句完整的话切断),要按句子结束符(句号、换行)切,并且通常保留 重叠(Overlap)(比如前一块末尾的 50 个字,下一块开头重复包含),防止关键信息恰好被分在边界处丢失。
2. Embedding(向量化)
核心任务:将上一步切好的每一个文本块,转换成一串固定长度的“数字密码”(浮点数数组,即向量)。
- 原理:调用专门的 Embedding 模型(如 OpenAI
text-embedding-3-small、开源的BGE或M3E)。这个模型懂得语义,会把意思相近的句子映射到向量空间中“距离较近”的位置。 - 举例:“苹果很好吃”和“我喜欢吃水果”这两个句子的向量在空间中会很接近,而“iPhone 手机”则会离它们较远。
- 产出:每一个文本块对应一个高维向量(通常 768 维或 1536 维)。
3. 存储至向量数据库(Vector Database)
核心任务:把上一步生成的(向量,原始文本块,元数据)这三者存入库中,并建立索引。
- 常用的向量数据库有 Milvus、Pinecone。
- 数据库内部会建立 ANN(近似最近邻)索引(如 HNSW 算法),这个索引不存储完整向量,而是一种“跳表”结构,能让后续检索在海量数据中实现毫秒级响应。
Retrieval & Generation
当用户真正提问时,实时走下面的流程。
4. 提供查询(Query Processing)
核心任务:处理用户的原生问题,让它更适合检索。
- 这一步不是简单地把问题原封不动扔出去。常见操作包括:
- Query Rewriting(查询改写):如果用户问“那个谁后来怎么样了?”,系统会结合对话历史改写为“鲁迅后来怎么样了?”。
- HyDE(假设性文档嵌入):有时系统会先让 LLM 自己凭空生成一个“假想答案”,然后用这个假想答案去检索,因为假想答案的措辞风格更接近知识库中的文档,反而比用户简短的问句检索得更准。
5. Retrieve(初检召回)
核心任务:用处理好的问题向量,从向量数据库中快速捞回最相关的前 N 个文本块(比如前 50 个)。
- 操作:用同样的 Embedding 模型将问题转换为向量,在数据库里执行 ANN 搜索,计算余弦相似度或点积,找出距离最近的 Top-N 块。
- 注意:这一步是“海选”,宁可多召回,不能漏掉。因为后面会有更精细的排序,所以这一步通常召回数量较大(50-100 条),追求的是高召回率(Recall)。
6. Rerank(精排重排序)
核心任务:把初检召回的 50 个块,用更昂贵的模型重新计算相关性,选出最顶部的 Top-K(比如 5-10 个)送入大模型。
为什么要多此一举? 因为初检的 Embedding 模型是“轻量级、通用型”的,它只看向量距离,会犯低级错误。例如:
- 用户问“如何杀灭蟑螂”,初检可能会召回“如何养殖蟑螂”,因为向量距离很近(都有“蟑螂”和“如何”)。
- 或者,相关文档排在倒数第 10 名,差点被漏掉。
Rerank 如何补救?
- 它使用专门的 交叉编码器(Cross-Encoder) 模型(如 Cohere Rerank、BGE-reranker),将问题与每个候选文本拼接在一起,同时输入模型做深度语义交互,输出一个 0-1 的相关性分数。
- 交叉编码器极准,但运算极慢(比 Embedding 慢几十倍),所以只能用于精排这几十条,不能用于全库扫描。
最终输出:将排名最高的 5 个文本块,按相关性分数从高到低排列,送入下一步。
7. 生成(Synthesis / Generation)
核心任务:将精排后的文本块作为“参考资料”,连同用户原始问题,一起拼装成 Prompt 喂 给大模型(LLM)。
- Prompt 结构通常是:
请根据以下参考资料回答用户的问题。如果参考资料中没有答案,请明确说不知道,不要编造。参考资料:[1] xxx[2] xxx(排名靠前的放在前面,权重更高)用户问题:xxxx
- 大模型(如 GPT-4、Claude)根据这些材料生成通顺、有条理的回答。因为参考资料是按相关度排序的,模型会优先参考最相关的几段,回答的准确性会大幅提升。
总结流程图(思维导图)
写入阶段(离线):
原始文档 → 解析切块 → Embedding 模型 → 向量库(建索引)
读取阶段(在线):
用户问题 → 查询改写/Embedding → 向量库 ANN 检索(召回 Top-50)
↓
Rerank 交叉编码器(重排 Top-5)
↓
拼接 Prompt + LLM 生成 → 最终答案