你了解RAG吗?,下面这些问题你是否能回答上来呢?ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: justify;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;" class="list-paddingleft-1">什么是 RAG(RAG 的流程是什么),为什么需要 RAG?如何对文档分块(Chunking)?分块大小如何选择?ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: justify;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;">本篇文章来详细介绍什么是 RAG?RAG 的流程以及RAG 进阶优化ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: justify;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;">干货满满,相信你看完文章之后会对RAG有更深入的理解。ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;letter-spacing: normal;orphans: 2;text-align: justify;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;">RAG 介绍ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: justify;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;">RAG(Retrieval Augmented Generation) 是一种无需微调即可扩充模型知识的常用方法。 借助 RAG,LLM可以从数据库中检索上下文文档,以提高答案的准确性。ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: justify;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;">因为 LLM 大模型通过海量数据进行训练,数据是有时效性的。如果询问最新的文档或者一些专业领域的知识,LLM 是无法回答的。所以检索增强生成(RAG) 通过将你的数据添加到 LLM 已有的数据中来解决此问题。ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: justify;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;">RAG 解决了纯生成模型的局限性(如幻觉、知识过时等),通过动态检索外部知识增强生成结果的可信度和时效性。ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;letter-spacing: normal;orphans: 2;text-align: justify;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;">RAG 流程ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: justify;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;">典型的 RAG 流程分为两个部分: ingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 16px;font-style: normal;font-variant-ligatures: normal;font-variant-caps: normal;font-weight: 400;letter-spacing: normal;orphans: 2;text-align: justify;text-indent: 0px;text-transform: none;widows: 2;word-spacing: 0px;-webkit-text-stroke-width: 0px;white-space: normal;background-color: rgb(255, 255, 255);text-decoration-thickness: initial;text-decoration-style: initial;text-decoration-color: initial;" class="list-paddingleft-1">构建向量存储:创建向量存储是构建检索增强生成 (RAG) 流程的第一步。文档会被加载(Load)、拆分(Split)、Embedding 存储到向量数据库中。
- 加载文档 Load加载各种非结构化的数据,例如:TXT 文本、PDF、JSON,HTML、Markdown 等。Langchain 封装了各种格式的DocumentLoaders文档加载器 。
- 切分文本 Split
- 转化向量 Embedding使用 Embedding 模型将文本转换为向量(浮点数数组)表示
- 向量数据库 VectorStore:存储 Embedding 向量,能够基于向量相似度高效地检索与查询“最相似”的数据。
2. 检索生成:根据用户输入用向量数据库进行相似性搜索,让后把用户的question和搜索到的context作为上下文喂给 LLM 大模型,LLM 分析推理回答用户的问题。
我使用LangGraph构建了基本的 RAG 流程: 
调用Retrieval Tool搜索相关文档,然后GradeDocument对文档进行评分:对从向量数据库检索到的文档进行评分: 如果检索到的文档与用户输入的内容相关,则GenerateAnswer生成答案返回,如果不相关,则Rewrite重新生成 query 进行检索。
代码已上传 Github: Agent-demo/tree/main/src/rag_agent" style="box-sizing: border-box !important;overflow-wrap: break-word;text-decoration: none;color: rgb(87, 107, 149);font-weight: 600;">https://github.com/Liu-Shihao/ai-agent-demo/tree/main/src/rag_agent 进阶 - RAG 优化文档 Chunking大模型对话的 token 数量是有限制的,文档切分是为了将文档切分为小的文本块,适合检索并且节省 token。切分的文本块长度也会影响 LLM 回答的质量。 常见的切分文档的方法: - 固定长度切分(重叠分块边界):按照字符或者 Token 数(如 512 个 token)切分。重叠分块以避免边界信息丢失。这种方式最简单,但是有可能会截断语义。
- 按照句子边界(标点符号)分块,例如使用 NLP 框架
SpaCy, 但是长段落可能语义断裂。 - 自定义规则分割:用正则表达式或者 DOM 解析器(如 BeautifulSoup)按照逻辑结构(标题,段落)分块。适合结构化文档,但是需要手动设计分割规则。
- 基于语义的分块: 用 Transformer 模型分析语义关系分块。
优化原则: - chunk 块大小需要匹配 embedding 模型和 llm 大模型的 tokne 限制。
相似性算法在 RAG(检索增强生成)和其他信息检索任务中,相似性算法用于衡量文本、向量或实体之间的关联程度。 欧氏距离(L2): 欧几里得距离测量连接两点的线段的长度(计算向量间的直线距离)。它是最常用的距离度量,当数据连续时非常有用。值越小,相似度越高。
余弦相似度(COSINE): 余弦相似度使用两组向量之间夹角的余弦来衡量它们的相似程度。余弦相似度始终在区间[-1, 1]内。余弦值越大,两个向量之间的夹角越小,表明这两个向量彼此越相似。适合文本 embedding 比较。
BM25((Best Matching 25)):BM25 基于词频(TF)和逆文档频率(IDF)。根据词频、倒排文档频率、文档规范化对相关性进行评分。用于评估文档与查询的相关性。 广泛应用于搜索引擎和问答系统。如 Elasticsearch 默认使用 BM25 排序。
- 词频(TF):衡量查询词在文档中的出现频率,但通过参数k1控制词频的饱和效应,避免高频词过度影响得分。
- 逆文档频率(IDF):惩罚常见词(如“的”“是”),提升罕见词的权重。反映某个术语在整个语料库中的重要性。出现在较少文档中的术语的 IDF 值较高,表明其对相关性的贡献较大。
- 文档长度归一化:较长的文档由于包含更多术语,往往得分更高。BM25 通过归一化文档长度来缓解这种偏差。通过参数调整长文档的得分,避免因文档长度导致的词频偏差。
Jaccard相似度(Jaccard Index): 比较集合的交集与并集比例。适用场景:关键词集合、推荐系统(如用户兴趣匹配)。范围[0,1],值越小,相似度越高。
RAG 中的典型应用 - 重排序:交叉编码器(精细排序 Top-K 结果)。
通过灵活组合这些算法,可以优化 RAG 系统的召回率、准确率和响应速度。 余弦相似度(COSINE)的缺点忽视向量长度信息:余弦相似度仅计算向量方向的夹角,忽略向量的长度(模)。这意味着
- 高频词干扰:TF-IDF或词频高的长文本可能主导方向,但实际语义不相关。会放大无关词的影响。
- 归一化依赖:未归一化的向量可能导致相似度计算偏差。长文本包含更多词汇,其向量各维度值累加后长度(模)显著大于短文本。
语义相似度 ≠ 相关性: 余弦相似度基于表面语义匹配。 表面匹配,但相关文档不一定语义相似: 如果两个文本共享许多相同的关键词(如“猫”“狗”“宠物”),即使逻辑不同,余弦相似度仍可能很高。 例如: 文档1:“猫和狗是常见的宠物。”(正向描述) 文档2:“猫和狗不适合作为宠物。”(负向观点) 余弦相似度高,但语义相反。 词序颠倒,但余弦相似度相同。示例: 句子A:“医生治疗病人。” 句子B:“病人治疗医生。” 解决方案: - 向量归一化:强制所有向量的单位长度(如L2归一化)。
- 结合其他指标:如点积相似度(考虑长度)或BM25(词频加权)。
- 重排序(Re-rank):用交叉编码器(如MiniLM)精细化排序。
- 混合检索:结合关键词匹配(BM25)或知识图谱关系。
Rerank 重排序重排序(Reranking)是对初步检索结果进行优化排序的技术,旨在提升结果的相关性和准确性。 初次检索(如余弦相似度)可能返回语义相关但冗余或低质量片段,重排序可结合更多特征优化顺序。 方法: - 交叉编码器(Cross-Encoder):如 MiniLM-L6-v2,计算查询与每个文档的相关性分数(比嵌入模型更准但更慢)。
- 学习排序(Learning to Rank):训练模型综合多特征(如关键词匹配、点击率)排序。
Graph RAG使用知识图谱(Knowledge Graph, KG)增强 RAG(检索增强生成)可以显著提升复杂推理、多跳问答和关系挖掘的能力。 通过将文档中的实体(Entities)和关系(Relations)提取为知识图谱,在检索阶段不仅返回文本片段,还返回相关的子图结构,从而增强生成模型的上下文理解能力。 与传统 RAG 的区别: 实现步骤: - 实体识别(NER)使用 SpaCy NLP 模型或者 LLM 大模型进行命名实体提取,从文本中识别提取人名,地名,组织名,地点,日期等实体。
- 关系抽取可以利用 LLM 大模型抽取三元组(〈主体 (Subject), 关系 (Predicate), 客体 (Object)〉)。
- 图谱存储将节点 Node 和关系 Relations 存储到图数据库中,如 Neo4j。
三元组(Triple)是知识图谱(Knowledge Graph)中的基本数据单元,用于表示实体(Entity)之间的关系(Relation),其结构为:〈主体 (Subject), 关系 (Predicate), 客体 (Object)〉
通过知识图谱的引入,RAG 系统能够从“平面检索”升级为“立体推理”,尤其适合需要深挖实体关系的复杂场景。 RAG Evaluate 评估对RAG的评估可以从以下两个部分进行:检索质量- 上下文准确率(Context Precision):是衡量上下文中相关词块比例的指标。准确率是排名为 k 的相关词块数量与排名为 k 的词块总数之比。
- 上下文召回率(Context Recall):前K个结果中相关文档的比例。衡量成功检索到的相关文档(或信息片段)数量。更高的召回率意味着遗漏的相关文档更少。
生成质量RAG 有哪些缺点?检索的质量依赖外部数据库:如果知识库不完整,过时,或者噪声多,检索到的内容可能不相关或者错误,导致生成的答案质量下降。 解决方案: 定期更新知识库(实时爬取权威数据源) 分块(Chunking)导致上下文碎片化:固定大小的分块可能截断关键信息。答案可能分散在多个 chunk 块中。 解决方案:动态分块(按照语义边界切分,如段落,章节·) 语义相关不等于答案相关::向量检索(如余弦相似度)可能返回语义相关但无实际答案的文档。(如查询“如何治疗感冒?”,可能检索到“感冒症状描述”而非治疗方案)。 解决方案: 引入重排序(Re-rank)模型(如交叉编码器);混合检索(结合关键词检索,如 BM25)。 生成模型忽视检索内容:生成模型可能忽略检索到的文档,仍依赖自身知识(幻觉)。 解决方案: 强化提示工程(如“严格基于以下上下文回答”)。 无法处理多跳推理:传统 RAG 难以回答需要多步推理的问题(如“A 公司的竞争对手的 CEO 是谁?”)。 解决方案: 引入知识图谱(GraphRAG)显式建模实体关系。 RAG 流程时间长:检索+生成两阶段流程导致响应时间较长(尤其涉及重排序时)。 解决方案:缓存高频查询结果。
| 缺点类别 | 具体问题 | 解决方案 |
|---|
| 检索质量 | | | | 生成偏差 | | | | 效率问题 | | | | 知识覆盖 | | | | 复杂推理 | | |
|