从 Naive RAG 到 Graph RAG,从"按字数切"到"语义化切片",一篇把 RAG 的坑和天花板全讲透。
适合正在给 Agent 搭知识库、或者发现自己的 RAG "搜不准"的选手。
一、RAG 到底是啥?为什么 Agent 离不开它?
1.1 先讲个悲伤的故事
你花 3 万块买了个 GPT-5 API 额度,兴冲冲地接上你的企业内部知识库,问它:
"我们公司去年 Q3 的退款率是多少?"
大模型优雅地回复:
"根据我的训练数据(截止 2024 年 1 月),我无法获知贵公司 2025 年 Q3 的退款数据。不过退款率通常受产品质量、客服响应速度等因素影响..."
你血压直接拉满。
这就是 LLM 的三大硬伤:
训练数据有截止日期
不知道今天发生了什么"] P2["🧠 幻觉
不懂装懂,凭空编造
还编得特别自信"] P3["📚 无私有知识
不知道你公司内部
的文档、代码、数据"] end subgraph RAG方案["💡 RAG = 给 LLM 配个图书管理员"] SOL1["📖 检索 (Retrieve)
从知识库找到相关内容"] SOL2["📎 增强 (Augment)
把相关内容塞进 prompt"] SOL3["✍️ 生成 (Generate)
基于真实资料回答"] end LLM问题 -->|"RAG 解决"| RAG方案 style LLM问题 fill:#ffeaa7,stroke:#fdcb6e style RAG方案 fill:#55efc4,stroke:#00b894
1.2 RAG 的基本工作流
'退款率是多少?'"] subgraph 离线阶段["📦 离线阶段(一次性)"] D1["📄 文档库"] -->|"切片"| D2["📝 Chunks
文本片段"] D2 -->|"Embedding"| D3["🔢 向量数据库
存储向量索引"] end subgraph 在线阶段["⚡ 在线阶段(每次查询)"] Q1["🔍 把问题转成向量"] -->|"相似度搜索"| Q2["📊 召回 Top-K 相关片段"] Q2 -->|"拼接"| Q3["📎 Prompt = 问题 + 检索到的上下文"] end U --> 在线阶段 离线阶段 -.->|"提供索引"| 在线阶段 Q3 -->|"喂给 LLM"| ANS["✅ 基于真实资料的回答"] style U fill:#6c5ce7,color:#fff style ANS fill:#00b894,color:#fff
翻译成人话:RAG 就是在 LLM 回答之前,先去知识库里搜一下相关资料,把搜到的内容贴在问题后面一起给 LLM。这样 LLM 就不用"凭记忆瞎编"了。
二、RAG 的进化史:从石器时代到星际文明
RAG 不是一成不变的。2023 年到 2026 年,它已经迭代了至少 5 代:
2.1 第一代:Naive RAG(天真 RAG)
转成向量"] EMB --> VEC["向量数据库
余弦相似度搜索"] VEC --> TOP["取 Top-K 结果"] TOP --> PROMPT["拼进 Prompt"] PROMPT --> LLM["LLM 生成回答"] style Q fill:#dfe6e9,stroke:#b2bec3 style LLM fill:#74b9ff,stroke:#0984e3,color:#fff
就像去图书馆,只会用"书名关键词"搜索------搜到了算运气,搜不到就瞎编。
核心问题:
- 查询短、模糊 → 搜不准
- 只做单次检索 → 信息量不够
- 没有验证机制 → 搜到不相关的也硬塞给 LLM
2.2 第二代:Advanced RAG(进阶 RAG)
在 Naive 基础上加了三个"外挂":
用 LLM 把短问题扩展成
更详细的搜索 query"] REWRITE --> MULTI["📡 多路召回
向量检索 + 关键词 BM25
+ 元数据过滤 同时搜"] MULTI --> RERANK["📊 重排序 (Re-rank)
用 Cross-Encoder 模型
对召回结果重新打分排序"] RERANK --> TOP["取重排后的 Top-K"] TOP --> PROMPT["拼进 Prompt → LLM 生成"] style REWRITE fill:#a29bfe,stroke:#6c5ce7,color:#fff style MULTI fill:#74b9ff,stroke:#0984e3,color:#fff style RERANK fill:#00b894,stroke:#00a381,color:#fff
三招核心优化:
| 技术 | 作用 | 类比 |
|---|---|---|
| 查询改写 (Query Rewriting) | 把"退款率"扩展成"2025年Q3客户退款金额占总订单金额的比例" | 你问图书管理员"那个关于星星的书",他帮你翻译成"《时间简史》霍金著" |
| 多路召回 (Hybrid Search) | 向量搜索(语义相似)+ BM25(关键词匹配)+ 元数据过滤 同时跑 | 不只查书名,还查作者、关键词、分类号 |
| 重排序 (Re-rank) | 用更强的模型对 Top-50 结果重新打分,筛出真正相关的 Top-5 | 粗筛 50 本书,再仔细翻目录挑出 5 本 |
2.3 第三代:Modular RAG(模块化 RAG)
把 RAG 拆成可插拔的乐高积木:
根据任务类型
动态组合模块"] end 检索模块 --> ORCH 增强模块 --> ORCH 生成模块 --> ORCH ORCH --> OUTPUT["📤 最终回答"] style ORCH fill:#6c5ce7,color:#fff style OUTPUT fill:#00b894,color:#fff
2.4 第四代:Agentic RAG(智能体 RAG)
这是目前 Agent 时代的主流方案 。不是"检索→生成"单向流水线,而是 Agent 自己决定什么时候检索、检索什么、怎么检索:
需要:Q2满意度数据 + Q3满意度数据 Agent->>KB: 🔍 检索 "Q2 客户满意度报告" KB-->>Agent: 📄 Q2 报告摘要 Agent->>Agent: 🧐 发现数据不够
还需要具体评分维度 Agent->>KB: 🔍 检索 "Q3 NPS 评分 客户反馈" KB-->>Agent: 📄 Q3 详细数据 Agent->>Agent: 🧐 发现两季度数据口径不同
需要统一标准 Agent->>KB: 🔍 检索 "满意度评分标准定义" KB-->>Agent: 📄 评分标准文档 Agent->>LLM: 📎 汇总三份资料 + 原问题 LLM-->>Agent: ✅ 生成对比分析 Agent-->>User: "Q2 满意度 4.2,Q3 升至 4.5..."
Agentic RAG 的核心特征:
自己分解问题,决定
检索什么、检索几次"] A2["🔧 工具调用
不只是向量搜索,
还能查 SQL、调 API"] A3["🔄 迭代检索
搜一次不够就再搜,
直到信息充分"] A4["✅ 自我验证
检查检索结果是否
真的回答了问题"] end style Agentic fill:#6c5ce7,color:#fff,stroke:#5a4bd1,stroke-width:3px
2.5 RAG 类型全景对比
个人笔记搜索"] A["Advanced RAG
企业文档问答"] end subgraph 复杂["🧩 复杂场景"] M["Modular RAG
多源数据融合"] AG["Agentic RAG
多步推理 + 工具调用"] end subgraph 终极["🚀 高阶场景"] GR["Graph RAG
全局理解 + 关系推理"] MUL["Multi-Agent RAG
多 Agent 协作检索"] end 简单 -->|"数据复杂度 ↑"| 复杂 复杂 -->|"推理深度 ↑"| 终极 style GR fill:#e17055,color:#fff,stroke:#d63031,stroke-width:2px
三、Graph RAG:当知识图谱遇上 RAG
3.1 传统 RAG 的"近视眼"问题
传统 RAG(包括 Advanced/Agentic)有一个本质局限:它只能看到"孤立的文本片段",看不到"片段之间的关系"。
举个例子:你问"谁负责审批李四的退款?"
- 传统 RAG 搜到 "张三是退款组组长" 和 "退款需要组长审批" 两个 chunk,但不知道张三和李四的关系,只能猜。
- Graph RAG 直接在图里走:
李四→提交→退款申请→需要→退款审批→负责→张三,精准答案。
3.2 Graph RAG 是什么?
Graph RAG 是 Microsoft 在 2024 年提出的方案,核心理念是:用知识图谱代替(或补充)向量检索。
+ 社区发现聚类"] G2 --> G3["查询 → 图遍历 + 社区检索"] G3 --> G4["返回结构化子图 → 喂给 LLM"] end style 传统RAG fill:#dfe6e9,stroke:#b2bec3 style GraphRAG fill:#6c5ce7,color:#fff,stroke:#5a4bd1,stroke-width:2px
3.3 Graph RAG 的核心流程(Microsoft 方案)
抽取实体和关系"] E1_DESC["实体: 张三、退款组、李四、退款申请
关系: [张三]担任[退款组组长]
[李四]提交[退款申请]"] end subgraph 第二步["② 构建知识图谱"] E2["实体 → 节点
关系 → 边
生成图结构"] end subgraph 第三步["③ 社区发现"] E3["用 Leiden 算法
发现图中的社区/集群
给相关节点分组"] E3_DESC["社区1: 退款流程相关
社区2: 用户管理相关
社区3: 财务结算相关"] end subgraph 第四步["④ 社区摘要生成"] E4["为每个社区生成
自然语言摘要
描述这个社区讲了什么"] end subgraph 第五步["⑤ 查询时检索"] E5["问题 → 匹配最相关的
社区摘要 → 返回该社区
的结构化信息"] end 第一步 --> 第二步 --> 第三步 --> 第四步 --> 第五步 style 第一步 fill:#74b9ff,stroke:#0984e3,color:#fff style 第二步 fill:#a29bfe,stroke:#6c5ce7,color:#fff style 第三步 fill:#fd79a8,stroke:#e84393,color:#fff style 第四步 fill:#00b894,stroke:#00a381,color:#fff style 第五步 fill:#e17055,stroke:#d63031,color:#fff
3.4 Graph RAG vs 传统 RAG:一张表讲清楚
'这个系统整体做了什么'"] G_WIN2["✅ 多跳推理天然支持"] G_WIN2_D["A→B→C→D 一步到位"] G_WIN3["✅ 结构化输出"] G_LOSE1["❌ 构建成本高
(每个chunk都要调LLM抽实体)"] G_LOSE2["❌ 实现复杂"] G_LOSE3["❌ 简单事实查询可能
不如向量检索精准"] end end style 传统 fill:#dfe6e9,stroke:#b2bec3 style 图谱 fill:#6c5ce7,color:#fff,stroke:#5a4bd1
| 维度 | 传统 RAG | Graph RAG |
|---|---|---|
| 检索方式 | 向量相似度 + 关键词 | 图遍历 + 社区检索 |
| 知识表示 | 独立文本片段 (Chunks) | 实体-关系-社区 层级图 |
| 适用问题 | 事实查找型:"退款率是多少?" | 全局归纳型:"整个退款系统是怎么设计的?" |
| 多跳推理 | 困难,需要多次检索 | 原生支持,图里走几步就到 |
| 构建成本 | 低(Embedding 一次) | 高(每个 chunk 需 LLM 抽取实体) |
| 查询延迟 | 毫秒级 | 可能秒级(图遍历 + 社区匹配) |
| 可解释性 | 弱("因为向量最相似") | 强("因为 A→B→C 的关系路径") |
| 维护成本 | 低(增删 chunk 即可) | 高(实体关系变更需更新图) |
3.5 到底什么时候该用 Graph RAG?
'X 的退款率是多少?'"| Q2{"数据量多大?"} Q1 -->|"全局理解
'总结整个退款流程'"| GR["✅ 用 Graph RAG"] Q1 -->|"多跳推理
'谁审批李四的退款?'"| GR Q1 -->|"对比分析
'Q2 vs Q3 的差异'"| Q2 Q2 -->|"< 10 万文档"| TRAD["✅ 传统 Advanced RAG 足够"] Q2 -->|"> 10 万文档
且关系复杂"| HYBRID["✅ 混合方案
向量检索 + 图检索"] style GR fill:#e17055,color:#fff style TRAD fill:#55efc4,color:#000 style HYBRID fill:#6c5ce7,color:#fff
一句话决策:如果你主要问"是什么/有多少/在哪里",传统 RAG 够用。如果你经常问"整体上/为什么/关系是什么",上 Graph RAG。
四、从 0 到 1 实现 RAG:那些让你抓狂的坑
理论聊完了,我们来点真实的。以下是每个 RAG 工程师必经的"五重炼狱":
4.1 第一重:切片之殇
这是 RAG 的第一个也是最要命的决策。切不好,后面全白搭。
每 500 字切一刀"] Q --> SEMANTIC["🧠 方案 B:语义化切片
按段落/章节自然边界切"] Q --> RECURSIVE["🔄 方案 C:递归切片
先大后小,逐级拆分"] Q --> AGENTIC["🤖 方案 D:Agent 切片
让 LLM 判断最佳切点"] FIXED --> FIXED_BAD["❌ 问题:一句话被拦腰截断
'退款流程需要...
(切)
...经过三级审批'"] SEMANTIC --> SEM_BAD["⚠️ 问题:段落长度不均
有的 100 字,有的 3000 字
长的 Embedding 效果差"] RECURSIVE --> REC_OK["✅ 当前最主流方案
先按段落切 → 太长再按句子切
→ 还太长按固定大小切"] AGENTIC --> AGT_OK["✅ 效果最好但最贵
每次切片都调一次 LLM
适合高价值文档"] style FIXED_BAD fill:#fab1a0,stroke:#e17055 style SEM_BAD fill:#ffeaa7,stroke:#fdcb6e style REC_OK fill:#55efc4,stroke:#00b894 style AGT_OK fill:#55efc4,stroke:#00b894
各种切片策略实测对比:
| 策略 | 做法 | 优点 | 缺点 | 推荐场景 |
|---|---|---|---|---|
| 固定字数 | 每 500 字一切 | 实现简单 | 经常截断语义单元 | 几乎不推荐 |
| 固定 Token | 每 256 token 一切 | 适配模型上下文 | 仍然可能截断语义 | 快速原型 |
| 按段落 | 以 \n\n 为边界 |
语义完整 | 段落长度不可控 | 结构良好的文档 |
| 按标题/章节 | 以 Markdown 标题为边界 | 结构清晰 | 需要文档有规范格式 | 技术文档 |
| 递归切片 | 先段落 → 句子 → 固定大小 | 平衡语义和长度 | 实现稍复杂 | 当前主流推荐 |
| 语义切片 | 用 Embedding 检测语义边界 | 切得最合理 | 慢、贵 | 高价值知识库 |
| Agent 切片 | LLM 判断最佳切点 | 最精准 | 极贵 | 法律/医疗等精确场景 |
| 句子窗口 | 以句子为单位 + 上下文窗口 | 灵活 | 参数调优麻烦 | 对话型应用 |
4.2 第二重:检索不准
你信心满满地上线了 RAG,然后发现:
真实案例:
用户问:"怎么退款?"
RAG 返回:"退款政策第 3.2 条...退款申请表...财务审批流程..."
但用户其实只想知道 "点哪里能退款"。
这就是经典的 "查询-文档语义鸿沟"------用户用口语问,文档用书面语写。
4.3 第三重:召回不全
搜到了 3 篇相关文档,但漏了第 4 篇最关键的那个。原因:
信息被分散到多个 chunk"] R2["🔸 语义漂移
'退款'和'退货'明明同义
但 Embedding 觉得不像"] R3["🔸 Top-K 太小
K=3 时第 4 个刚好是最重要的"] R4["🔸 查询太短
'退款'两个字信息量不够"] R5["🔸 文档同质化
相似内容太多,干扰排序"] R6["🔸 缺少元数据过滤
搜到去年的文档而非今年的"] end style 原因 fill:#fab1a0,stroke:#e17055
4.4 第四重:答案被"中间地带"污染
RAG 召回了一堆"有点相关但不精准"的内容,LLM 基于这些模糊信息生成的答案自然也不精准。
Garbage in, garbage out. 检索质量直接决定 RAG 的上限。
4.5 第五重:上下文窗口爆炸
Agentic RAG 多次检索后,积累了 20 个 chunk,总共 15000 token,直接把 LLM 的上下文窗口塞满了------然后 LLM 开始"忽略中间内容"(Lost in the Middle 效应)。
五、如何提升 RAG 的召回质量?一份实操清单
以下策略按性价比排序(效果/实施成本):
投入: 低 | 效果: 显著"] B2["② 查询改写
投入: 低 | 效果: 显著"] B3["③ 混合检索
投入: 中 | 效果: 显著"] end subgraph 进阶["🟡 进阶优化(推荐)"] A1["④ Re-rank 重排序
投入: 中 | 效果: 明显"] A2["⑤ HyDE 假设文档
投入: 中 | 效果: 明显"] A3["⑥ 元数据过滤
投入: 低 | 效果: 中等"] end subgraph 高级["🔴 高级优化(按需)"] H1["⑦ Fine-tune Embedding
投入: 高 | 效果: 显著"] H2["⑧ 知识图谱增强
投入: 高 | 效果: 质变"] H3["⑨ Agent 自主检索
投入: 高 | 效果: 质变"] end 基础 --> 进阶 --> 高级 style 基础 fill:#55efc4,stroke:#00b894 style 进阶 fill:#ffeaa7,stroke:#fdcb6e style 高级 fill:#fab1a0,stroke:#e17055
5.1 基础优化(不做就别上线)
① 递归语义切片 --- 别再用固定字数了!
python
# ❌ 石器时代做法
chunks = [doc[i:i+500] for i in range(0, len(doc), 500)]
# ✅ 现代做法:递归字符分割 + 语义边界
from langchain.text_splitter import RecursiveCharacterTextSplitter
splitter = RecursiveCharacterTextSplitter(
chunk_size=500, # 目标大小
chunk_overlap=50, # 重叠窗口(防止边界截断)
separators=["\n\n", "\n", "。", ".", " ", ""] # 按优先级依次尝试
)
chunks = splitter.split_documents(docs)
overlap 的重要性:
② 查询改写 --- 让问题先"变聪明"
退款条件、退款步骤、
所需材料、处理时间" Rewrite->>Search: 用改写后的 query 检索 Search-->>User: 精准结果
实操代码思路:
python
rewrite_prompt = """把用户的简短问题改写成用于向量检索的详细查询。
包含可能相关的同义词、别名、具体术语。
用户问题: {question}
改写后的查询:"""
rewritten = llm.invoke(rewrite_prompt.format(question="退款怎么搞?"))
# 输出: "退款流程 退款申请 退款条件 退款步骤 所需材料 处理时间 退款政策"
③ 混合检索 --- 向量不够,关键词来凑
语义相似度"] Q --> BM25["📝 BM25 关键词检索
精确匹配"] Q --> META["🏷️ 元数据过滤
时间/类型/来源"] VEC --> FUSION["🔄 结果融合
RRF (Reciprocal Rank Fusion)
综合排序"] BM25 --> FUSION META --> FUSION FUSION --> TOP["📊 Top-K 结果"] style FUSION fill:#6c5ce7,color:#fff
RRF 融合算法(简单但有效):
python
def reciprocal_rank_fusion(results_lists, k=60):
"""
results_lists: 多个检索器返回的排序列表
k: 平滑参数
"""
scores = {}
for results in results_lists:
for rank, doc_id in enumerate(results):
scores[doc_id] = scores.get(doc_id, 0) + 1 / (k + rank + 1)
return sorted(scores.items(), key=lambda x: x[1], reverse=True)
5.2 进阶优化(投入产出比最高)
④ Re-rank --- 粗筛 50 篇,精选 5 篇
这是单个效果最明显的优化:
向量检索 Top-50
速度快、覆盖面广"] FAST --> RERANK["🎯 Cross-Encoder 重排序
对 50 个候选逐一精细打分
模型: bge-reranker / Cohere Rerank"] RERANK --> TOP5["✅ 精选 Top-5
准确率大幅提升"] style RERANK fill:#6c5ce7,color:#fff
一句话:用便宜的向量模型广撒网(Top-50),用贵的 Cross-Encoder 精挑(Top-5)。
⑤ HyDE (Hypothetical Document Embeddings) --- 让 LLM 先"脑补"一篇文档
'用户想了解退款流程。首先需要
登录账户,进入订单页面,点击
申请退款按钮...'"] HYDE --> EMB["🔢 用这篇假设文档的向量
去检索真实文档"] Q --> DIRECT["直接用问题向量检索"] EMB -->|"✅ 更准
假设文档用语和真实文档更接近"| RESULT["检索结果"] DIRECT -->|"⚠️ 可能偏差
口语 vs 书面语的鸿沟"| RESULT style HYDE fill:#a29bfe,stroke:#6c5ce7,color:#fff
为什么 HyDE 有效? 因为 LLM 生成的"假设文档"使用的是书面语/专业术语,和知识库里的真实文档在语义空间里更接近,比用户的口语化问题更容易匹配到正确文档。
⑥ 元数据过滤 --- 别让去年的文档污染今年的答案
python
# 检索时加入元数据过滤
results = vector_store.search(
query="退款流程",
filter={
"doc_type": "policy", # 只要政策文档
"year": 2025, # 只要今年的
"department": "customer_service" # 只要客服部门的
},
top_k=10
)
5.3 高级优化(追求极致)
⑦ Fine-tune Embedding 模型 --- 让你的向量"懂行话"
通用 Embedding 模型不知道你们公司的"RT"是"Refund Ticket"还是"Real-Time"。微调后,Embedding 模型能理解领域术语。
⑧ 知识图谱增强 --- 给 RAG 装上"关系大脑"
这正是 Graph RAG 的领域。在向量检索的基础上,叠加知识图谱的关系推理能力。
⑨ Agent 自主检索 --- 让 RAG 学会"思考"
不是"搜一次就完",而是 Agent 自己判断:
- 这个问题需要检索吗?(不需要就别调 RAG,省 Token)
- 需要检索几次?(一次够不够?)
- 需要检索什么?(向量?SQL?API?)
- 检索结果够好吗?(不够就改写查询再搜)
5.4 完整质量提升路线图
+ 合理 overlap"] CHUNK --> EMBED["② 选好 Embedding 模型
推荐: bge-large / text-embedding-3"] EMBED --> HYBRID["③ 实现混合检索
向量 + BM25"] HYBRID --> REWRITE_QRY["④ 加查询改写"] REWRITE_QRY --> RERANK_STEP["⑤ 加 Re-rank 重排序"] RERANK_STEP --> EVAL["⑥ 建立评估体系
每个改动都要量化效果"] EVAL --> CHECK1{"检索准确率
> 80%?"} CHECK1 -->|"否"| FIX1["调优切片参数
+ 尝试 HyDE"] FIX1 --> EVAL CHECK1 -->|"是"| CHECK2{"复杂问题
效果好吗?"} CHECK2 -->|"否"| FIX2["上 Agentic RAG
多步检索 + 工具调用"] FIX2 --> EVAL2["重新评估"] CHECK2 -->|"是"| CHECK3{"需要全局理解
/多跳推理?"} CHECK3 -->|"是"| FIX3["上 Graph RAG
知识图谱增强"] CHECK3 -->|"否"| DONE(["✅ 你的 RAG 已经很能打了"]) EVAL2 --> CHECK3 style START fill:#6c5ce7,color:#fff style DONE fill:#00b894,color:#fff style EVAL fill:#ffeaa7,stroke:#fdcb6e style FIX3 fill:#e17055,color:#fff
六、RAG 评估:你的改进到底有没有用?
很多人改了切片策略就觉得自己"优化了 RAG",但没有评估的优化都是耍流氓。
6.1 关键指标
前K个结果中,相关文档
被召回的比例"] RET2["MRR (Mean Reciprocal Rank)
第一个相关结果排在第几位
排名越靠前越好"] RET3["NDCG
考虑排序位置的相关性
越相关排越前 = 分越高"] end subgraph 生成指标["📝 生成质量指标"] GEN1["Faithfulness
答案是否基于检索到的文档
还是 LLM 自己编的?"] GEN2["Answer Relevance
答案是否真的回答了问题"] GEN3["Context Relevance
检索到的文档是否真的相关"] end style 检索指标 fill:#74b9ff,stroke:#0984e3,color:#fff style 生成指标 fill:#00b894,stroke:#00a381,color:#fff
6.2 最小可行评估集
不需要复杂的框架,一个简单的评估流程:
python
# 准备 50-100 个真实的用户问题 + 标准答案
eval_set = [
{
"question": "退款需要什么材料?",
"ground_truth": "需要订单号、退款原因、支付凭证",
"relevant_docs": ["doc_123", "doc_456"] # 标注哪些文档包含答案
},
# ... 至少 50 条
]
# 每次改动后跑一遍
def evaluate(rag_pipeline, eval_set):
recall_scores = []
for item in eval_set:
retrieved = rag_pipeline.retrieve(item["question"], top_k=5)
hits = len(set(retrieved) & set(item["relevant_docs"]))
recall_scores.append(hits / len(item["relevant_docs"]))
return sum(recall_scores) / len(recall_scores)
七、总结:RAG 技术选型决策树
(有标题/章节)"| SOL1["✅ Advanced RAG
递归语义切片
+ 混合检索 + Re-rank"] Q1 -->|"非结构化
(聊天记录/邮件)"| SOL2["✅ Agentic RAG
让 Agent 动态决定
检索策略"] Q2 -->|"事实查找为主"| SOL3["✅ Advanced RAG
+ Fine-tuned Embedding
+ 元数据过滤"] Q2 -->|"全局归纳/总结
多跳推理"| SOL4["✅ Graph RAG
知识图谱 + 社区摘要
+ 混合检索"] Q2 -->|"两者都要"| SOL5["✅ Hybrid RAG
向量检索 + 图检索
双路并行,结果融合"] style START fill:#6c5ce7,color:#fff style SOL1 fill:#55efc4,color:#000 style SOL2 fill:#55efc4,color:#000 style SOL3 fill:#55efc4,color:#000 style SOL4 fill:#e17055,color:#fff style SOL5 fill:#e17055,color:#fff
最后一张速查表:遇到问题怎么修
| 症状 | 可能原因 | 先试这个 | 还不行再试 |
|---|---|---|---|
| 搜不到 | 切片太碎/查询太短 | 增大 chunk_size + 查询改写 | HyDE |
| 搜不准 | 语义鸿沟 | 混合检索(+BM25) | Re-rank + Fine-tune Embedding |
| 搜不全 | 信息分散在多个 chunk | 增大 Top-K + overlap | Agent 多步检索 |
| 答案编造 | LLM 忽略检索结果 | 强化 prompt 指令 | Graph RAG 结构化上下文 |
| 太慢 | 检索链路太长 | 去掉不必要的重排 | 缓存热点查询 |
| 太贵 | LLM 调用太多 | 减少 query rewrite 频率 | 用小模型做预处理 |
| 中间内容丢失 | Lost in the Middle | 把核心内容放开头/结尾 | 上下文压缩 |
八、趋势展望:RAG 的下一步
(图+表+代码)"] end subgraph 未来["🔮 未来 1-2 年"] FUT1["Self-Evolving RAG
从用户反馈中自动优化检索"] FUT2["Federated RAG
跨组织安全检索"] FUT3["Codeless RAG
拖拽式配置,零代码"] end 现在 --> 未来 style 现在 fill:#74b9ff,stroke:#0984e3,color:#fff style 未来 fill:#6c5ce7,stroke:#5a4bd1,color:#fff
- Agentic RAG 成为标配 --- 不是"要不要 Agent",而是 Agent 的自主程度有多高
- Graph RAG 降本 --- Microsoft 的方案太贵,社区正在搞更轻量的图构建方案
- Small-2-Big 混合体 --- 用小模型做检索,大模型做生成,成本砍半
- 评估自动化 --- RAG 的评估从人工标注走向 LLM-as-Judge 自动打分
- 端到端可观测 --- 每个检索-生成链路都埋点,精准定位哪个环节拉胯
本文是 RAG 实用主义的产物------不讲论文里的花活,只讲你在真实项目中会遇到的坑和能用的解法。如果你正在给 Agent 搭知识库,希望这篇文章能让你少走弯路。