RAG 介绍
RAG (Retrieval Augmented Generation) 是一种无需微调即可扩充模型知识的常用方法。 借助 RAG,LLM 可以从数据库中检索上下文文档,以提高答案的准确性。
因为 LLM 大模型通过海量数据进行训练,数据是有时效性的。如果询问最新的文档或者一些专业领域的知识,LLM 是无法回答的。所以 检索增强生成 (RAG) 通过将你的数据添加到 LLM 已有的数据中来解决此问题。
RAG 解决了纯生成模型的局限性(如幻觉、知识过时等),通过动态检索外部知识增强生成结果的可信度和时效性。

RAG 流程
典型的 RAG 流程分为两个部分:
构建向量存储:创建向量存储是构建检索增强生成 (RAG) 流程的第一步。文档会被加载(Load)、拆分(Split)、Embedding 存储到向量数据库中。
加载文档 Load
加载各种非结构化的数据,例如:TXT 文本、PDF、JSON,HTML、Markdown 等。Langchain 封装了各种格式的 DocumentLoaders 文档加载器 。
切分文本 Split
将文本切分成更小的文本块(Chunk)。
转化向量 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 模型分析语义关系分块。
优化原则:
相似性算法
在 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 中的典型应用
通过灵活组合这些算法,可以优化 RAG 系统的召回率、准确率和响应速度。
余弦相似度(COSINE)的缺点
忽视向量长度信息:余弦相似度仅计算向量方向的夹角,忽略向量的长度(模)。这意味着
语义相似度 ≠ 相关性: 余弦相似度基于表面语义匹配。
表面匹配,但相关文档不一定语义相似: 如果两个文本共享许多相同的关键词(如“猫”“狗”“宠物”),即使逻辑不同,余弦相似度仍可能很高。 例如:
文档1:“猫和狗是常见的宠物。”(正向描述)
文档2:“猫和狗不适合作为宠物。”(负向观点)
余弦相似度高,但语义相反。
词序颠倒,但余弦相似度相同。 示例:
句子A:“医生治疗病人。”
句子B:“病人治疗医生。”
解决方案:
向量归一化:强制所有向量的单位长度(如L2归一化)。
结合其他指标:如点积相似度(考虑长度)或BM25(词频加权)。
重排序(Re-rank):用交叉编码器(如MiniLM)精细化排序。
混合检索:结合关键词匹配(BM25)或知识图谱关系。
Rerank 重排序
重排序(Reranking)是对初步检索结果进行优化排序的技术,旨在提升结果的相关性和准确性。
初次检索(如余弦相似度)可能返回语义相关但冗余或低质量片段,重排序可结合更多特征优化顺序。
方法:
Graph RAG
使用知识图谱(Knowledge Graph, KG)增强 RAG(检索增强生成)可以显著提升复杂推理、多跳问答和关系挖掘的能力。 通过将文档中的 实体(Entities) 和 关系(Relations) 提取为知识图谱,在检索阶段不仅返回文本片段,还返回相关的子图结构,从而增强生成模型的上下文理解能力。
与传统 RAG 的区别:
特性 | 传统 RAG | GraphRAG |
|---|
检索单元 | 文本片段(Chunks) | 实体+关系子图 |
推理能力 | 单跳语义匹配 | 多跳推理(如 A→B→C) |
适用场景 | 简单问答 | 复杂关系查询 |
实现步骤:
实体识别(NER)
使用 SpaCy NLP 模型或者 LLM 大模型进行命名实体提取,从文本中识别提取人名,地名,组织名,地点,日期等实体。
关系抽取
可以利用 LLM 大模型抽取三元组(〈主体 (Subject), 关系 (Predicate), 客体 (Object)〉)。
图谱存储
将节点 Node 和关系 Relations 存储到图数据库中,如 Neo4j。
三元组(Triple)是知识图谱(Knowledge Graph)中的基本数据单元,用于表示实体(Entity)之间的关系(Relation),其结构为:〈主体 (Subject), 关系 (Predicate), 客体 (Object)〉
通过知识图谱的引入,RAG 系统能够从 “平面检索” 升级为 “立体推理” ,尤其适合需要深挖实体关系的复杂场景。
RAG Evaluate 评估
对RAG的评估可以从以下两个部分进行:
检索质量
生成质量
RAG 有哪些缺点?
检索的质量依赖外部数据库:如果知识库不完整,过时,或者噪声多,检索到的内容可能不相关或者错误,导致生成的答案质量下降。
解决方案: 定期更新知识库(实时爬取权威数据源)
分块(Chunking)导致上下文碎片化:固定大小的分块可能截断关键信息。答案可能分散在多个 chunk 块中。
解决方案:动态分块(按照语义边界切分,如段落,章节·)
语义相关不等于答案相关: :向量检索(如余弦相似度)可能返回语义相关但无实际答案的文档。(如查询“如何治疗感冒?”,可能检索到“感冒症状描述”而非治疗方案)。
解决方案: 引入重排序(Re-rank)模型(如交叉编码器);混合检索(结合关键词检索,如 BM25)。
生成模型忽视检索内容:生成模型可能忽略检索到的文档,仍依赖自身知识(幻觉)。
解决方案: 强化提示工程(如“严格基于以下上下文回答”)。
无法处理多跳推理:传统 RAG 难以回答需要多步推理的问题(如“A 公司的竞争对手的 CEO 是谁?”)。
解决方案: 引入知识图谱(GraphRAG)显式建模实体关系。
RAG 流程时间长:检索+生成两阶段流程导致响应时间较长(尤其涉及重排序时)。
解决方案:缓存高频查询结果。
缺点类别
具体问题
解决方案
|
|
|
检索质量 | 知识库不完整/碎片化 | 动态更新知识库、语义分块、重排序 |
生成偏差 | 忽视检索内容/幻觉 | 提示工程、模型微调 |
效率问题 | 高延迟/高计算成本 | 缓存、量化、分层检索 |
知识覆盖 | 领域盲区/偏见 | 多源数据融合、去偏处理 |
复杂推理 | 多跳推理困难 | GraphRAG、迭代检索 |