RAG(检索增强生成)是把外部知识库"接"到大模型上的技术。本文基于一次真实的企业内部知识库项目, 系统讲清 RAG 的概念、原理、进阶技术、实战踩过的坑,以及一套可以亲手把玩的迷你 RAG。
大语言模型(LLM)有固有的局限:① 知识有时效性——只学到训练截止日期前的知识,无法知晓之后发生的事; ② 会产生幻觉——对不知道的问题,可能编造出看似合理实则错误的内容; ③ 缺乏领域知识——通用模型不了解特定企业或行业的制度与规则。
RAG(检索增强生成)的解法:在模型回答前,先从外部知识库检索相关资料,把资料作为上下文提供给模型,让它基于材料作答。 本质上就是"带着参考书答题"。
| 大模型的局限 | 具体表现 | RAG 的解法 |
|---|---|---|
| 知识时滞 | 不知道训练截止后的事(新政策、新产品、实时数据) | 知识库随时更新,新内容入库即可检索 |
| 幻觉 | 编造看似合理实则错误的内容 | 强制基于检索内容作答,答不上来明说不知道 |
| 领域盲区 | 缺乏企业/行业专门知识 | 外挂领域知识库(制度、手册、FAQ) |
| 数据隐私 | 可能泄露敏感数据 | 敏感资料留在内部知识库,模型只查不记 |
| 不可溯源 | 回答无出处,无法追责 | 每条答案可指向原文片段,可追溯 |
RAG 系统分两大阶段。离线阶段(提前完成,构建知识索引):收集文档 → 切分 → 向量化 → 入库。 在线阶段(用户提问时实时发生):把问题向量化 → 检索相似片段 → 连同问题一起交给模型生成答案。
一句话在模型里被映射成一组向量数值。下图展示 3 个词的向量分布(示意)—— "猫"和"猫咪"的向量几乎一致(相似度 0.93),而"汽车"与它们差异明显(相似度 0.21)。
向量检索通过计算"问题向量与片段向量的相似度"来排序。常见方式:
| 方式 | 说明 | 特点 |
|---|---|---|
| 向量相似度 | 比较向量方向是否一致(余弦相似度最常用) | 能识别同义词与语义相近的文本 |
| 关键词匹配(BM25) | 统计查询词与文档的词频重合度 | 精确匹配专有名词,但不理解语义 |
| 入门 Naive RAG | 进阶 Advanced RAG | 模块化 Modular RAG | |
|---|---|---|---|
| 流程 | 索引 → 检索 → 生成(直线) | 检索前后增加优化步骤 | 积木式可编排 |
| 代表技术 | 基础向量检索 | 查询重写、结果重排 Rerank、混合检索 | 动态路由、多路融合、自我修正 |
| 优点 | 简单直接 | 准确率提升明显 | 灵活、可定制 |
| 代价 | 效果不稳定 | 流程固定、优化空间有限 | 系统复杂、调试成本高 |
优化手段按改动成本从低到高排列:提示词工程 → RAG → 微调。 核心区分:想解决"知道什么"(缺知识、知识过时、需要引用来源)→ 用 RAG; 想改变"怎么做"(输出格式、说话风格)→ 才考虑微调。
| 手段 | 改动什么 | 适合场景 | 成本 |
|---|---|---|---|
| 提示词工程 | 只改提问方式 | 模型本身会,只是未被引导 | 极低 |
| RAG | 外挂知识库,不改模型 | 模型缺特定/实时知识 | 中(需建库) |
| 微调 | 改变模型权重 | 改变行为/风格/格式 | 高(算力+数据) |
嵌入模型和 LLM 都有上下文窗口限制——一次能处理的文本量有限。整篇 10 万字的文档无法一次性向量化, 必须切成小块。同时,块的大小直接影响检索效果。
块的大小需要权衡:块过大导致内容主题混杂、检索不精准; 块过小导致语义断裂、上下文不完整。
| 块切太大 | 块切太小 |
|---|---|
| 主题混杂——一个块含多个主题,查询难以精准命中 | 语义断裂——一句话被切两半,上下文不完整 |
| "大海捞针"——长上下文中关键信息被稀释、易被忽略 | 主题分散——同一主题散落多块,检索不完整 |
| 向量稀释——长文本向量化后重点信息被淹没 | 块数膨胀——向量库膨胀,检索变慢 |
| 策略 | 原理 | 优点 | 缺点 |
|---|---|---|---|
| 固定大小 | 按固定字符数切 | 简单、快 | 易切断语义 |
| 递归字符 | 按分隔符层级切 | 语义较完整,通用 | 中文需配置分隔符 |
| 语义分块 | 模型检测语义断点 | 块内主题聚焦 | 慢、需调参 |
| 结构分块 | 按标题切 | 保留章节元数据 | 依赖文档结构 |
一个实用的设计:小的子分段负责"匹配",大的父分段负责"返回"。 查询命中某个小子分段后,返回的是它所属的整个父分段——既获得精确匹配,又保有完整上下文。 这也是本项目知识库采用的机制。
## 标题层级;每块超过约 1022 字符会被硬切。详见 04 节。
单一向量检索擅长"语义理解"但不擅长"精确匹配"(如产品型号、人名、缩写)。 混合检索 = 密集向量(语义检索) + 稀疏向量(BM25 关键词检索) 并行执行,再融合结果。
| 密集向量(语义) | 稀疏向量(关键词) | |
|---|---|---|
| 实现 | Embedding 模型(BGE、OpenAI) | BM25 / TF-IDF |
| 擅长 | 同义词、语义相近的匹配 | 专有名词、型号、缩写精确命中 |
| 弱点 | 短词区分度低 | 不理解语义("汽车"≠"轿车") |
| 融合 | 倒数排名融合 RRF 或加权线性组合 | |
向量检索先召回 TopK 个候选(可能含噪声),再用更强的重排序模型对这 TopK 个重新打分排序,把真正相关的排到前面。 Rerank 只负责"排序"不负责"召回"——所以召回阶段的候选数(TopK)不能太小。
| 技术 | 解决的问题 | 做法 |
|---|---|---|
| 查询重写 | 用户问得含糊、有指代 | 把问题改写成利于检索的形式(补全指代、扩展同义) |
| HyDE | 问题太短、向量区分度低 | 先用 LLM 生成一段"假答案",再拿假答案去检索 |
| 多路召回 | 单一检索可能漏 | 同时跑向量 + 关键词 + 数据库查询,融合结果 |
| Text2SQL | 用户想查结构化数据 | 把自然语言转成 SQL 去查数据库 |
| 维度 | 问什么 | 常用指标 |
|---|---|---|
| 检索相关性 | 召回内容里有多少是真正相关的 | Recall@K、Precision@K、命中率 |
| 生成质量 | 答案是否正确、忠实于原文 | 忠实度(Faithfulness)、答案相关度 |
| 端到端 | 整体能否解决用户问题 | RAGAS、TruLens 自动化评估 |
retriever_resources.content 是否含原文关键句和 URL,
而非仅判断"答案像不像对"。答案流畅 ≠ 用到了知识库,必须确认模型"喂进去"的上下文正确。
:// 仍在。## 标题控制父分段数量;块内写成连续文字。## 块,或压缩冗余连接词。## 标题;想要 1 个就写成无换行连续文本(≤1022)。.md,控制换行即控制分段。/chat-messages 检查 retriever_resources.content 是否含原文关键句和 URL。