Files
2026-09-22 15:42:25 +08:00

131 lines
11 KiB
Markdown
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 阶段八 · 项目 2:Level2 进阶 —— 知识库 RAG Agent
> 所属:阶段八 从入门到生产的实战项目路线
> 定位:给 Agent 装上「自己的资料」。这一级把文档变成可检索的知识底座,并让它按需查询、带来源作答,是绝大多数「企业知识问答」产品的最小原型。
## 项目概览
| 项 | 内容 |
|-|-|
| 难度 | Level2 进阶 |
| 核心功能 | 文档上传、知识库问答、引用溯源、流式输出 |
| 技术栈 | LlamaIndex + Qdrant + LangGraph + Streamlit |
| 周期 | 2-3 周 |
| 核心学习目标 | RAG 与 Agent 结合;向量库使用;流式输出;文档解析各类异常 |
## 一句话看懂本项目的数据流
```mermaid
graph LR
A[文档上传] --> B[加载+解析<br/>PDF/扫描件/超大文件]
B --> C[分块<br/>语义/父子分块]
C --> D[向量化<br/>中文BGE Embedding]
D --> E[存入Qdrant<br/>带元数据]
F[用户提问] --> G{Agent判断}
G -->|需要查| H[混合检索<br/>向量+BM25]
H --> I[Rerank精排]
I --> J[元数据过滤]
J --> K[组装上下文→LLM]
K --> L[答案+引用溯源<br/>来源+页码]
```
> 核心认知:**RAG 的价值在于「能用公司的资料回答,而不是编」**。检索质量(分块、混合、精排)直接决定回答质量,检索垃圾,模型再强也答不对。
> 🔬 **深度理解 · 知识库 RAG(检索增强生成)**:
> 1. **本质**:RAG 不是一种检索算法,而是"先检索、再把检索结果拼进上下文让它生成"的组合范式——它通过"给模型在生成时喂入外部事实",把模型的生成能力约束在"基于证据回答"上,从而缓解幻觉与知识过期。
> 2. **机制**:离线把文档切块 Embedding 成向量入库;在线把用户提问也 Embedding 成向量,用相似度在库里召回 Top-K 片段,将片段拼入 prompt 后让 LLM 基于这些内容作答。质量的关键不在 Embedding 本身,而在"怎么切块、怎么召回、怎么排序(分块质量 + 混合检索 + Rerank)"这条链路。
> 3. **为什么重要**:它解决了 LLM 三大硬伤里最现实的两种——知识不在训练集内(新文档/私有资料)与知识过期(模型训练截止后的事实),且比微调更轻、可控、可追溯来源。
> 4. **易错点/常见误解**:最容易踩的坑是"检索到的片段顺序/相关性不够也硬答"——RAG 提升的是"答对的概率",前提是检索质量过关;同时别忘了"检索无关内容也算污染",垃圾进则垃圾出,模型再强也救不回低质量检索,所以必须有 score 阈值与"宁可不答"的兜底。
## 学习内容详情
### 1. 数据链路(离线索引阶段)
文档加载 → 分块(语义分块 / 父子分块)→ 向量化(中文 BGE Embedding)→ 存入 Qdrant。这一步只做一次,产出可检索的向量索引。
> ⏳ **短期可不深究**:语义分块 vs 父子分块的具体切分算法(如何感知段落边界、父块与子块如何映射)第一遍知道"分块影响检索粒度"即可,等真正遇到"长文档召回碎片化/上下文不足"再回来调分块策略,不必一开始就纠结原理。
### 2. 检索进阶(在线查询阶段)
| 手段 | 作用 | 说明 |
|-|-|-|
| 混合检索 | 召回更全 | 向量(语义)+ BM25(关键词)互补 |
| Rerank 精排 | 排序更准 | 对召回结果做交叉注意力精排 |
| 元数据过滤 | 更精准 | 按文档 / 章节 / 权限过滤,只查该查的 |
### 3. Agent 化:Agent-RAG 而非普通 RAG
把检索封装成 `@tool`,用 LangGraph 编排——模型自主决定「何时查、查几轮、要不要追问」,区别于一次性「查完就答」的朴素 RAG。
> 🔬 **深度理解 · Agent-RAG vs 一次性朴素 RAG**:
> 1. **本质**:两者的差别不在"会不会检索",而在"检索是不是一个可被模型在推理过程中反复决策的动作"。朴素 RAG 是"查一次就答"的流水线,Agent-RAG 把检索变成可多轮调用的工具。
> 2. **机制**:朴素 RAG 在生成前强行走一遍"向量化→召回→拼接",一次成型;Agent-RAG 则让模型自主决定「这个问题要不要查、查几轮、查到什么程度再回答」——可以在中途追问用户、可以基于上一轮检索结果再查,把检索从固定步骤升级为策略性动作。
> 3. **为什么重要**:它解决了朴素 RAG 的两个弱点——"无需检索的闲聊也硬查一遍(浪费+引入噪声)"和"一个问题需要分解成多次检索(复杂查询一次查不完)"。
> 4. **易错点/常见误解**:不要把"多轮检索"等同于"质量自动更高"——给模型更多检索自由度也意味着更多失败点与成本,通常要配检索失败降级、轮次上限与 score 阈值;Agent-RAG 适合复杂、多跳查询,简单事实问答用朴素 RAG 已经足够且更稳。
```python
@tool("search_kb")
def search_kb(query: str, top_k: int = 5) -> list:
"""Agent-RAG 的检索工具: 模型自主决定何时调用、调几轮"""
hits = hybrid_search(query, top_k=top_k) # 向量+BM25 混合
hits = rerank(query, hits) # 精排
return [{"content": h.text, "source": h.meta["file"], "page": h.meta["page"]}
for h in hits[:top_k]]
```
### 4. 引用溯源 + 流式输出
- **引用溯源**:答案必须标注来源文件与页码(生产必备,否则答错无从追责)。
- **流式输出**:用 SSE 逐 token 返回,前端 Streamlit / 浏览器呈现打字机效果,体感更快。
## 必须处理的异常
- **文档解析**:PDF 乱码、扫描件(需 PaddleOCR)、超大文件分块、编码问题——这是索引阶段最现实的一批坑。
- **检索无结果 / 低分块干扰**:加 score 阈值过滤,宁可「不知道」也不乱答。
- **模型输出 JSON 残缺**:pydantic 兜底 + 让模型重写(对照阶段四 RAG 与阶段六内容创作)。
> ⏳ **短期可不深究**:扫描件的 PDF 需要 PaddleOCR 这类 OCR 方案把图片文字还原成可检索文本,这一课第一遍遇到"文档能读"即可跳过,等真正拿到大量扫描件/图片型 PDF 的业务场景再专门攻坚 OCR,属于"遇到再学"的边缘需求。
## 本节验收清单
- [ ] 能上传多种格式文档并完成知识库索引
- [ ] 问答带引用溯源(来源 + 页码)
- [ ] 实现了 SSE 流式输出
- [ ] 混合检索 + Rerank 已落地并对比过单路检索的提升
## 排期与前置依赖
- **前置**:阶段四 RAG 技术体系 + 向量数据库记忆存储([rag_agent.py](../../code/阶段四/rag_agent.py) 先跑通)。
- **建议排期**:第 9-10 周,2-3 周完成;与阶段八 Level4(数据分析)共享向量库与检索经验。
- **关键对照**:本项目是「文档知识」RAG;Level4 是「结构化数据库」SQL Agent,两者共同点是都要求「答得准、可追溯」。
## 本节常见面试题(深度解析)
> 针对本节核心知识的面试高频点,配合"本质+机制"式理解,能让你答得既有深度又有广度。
### 面试题 1:请解释 RAG 的工作流程,并指出决定其问答质量的关键环节是什么?
- **面试官想考察**:你是把 RAG 当成"检索+生成"两步,还是真的理解整条链路里每个环节都在影响质量。
- **专业作答(含深度)**:
1. 流程拆环:文档加载 → 分块 → Embedding 向量化 → 入库;查询时把用户问题向量化 → 相似度召回 → 拼接上下文 → 让 LLM 基于证据作答。可补充混合检索(向量+BM25)与 Rerank 作为提升召回/排序的手段。
2. 点出关键:质量瓶颈通常不在 LLM,而在检索链——分块粒度决定"召回的是块还是破碎片段",召回质量决定"喂进上下文的证据对不对",排序质量决定"正确片段是否排在前面被采信"。
3. 给出判断标准:检索垃圾 → 生成必错(垃圾进垃圾出);所以要配 score 阈值、"宁可不答"与引用溯源来兜底。
4. 适当抽象:RAG 本质是"给生成加证据约束",与微调的差别在于不动模型权重、可控、可溯源。
- **加分亮点 / 深度追问**:可主动对比"朴素 RAG vs Agent-RAG"与"向量检索 vs 混合检索",并提到父子分块解决"召回碎片化"这类进阶痛点;追问"RAG 与微调怎么选"时可答"资料私有/更新频繁用 RAG,风格/领域能力固化用微调,二者常互补"。
### 面试题 2:为什么单靠向量(语义)检索还不够,还要上混合检索和 Rerank?
- **面试官想考察**:你是否理解语义检索的盲区,以及"召回"与"精排"两个阶段目标的不同。
- **专业作答(含深度)**:
1. 说清向量检索的盲区:它擅长"语义近义"("退款流程"召回"退货怎么操作"),但对精确标识符/专有名词准召回弱(如 SKU、型号、人名/编号),关键词组成的边界硬查询反而查不准。
2. 混合检索的分工:BM25 精准命中关键词/专有词,向量捕捉词面不同但意思相近的表达,两者互补召回更全。
3. Rerank 解决的问题:召回的 Top-K 还都是"粗排",用交叉注意力(query 与每个片段整体做深度交互打分)把真正相关的那条顶上,修正向量距离度量的浅层局限。
4. 权衡与误区:多一路检索与精排都增加延迟与成本,简单知识库未必需要;Rerank 是把"两阶段"质量再做一次排序增强,不是万能,召回阶段就丢了的内容精排也救不回。
- **加分亮点 / 深度追问**:可提"召回率 vs 精度的取舍(先求全再求准)",以及"为何要先召回粗排再精排(避免对全库做昂贵交叉注意力)";被追问时可解释 BM25 的词频—逆文档频率直觉与向量维数/度量(余弦等)的差异。
### 面试题 3:RAG 系统如何保证"答得准"并"可追溯"?产品化要注意什么?
- **面试官想考察**:你是否具备把 RAG 从 Demo 变成可靠功能的工程意识(兜底 + 问责)。
- **专业作答(含深度)**:
1. 答得准:检索这一侧用混合检索+Rerank 提质量;判定这一侧加 score 阈值,低于阈值宁可"不知道"也不乱答,配合检索无结果/低分块过滤。
2. 可追溯:返回结果必须带引用溯源(来源文件+页码+片段),让答案能对得上证据,查错可追责——这是企业级 RAG 的底线能力。
3. 结构可靠性:模型输出做结构化校验(JSON pydantic 兜底、残缺重写),避免下游解析崩。
4. 工程闭环:建评测集验证"改检索参数/改动 prompt"是否真的变好,避免凭感觉调参;与 Level5 的 Bad-case 回流与回归测试联动。
- **加分亮点 / 深度追问**:可主动引入"索引与查询分离(离线建好库、在线只查)",并提到权限控制(按元数据过滤控制谁能查哪些文档);追问"低分结果该不该暴露给用户"时可答倾向不暴露并给引导式回复,避免误导。