从 RAG 到 Agentic RAG、GraphRAG:一篇讲透企业级知识增强系统的设计、实现与落地
这不是一篇“RAG 是什么”的入门短文,而是一篇面向工程实践的系统化整理。
目标读者:前端 / 后端 / AI 应用开发 / 技术负责人 / 正在做知识库问答、企业 AI 助手、文档检索系统的人。
你可以把它当成:
- 学习笔记
- 技术分享底稿
- 掘金长文
- 企业内部培训材料
目录
- 1. 为什么今天还要认真学 RAG
- 2. 什么是 RAG:它不是向量库,更不是一个 Prompt 技巧
- 3. 为什么 Long Context 不会杀死 RAG
- 4. RAG 的完整系统分层
- 5. Indexing:知识如何变成“可被检索”的结构
- 6. Retrieval:为什么检索质量决定 RAG 上限
- 7. Rerank:为什么只靠向量检索不够
- 8. Generation:如何让模型“基于证据回答”
- 9. RAG 的几种主要形态:Basic / Advanced / Modular / Long / Agentic / Graph
- 10. 实际项目里哪种用得最多
- 11. Python 代码:从一个最小 RAG Demo 开始
- 12. Python 代码:加入 Rerank 与 Metadata Filter 的增强版 RAG
- 13. Python 代码:Agentic RAG 的一个最小伪实现
- 14. GraphRAG 应该怎么理解
- 15. 工程落地时最容易踩的坑
- 16. 如何评测一个 RAG 系统是不是“真的可用”
- 17. 技术选型建议
- 18. 一张图总结全文
- 19. 最后的结论
1. 为什么今天还要认真学 RAG
很多人第一次接触大模型,会先经历一个认知阶段:
- ChatGPT 很聪明
- Claude 上下文很长
- 看起来已经什么都能答
- 那还要不要做知识库?还要不要做 RAG?
这个问题非常常见,而且很容易把人带偏。
因为如果你只是日常聊天,模型确实已经很好用了;但一旦进入企业场景,你会立刻遇到几个现实问题:
- 模型不知道你公司的内部知识
- 模型不知道训练截止之后的新信息
- 模型会幻觉
- 模型没有天然的可追溯性
- 模型不是数据库,也不是搜索引擎
所以从工程视角看,RAG 之所以重要,不是因为它是一个热门名词,而是因为:
它解决了“大模型无法稳定访问外部知识”这个核心问题。
2. 什么是 RAG:它不是向量库,更不是一个 Prompt 技巧
2.1 定义
RAG,Retrieval-Augmented Generation,中文通常翻译为 检索增强生成。
它的核心思想是:
- 用户提出问题
- 系统先去外部知识库中找相关内容
- 再把“问题 + 相关内容”一起交给大模型
- 模型基于这些资料生成答案
用一句话概括:
RAG = 检索系统 + 大模型生成系统
2.2 它不是什么
RAG 经常被误解成几种东西:
误解 1:RAG = 向量数据库
不对。
向量数据库只是 RAG 中的一个存储组件。
误解 2:RAG = 给 Prompt 多加一点上下文
也不对。
如果没有检索、没有索引、没有上下文构建,你只是“塞更多文本”,不叫真正的 RAG。
误解 3:RAG = 让模型知道更多
也不准确。
RAG 不是真把知识写进模型参数里,而是让系统在回答问题时临时访问正确知识。
2.3 从系统视角重新理解 RAG
从工程视角看,一个完整的 RAG 至少包含四件事:
- 信息索引系统
- 检索召回系统
- 上下文构建系统
- 生成系统
也就是说,RAG 的本质不是“模型本身变强了”,而是:
系统把“正确知识”送到了模型面前。
3. 为什么 Long Context 不会杀死 RAG
这是现在最常被问到的问题之一。
3.1 表面上的疑问
既然现在模型上下文已经能做到几十万、上百万 token:
- 我是不是可以把一整本书塞进去?
- 我是不是可以把所有文档都塞进去?
- 那我为什么还需要 RAG?
3.2 真正的问题不是“能不能塞”,而是“应不应该塞”
Long Context 解决的是:
- 一次能读更多材料
- 更适合跨段落推理
- 更适合长文精读
但它没有解决:
- 从海量知识里筛选相关信息
- 成本控制
- 首字延迟
- 脏上下文污染
- 组织级知识规模远大于单次窗口
3.3 正确结论
RAG 负责广度,Long Context 负责深度。
你可以把它们理解成这样:
- RAG:先从“整个图书馆”里找出最相关的那一小批书
- Long Context:再把这些书里的关键内容交给模型精读
这也是为什么未来更合理的方向不是“只有 RAG”或“只有 Long Context”,而是:
Long RAG
4. RAG 的完整系统分层
一个成熟的 RAG 系统,建议至少从四层去理解:
flowchart TD
A[数据层] --> B[索引层]
B --> C[检索层]
C --> D[上下文构建层]
D --> E[生成层]
E --> F[评测与监控层]
4.1 数据层
负责文档来源、清洗、解析、更新。
4.2 索引层
负责把文档变成可被高效匹配的数据结构。
4.3 检索层
负责把用户问题映射到最相关的候选知识片段。
4.4 上下文构建层
负责筛选、重排、去重、清洗,形成高质量上下文。
4.5 生成层
负责把问题和证据组织成 Prompt,让模型回答。
4.6 评测与监控层
负责回答一个更现实的问题:
它是不是在真实业务里真的可用?
5. Indexing:知识如何变成“可被检索”的结构
很多初学者对索引阶段理解不深,觉得就是把文件扔进向量库。
其实不是。
5.1 索引链路
原始文档 → 解析 → 分割 → 向量化 → 存储
5.2 文档解析
实际项目里,你的知识来源可能不是纯文本,而是:
- Word
- Excel
- 网页
- API 文档
- Markdown
- 数据库记录
- 聊天记录
- 工单系统
所以第一步往往是“解析成统一文本结构”。
5.3 分割(Chunking)
长文档不能直接作为检索单元,因此需要切分。
固定长度切分
优点:
- 实现简单
- 处理快
缺点:
- 容易把语义切碎
递归切分
优点:
- 更保留语义完整性
- 通常是最通用方案
缺点:
- 实现比固定长度更复杂
LLM 辅助切分
优点:
- 语义边界最好
- 适合高精度场景
缺点:
- 成本高
- 速度慢
5.4 Chunking 的本质不是“切文本”,而是“做信息建模”
这是一个非常重要的判断。
- 切太小:容易缺上下文
- 切太大:容易引入噪声
所以 chunk size 不是机械参数,而是召回质量与生成质量的共同上游变量。
5.5 Embedding
Embedding 的作用是把文本映射到向量空间。
要求至少包括:
- 索引侧和查询侧使用同一 embedding 模型
- embedding 模型和业务语料相匹配
- 向量归一化策略清晰统一
5.6 存储
常见选型:
- Pinecone:托管型
- Chroma:轻量级,本地/中小型项目友好
- Milvus:大规模向量检索
- Weaviate:企业级方案
- FAISS:本地索引库
- PGVector:Postgres 扩展
实际项目里,元数据也非常重要,例如:
- 文档标题
- 章节
- 时间
- 来源
- 权限
- 业务线
- 产品线
很多时候,Metadata Filter 和向量检索同等重要。
6. Retrieval:为什么检索质量决定 RAG 上限
RAG 的核心瓶颈,通常不在模型,而在检索。
6.1 语义检索
用户问题也会被 embedding 成向量。
然后系统用它去跟知识库里的向量做相似度比较,找出最相近的片段。
6.2 相似度计算
最常见的是余弦相似度:
cos(θ) = (A · B) / (|A| × |B|)
直觉上可以理解成:
- 更看方向
- 不太看长度
- 适合语义匹配
6.3 Top-K 召回
系统通常先取相似度最高的前 K 条。
但这里一定要注意:
- K 太小:可能漏掉关键证据
- K 太大:噪声增加,上下文污染
所以 Top-K 从来不是越大越好,而是 recall 和 precision 的权衡点。
6.4 为什么关键词检索还没有过时
很多人一听到 RAG,就只想到向量检索。
但现实里,很多信息其实更适合 sparse / keyword retrieval:
- 版本号
- 编号
- 产品型号
- 错误码
- 专有名词
- 人名
- 合同条款编号
所以真实系统里,经常会使用:
Hybrid Search = Dense Retrieval + Sparse Retrieval
7. Rerank:为什么只靠向量检索不够
向量检索更像“粗召回”,它能帮你找到看起来相关的内容,但未必能准确判断:
哪些内容最适合回答当前这个问题
7.1 Rerank 的作用
Rerank 通常用来:
- 重新排序候选片段
- 提升上下文精度
- 去掉弱相关内容
- 保证最终给模型的是“高密度证据”
7.2 两阶段架构
Recall → Rerank → Context Build
这是非常常见的线上结构。
7.3 上下文构建不仅是“拼接”
还应该做:
- 去重
- 清洗噪声
- 过滤过期内容
- 控制 token budget
- 保留高价值事实片段
- 按回答需要排序
一句话:
高质量 RAG 的关键,不只是找到内容,而是构造高质量上下文。
8. Generation:如何让模型“基于证据回答”
很多人以为检索完成就差不多了,但生成阶段同样决定最终质量。
8.1 一个更稳定的目标
生成阶段应该尽量做到:
- 基于证据回答
- 不知道就拒答
- 输出结构清晰
- 尽量带引用
- 不随意扩写证据之外内容
8.2 常见提示约束
例如:
- 仅依据提供上下文回答
- 如果证据不足,明确说明
- 列出引用来源
- 用结构化格式输出
- 禁止编造未提供事实
8.3 为什么很多系统“看起来检索对了,回答却还是不稳”
因为生成阶段常见问题包括:
- Prompt 边界不清晰
- 引用要求太弱
- 模型倾向过度总结
- 证据排序不合理
- 上下文噪声未清理
9. RAG 的几种主要形态:Basic / Advanced / Modular / Long / Agentic / Graph
这部分是很多文章没讲完整的,但恰恰是工程里最重要的部分之一。
9.1 Basic RAG
最基础的线性形态:
文本分片 → 向量化 → 检索 → 拼接 → 生成
适用场景
- FAQ
- 单文档问答
- 制度说明
- 产品参数查询
优势
- 实现快
- 成本低
- 非常适合做 MVP
缺点
- 一旦文档复杂、噪声多、问法不稳定,效果容易下降
9.2 Advanced RAG
它不是换了一个新东西,而是在 Basic RAG 基础上加入一系列增强能力:
- Query Rewrite
- Query Decomposition
- Hybrid Search
- Metadata Filter
- Rerank
- Context Cleaning
本质
让“找到的内容更准”,让“给模型的上下文更干净”
这是现实项目里最常见的形态
因为 Basic RAG 很多时候只能验证方向,而真正上线通常会演进成 Advanced RAG。
9.3 Modular RAG
Modular RAG 的关键不是“更聪明”,而是“更工程化”。
它不再把 RAG 看成一条固定流水线,而是拆成多个可组合模块,例如:
- Search Module
- Memory Module
- Rerank Module
- Router / Planner
- Tool Module
- Database Module
好处
- 可插拔
- 易扩展
- 更适合复杂业务
作用
这是很多系统走向 Agent 化之前的关键过渡阶段。
9.4 Long RAG
Long RAG 是对 “Long Context 不会杀死 RAG” 的一个工程化回答。
它的基本思路是:
海量知识库
↓
检索缩小范围
↓
重排 + 清洗 + 上下文构建
↓
高质量长上下文
↓
长窗口模型深度理解
↓
答案
它解决什么问题
- 保留 RAG 的广度筛选能力
- 利用长上下文增强深度推理能力
特别适合
- 长 PDF
- 手册
- 合同
- 技术规范
- 长日志分析
9.5 Agentic RAG(ARAG)
Agentic RAG 的关键不是“换个名字”,而是整个系统开始具备:
- 任务拆解
- 多轮检索
- 工具调用
- 动态决策
- 反思与重试
它不再是:
“检索一次 → 回答一次”
而更像: “先想清楚怎么解决,再决定检索什么、查什么、调什么工具”
适用场景
- 多步骤复杂任务
- 多轮问答
- 需要 API / 数据库 / 工具参与
- 复杂分析类问题
代价
- 成本更高
- 延迟更高
- 不确定性更高
- 调试更难
9.6 GraphRAG
GraphRAG 更适合关系型知识。
它的核心不是“找最像的文本”,而是:
理解实体之间的关系网络
适用问题
- 路径推理
- 多实体关系分析
- 因果链条梳理
- 跨文档多跳推理
技术栈通常涉及
- 实体识别
- 关系抽取
- 图数据库(如 Neo4j)
- 图检索
- LLM 生成
它特别擅长
- 谁影响谁
- 谁依赖谁
- 沿着什么路径传播
10. 实际项目里哪种用得最多
如果从真实工程落地看,最常见的并不是“纯 Basic RAG”。
一个更接近实际的结论是:
- Basic RAG:常见于 Demo / MVP
- Advanced RAG:最主流
- Long RAG:越来越多
- Agentic RAG:用于更复杂任务
- GraphRAG:小众但高价值
可以粗略理解成:
80% 的项目最终都会落在 Advanced RAG / Long RAG 这一带
因为它们在“效果 / 成本 / 稳定性 / 维护成本”之间更平衡。
11. Python 代码:从一个最小 RAG Demo 开始
下面给一个非常简化的本地化 Python 示例,帮助你建立最小闭环。
11.1 依赖
pip install sentence-transformers faiss-cpu numpy
11.2 最小示例
from sentence_transformers import SentenceTransformer
import faiss
import numpy as np
# 1. 准备文档
docs = [
"公司差旅制度规定:国内出差住宿上限为 500 元/晚。",
"高级别管理人员住宿上限为 800 元/晚。",
"餐补标准为 100 元/天。",
"国外差旅标准另行规定。"
]
# 2. 向量化
model = SentenceTransformer("BAAI/bge-small-zh-v1.5")
doc_embeddings = model.encode(docs, normalize_embeddings=True)
# 3. 建索引
dimension = doc_embeddings.shape[1]
index = faiss.IndexFlatIP(dimension) # 归一化后可用内积近似余弦相似度
index.add(np.array(doc_embeddings, dtype=np.float32))
# 4. 查询
query = "我们公司住宿报销上限是多少?"
query_embedding = model.encode([query], normalize_embeddings=True)
# 5. 检索 Top-K
scores, indices = index.search(np.array(query_embedding, dtype=np.float32), k=2)
hits = [docs[i] for i in indices[0]]
print("Top Hits:")
for h in hits:
print("-", h)
# 6. 构造上下文(真实项目中这里会接 LLM)
context = "
".join(hits)
prompt = f'''
请仅依据以下资料回答问题。
资料:
{context}
问题:
{query}
'''
print(prompt)
11.3 这个示例说明了什么
它虽然非常简单,但已经具备了最基础的 RAG 主链路:
- 文档准备
- embedding
- 向量索引
- 检索
- 构造上下文
真实项目当然会复杂很多,但本质就是这条链路逐步增强。
12. Python 代码:加入 Rerank 与 Metadata Filter 的增强版 RAG
下面给一个更贴近工程的简化版本。
12.1 数据结构
documents = [
{
"text": "国内出差住宿上限为 500 元/晚。",
"meta": {"department": "general", "year": 2026, "source": "差旅制度"}
},
{
"text": "高级别管理人员住宿上限为 800 元/晚。",
"meta": {"department": "executive", "year": 2026, "source": "差旅制度"}
},
{
"text": "餐补标准为 100 元/天。",
"meta": {"department": "general", "year": 2026, "source": "差旅制度"}
},
]
12.2 示例代码
from sentence_transformers import SentenceTransformer, CrossEncoder
import numpy as np
import faiss
embed_model = SentenceTransformer("BAAI/bge-small-zh-v1.5")
rerank_model = CrossEncoder("BAAI/bge-reranker-base")
documents = [
{
"text": "国内出差住宿上限为 500 元/晚。",
"meta": {"department": "general", "year": 2026, "source": "差旅制度"}
},
{
"text": "高级别管理人员住宿上限为 800 元/晚。",
"meta": {"department": "executive", "year": 2026, "source": "差旅制度"}
},
{
"text": "餐补标准为 100 元/天。",
"meta": {"department": "general", "year": 2026, "source": "差旅制度"}
},
]
texts = [d["text"] for d in documents]
doc_embeddings = embed_model.encode(texts, normalize_embeddings=True)
index = faiss.IndexFlatIP(doc_embeddings.shape[1])
index.add(np.array(doc_embeddings, dtype=np.float32))
def metadata_filter(docs, department=None, year=None):
results = []
for d in docs:
if department and d["meta"].get("department") != department:
continue
if year and d["meta"].get("year") != year:
continue
results.append(d)
return results
def retrieve(query, top_k=5):
query_vec = embed_model.encode([query], normalize_embeddings=True)
scores, indices = index.search(np.array(query_vec, dtype=np.float32), k=top_k)
return [documents[i] for i in indices[0]]
def rerank(query, candidates, top_n=2):
pairs = [[query, c["text"]] for c in candidates]
scores = rerank_model.predict(pairs)
ranked = sorted(zip(candidates, scores), key=lambda x: x[1], reverse=True)
return [item[0] for item in ranked[:top_n]]
query = "普通员工住宿报销上限是多少?"
# 1. 粗召回
candidates = retrieve(query, top_k=3)
# 2. 元数据过滤(这里假设只看 general 类)
filtered = metadata_filter(candidates, department="general", year=2026)
# 3. Rerank
final_hits = rerank(query, filtered, top_n=2)
for item in final_hits:
print(item)
12.3 这个版本比最小 demo 强在哪
它已经出现了真正线上系统的典型组件:
- embedding recall
- metadata filter
- rerank
这就是从 Basic RAG 向 Advanced RAG 演进的最常见路径。
13. Python 代码:Agentic RAG 的一个最小伪实现
Agentic RAG 的重点不在“换模型”,而在“编排方式变化”。
13.1 一个极简伪代码
state = {
"query": "分析近三个月 A 产品退货率上升原因,并给出建议",
"context": [],
"steps": []
}
def planner(state):
if "sales_data" not in state:
return {"type": "tool", "tool": "query_sales_db"}
if "complaints" not in state:
return {"type": "retrieve", "target": "complaint_docs"}
return {"type": "final"}
def query_sales_db():
return {"sales_data": "近三个月退货率从 2% 升到 5%"}
def retrieve_docs():
return {"complaints": ["物流慢", "包装破损", "屏幕瑕疵"]}
while True:
action = planner(state)
if action["type"] == "tool":
result = query_sales_db()
state.update(result)
state["steps"].append(("tool", result))
elif action["type"] == "retrieve":
result = retrieve_docs()
state.update(result)
state["steps"].append(("retrieve", result))
elif action["type"] == "final":
break
print(state)
13.2 为什么这和普通 RAG 差很多
因为它已经不是:
检索一次 → 回答一次
而是:
先规划 → 决定调什么 → 再检索 / 再查工具 → 汇总
这就是 Agentic RAG 与普通 RAG 最大的工程差异。
14. GraphRAG 应该怎么理解
很多人看到 GraphRAG 会以为它只是“把图数据库接上”。
其实它本质上是在回答一个不同类型的问题:
当知识的核心不在文本块,而在实体关系时,普通 RAG 不够用了。
14.1 图谱视角
例如你问:
- 某政策变化如何影响供应链上的多个公司?
- 某企业股权变更如何传导到信贷评级?
- 某设备异常是否可能和上游工序有关?
这类问题的难点不是“找到一段最像的文字”,而是:
- 找到实体
- 找到关系
- 找到路径
- 推理传播链
14.2 一个简化思路
query = "政策A如何影响企业B和供应商C?"
# 1. 从 query 中抽实体
entities = ["政策A", "企业B", "供应商C"]
# 2. 图数据库查询子图
subgraph = '''
政策A -> 行业补贴变化 -> 企业B成本下降
企业B -> 订单增加 -> 供应商C产能压力上升
'''
# 3. 把关系子图转成可读上下文,再交给 LLM
prompt = f'''
请基于以下关系图回答问题:
{subgraph}
问题:
{query}
'''
print(prompt)
真实 GraphRAG 当然会复杂得多,但你至少可以先记住一句话:
GraphRAG 查的不只是文本,而是关系网络。
15. 工程落地时最容易踩的坑
15.1 以为换更大的模型,RAG 效果就会自动变好
不一定。
很多效果问题根本不在模型,而在:
- chunk 切法
- query 改写
- 检索策略
- rerank
- 脏上下文
15.2 以为上下文塞得越多越好
不一定。
很多时候,更少但更干净的上下文,效果更好。
15.3 只做向量检索,不做关键词、过滤与排序
这样很容易在:
- 错误码
- 编号
- 型号
- 条款号
这类场景翻车。
15.4 一上来就做最复杂架构
很多团队一开始就想上 Agent、Graph、长链路编排,最后把自己复杂死。
更合理的路径通常是:
Basic RAG → Advanced RAG → Long RAG / Agentic RAG / GraphRAG
16. 如何评测一个 RAG 系统是不是“真的可用”
RAG 不能只看“演示时答得像不像”。
16.1 建议至少关注这些指标
检索层
- 召回率
- 命中率
- MRR / NDCG(如果有条件)
- Top-K 命中情况
生成层
- 最终答案可用性
- 引用准确性
- 拒答准确性
- 幻觉率
系统层
- 首字延迟
- 单次回答成本
- 吞吐
- 缓存命中率
用户层
- 用户追问率
- 用户修正率
- 满意度
- 任务完成率
16.2 为什么评测这么重要
因为没有评测,你就无法知道:
- query rewrite 是否真的有效
- rerank 是否真的提升质量
- top_k 调整有没有帮助
- 新 embedding 模型是不是更适合你的业务
没有评测,优化基本只能靠感觉。
17. 技术选型建议
如果你是第一次做项目,我建议这样走:
阶段 1:先做可用
- Basic RAG
- Chroma / FAISS
- 一个稳定的 embedding 模型
- 一个通用 LLM
- 做最小问答闭环
阶段 2:再做更准
- Query Rewrite
- Hybrid Search
- Rerank
- Metadata Filter
- Context Cleaning
阶段 3:再做更复杂
- Long RAG:长文阅读、手册、合同
- Agentic RAG:复杂任务、工具调用
- GraphRAG:关系推理、多跳路径
阶段 4:最后做工程化
- 评测集
- 监控
- 缓存
- 权限控制
- 多租户
- 文档更新机制
18. 一张图总结全文
你可以把整篇文章压缩成下面这张图:
flowchart TD
A[用户问题] --> B[Query Rewrite / Decompose]
B --> C[Recall: Dense + Sparse]
C --> D[Rerank]
D --> E[Context Build]
E --> F[LLM Generation]
F --> G[引用 / 拒答 / 结构化输出]
H[Basic RAG] --> I[Advanced RAG]
I --> J[Long RAG]
I --> K[Agentic RAG]
I --> L[GraphRAG]
一句话理解就是:
- Basic RAG:先跑起来
- Advanced RAG:先把质量做稳
- Long RAG:处理长文精读
- Agentic RAG:处理复杂任务链
- GraphRAG:处理关系网络推理
19. 最后的结论
19.1 关于 Long Context 与 RAG
- Long Context 不会杀死 RAG
- RAG 负责从海量知识中缩小范围
- Long Context 负责对高价值材料做深度阅读
- 未来主流方向是 Long RAG
19.2 关于架构选择
- Basic RAG:解决基础知识问答
- Advanced RAG:解决正式上线的质量问题
- Long RAG:解决长文精读问题
- Agentic RAG:解决复杂任务链问题
- GraphRAG:解决关系型、多跳推理问题
19.3 最值得记住的一句话
RAG 的本质不是“让模型知道更多”,而是“让系统以更低成本、更高可信度访问正确知识”。