🔎检索增强生成(RAG)入门:从原理到上手
约 3131 字大约 10 分钟
RAGLLMVector SearchEmbedding
2026-06-06
在谈 RAG 之前,得先承认一件事:RAG 不是凭空出现的,它是对 LLM 三个老毛病的一剂解药。
- 第一个是幻觉。大模型的底层是基于概率生成下一个 token,所以它会"一本正经胡说八道"。问 ChatGLM "博物院下周一开门吗?",它有概率直接编一个开放时间,还带着礼貌口吻——这要是接到了 12345 投诉电话上,事情就难看了。
- 第二个是新鲜度。模型再大,训练数据也有截止日期。ChatGPT 3.5 的知识截止到 2021 年,问它"今晚有什么电影值得看",它只能礼貌地告诉你它不知道。
- 第三个是数据安全。把企业经营数据、合同文件上传到公网大模型,想起来就头皮发麻。企业真正想要的往往是一个"在内部跑、安全、还能借助大模型能力"的搜索——这正是 RAG 的用武之地。
RAG = Retrieval Augmented Generation = 检索增强生成。它的核心思想很简单:回答问题之前,先去私有知识库里把相关的资料捞出来,然后让 LLM 基于这些资料生成答案。这样既利用了 LLM 的归纳能力,又解决了"不知道""瞎说""不敢上传"三个问题。
什么是 RAG
把 RAG 的全称拆开看:检索 + 增强 + 生成。对应到工程上就是三段式:
- 索引(Indexing):把私有知识(PDF、Markdown、Notion、数据库)切成小段,编码成向量存进向量数据库
- 检索(Retrieval):用户提问时,把问题也编码成向量,去向量库里找最相关的几段
- 生成(Generation):把检索到的资料 + 用户问题拼成一个 prompt,交给 LLM 生成答案
提示
离线阶段跑一次,把知识固化下来;在线阶段每次用户提问都跑一次。两者解耦后,离线阶段可以慢慢建索引、慢慢评估,在线阶段只要追求"快 + 准"。
核心机制详解
1. 数据提取与切片
文档进来后,第一步是切片(Chunking)。为什么不能把整篇文档直接编码?因为大多数 Embedding 模型有 token 上限(512/1024/2048),而 LLM 也有上下文窗口。切片不是简单按字数切,按以下策略效果更好:
| 切片策略 | 原理 | 适用场景 |
|---|---|---|
| 固定大小 | 每块 N token,相邻块重叠 10-15% | 通用起点 |
| 递归切 | 优先按段落 → 句子 → 字符 | 结构化文档 |
| 语义切 | 相邻句 Embedding 相似度低于阈值时切 | 主题跳跃大的文档 |
| 句子切 | 按标点分句 | 对话、评论 |
| 文档结构切 | 按标题层级、表格、图片说明切 | 论文、合同 |
| Agent 驱动切 | 让 LLM 决定如何切(按目标自适应) | 实验性 |
笔记
经验值:从 chunk_size=512 + overlap=10-15% 开始。GPT-5+ 这种 1M context 大模型,可以试 1024-2500 token 的大块做深度推理。但大块意味着 top-k 取的块数变少,灵活性下降。
2. Embedding(向量化)
把文本变成向量的过程叫 Embedding。Embedding 模型的好坏直接决定检索质量。主流选择:
| 模型 | 维度 | 优势 |
|---|---|---|
| BGE (BAAI 系列) | 768/1024 | 中文 MTEB 排名前 2,支持中英文 |
| M3E | 768 | 轻量中文 Embedding,部署友好 |
| text-embedding-3-large (OpenAI) | 3072 | 通用 SOTA,英文最强 |
| NV-EmbedQA (NVIDIA) | 1024 | 长文档检索强 |
3. 向量数据库
存向量的地方叫向量数据库。区别于传统数据库,向量数据库用 HNSW 或 IVF 索引做近似最近邻(ANN)搜索。
| 向量库 | 定位 | 适合 |
|---|---|---|
| Chroma | 嵌入式、零配置 | 本地开发、原型 |
| Milvus / Qdrant | 分布式生产级 | 大规模(百万+ 文档) |
| pgvector | PG 扩展 | 已有 PG 基础设施 |
| Pinecone / Weaviate (Cloud) | 全托管 | 不想运维 |
4. 重排序(Rerank)
向量检索返回 top-k 后,Reranker 会对这 k 个文档做精细排序,把最相关的往上提。生产环境只做向量检索不够,Dify 引用 Microsoft Azure 的实测数据表明:纯向量检索在企业级场景下表现差强人意,加 Reranker 效果通常提升 15-30%。
| Reranker | 来源 |
|---|---|
| bge-reranker-v2-m3 | BAAI 开源 |
| Cohere Rerank 3 | 商业 API,英文最强 |
| NV-RerankQA | NVIDIA |
主流框架对比(2026 视角)
| 框架 | 定位 | 适合场景 | 学习曲线 |
|---|---|---|---|
| LangChain | 全能编排(chain/agent/工具调用) | 复杂多步应用、Agent 集成 | 较陡 |
| LlamaIndex | 数据框架(专注 indexing + querying) | 文档问答、检索层 | 中等 |
| Haystack | 工业级搜索管道 | QA 系统、企业搜索 | 较低 |
| Dify | 低代码可视化平台 | 非技术用户快速搭 chatbot | 极低 |
| Hugging Face | 模型 + 工具市场 | 用最新开源模型 | 中等 |
提示
2026 的主流组合:LlamaIndex 做"知识层" + LangChain 做"编排层" + n8n 做"工作流引擎"——三者拼装后是个工业级 RAG 平台。入门建议从 LangChain 起手,习惯后再拆 LlamaIndex 出来做检索。
GitHub 热门 RAG 仓库
社区里 RAG 相关的"必看仓库"主要分两类:Awesome 资源汇总 + 生产级可运行项目。
入门路径:先看
rag-from-scratch跑通最小闭环 → 看RAG_Techniques学进阶技巧 → 看llama_index主仓库了解工业级 API。
怎么上手:最小闭环
下面是一段 30 行的最小可运行 RAG(Python + LangChain + Chroma + OpenAI):
from langchain_community.document_loaders import TextLoader
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_openai import OpenAIEmbeddings, ChatOpenAI
from langchain_community.vectorstores import Chroma
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.runnables import RunnablePassthrough
from langchain_core.output_parsers import StrOutputParser
# 1. 加载 + 切片
docs = TextLoader("knowledge.txt").load()
splits = RecursiveCharacterTextSplitter(chunk_size=512, chunk_overlap=64).split_documents(docs)
# 2. Embedding + 入库
vectordb = Chroma.from_documents(splits, OpenAIEmbeddings(model="text-embedding-3-small"))
retriever = vectordb.as_retriever(search_kwargs={"k": 4})
# 3. Prompt 模板
prompt = ChatPromptTemplate.from_template("""
基于以下参考资料回答问题。如果资料里没有答案,请直接说"我不知道"。
参考资料:
{context}
问题:{question}
""")
# 4. 链式调用
llm = ChatOpenAI(model="gpt-5-mini")
chain = (
{"context": retriever, "question": RunnablePassthrough()}
| prompt | llm | StrOutputParser()
)
print(chain.invoke("RAG 是什么?"))笔记
关键点:Prompt 里写"如果资料里没有答案,请直接说我不知道"——这是防幻觉的硬性护栏,比 LLM 自由发挥要稳得多。
生产实践要点
1. 切片策略的取舍
ihower 在 2024 年用繁體中文实测了 38 种 Chunking 组合,结论是:
- 优先看 Recall:正确资料都检索不到的话,后面 LLM 再强也救不回来
- Recall 差不多时看 Precision:同样的 top-k,Precision 高的更"精",节省 context
- 小模型 + 小 context → 切小块(256-512 token,避免噪声干扰)
- 大模型 + 大 context → 切大块(1024-2500 token,让模型做长程推理)
2. 混合检索(Hybrid Search)
纯向量检索的弱点:对专有名词、缩写、ID 类查询不敏感。比如用户搜 "Q3 营收环比",向量检索可能找不到"2024 年第三季度"那段话。
解法:BM25(关键词检索)+ 向量检索 + Reranker。三路召回后用 RRF(Reciprocal Rank Fusion)或线性加权融合,再交给 Reranker 精排。这是 Dify 在企业场景下推荐的标准做法。
3. 元数据过滤
把文档的"时间 / 部门 / 文件类型 / 标签"作为 metadata 存进向量库,检索时先按 metadata 过滤再向量召回,能大幅提升相关度:
问题:帮我找 3 月份 XX 部门的合同
向量库先过滤 metadata = {月份: 3, 部门: XX},再在子集里做向量检索评估:用 RAGAS 看效果
没有评估就没有优化。社区里 RAGAS 是事实标准框架,核心指标有 4 个:
| 指标 | 含义 | 优化方向 |
|---|---|---|
| Context Recall | 检索到的相关文档占全部相关文档的比例 | 切片策略、混合检索、Embedding |
| Context Precision | 检索结果中真正相关的比例 | Reranker、metadata 过滤 |
| Faithfulness | 答案是否忠于检索到的资料 | Prompt 护栏、模型选择 |
| Answer Relevancy | 答案与用户问题的相关度 | Query Rewriting、模型选择 |
提示
先看 Recall:Recall 拉不上去就调切片;Recall 上去了 Precision 还低,就加 Reranker。两个都 OK 但 Faithfulness 低,就改 Prompt 护栏。
进阶技巧
HyDE(Hypothetical Document Embedding)
传统检索用"问题"去查,但"问题"和"答案"的 Embedding 分布可能差很远。HyDE 的思路:让 LLM 先给问题生成一个"假设答案",然后用这个假设答案去检索——因为假设答案和真实答案的分布更接近,命中率反而更高。
适用:开放域问题、专业领域问答。 不适用:需要严格基于已知文档的合规场景(假设答案可能引入幻觉)。
RAG Fusion / Multi-Query
一个用户问题可能表达不完整。RAG Fusion 让 LLM 生成 N 个相似问题(不同角度、不同表述),每个问题都去检索一次,最后把所有结果融合排序。
实际收益:在 query 表达模糊时(如口语化提问)显著提升 Recall。
Step-back / Least-to-most
遇到"对比 X 和 Y 优劣"这种复杂问题,先用 LLM 抽象出"X 是什么"+"Y 是什么"两个子问题,分别检索后再综合。能解决"问题太复杂、检索一次只能拿到片面信息"的情况。
Self-query
让 LLM 把自然语言问题翻译成结构化过滤条件:
用户问:"价格低于 500 元的 Python 入门书"
LLM 翻译:filter = {category: "book", topic: "python", price: <500}然后用结构化条件 + 向量检索一起召回。
适用边界
RAG 不是银弹,认清边界比盲目使用重要:
| 场景 | 是否适合 RAG | 替代方案 |
|---|---|---|
| 私域知识问答(公司文档、产品手册) | ✅ 首选 | — |
| 客服 / FAQ | ✅ 首选 | — |
| 需要实时反应(股票、外卖状态) | ⚠️ 可加 RAG 做兜底 | 直接调 API |
| 结构化数据分析 | ❌ | SQL / pandas 更直接 |
| 超长文档总结(> 1M token) | ❌ | 直接用 1M context 模型更划算 |
| 严格合规、不能容错 | ⚠️ 谨慎 | 微调 + 规则引擎 |
结语
RAG 入门简单(30 行代码就能跑通),但要做好并不容易——切片策略、检索质量、评估体系这三座大山,每一座都需要在真实业务数据上反复打磨。
2026 年的主流共识是:RAG + 短上下文小模型 在多数企业场景下比 微调 + 大模型 更经济、更可解释、更易迭代。入手 RAG 不需要从论文读起——跑通 rag-from-scratch,再看 RAG_Techniques,再针对你的业务数据做评估,三步走就够。
参考源
本文写作过程中参考的权威来源(按引用顺序):
