1. 学习目标
本课程围绕 RAG(Retrieval-Augmented Generation,检索增强生成)展开,核心内容包括:
- 大模型应用开发的三种模式:提示工程、RAG、微调
- RAG 的核心原理与流程
- Native RAG 的 Indexing、Retrieval、Generation 三阶段
- Embedding 模型选择
- DeepSeek + FAISS 搭建本地知识库检索案例
- Query 改写
- Query + 联网搜索
2. 什么是 RAG
RAG,全称 Retrieval-Augmented Generation,中文通常叫 检索增强生成。
它的核心思想是:
先从外部知识库中检索相关资料,再把检索结果作为上下文交给大模型生成答案。
也就是说,大模型不是完全依赖自身参数里的旧知识回答,而是可以结合:
- 企业内部文档
- PDF 文件
- 数据库数据
- 网页内容
- 实时搜索结果
- 业务知识库
来生成更准确、更可追溯的答案。
3. 为什么需要 RAG
传统大模型存在几个典型问题:
| 问题 | 说明 | 对应解决方式 |
|---|---|---|
| 没问清楚 | 用户问题模糊、上下文不足 | 提示工程 / Query 改写 |
| 缺乏背景知识 | 模型不了解企业私有知识或最新知识 | RAG |
| 能力不足 | 模型本身对某类任务能力不够 | 微调 |
RAG 的主要优势:
-
解决知识时效性问题
大模型训练数据是静态的,而 RAG 可以实时检索外部知识库或联网信息。 -
减少模型幻觉
通过提供真实上下文,让模型基于资料回答,而不是凭空生成。 -
提升垂直领域问答质量
对金融、政务、医疗、法律、电商、企业制度等专业场景,可以结合专属知识库回答。 -
增强可解释性
可以返回来源页码、文档名称、URL,方便用户验证。 -
降低微调成本
不需要每次知识更新都重新训练模型,只需要更新知识库和索引。
4. RAG 核心流程
RAG 可以分为三个大阶段:
flowchart LR
A[原始文档<br/>PDF / Word / 网页 / 数据库] --> B[文档解析]
B --> C[文档分块 Chunking]
C --> D[Embedding 向量化]
D --> E[向量数据库<br/>FAISS / Milvus / Qdrant / ES]
U[用户问题] --> Q[Query 改写 / Query 向量化]
Q --> R[向量检索]
E --> R
R --> RR[重排序 Rerank]
RR --> Ctx[上下文组装]
Ctx --> LLM[大语言模型]
LLM --> Ans[最终答案 + 来源引用]
4.1 Indexing:索引构建阶段
目标:把知识更好地存起来。
主要步骤:
- 收集文档
- 文档解析
- 文本清洗
- 文档分块
- Embedding 向量化
- 写入向量数据库
- 保存元数据,例如来源文件、页码、标题、章节等
4.2 Retrieval:检索阶段
目标:从大量知识中找到最相关的一小部分资料。
主要步骤:
- 用户问题预处理
- Query 改写
- Query 向量化
- 向量相似度检索
- Top-K 文档召回
- 可选:Rerank 重排序
4.3 Generation:生成阶段
目标:把用户问题和检索到的知识结合,让模型生成答案。
主要步骤:
- 组装 Prompt
- 拼接检索上下文
- 调用大模型
- 输出答案
- 返回引用来源
5. Native RAG 的三个核心步骤
课程中将 Native RAG 总结为:
| 阶段 | 英文 | 核心问题 |
|---|---|---|
| 索引 | Indexing | 如何更好地把知识存起来 |
| 检索 | Retrieval | 如何在大量知识中找到有用内容 |
| 生成 | Generation | 如何结合问题和知识生成答案 |
虽然这三个步骤看起来简单,但真正落地时会遇到很多工程问题,例如:
- PDF 解析失败
- 表格、图片、扫描件无法正常抽取
- Chunk 切分不合理
- 页码映射不准确
- Embedding 模型选型困难
- 召回结果不准
- Prompt 上下文过长
- 来源引用不可靠
- 向量库持久化和版本管理
- 权限控制和数据隔离
6. Embedding 模型选择
Embedding 模型负责把文本转换成向量,是 RAG 检索效果的基础。
6.1 常见模型类型
| 类型 | 示例 | 适合场景 |
|---|---|---|
| 通用文本嵌入模型 | BGE-M3、text-embedding-3-large、Jina Embeddings | 通用语义检索 |
| 中文嵌入模型 | M3E、xiaobu-embedding、stella 中文模型 | 中文知识库、本地化应用 |
| 指令型嵌入模型 | gte-Qwen2-instruct、E5-mistral | 复杂问答、指令驱动检索 |
| 企业级混合检索模型 | BGE-M3 等 | 企业知识库、跨语言、多路召回 |
6.2 选型建议
| 选择维度 | 建议 |
|---|---|
| 中文为主 | 优先测试 BGE-M3、M3E、stella 中文模型、gte-Qwen 系列 |
| 英文为主 | 可考虑 OpenAI embedding、E5、Jina 等 |
| 本地部署 | 关注模型大小、显存占用、推理速度 |
| 企业检索 | 优先考虑混合检索、长文本能力、Rerank 搭配 |
| 实时高并发 | 选择轻量模型或使用缓存、批量向量化 |
| 高精度问答 | Embedding + BM25 + Rerank 组合通常更稳 |
6.3 不能只看榜单
MTEB 排行榜可以作为参考,但不能直接等同于业务效果。真正落地时应该结合自己的文档和问题做评测,例如:
- Top-K 命中率
- Recall@K
- MRR
- nDCG
- 答案准确率
- 来源引用准确率
- 响应耗时
- 费用成本
7. DeepSeek + FAISS 本地知识库案例总结
课程案例使用:
| 模块 | 技术 |
|---|---|
| PDF 文本提取 | PyPDF2 |
| 文本切分 | RecursiveCharacterTextSplitter |
| Embedding | DashScope text-embedding-v1 |
| 向量数据库 | FAISS |
| 大语言模型 | deepseek-v3 / Tongyi 接入 |
| 问答方式 | 检索 Top-K 文档片段后组装上下文生成答案 |
7.1 原始流程
flowchart TD
A[PDF 文件] --> B[PyPDF2 提取文本]
B --> C[记录字符或行对应页码]
C --> D[RecursiveCharacterTextSplitter 分块]
D --> E[DashScope Embedding 向量化]
E --> F[FAISS 创建向量索引]
F --> G[用户 Query]
G --> H[similarity_search 检索 Top-K]
H --> I[组装上下文 Prompt]
I --> J[调用 deepseek-v3]
J --> K[输出答案和来源页码]
7.2 课程代码中的关键参数
text_splitter = RecursiveCharacterTextSplitter(
separators=["\n\n", "\n", ".", " ", ""],
chunk_size=1000,
chunk_overlap=200,
length_function=len,
)
含义:
chunk_size=1000:每个文本块约 1000 字符chunk_overlap=200:相邻块重叠 200 字符,避免语义断裂separators:优先按段落、换行、句号、空格、字符切分
7.3 需要优化的点
课程中的 PyPDF2 方案在部分 PDF 上可能出现解析异常或页码映射不准。更稳的工程实践是:
- PDF 解析使用 PyMuPDF、pdfplumber、Unstructured 等更稳的解析器
- 每页生成一个
Document - 页码放到
metadata中,而不是后置计算 - 使用
split_documents()保留元数据 - 对扫描版 PDF 增加 OCR
- 对表格类 PDF 单独抽取表格结构
推荐结构:
Document(
page_content="页面文本内容",
metadata={
"source": "xxx.pdf",
"page": 12,
"title": "章节标题"
}
)
8. LangChain 问答链类型
课程中提到 LangChain 问答链的四种 chain_type:
| chain_type | 说明 | 优点 | 缺点 |
|---|---|---|---|
| stuff | 直接把所有文档塞进 Prompt | 简单、调用次数少 | 上下文容易超长 |
| map_reduce | 每个 chunk 先单独处理,再汇总 | 可并发、适合长文档 | 文档之间上下文弱 |
| refine | 逐步读取 chunk 并迭代修正答案 | 可保留部分上下文 | 调用次数较多 |
| map_rerank | 每个 chunk 独立回答并打分 | 能挑选最佳结果 | 调用成本高 |
实际工程建议:
- 文档少、Top-K 少:优先
stuff - 文档长、上下文多:考虑
map_reduce或refine - 对准确率要求高:检索后先 Rerank,再 Stuff
- 生产环境:更推荐自己组装 Prompt,而不是完全依赖老式 QA Chain
9. Query 改写
Query 改写的目标是:
把用户口语化、上下文依赖、模糊、多意图的问题,改写成更适合检索的标准问题。
9.1 为什么需要 Query 改写
RAG 的第一步是检索,如果检索走偏,后面生成再强也很难回答准确。
用户问题通常有这些特点:
- 口语化
- 省略上下文
- 有模糊指代
- 多个问题混在一起
- 带有情绪或反问
而知识库中的文本通常是正式、客观、陈述性的。Query 改写就是把用户问题转换成更适合知识库匹配的检索语句。
9.2 Query 改写类型
| 类型 | 特征 | 示例 | 改写结果 |
|---|---|---|---|
| 上下文依赖型 | 还有、其他、继续 | 还有其他设施吗? | 除了前面提到的设施外,某园区还有哪些其他设施? |
| 对比型 | 哪个、更、比较 | 哪个更好玩? | A 园区和 B 园区哪个更适合游玩? |
| 模糊指代型 | 它、这个、都 | 都什么时候开始? | 上海迪士尼和香港迪士尼的烟花表演分别什么时候开始? |
| 多意图型 | 多个问题并列 | 门票多少钱?需要预约吗? | 拆成两个独立问题 |
| 反问型 | 不会、难道 | 这不会也要提前一个月吧? | 是否需要提前一个月预约? |
9.3 Query 改写推荐流程
flowchart TD
A[用户原始问题] --> B[识别 Query 类型]
B --> C{是否依赖上下文}
C -->|是| D[补全上下文]
C -->|否| E[保留核心问题]
D --> F{是否多意图}
E --> F
F -->|是| G[拆分多个子问题]
F -->|否| H[生成标准检索 Query]
G --> I[分别检索]
H --> I
I --> J[合并检索结果]
9.4 推荐 JSON 输出格式
{
"query_type": "上下文依赖型",
"rewritten_query": "除前面提到的游乐设施之外,上海迪士尼疯狂动物城园区还有哪些其他设施?",
"confidence": 0.95
}
10. Query + 联网搜索
不是所有问题都应该只走本地知识库。对于强时效性问题,应该联网搜索。
10.1 需要联网的典型问题
| 类型 | 关键词 | 示例 |
|---|---|---|
| 时效性信息 | 最新、今天、现在、当前、实时 | 今天开放吗? |
| 价格信息 | 多少钱、价格、费用、票价 | 下周六门票多少钱? |
| 营业信息 | 营业时间、闭园、开放 | 现在开门吗? |
| 活动信息 | 活动、演出、节日、庆典 | 最近有什么活动? |
| 天气信息 | 天气、下雨、温度 | 明天天气怎么样? |
| 交通信息 | 怎么去、地铁、公交 | 从机场怎么去? |
| 预订信息 | 预约、订票、购票 | 要提前多久预约? |
| 实时状态 | 排队、人流量、拥挤 | 现在人多不多? |
10.2 联网搜索判断输出格式
{
"need_web_search": true,
"search_reason": "问题涉及今天开放时间和当前人流量,属于强时效信息,需要联网搜索。",
"confidence": 0.98
}
10.3 联网 Query 改写输出格式
{
"rewritten_query": "上海迪士尼乐园 今日开放时间 当前人流量",
"search_keywords": ["上海迪士尼乐园", "今日开放时间", "人流量", "排队时间"],
"search_intent": "查询上海迪士尼今日营业状态和实时游客密度",
"suggested_sources": ["官方网站", "旅游平台", "地图平台", "本地生活平台"]
}
11. 联网搜索与本地 RAG 的融合架构
flowchart TD
Q[用户问题] --> RQ[Query 改写]
RQ --> Judge{是否需要联网?}
Judge -->|否| Local[本地知识库检索]
Judge -->|是| Web[联网搜索]
Local --> Merge[结果融合]
Web --> Merge
Merge --> Rerank[重排序]
Rerank --> Prompt[上下文组装]
Prompt --> LLM[大模型生成]
LLM --> A[答案 + 来源]
推荐策略:
- 企业制度、内部文档、固定业务规则:走本地 RAG
- 价格、天气、新闻、活动、政策变动:走联网搜索
- 两者都可能相关时:本地知识库 + 联网搜索混合召回
- 最终答案必须标注来源,区分“本地文档来源”和“联网来源”
12. 面向 Java 后端的落地建议
如果你要把这个课程做成一个企业级后端项目,可以按下面的方式设计。
12.1 核心模块
| 模块 | 职责 |
|---|---|
| 文档上传模块 | 上传 PDF、Word、Excel、HTML 等文件 |
| 文档解析模块 | 抽取文本、表格、图片 OCR |
| 分块模块 | 按标题、段落、Token、语义切分 |
| Embedding 模块 | 调用 DashScope / BGE / 本地模型生成向量 |
| 向量存储模块 | FAISS / Milvus / Elasticsearch / Qdrant |
| Query 改写模块 | 上下文补全、多意图拆分、模糊指代消解 |
| 检索模块 | 向量检索、关键词检索、混合检索 |
| Rerank 模块 | 对召回结果重新排序 |
| 问答生成模块 | 组装 Prompt,调用 LLM |
| 来源追踪模块 | 返回文档名、页码、段落、URL |
| 任务管理模块 | 文档向量化任务状态持久化 |
12.2 推荐接口设计
POST /api/rag/documents/upload
POST /api/rag/documents/{documentId}/index
POST /api/rag/query/rewrite
POST /api/rag/chat/ask
GET /api/rag/tasks/{taskId}
GET /api/rag/documents/{documentId}/chunks
12.3 任务状态表建议
CREATE TABLE rag_index_task (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
task_id VARCHAR(64) NOT NULL,
document_id VARCHAR(64) NOT NULL,
status VARCHAR(32) NOT NULL COMMENT 'PENDING/RUNNING/SUCCESS/FAILED',
total_chunks INT DEFAULT 0,
finished_chunks INT DEFAULT 0,
error_message TEXT,
create_time DATETIME NOT NULL,
update_time DATETIME NOT NULL,
UNIQUE KEY uk_task_id (task_id)
);
12.4 生产级注意事项
- 文档解析和向量化要异步执行,避免接口阻塞
- 任务状态需要落 MySQL,避免进程重启后任务丢失
- 大文件要分批处理,避免 OOM
- Embedding 调用要批量化和限流
- 向量库要支持版本管理和重建索引
- 用户权限要下沉到检索阶段,避免越权召回
- 回答必须带来源,不能只给自然语言答案
- 对无依据问题,要明确回答“根据当前知识库无法确定”
13. 结合联网资料后的补充修正
13.1 RAG 不只是简单“向量检索 + Prompt”
现代 RAG 更强调:
- 数据治理
- 多路召回
- 混合检索
- Rerank
- 评测体系
- 权限控制
- 可观测性
- 答案引用
13.2 FAISS 适合本地 Demo 和高性能向量检索
FAISS 是高效的向量相似度搜索库,非常适合本地知识库 Demo、离线索引和高性能召回。但在企业服务化场景中,还要考虑:
- 多租户
- 权限过滤
- 分布式扩展
- 运维监控
- 数据备份
- 在线更新
如果需要服务化,可以考虑 Milvus、Qdrant、Elasticsearch / OpenSearch 向量检索能力。
13.3 PDF 解析建议使用更稳方案
课程里使用 PyPDF2,但从你的实际报错看,部分 PDF 会因为编码或结构问题导致 extract_text() 崩溃。
更稳的方案:
- 文本型 PDF:PyMuPDF / pdfplumber
- 表格 PDF:Camelot / Tabula / pdfplumber
- 扫描件:OCR
- 复杂版式:Unstructured / MinerU / PaddleOCR-VL 类工具
14. 最终总结
RAG 的本质是:
用检索系统给大模型提供可靠上下文,让大模型基于真实资料回答问题。
它解决的核心问题包括:
- 大模型知识过时
- 企业私有知识无法直接回答
- 模型容易幻觉
- 回答缺少来源
- 微调成本高、更新慢
一个完整的 RAG 系统应该包括:
- 文档解析
- 文档切分
- Embedding 向量化
- 向量数据库
- Query 改写
- 向量检索
- Rerank
- Prompt 组装
- LLM 生成
- 来源引用
- 联网搜索补充
- 评测与监控
15. 参考资料
- 用户上传文件:《1-RAG技术与应用.pdf》
- LangChain Retrieval 文档:docs.langchain.com/oss/python/…
- LangChain RAG 教程:docs.langchain.com/oss/python/…
- FAISS 官方文档:faiss.ai/index.html
- LangChain FAISS 集成文档:docs.langchain.com/oss/python/…
- Hugging Face MTEB Leaderboard:huggingface.co/spaces/mteb…
- PyMuPDF 文本提取文档:pymupdf.readthedocs.io/en/latest/a…