主题
01 - RAG 全链路详解
RAG 完整流水线
┌─────────────────────────────────────────────────────────────────┐
│ RAG 全链路 │
│ │
│ ┌─────────────────── 离线阶段(建索引)──────────────────────┐ │
│ │ │ │
│ │ 文档 → 分块(Chunking) → 向量化(Embedding) → 存入向量数据库│ │
│ │ │ │
│ │ ┌──────┐ ┌──────────┐ ┌──────────┐ ┌───────────┐ │ │
│ │ │ PDF │ │ Chunk 1 │ │ [0.1,0.3 │ │ Vector │ │ │
│ │ │ MD │──▶│ Chunk 2 │──▶│ 0.7,...] │──▶│ Database │ │ │
│ │ │ HTML │ │ Chunk 3 │ │ (1536维) │ │ │ │ │
│ │ └──────┘ └──────────┘ └──────────┘ └───────────┘ │ │
│ │ 文档加载 文本分块 向量嵌入 向量存储 │ │
│ └───────────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────── 在线阶段(查询)───────────────────────┐ │
│ │ │ │
│ │ 用户提问 → 向量化 → 检索 → 重排 → 组装 Prompt → LLM │ │
│ │ │ │
│ │ "退款政策?" │ │
│ │ │ │ │
│ │ ▼ │ │
│ │ ┌──────────┐ ┌──────────┐ ┌────────┐ ┌────────────┐ │ │
│ │ │ Embedding│ │ 向量检索 │ │ Rerank │ │ LLM 生成 │ │ │
│ │ │ 查询向量化│─▶│ Top-K │─▶│ 重排序 │─▶│ 基于文档 │ │ │
│ │ │ │ │ 最相似 │ │ 精排 │ │ 回答用户 │ │ │
│ │ └──────────┘ └──────────┘ └────────┘ └────────────┘ │ │
│ │ │ │
│ └───────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘1. 文档分块(Chunking)
为什么要分块?
┌────────────────────────────────────────────────────────┐
│ 一篇 10 万字的文档塞不进 LLM 的上下文窗口 │
│ 就算塞得下,相关的信息也会被稀释,影响回答质量 │
│ → 切成小块,只检索最相关的几块 │
└────────────────────────────────────────────────────────┘
分块策略:
1. 固定大小分块 (Fixed Size):
┌───────────────────────────────────────────────┐
│ █████████████████████ │ ████████████████████ │ ...
│ Chunk 1 (500 token) │ Chunk 2 (500 token) │
│ ┌──overlap──┐ │ │
└───────────────────────────────────────────────┘
简单,但可能把句子切断
2. 按句子/段落分块 (Semantic):
┌─────────────────┐ ┌──────────────────┐ ┌────────┐
│ 第一段的完整内容 │ │ 第二段的完整内容 │ │ 第三段 │
│ 保持语义完整性 │ │ │ │ │
└─────────────────┘ └──────────────────┘ └────────┘
保持语义完整,大小不均匀
3. 递归分块 (Recursive):
先按 \n\n 分段 → 太长再按 \n 分行 → 还太长按句号分
┌──────────────────────────────────────────┐
│ 尝试 \n\n → 每块太长? │
│ → 尝试 \n → 每块太长? │
│ → 尝试 。→ 每块太长? │
│ → 强制按字数切 │
└──────────────────────────────────────────┘
LangChain 默认使用此策略
参数建议:
┌──────────────────────────────────────────────┐
│ chunk_size: 500~1000 token │
│ chunk_overlap: 50~200 token(保留上下文) │
│ │
│ 太小: 丢失上下文,检索碎片化 │
│ 太大: 噪音多,检索精度下降 │
└──────────────────────────────────────────────┘2. 向量嵌入(Embedding)
把文本变成数字向量,语义相近的文本距离相近
"今天天气真好" → [0.12, 0.85, 0.33, ...] ─┐
"天气不错啊" → [0.13, 0.82, 0.35, ...] ─┤ 语义相近
│ → 向量距离近
"明天有会议" → [0.91, 0.15, 0.67, ...] │
│ 语义不同
│ → 向量距离远
向量空间可视化(降维到2D):
天气好 ● ● 天气不错 ← 聚在一起
● 今天很晴
● 明天开会
● 下周有会议 ← 聚在一起
● 退款政策
● 如何退货 ← 聚在一起
常用 Embedding 模型(2025年):
┌──────────────────────────────────┬────────┬──────────────────────┐
│ 模型 │ 维度 │ 特点 │
├──────────────────────────────────┼────────┼──────────────────────┤
│ nvidia/NV-Embed-v2 (开源) │ 4096 │ MTEB 榜首,可自部署 │
│ Cohere embed-v4 │ 1024 │ 多语言最强,API 可用 │
│ OpenAI text-embedding-3-large │ 3072 │ 无需自托管的稳定选择 │
│ BGE-M3 / GTE-Qwen2 (开源) │ 1024+ │ 中文效果好,可自部署 │
│ Voyage AI voyage-3 │ 1024 │ 代码/文档检索好 │
└──────────────────────────────────┴────────┴──────────────────────┘
注: text-embedding-3-large 在 MTEB 约 64 分,NV-Embed-v2 超过 70 分3. 向量检索
相似度计算方法:
余弦相似度 (Cosine Similarity) — 最常用
sim(A, B) = A · B / (|A| × |B|)
┌──────────────────────────────────────────┐
│ B │
│ ╱ │
│ ╱ θ (夹角越小越相似) │
│ ╱ │
│ ─────╱───────── A │
│ │
│ cos(0°) = 1.0 完全相同 │
│ cos(90°) = 0.0 完全无关 │
└──────────────────────────────────────────┘
向量数据库:
┌────────────────┬─────────────────────────────────┐
│ Pinecone │ 云端托管,开箱即用 │
│ Weaviate │ 开源,支持混合搜索 │
│ Milvus │ 开源,大规模场景 │
│ ChromaDB │ 轻量级,适合原型开发 │
│ pgvector │ PostgreSQL 扩展,运维简单 │
│ Qdrant │ Rust 写的,性能好,Go SDK 完善 │
└────────────────┴─────────────────────────────────┘
检索流程:
查询: "退款要几天?"
│
▼ Embedding
[0.2, 0.8, 0.5, ...]
│
▼ ANN 近似最近邻搜索
┌──────────────────────────────────────────────┐
│ Top-3 结果: │
│ 1. "退款将在 7 个工作日内到账" score: 0.92 │
│ 2. "申请退款后可在订单页查看进度" score: 0.87 │
│ 3. "退货地址是..." score: 0.61 │
└──────────────────────────────────────────────┘4. 重排序(Rerank)— 提升精度的关键步
为什么需要 Rerank?
Embedding 检索是 "粗排"(快但不够精确)
Rerank 是 "精排"(用更复杂的模型重新打分)
┌──────────────────────────────────────────────────────┐
│ │
│ 粗排 (Embedding): Top-20 候选 │
│ │ │
│ ▼ │
│ 精排 (Rerank): 对 Top-20 重新打分 │
│ │ 用交叉编码器 (cross-encoder) │
│ ▼ 考虑 query 和 doc 的深层语义关系 │
│ Top-5 最终结果 │
│ │
│ 为什么不直接用 Rerank? │
│ → 太慢! 交叉编码器需要对每个候选逐一打分 │
│ → 先用 Embedding 快速缩小范围,再用 Rerank 精排 │
│ │
│ 常用 Rerank 模型: │
│ • Cohere Rerank │
│ • Voyage Rerank │
│ • BGE Reranker (开源) │
│ • Cross-Encoder (sentence-transformers) │
└──────────────────────────────────────────────────────┘5. 高级 RAG 优化策略
┌──────────────────────────────────────────────────────────────┐
│ RAG 优化技术 │
├──────────────────────────────────────────────────────────────┤
│ │
│ 1. HyDE (假设性文档嵌入): │
│ 查询 → LLM 先生成一个"假答案" → 用假答案做检索 │
│ 效果: 假答案和真文档在向量空间更接近 │
│ │
│ 2. 查询改写 (Query Rewriting): │
│ "退款要多久" → LLM 改写成多个版本: │
│ • "退款处理时间" │
│ • "退款到账周期" │
│ • "退款需要几个工作日" │
│ 分别检索后合并结果 → 提高召回率 │
│ │
│ 3. 混合搜索 (Hybrid Search): │
│ 向量搜索 (语义) + 关键词搜索 (BM25) 结果融合 │
│ ┌─────────────┐ ┌─────────────┐ │
│ │ 向量搜索 │ + │ BM25 搜索 │ → 融合排序 │
│ │ (语义相关) │ │ (关键词匹配) │ │
│ └─────────────┘ └─────────────┘ │
│ │
│ 4. 父子文档检索 (Parent-Child): │
│ 小块用于检索(精确匹配) │
│ 命中后返回大块(保留上下文) │
│ ┌──────────────────────────────────┐ │
│ │ 父文档 (大块,给 LLM 读) │ │
│ │ ┌──────┐ ┌──────┐ ┌──────┐ │ │
│ │ │子文档1│ │子文档2│ │子文档3│ │ │
│ │ │(检索) │ │(命中!)│ │(检索) │ │ │
│ │ └──────┘ └──────┘ └──────┘ │ │
│ └──────────────────────────────────┘ │
│ │
│ 5. 多步推理 (Self-RAG / CRAG): │
│ LLM 评估检索结果是否有用 │
│ 没用 → 重新检索或放弃 │
│ 有用 → 生成回答 → 自我验证 │
│ │
└──────────────────────────────────────────────────────────────┘6. 2025 年 RAG 新趋势
┌──────────────────────────────────────────────────────────────┐
│ RAG 技术演进(2025) │
├──────────────────────────────────────────────────────────────┤
│ │
│ Agentic RAG(主流趋势) │
│ ┌────────────────────────────────────────────────────────┐ │
│ │ 传统 RAG: 用户问 → 检索 → 生成(被动、固定流程) │ │
│ │ Agentic RAG: Agent 主动规划检索策略 │ │
│ │ • 判断是否需要检索(简单问题直接回答) │ │
│ │ • 决定检索哪个知识库 │ │
│ │ • 检索结果不够好时自动重新检索 │ │
│ │ • 多跳推理:多轮检索逐步组装答案 │ │
│ └────────────────────────────────────────────────────────┘ │
│ │
│ 层次化检索(KohakuRAG / RAPTOR) │
│ ┌────────────────────────────────────────────────────────┐ │
│ │ 文档 → 章节 → 段落 → 句子 四级树结构 │ │
│ │ 检索时根据问题粒度选择合适层级 │ │
│ │ 提升多粒度问题的召回精度 │ │
│ └────────────────────────────────────────────────────────┘ │
│ │
│ 多模态 RAG(新方向) │
│ ┌────────────────────────────────────────────────────────┐ │
│ │ 文本 + 图像 + 表格 跨模态联合检索 │ │
│ │ 适合: 产品手册、技术文档、财报等混合内容 │ │
│ └────────────────────────────────────────────────────────┘ │
│ │
└──────────────────────────────────────────────────────────────┘下一节: 02 - Go 实现 RAG