RAG
基础
RAG(Retrieval-Augmented Generation)定义与原理
RAG(检索增强生成)指:在让大语言模型(LLM)生成答案 之前,先从 外部知识库(文档、数据库、网页等)中 检索 与用户问题相关的片段,再把这些片段作为 上下文 一并输入模型,从而 约束 模型的输出依据。
为什么需要 RAG(知识截止、幻觉、实时性)
- 知识截止(Knowledge Cutoff):预训练/基座模型只在某个时间点之前的数据上学习,之后发生的事实它「天然不知道」。
- 幻觉(Hallucination):模型在缺乏依据时仍会「编得像真的」。
- 实时性:业务数据(工单、库存、政策)每分钟都在变,仅靠静态模型参数无法反映。
文档解析与预处理
PDF、Word、HTML、Markdown 解析工具
解析是把 二进制或标记格式 变成 可切分的纯文本(并尽量保留标题层级、表格位置等结构信息)。
PDF 解析常见坑有哪些?
- 扫描件无文本层,必须 OCR;
- 多栏、脚注、页码混入正文;
- 表格被拆成无序碎片;
- 字体编码异常导致乱码。
对策:版面分析(layout)、表格专用解析、人工抽检与清洗规则。
为什么很多团队推荐 Unstructured?
它把文档分成带类型的元素(Title、NarrativeText、Table 等),便于 按结构分块 和后续路由(表格走表格策略)。
OCR 处理
表格和图片的处理策略
- 表格:保留为 Markdown/HTML 表格字符串;或转为 JSON 行记录 存两份索引(自然语言版 + 结构化版)。
- 图片:用 Caption 模型(如 BLIP、多模态大模型)生成描述文本再入库;或对关键图做 人工标注。
- 图文混排:按阅读顺序拼接「图注 + OCR/Caption + 相邻段落」为一个块或父子块。
表格为什么难做 RAG?
表格语义依赖 行列关系 与 表头;固定长度切分易切断行列。应用 表头感知分块、SQL/结构化检索 或 专用表格问答模型 辅助。
数据清洗与标准化
- 统一编码(UTF-8)、去除不可见字符
- 合并多余空白与断行
- 全角半角、数字与单位格式统一
- 去重(MinHash/SimHash 或 embedding 聚类)
- PII 脱敏(电话、身份证)按合规要求
文档分块策略(Chunking)
固定长度分块(Fixed Size)
概念解释
按字符数或 token 数切分,例如每 512 字符一块,简单高效。
原理与缺陷 实现简单,但常在 句子中间 切断,语义不完整;对代码、Markdown 结构不友好。
递归字符分割(RecursiveCharacterTextSplitter)
概念解释
LangChain 中常见:按 分隔符优先级 递归切分,例如 ["\n\n", "\n", " ", ""],尽量在段落、句子边界断开。
原理
先找高优先级分隔符;若块仍超长,再用下一级分隔符切,直到满足 chunk_size,并用 chunk_overlap 保留上下文衔接。
语义分块(Semantic Chunking)
概念解释
按 语义相似度变化 切分:相邻句子/段落嵌入向量,若相似度骤降则认为话题转换,在此处断开。
原理
更贴近「话题边界」,但 计算成本高,需设定阈值与最小块长度,避免过碎。
按文档结构分块(Markdown Header、HTML Section)
概念解释
利用 # 标题 或 HTML 的 <section> / 标题标签,把 同一小节 作为块或父文档。
原理
保证块内主题一致;检索命中时可返回 完整小节。
滑动窗口分块
概念解释
以窗口长度 (W) 和步长 (S)((S < W))滑动切分,相邻窗口重叠 (W-S)。
原理
减少边界信息丢失;代价是 存储膨胀 与 冗余检索,常配合去重或 MMR。
chunk_size 与 chunk_overlap 选择策略
经验法则(需实测)
- chunk_size:应覆盖 完整命题(一条规定、一个步骤),常见几百到一两千 token 量级;太小上下文不足,太大噪声多。
- chunk_overlap:通常为 size 的 10%–20%,避免切断关键句;overlap 越大,索引越大。
- 以评估为准:同一数据集扫网格,看 召回率与答案质量。
分块太大或太小分别会怎样?
太小 → 语义不完整、检索片段缺主语或条件;太大 → 混入无关内容、噪声干扰生成、embedding 语义模糊、费用上升。
父子文档分块(Parent-Child Chunking)
概念解释
子块(小,用于检索embedding)+ 父块(大,用于喂给 LLM),检索命中子块后取回其父块全文。
原理
兼顾 检索精度(细粒度匹配)与 生成上下文完整性(父块提供更多句子)。
父子块在向量库里怎么建索引?
仅对 子块 写入向量与 child_id;元数据中存 parent_id 与父块全文或父块存储路径。检索命中子块后,用 parent_id 取父块 拼进 Prompt。若父块过长,可对父块再 摘要 后送入。
向量化(Embedding)
什么是文本嵌入(Embedding)
文本嵌入
Embedding 把离散文本映射为 固定维度的稠密向量,语义相近的文本在向量空间中 距离更近(常用余弦相似度或内积)。
原理详解
训练目标多为 对比学习:同义句拉近、无关句推远。下游用向量近似 语义检索。
Embedding 模型选型标准
- 语言与领域:中文优先中文强化模型;医疗/法律可看领域微调版。
- 序列长度:长文档需更长上下文 embedding 或先分段再聚合。
- 许可证与部署:云端 API vs 私有化。
- 与重排/生成模型一致性:有时同一厂商链路更省心(非必须)。
维度、速度、效果的权衡
- 维度高:通常表达能力更强,但索引更大、ANN 更慢。
- 速度:批量推理、GPU、量化(INT8)可加速。
- 效果:以 检索召回@K 与 端到端问答 为准。
同一个 Embedding 用于中英文混合文档要注意什么?
选 多语言模型 或分别建索引;单语模型可能导致跨语言语义空间不一致。混合检索(BM25)可补关键词。
向量数据库
什么是向量数据库
概念解释
面向 高维向量 的存储与 近似最近邻(ANN) 查询系统,支持 insert/delete/query,常附带元数据过滤(时间、租户、标签)。
原理
暴力精确检索在高维下不可行;用 ANN 算法 换 略微精度 换 数量级加速。
主流选型对比
| 产品 | 特点 | 适用场景 |
|---|---|---|
| FAISS(Meta) | 单机库,非完整数据库;极致性能研究向 | 原型、离线实验、嵌入现有服务 |
| Milvus | 云原生、分布式、可扩展至百亿级 | 大规模生产、需要分区与多副本 |
| Pinecone | 全托管 SaaS,零运维 | 快速上线、无运维团队 |
| Chroma | 轻量、易上手 | 原型、小项目 |
| Weaviate | GraphQL API、内置模块 | 需要图式查询与生态集成 |
| Qdrant | Rust 实现、过滤丰富、性能强 | 自托管生产、复杂过滤 |
FAISS 和 Milvus 本质区别?
FAISS 是 ANN 算法库,需自建存储、服务、容灾;Milvus 是 向量数据库系统,提供分布式存储、运维能力与数据管理接口。
检索策略
向量检索(语义相似度)
概念解释
Query 与文档块 embedding 后做 Top-K 最近邻。
短板
专有名词、型号、编号等 精确匹配 不如关键词检索。
关键词检索(BM25)
概念解释
BM25 是经典 词频-逆文档频率 加权排序函数,擅长 精确词匹配。
混合检索(Hybrid Search)
概念解释
BM25 分数 + 向量分数 线性加权或归一化后融合,兼顾语义与字面。
多路检索与结果融合(RRF)
概念解释
RRF(Reciprocal Rank Fusion)是不依赖分数值、只看排序名次的加权融合方法,对各路(向量/关键词/元数据)加权后按排名的倒数加总,适合 跨库、异构检索的无监督融合。
为什么混合检索比单路向量更有效?
向量捕获语义,但可能漏掉 专有名词与编号;BM25 补精确匹配。二者融合提高鲁棒性,尤其在技术文档与电商场景。
当两路分数 量纲一致或已可靠归一化 时,加权融合直观可调;当一路是 排名、一路是 概率、或分数 不可比 时,RRF 更稳,且少调参(经典 (k=60))。
查询改写(Query Rewriting)
概念解释
把用户原始问句改写成 更易被检索匹配 的形式,或生成 多条查询变体 做多路召回。
原理详解
口语与文档书面语不一致(「咋办」vs「处理流程」);改写可 对齐术语。可用规则、同义词表,或用 LLM 生成「检索专用 Query」。
策略
同义扩展、拆问句、补全主语
用 LLM 生成 检索友好 的 query 变体多条,多路检索再融合
查询改写会不会引入噪声?
会。LLM 可能 篡改实体 或 添加未提及条件。对策:多路检索 + RRF、重排、引用校验,高敏场景用 人工词表 + 模板 优先。
需要保留原 Query 吗?
需要。常 原句 + 改写句 同时检索再融合,避免改写跑偏。
HyDE(假设文档嵌入)
概念解释
让 LLM 先写 假想的答案文档(可能含错),再对假想文档做 embedding 去检索。
原理
拉近查询与文档在向量空间的距离,缓解 查询与文档表述风格不一致。
风险
假想文档可能引入错误主题,需 重排与引用校验。
子问题分解
概念解释
对 多跳、多条件 问题,先由 LLM 或规则拆成 子问题序列,对每个子问题检索,再 拼接或图式合并 证据。
原理详解
单句 embedding 难以覆盖「先 A 再 B」的复合语义;分解后每步检索更 聚焦,类似 多步检索增强。
子问题分解的典型失败模式?
分解错误(实体指代错)、子问题遗漏约束、或 合并时矛盾未检测。需要 一致性检查 与 重排 过滤无关块。
Details
子问题分解可以是 固定模板/一次 LLM 调用;Agentic 更强调 动态决定是否再检索,工具边界更宽。
重排序(Reranking)
为什么需要重排序
概念解释
向量检索(Bi-Encoder)为速度对 query-doc 独立编码,交互信息不足;Cross-Encoder 把 query 与 doc 拼在一起 打分,精度更高但慢,故放在 Top-K 之后做小范围重排。
Cross-Encoder vs Bi-Encoder
| 类型 | 机制 | 优点 | 缺点 |
|---|---|---|---|
| Bi-Encoder | 两路编码,点积/余弦 | 快,可 ANN | 精度低于 CE |
| Cross-Encoder | 拼接后深度交互 | 精度高 | 慢,只能小批量 |
RAG 高级模式
GraphRAG(基于知识图谱的 RAG)
概念解释
从文本抽取 实体与关系 构建图,检索时沿 子图 或 社区摘要 获取证据,适合 多跳关系 与 全局问题(「整体主题是什么」)。
对比普通 RAG
普通向量 RAG 擅 局部相似块;GraphRAG 强化 关系推理与全局聚合(微软 GraphRAG 等工作)。
Agentic RAG(Agent 驱动的 RAG)
概念解释
由 Agent 决定何时检索、检索什么、是否再检索,可调用 多工具(搜索、数据库、代码执行)。
原理
把 RAG 从「一次检索」变为 多步决策循环,适合复杂任务。
Self-RAG(自我反思的 RAG)
概念解释
模型在生成过程中插入 反思 token:是否需要检索、检索内容是否有用、生成是否支持等,形成 自我批评与修正 循环。
Corrective RAG(纠正性 RAG)
概念解释
当检索质量 不达标 时,触发 额外检索(如网页搜索)或 改写查询,纠正证据不足。
Adaptive RAG
概念解释
按问题类型 路由 到不同链路:有的只需单跳向量检索,有的需多跳或工具,避免 过度检索 浪费成本。
原理详解
常见实现:用 轻量分类器 或 小模型 判断「需不需要检索 / 需要 SQL 还是文档 / 是否需要多跳」,再 分发 到不同子管道;与 Agentic RAG 的边界在于:Adaptive 强调 路由策略,Agentic 强调 循环决策与工具调用。
GraphRAG 的成本与挑战?
构图与抽取 成本高、抽取错误会污染图;运维复杂。适合关系密集、愿意投入工程化的场景。
Agentic RAG 与 Self-RAG 有什么共同点?
都引入 多步决策与反思;区别在于 Agentic 常外显为 工具调用与规划,Self-RAG 用 反思 token/标签 把「要不要检索、证据是否支持」内嵌在生成格式中,更偏 训练与解码策略。
Adaptive RAG 如何避免路由误判?
混合路由(并行短路与完整链路)、置信度阈值 + 默认安全策略(不确定则走更强检索)、持续用 线上反馈 迭代分类器。
小公司是否值得上 GraphRAG?
若数据以 说明文、FAQ 为主,向量 RAG + 混合检索 + 重排 通常足够;图适合 关系问题占比高 且团队有 图谱与评测 能力时再投入
RAG 评估
评估指标:忠实度、相关性、答案正确性
- 忠实度(Faithfulness):答案是否可由检索上下文推出,不编造。
- 上下文相关性(Context Relevance):检索块与问题是否相关。
- 答案正确性 / 有用性(Answer Correctness / Usefulness):是否真正解决问题(可用人工或强模型裁判)。
RAGAS 框架
概念解释
RAGAS 提供一组 基于 LLM 的指标(如 faithfulness、answer relevancy、context precision/recall),自动化评估 RAG 管道。
使用注意
裁判模型本身有偏差,应 抽样人工复核。
评估数据集构建
- 从真实日志 脱敏 抽样问题
- 标注 标准答案 或 支持文档 ID
- 覆盖 简单事实、多跳、拒答、无答案 等类型
为什么说「只看最终答案对错」不够?
可能 猜对 或 上下文不相关仍生成;需同时评 检索质量 与 忠实度,定位瓶颈在检索还是生成。
RAG 生产优化
索引优化
- 选择合适的 ANN 参数(HNSW 的 M、efConstruction、efSearch)
- 分段分区(按租户、时间、产品线)减少搜索空间
- 定期重建 vs 增量插入 权衡
缓存策略
- Query 级缓存:相同问题直接返回答案(注意权限与 TTL)
- Embedding 缓存:热门 query 的向量
- LLM 响应缓存:对低敏场景可缩短延迟
增量更新
- 文档变更 版本化;删除旧向量 按 doc_id
- 大批量用 离线任务 重建分区索引,小批量 实时 upsert
多租户设计
- 逻辑隔离:tenant_id 元数据强制过滤
- 物理隔离:大客户独立集群或命名空间
- 配额与限流:按租户限制 QPS 与存储
Token 成本控制
- 控制 检索条数与块长度
- 选用 更小上下文模型 做摘要与路由
- 压缩检索结果(抽取句子级证据再喂给主模型)
多租户下最常见的安全事故是什么?
检索 未带租户过滤 导致 跨租户数据泄露;必须在数据库层与查询层 双重校验。
综合
简述 RAG 两步流水线(离线与在线)。
离线:解析→清洗→分块→嵌入→建索引;
在线:Query(可选改写)→检索→(可选重排)→拼 Prompt→生成。
语义分块比递归分块更好吗?
不一定;语义分块成本高、阈值敏感。应用数据 A/B 测试。
BM25 在中文要不要分词?
依赖引擎;中文常需 分词或 n-gram,否则粒度不当影响效果。
Cross-Encoder 为何不能替代向量索引?
需对 每个 doc 与 query 运行,复杂度高,无法对百万级全库实时扫描。
GraphRAG 解决普通 RAG 的什么痛点?
多跳关系与部分 全局聚合类 问题。
索引频繁更新如何保持一致性?
版本号、双写切换、后台重建与灰度;读写分离。