06 RAG从入门到生产:你需要知道的一切
这是”AI Agent落地:业务系统智能化改造”系列的第六篇。前五篇讲了Agent怎么建、需要什么能力、怎么评测、怎么编排、怎么写Prompt。这篇讲Agent最常见的能力:RAG。
目录
引言:你做的RAG为什么效果不好
你搭了一个RAG系统,用向量数据库存了文档,用户提问时检索TopK结果,塞给大模型生成答案。上线后发现:检索不准、幻觉严重、改了Prompt不知道变好还是变差。
这是很多刚接触RAG的人会遇到的问题。原因很简单:RAG不是向量库+TopK,而是多环节管线的组合优化。
向量检索只是RAG的一个环节。一个完整、稳定、可用的RAG系统,通常要经过7层:文档准备、索引构建、查询增强、多路召回、融合重排、上下文组织、生成控制。每一层都有多种技术选择,组合方式不同,效果差异很大。
这篇文章帮刚接触RAG的人建立全面认知:RAG是什么、怎么演进的、每个环节的作用、怎么选方案、常见踩坑有哪些。目标是让你在项目RAG设计这块心中有数。
一、RAG到底是什么
一句话定义
RAG是**检索增强生成**(Retrieval-Augmented Generation)的缩写。核心思想是:先从知识库中检索相关内容,再把检索结果作为上下文,让大模型基于这些内容生成答案。
简单说就是:先找资料,再回答问题。
为什么需要RAG
大模型有三个痛点,RAG能缓解:
| 痛点 | 说明 | RAG怎么解决 |
|---|---|---|
| 知识过时 | 模型训练数据有截止日期,无法获取最新信息 | 实时检索最新文档 |
| 幻觉 | 模型会编造不存在的信息 | 基于真实文档生成,有据可依 |
| 隐私 | 敏感数据不能传给外部模型 | 本地知识库,数据不出域 |
RAG vs 长上下文 vs Fine-tuning
除了RAG,还有两种方式让大模型获取外部知识:
| 方式 | 原理 | 适用场景 | 局限 |
|---|---|---|---|
| RAG | 检索+生成 | 知识库大、需要实时更新、需要引用来源 | 检索质量影响生成效果 |
| 长上下文 | 把更多内容塞进模型输入窗口 | 知识库小(<100K token)、文档间关系复杂 | 成本高、有窗口限制 |
| Fine-tuning | 用特定数据微调模型参数 | 特定领域风格、格式要求严格 | 不能获取新知识、成本高 |
关键结论:三者互补而非替代。小库用长上下文,大库/动态知识用RAG,特定风格用Fine-tuning。很多生产系统是混合使用。

二、RAG的演进:从Naive到Agentic
RAG技术在过去三年经历了快速演进。了解这个脉络,能帮你判断当前项目应该用哪种方案。
Naive RAG(2023前):最简单的三步流程
最简单的RAG只有三步:
用户提问 → 向量检索TopK → 塞给模型生成答案
这种方案能跑通Demo,但生产环境问题很多:检索不准、上下文噪声大、无法处理复杂查询。
Advanced RAG(2024):7层管线优化
针对Naive RAG的问题,业界逐步优化出7层管线:
文档准备 → 索引构建 → 查询增强 → 多路召回 → 融合重排 → 上下文组织 → 生成控制
核心改进:
- 查询增强:改写用户问题,提升召回率
- 多路召回:全文+向量并行检索,互补短板
- 融合重排:RRF合并+Rerank精排,提升准确率
- 上下文压缩:裁剪、去重,减少噪声
这是当前主流方案,大多数生产系统都在这个阶段。
Agentic RAG(2024-2025最热):Agent动态决定检索
Agentic RAG的核心思想是:让Agent自己决定何时检索、检索什么、如何组合。
传统RAG是”被动检索”:用户问一个问题,系统固定走一遍检索流程。Agentic RAG是”主动检索”:Agent根据问题复杂度,动态决定要不要检索、检索几次、用什么查询词。
适用场景:复杂多步骤任务,比如”帮我分析这个政策对华东地区的影响”,Agent需要先检索政策内容,再检索华东地区数据,最后综合分析。
Self-RAG:模型自我反思决定是否需要检索
Self-RAG更进一步:模型自己判断”我需不需要检索”。
核心机制:模型生成答案时,会自问几个问题:
- 这个问题我需要检索吗?
- 检索结果和问题相关吗?
- 我的答案有没有基于检索结果?
- 我的答案有没有幻觉?
如果模型认为自己能回答,就不检索;如果不确定,再触发检索。这能减少不必要的检索调用,降低成本。

三、核心组件:每个环节的作用
理解RAG的每个环节,才能在项目中做出正确的技术选择。
3.1 文档处理:切片策略决定检索质量
什么是切片:把长文档拆成小段(Chunk),便于检索和拼接。切片质量直接影响检索效果。
常见切片方法:
| 方法 | 做法 | 适用场景 | 注意 |
|---|---|---|---|
| 固定长度+重叠 | 按固定字符数切分,相邻块带overlap | 快速搭基线、格式杂乱的文本 | 容易在句子中间截断 |
| 按文档结构 | 以标题、章节为边界 | 技术手册、政策条文 | 单节过长时需二次切分 |
| 语义切片 | 逐句向量化,相似度骤降处断开 | 话题频繁切换的长文 | 计算成本高,阈值敏感 |
| Parent-Child | 小块用于检索,大块用于生成 | 需要精确检索但上下文要完整 | 需要维护两级索引 |
组合策略:多数线上系统用”结构优先→超长二次切→overlap”,在召回率和索引体积之间折中。
3.2 索引构建:不只是向量
索引是”提前建好的目录结构”,用于快速定位内容。RAG有四类索引:
| 索引类型 | 原理 | 擅长 | 短板 |
|---|---|---|---|
| 全文索引(BM25) | 按关键词匹配 | 专有名词、地名、年份、编号 | 不理解同义词 |
| 向量索引(Embedding) | 把文本转成数字向量,按语义相似度查找 | 同义表达、改写问法 | 对精确词项不稳定 |
| 图索引(Graph RAG) | 抽实体建关系,按关系链路查找 | 关系推理、多跳问题 | 构建维护成本高 |
| 树状索引 | 按目录/主题层级组织,先粗定位再下钻 | 长文档、结构化资料 | 跨层级灵活性差 |
工程组合:生产里通常不是四选一,而是组合:全文召回+向量召回并行,关系型问题补图检索,融合后做Rerank。
Embedding模型选型:不要只看排行榜,要在自有数据上评估。中文场景推荐BGE、M3E,英文推荐OpenAI text-embedding-3。
3.3 检索策略:混合检索是主流
什么是混合检索:全文检索和向量检索并行执行,结果合并排序。
为什么需要混合检索?因为两种检索方式互补:
| 检索方式 | 擅长 | 不擅长 |
|---|---|---|
| 全文检索(BM25) | “2024年产业园政策” — 精确匹配关键词 | “怎么申请补贴” — 同义表达 |
| 向量检索 | “怎么申请补贴” — 语义相近 | “2024年产业园政策” — 精确词项 |
RRF融合算法:把两种检索结果合并的常用方法。核心思想是”多路都靠前的结果胜出”:
# RRF(Reciprocal Rank Fusion)公式
# score = Σ 1/(k + rank)
# k通常取60
def rrf_score(rank, k=60):
return 1 / (k + rank)
# 示例:一个文档在全文检索排第3,向量检索排第5
# RRF分数 = 1/(60+3) + 1/(60+5) = 0.0159 + 0.0154 = 0.0313
查询增强:在检索前改写用户问题,提升召回率。比如用户问”销售额怎么样”,可以改写为”销售额趋势、销售额同比、销售额分区域”,分别检索再合并。
3.4 后处理:重排和压缩
为什么需要重排:召回是粗筛(找全),重排是精排(排对)。BM25和向量检索的分数不能直接比较,需要一个更精确的模型重新排序。
Rerank模型:用Cross-Encoder模型,把查询和每个候选结果一起输入,计算相关性分数。比Bi-Encoder(向量检索用的)更准,但更慢,所以只用于重排,不用于召回。
上下文压缩:减少塞给模型的token量,降低成本、提升质量。
- 裁剪:只保留和查询相关的段落
- 去重:移除重复或高度相似的内容
- 摘要:对长段落生成摘要

四、方案选型:心中有数
4.1 技术方案对比
| 方案 | 原理 | 适用场景 | 复杂度 |
|---|---|---|---|
| 纯向量检索 | 只用Embedding+向量数据库 | Demo、PoC、小规模 | 低 |
| 混合检索 | 全文+向量并行,RRF融合 | 大多数生产场景 | 中 |
| Graph RAG | 知识图谱+图检索 | 关系推理、多跳问题 | 高 |
| 长上下文 | 把文档塞进模型输入窗口 | 小库(<100K token) | 低 |
当前共识:混合检索是主流,BM25+向量的组合被广泛采用。
4.2 技术方案选型:SQLite、PG、ES还是混合检索
很多人的RAG选型止步于”选哪个向量数据库”。但真正的技术方案要回答三个问题:检索用什么引擎、数据怎么存、两者怎么配合。
我调研了业内主流的几种方案,发现它们走了完全不同的路:
SQLite全家桶:一个文件搞定一切
SQLite + FTS5 + sqlite-vec + 本地rerank的组合,核心思想是:一个本地数据库文件里把全文检索和向量检索都做掉。
为什么很多人喜欢它?因为很”收敛”——零外部依赖、本地开发调试简单、数据直接落文件、部署成本低。sqlite-vec是Mozilla Builders项目(4K+ GitHub stars),背后有Mozilla、Fly.io、Turso等赞助。
真实案例:SQLite Cloud文档搜索(182个文档,查询平均370ms)、NBC新闻标题搜索(14,500条,FTS5+sqlite-vec+RRF融合)、Hermes Agent的session_search(FTS5做对话历史检索)。
| 维度 | 分析 |
|---|---|
| 优势 | 架构简单可靠、零依赖零运维、数据主权完整(数据不离开设备)、支持混合检索(FTS5+sqlite-vec+RRF) |
| 劣势 | sqlite-vec仍偏新、高并发能力有限、水平扩展能力弱 |
| 适用 | 用户量少、知识库<50万文档、本地应用、快速验证 |
| 不适用 | 已有成熟服务端、需要高并发、十亿级向量规模 |
PostgreSQL + pgvector:生产稳健选择
把向量检索直接放进PostgreSQL体系——PG负责关系数据、过滤、元数据、事务,pgvector负责向量列与近邻搜索,配上全文检索/BM25能力,就能在一个数据库里做混合检索。
为什么很多团队选它?不是因为性能一定最强,而是系统整体更简单:运维熟悉、备份恢复成熟、权限审计成熟、与现有业务库集成容易、数据同步链路更短。
RAGFlow:MySQL/PG + Elasticsearch双引擎
RAGFlow把业务数据存MySQL/PG,分块原文和向量都存Elasticsearch。每个租户一个ES索引,分块原文和向量在同一个索引里,检索时不需要二次查询。全文检索权重0.05、向量权重0.95。
优点是ES天然支持分布式,性能强。缺点是部署复杂——需要MySQL + ES + MinIO + Redis四个组件。
Hybrid Search:不是产品,是架构模式
混合检索不是某一个具体产品,而是一类检索架构:BM25做关键词召回 + Vector Search做语义召回 + Reranking做最终排序。
单一路线都有明显缺陷:只有BM25听不懂改写和语义,只有Vector抓不住精确词和专有名词,只有Rerank前面召回不对重排也救不回来。混合检索就是把三者的职责拆清楚。
工程实现:并行召回(全文+向量各一份)→ 结果融合(RRF)→ 候选重排(BGE Reranker/Cross-Encoder)。
我的选择:参考MaxKB,PostgreSQL + pgvector
| 考量 | 说明 |
|---|---|
| 规模 | 167个文档、约3000个分块,不需要ES的分布式能力 |
| 运维 | 单一数据库,不用维护ES+MySQL+Redis |
| 事务 | ACID保证数据一致性 |
| 扩展 | 后续加用户权限、多租户,PG原生支持 |
不选SQLite是因为需要后续多用户并发和管理功能。不选RAGFlow是因为167个文档用ES过度。不选纯向量库是因为缺乏关系型数据管理能力。
数据库设计要点:
知识库(knowledge_bases)
└── 文档(documents)
├── 文字块(text_blocks) — content + embedding + search_vector
├── 表格(tables) — html_content + caption_embedding
├── 图片(images)
└── RAG分块(chunks) — content + embedding + search_vector
关键设计:
- 每个分块同时存
embedding(向量)和search_vector(全文),支持混合检索 - 中文全文检索需要安装zhparser扩展:
CREATE EXTENSION zhparser; CREATE TEXT SEARCH CONFIGURATION chinese (PARSER = zhparser); bbox字段记录原文在PDF中的位置,检索结果可以直接跳转到PDF对应位置file_hash字段支持增量更新——文件没变就不重新处理
三种检索模式:
| 模式 | 原理 | 适用 |
|---|---|---|
| 向量检索 | pgvector cosine距离 | 语义相似的模糊查询 |
| 关键词检索 | tsvector + ts_rank_cd | 精确匹配(政策名、编号) |
| 混合检索(推荐) | 向量0.7 + 关键词0.3加权 | 大多数场景 |
混合检索的实现:用户问题同时走向量检索(Top-20)和关键词检索(Top-20),合并去重后加权排序,返回Top-5。这比纯向量检索的效果好很多,因为关键词检索能捕获向量检索容易漏掉的精确匹配(政策名、年份、编号)。
4.3 场景→方案映射
| 场景 | 技术方案 | 框架/工具 | 原因 |
|---|---|---|---|
| 快速原型验证 | SQLite全家桶 | Dify | 零依赖,最快跑通 |
| 企业知识库 | PG+pgvector+混合检索 | LangChain/LlamaIndex | 功能全面,可定制 |
| 文档问答(扫描件) | PG+pgvector+混合检索 | RAGFlow | 文档解析能力强 |
| 关系推理/多跳 | Graph RAG | LangChain+Neo4j | 支持图检索 |
| 小库(<100K token) | 长上下文 | 直接塞模型窗口 | 简单直接 |
| 本地应用/桌面工具 | SQLite全家桶 | 无框架 | 数据不离开设备 |
| 大规模/多租户 | ES+混合检索 | RAGFlow | 分布式性能强 |
4.3 场景→方案映射
| 场景 | 技术方案 | 框架/工具 | 原因 |
|---|---|---|---|
| 快速原型验证 | SQLite全家桶 | Dify | 零依赖,最快跑通 |
| 企业知识库 | PG+pgvector+混合检索 | LangChain/LlamaIndex | 功能全面,可定制 |
| 文档问答(扫描件) | PG+pgvector+混合检索 | RAGFlow | 文档解析能力强 |
| 关系推理/多跳 | Graph RAG | LangChain+Neo4j | 支持图检索 |
| 小库(<100K token) | 长上下文 | 直接塞模型窗口 | 简单直接 |
| 本地应用/桌面工具 | SQLite全家桶 | 无框架 | 数据不离开设备 |
| 大规模/多租户 | ES+混合检索 | RAGFlow | 分布式性能强 |
五、常见踩坑和优化
以下的前提是数据质量要过关,实际在生产中数据治理要花费更多的时间!
检索质量是第一瓶颈
RAG效果不好,80%的问题出在检索环节。优化方向:
- 混合检索:全文+向量互补
- 查询增强:改写、扩展、拆分用户问题
- Rerank:用更精确的模型重新排序
分块策略决定成败
分块太大会引入噪声,太小会丢失上下文。建议:
- 从500-1000字符开始,按业务场景调优
- 用Parent-Child策略:小块检索,大块生成
- 表格、代码块尽量作为原子单元
Embedding模型需自评
不要只看排行榜,要在自有数据上评估。建议:
- 准备50-100个真实查询和期望结果
- 对比不同模型的召回率
- 中文场景优先选BGE、M3E
Prompt设计影响生成质量
Prompt要明确约束,减少幻觉:
- 明确告诉模型”只基于提供的文档回答”
- 要求模型引用来源
- 没有相关信息时,让模型说”暂无数据”
语义缓存:降低40%成本
语义缓存的核心思想:相似的查询直接返回缓存结果,不走检索+生成流程。
适用场景:高频重复查询(如客服、FAQ)。实现方式:计算查询的Embedding,和缓存中的查询比较相似度,超过阈值直接返回。
评测是迭代的基础
用RAGAS框架评估RAG系统,核心指标:
- Faithfulness:答案有没有基于检索结果
- Answer Relevancy:答案和问题相不相关
- Context Precision:检索结果精不精确
- Context Recall:检索结果全不全
评测集需要定期校准,确保覆盖真实业务场景。
多轮对话的RAG处理
多轮对话场景比单次查询复杂。用户问”这个政策有什么要求?”,第二轮问”那申请流程呢?”,第二轮的”那”指的是第一轮的政策。处理方式:把对话历史和当前问题一起传给检索模块,或者用LLM先把指代消解成完整问题再检索。这部分的完整实现将在第二篇”RAG架构详解”中展开。

六、从哪里开始
第一步:跑通最简单的RAG
用LangChain RAG Tutorial,10行代码跑通最简单的流程:
from langchain_openai import ChatOpenAI, OpenAIEmbeddings
from langchain_community.vectorstores import Chroma
from langchain.chains import RetrievalQA
# 1. 创建向量数据库
vectorstore = Chroma.from_documents(documents, OpenAIEmbeddings())
# 2. 创建RAG链
qa_chain = RetrievalQA.from_chain_type(
llm=ChatOpenAI(model="deepseek-v4-flash"),
retriever=vectorstore.as_retriever(search_kwargs={"k": 5}),
)
# 3. 提问
answer = qa_chain.invoke("2024年产业园申报有什么要求?")
第二步:加BM25混合检索
from langchain.retrievers import EnsembleRetriever
from langchain_community.retrievers import BM25Retriever
# BM25检索器
bm25_retriever = BM25Retriever.from_documents(documents)
bm25_retriever.k = 5
# 向量检索器
vector_retriever = vectorstore.as_retriever(search_kwargs={"k": 5})
# 混合检索
ensemble_retriever = EnsembleRetriever(
retrievers=[bm25_retriever, vector_retriever],
weights=[0.4, 0.6], # BM25权重0.4,向量权重0.6
)
第三步:加Rerank模型
from langchain.retrievers import ContextualCompressionRetriever
from langchain_cohere import CohereRerank
# Rerank模型
reranker = CohereRerank(model="rerank-v3.5", top_n=3)
# 带Rerank的检索器
compression_retriever = ContextualCompressionRetriever(
base_compressor=reranker,
base_retriever=ensemble_retriever,
)
第四步:用RAGAS评测
from ragas import evaluate, SingleTurnSample, EvaluationDataset
from ragas.metrics import Faithfulness, AnswerRelevancy
# 构建评测样本
samples = [
SingleTurnSample(
user_input="2024年产业园申报有什么要求?",
response="需要编制实施方案和资金使用方案...",
retrieved_contexts=["创建阶段:编制实施方案、资金使用方案..."],
reference="申请国家级产业园需要编制实施方案、资金使用方案、基本情况表",
),
]
# 运行评测
result = evaluate(
dataset=EvaluationDataset(samples=samples),
metrics=[Faithfulness(), AnswerRelevancy()],
)
print(result)
第五步:按业务场景调优
- 调整分块大小和overlap
- 调整BM25和向量的权重
- 优化Prompt约束
- 扩充评测集
完整代码示例将在第二篇”RAG架构详解”中展开。
总结
从”向量检索”到”理解RAG的完整体系”。 RAG不是向量库+TopK,而是7层管线的组合优化。每一层都有多种技术选择,组合方式不同,效果差异很大。
从”Demo能跑”到”生产能用”。 混合检索、Rerank、查询增强、语义缓存,这些Demo阶段不会遇到的优化,才是RAG能不能上线的关键。
关键不是选什么框架,而是理解每个环节的作用。 框架会变,但RAG的核心原理不会变。理解了每个环节的作用,不管用什么框架,都能做出好的RAG系统。欢迎评论区交流~
关键词:RAG、检索增强生成、向量检索、混合检索、BM25、Embedding、Rerank、Agentic RAG、RAGAS、LangChain、LlamaIndex、Dify、RAGFlow
更多推荐


所有评论(0)