RAG 详细介绍
RAG(Retrieval-Augmented Generation,检索增强生成) 是一种将外部知识检索与大语言模型生成相结合的技术架构。它解决的核心问题是:LLM 的训练数据有截止日期,且不包含你的私有数据,通过 RAG 可以让 LLM “现查现答”。
一、为什么需要 RAG
LLM 有三个根本性限制:
| 限制 | 表现 | RAG 如何解决 |
|---|---|---|
| 知识截止 | 模型不知道训练数据之后发生的事 | 实时检索最新文档 |
| 无私有数据 | 模型不了解你的公司内部文档、代码、业务数据 | 检索你的私有知识库 |
| 幻觉问题 | 模型会一本正经地编造事实 | 基于真实文档生成,可溯源验证 |
其他方案对比:
| 方案 | 原理 | 缺点 |
|---|---|---|
| 微调 Fine-tuning | 用你的数据重新训练模型 | 成本高、更新慢、不适合频繁变化的知识 |
| 长上下文直接塞 | 把所有文档放进 Prompt | 有 token 上限、成本高、检索不精确 |
| RAG | 先检索相关片段,再交给 LLM | 灵活、成本低、知识可实时更新 |
二、RAG 的核心工作流程
整个流程分为两大阶段:离线索引 和 在线查询。
阶段一:离线索引(Indexing) —— 构建知识库
把你的文档变成 LLM 能高效检索的格式。
1 | 原始文档 分块 向量化 存入向量数据库 |
步骤详解:
第 1 步:文档加载(Load)
把各种格式的原始文档读取为纯文本。
1 | # 支持的文档类型示例 |
第 2 步:文档分块(Chunk / Split)
大文档不能整篇存入,需要切成小段。这是 RAG 质量的关键环节。
1 | from langchain.text_splitter import RecursiveCharacterTextSplitter |
分块策略的核心考量:
| 参数 | 太小 | 太大 |
|---|---|---|
| chunk_size | 丢失上下文,答案碎片化 | 混入无关内容,检索精度下降 |
| chunk_overlap | 相邻块断裂,语义不连贯 | 冗余存储,检索到重复内容 |
常见的分块策略:
1 | 1. 固定大小分块 → 简单粗暴,适合通用场景 |
第 3 步:向量化(Embedding)
将每个文本块转化为一个高维数学向量(通常 768~3072 维)。语义相近的文本,向量距离也近。
1 | from openai import OpenAI |
为什么要向量化?因为关键词搜索有局限:
1 | 用户问:"怎么查看数据面板" |
常见 Embedding 模型:
| 模型 | 维度 | 特点 |
|---|---|---|
OpenAI text-embedding-3-small |
1536 | 性价比高,英文和中文都不错 |
OpenAI text-embedding-3-large |
3072 | 更精确,成本更高 |
BAAI/bge-large-zh-v1.5 |
1024 | 开源,中文表现优秀,可本地部署 |
nomic-embed-text |
768 | 开源,配合 Ollama 可完全本地化 |
第 4 步:存入向量数据库(Vector Store)
向量数据库专门用于高效存储和检索高维向量。
1 | import chromadb |
常见向量数据库:
| 数据库 | 部署方式 | 适合场景 |
|---|---|---|
| ChromaDB | 本地/嵌入式 | 原型开发、小型项目 |
| PostgreSQL + pgvector | 本地/云 | 已有 PG 的项目(比如你用 Supabase) |
| Pinecone | 云托管 | 生产环境,免运维 |
| Weaviate | 自托管/云 | 需要混合搜索(向量+关键词) |
| Qdrant | 自托管/云 | 高性能,支持过滤 |
| FAISS | 内存/本地 | 纯研究实验用 |
阶段二:在线查询(Retrieval + Generation) —— 用户提问时
1 | 用户提问 向量化查询 检索相关文档 LLM 生成回答 |
步骤详解:
第 1 步:查询向量化
把用户的问题用同一个 Embedding 模型转为向量。
第 2 步:向量检索
在向量数据库中找到与查询向量最相似的 Top-K 个文档块。
1 | results = collection.query( |
第 3 步:构造增强 Prompt
将检索到的文档块拼入 Prompt,让 LLM 基于这些真实内容回答。
1 | context_docs = "\n\n---\n\n".join(results["documents"][0]) |
第 4 步:LLM 生成回答
LLM 基于 Prompt 中的真实文档内容生成回答,而不是凭空编造。
三、进阶 RAG 技术
基础 RAG(上面介绍的)也叫 Naive RAG。实际生产中常用更高级的变体:
1. 查询优化(Query Transformation)
用户的问题往往不适合直接检索,需要先优化:
1 | 原始问题:"这个项目的数据库有啥问题" |
常见技术:
- 查询改写(Query Rewriting):让 LLM 将模糊问题改写为更适合检索的精确表述
- HyDE(假设文档嵌入):让 LLM 先生成一段假设性答案,用这段答案去检索(往往比用问题检索更准)
- 多查询(Multi-Query):将一个问题生成多个角度的子查询,分别检索后合并
2. 混合检索(Hybrid Search)
向量搜索擅长语义匹配,但对精确关键词(如函数名 console_dashboard_rpc_v2)可能不如关键词搜索。混合检索结合两者:
1 | 用户查询 |
3. 重排序(Re-ranking)
初步检索返回的 Top-K 结果中,排序不一定准确。用一个专门的重排序模型精细打分:
1 | 初步检索 Top-20 ──► Reranker 模型精排 ──► 取 Top-5 给 LLM |
常用重排序模型:Cohere Rerank、BAAI/bge-reranker-v2-m3(开源)。
4. 父子分块(Parent-Child Chunking)
检索时用小块保证精确度,传给 LLM 时返回该小块所属的大块保证上下文完整:
1 | 大文档 |
5. 自适应 RAG(Adaptive RAG)
不是所有问题都需要检索。让 LLM 先判断是否需要查资料:
1 | 用户问题 |
四、RAG 系统的典型架构图
1 | ┌─────────────────────────────────────────────────────────────┐ |
五、RAG 与其他技术的关系
1 | ┌─────────────────┐ |
- RAG 是一种”给 LLM 补充知识”的技术,本身不具备行动能力
- Agent 是”能自主行动的系统”,可以把 RAG 当作其中一个工具
- 两者经常组合使用:Agent 需要查资料时调用 RAG,需要执行操作时调用其他工具
六、一句话总结
RAG = 先从你的知识库中找到相关内容,再让 LLM 基于这些真实内容回答问题。 它让 LLM 从”凭记忆回答”变成”查资料后回答”,大幅提升准确性和可控性,是当前将 LLM 应用于私有数据场景最主流的技术方案。