RAG 检索增强生成:原理、架构与实战指南

1. 什么是 RAG

RAG(Retrieval-Augmented Generation,检索增强生成)是一种将信息检索与大语言模型(LLM)生成能力相结合的技术范式。它的核心思想是:在模型生成回答之前,先从外部知识库中检索与用户问题相关的文档片段,将这些片段作为上下文提供给大语言模型,从而让模型基于真实、最新的信息生成回答。

RAG 的出现主要为了解决大语言模型的三大痛点:

  • 知识时效性差:模型训练数据存在截止日期,无法回答训练之后发生的事件。
  • 幻觉问题:模型可能编造不存在的事实,尤其在专业领域。
  • 缺乏私有知识:模型无法访问企业内部的文档、数据库等私有数据。

通过引入外部检索,RAG 让模型能够"先查资料、再回答",显著提升了回答的准确性和可信度。

2. RAG 的核心架构

一个典型的 RAG 系统由三个核心模块组成:

2.1 索引阶段(Indexing)

索引阶段负责将原始文档处理成可供检索的形式,主要步骤包括:

  1. 文档加载:从 PDF、Word、网页、数据库等来源读取原始文档。
  2. 文本切分(Chunking):将长文档切分为适当大小的文本块。切分策略直接影响检索效果。
  3. 向量化(Embedding):使用嵌入模型将每个文本块转换为高维向量。
  4. 向量存储:将向量及其对应的原始文本存入向量数据库(如 FAISS、Milvus、Chroma、pgvector)。

2.2 检索阶段(Retrieval)

当用户提出问题时,系统执行以下操作:

  1. 将用户问题用同一个嵌入模型转换为查询向量。
  2. 在向量数据库中执行相似度检索(如余弦相似度、欧氏距离),召回最相关的 Top-K 个文本块。
  3. 可选地结合重排序(Rerank) 模型,对召回结果做精细化排序,提升相关性。

2.3 生成阶段(Generation)

将检索到的相关文本块与用户问题一起组装成 Prompt,交给大语言模型生成最终回答。模型可以引用检索到的内容作答,从而减少幻觉。

下面是 RAG 系统的整体流程图:
#mermaid-svg-egwnlFgy3t46ai5W{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-egwnlFgy3t46ai5W .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-egwnlFgy3t46ai5W .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-egwnlFgy3t46ai5W .error-icon{fill:#552222;}#mermaid-svg-egwnlFgy3t46ai5W .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-egwnlFgy3t46ai5W .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-egwnlFgy3t46ai5W .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-egwnlFgy3t46ai5W .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-egwnlFgy3t46ai5W .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-egwnlFgy3t46ai5W .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-egwnlFgy3t46ai5W .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-egwnlFgy3t46ai5W .marker{fill:#333333;stroke:#333333;}#mermaid-svg-egwnlFgy3t46ai5W .marker.cross{stroke:#333333;}#mermaid-svg-egwnlFgy3t46ai5W svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-egwnlFgy3t46ai5W p{margin:0;}#mermaid-svg-egwnlFgy3t46ai5W .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-egwnlFgy3t46ai5W .cluster-label text{fill:#333;}#mermaid-svg-egwnlFgy3t46ai5W .cluster-label span{color:#333;}#mermaid-svg-egwnlFgy3t46ai5W .cluster-label span p{background-color:transparent;}#mermaid-svg-egwnlFgy3t46ai5W .label text,#mermaid-svg-egwnlFgy3t46ai5W span{fill:#333;color:#333;}#mermaid-svg-egwnlFgy3t46ai5W .node rect,#mermaid-svg-egwnlFgy3t46ai5W .node circle,#mermaid-svg-egwnlFgy3t46ai5W .node ellipse,#mermaid-svg-egwnlFgy3t46ai5W .node polygon,#mermaid-svg-egwnlFgy3t46ai5W .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-egwnlFgy3t46ai5W .rough-node .label text,#mermaid-svg-egwnlFgy3t46ai5W .node .label text,#mermaid-svg-egwnlFgy3t46ai5W .image-shape .label,#mermaid-svg-egwnlFgy3t46ai5W .icon-shape .label{text-anchor:middle;}#mermaid-svg-egwnlFgy3t46ai5W .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-egwnlFgy3t46ai5W .rough-node .label,#mermaid-svg-egwnlFgy3t46ai5W .node .label,#mermaid-svg-egwnlFgy3t46ai5W .image-shape .label,#mermaid-svg-egwnlFgy3t46ai5W .icon-shape .label{text-align:center;}#mermaid-svg-egwnlFgy3t46ai5W .node.clickable{cursor:pointer;}#mermaid-svg-egwnlFgy3t46ai5W .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-egwnlFgy3t46ai5W .arrowheadPath{fill:#333333;}#mermaid-svg-egwnlFgy3t46ai5W .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-egwnlFgy3t46ai5W .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-egwnlFgy3t46ai5W .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-egwnlFgy3t46ai5W .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-egwnlFgy3t46ai5W .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-egwnlFgy3t46ai5W .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-egwnlFgy3t46ai5W .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-egwnlFgy3t46ai5W .cluster text{fill:#333;}#mermaid-svg-egwnlFgy3t46ai5W .cluster span{color:#333;}#mermaid-svg-egwnlFgy3t46ai5W div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-egwnlFgy3t46ai5W .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-egwnlFgy3t46ai5W rect.text{fill:none;stroke-width:0;}#mermaid-svg-egwnlFgy3t46ai5W .icon-shape,#mermaid-svg-egwnlFgy3t46ai5W .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-egwnlFgy3t46ai5W .icon-shape p,#mermaid-svg-egwnlFgy3t46ai5W .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-egwnlFgy3t46ai5W .icon-shape .label rect,#mermaid-svg-egwnlFgy3t46ai5W .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-egwnlFgy3t46ai5W .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-egwnlFgy3t46ai5W .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-egwnlFgy3t46ai5W :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 用户提问
查询向量化
向量数据库检索
Top-K 相关文档块
重排序 Rerank
组装 Prompt
大语言模型生成
最终回答

3. 为什么需要 RAG:与微调的对比

在引入 RAG 之前,让模型掌握特定领域知识的主流方案是微调(Fine-tuning)。两者各有适用场景:

维度 RAG 微调
知识更新 更新知识库即可,成本低 需重新训练,周期长
幻觉控制 可引用检索来源,幻觉较低 仍可能产生幻觉
私有数据 天然支持外部知识库 需构造训练数据
推理成本 需维护检索链路 推理相对简单
适用场景 知识问答、客服、文档解读 风格模仿、格式遵循、特定任务能力

RAG 适合知识密集型 任务,微调适合能力与风格调整任务。在实际工程中,两者也常结合使用:先微调让模型适应领域表达,再用 RAG 注入实时知识。

4. RAG 的关键技术细节

4.1 文本切分策略

切分粒度直接影响检索质量:

  • 切分过小:语义不完整,检索到的片段缺乏上下文。
  • 切分过大:噪声多,且可能超出模型上下文窗口。

常用策略包括固定长度切分、按段落/标题结构切分、递归字符切分,以及基于语义的智能切分。实践中通常设置 chunk_size=500 左右并保留 overlap=50 的重叠,以保持语义连贯。

4.2 嵌入模型选择

嵌入模型决定了向量空间的语义表达能力。选择时需考虑:

  • 是否支持中文等多语言;
  • 向量维度与检索性能的平衡;
  • 与向量数据库的兼容性。

4.3 混合检索

仅靠向量检索有时会漏掉关键词精确匹配的场景。生产环境常采用混合检索:同时执行向量检索与 BM25 关键词检索,再用 RRF(Reciprocal Rank Fusion)融合排序,兼顾语义与字面匹配。

4.4 重排序

向量检索召回 Top-50,再用重排序模型精排取 Top-5 送入生成,是兼顾效果与成本的常见做法。

5. 代码实战:基于 LangChain 搭建 RAG

下面用一个可运行的示例演示如何搭建一个最小可用的 RAG 系统。

5.1 安装依赖

bash 复制代码
pip install langchain langchain-community langchain-openai chromadb

5.2 构建知识库索引

python 复制代码
from langchain_community.document_loaders import TextLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_openai import OpenAIEmbeddings
from langchain_community.vectorstores import Chroma

# 1. 加载文档
loader = TextLoader("knowledge.txt", encoding="utf-8")
documents = loader.load()

# 2. 文本切分
text_splitter = RecursiveCharacterTextSplitter(
    chunk_size=500,
    chunk_overlap=50,
)
chunks = text_splitter.split_documents(documents)

# 3. 向量化并存储
embeddings = OpenAIEmbeddings(model="text-embedding-3-small")
vectorstore = Chroma.from_documents(
    documents=chunks,
    embedding=embeddings,
    persist_directory="./chroma_db",
)

5.3 检索并生成回答

python 复制代码
from langchain_openai import ChatOpenAI
from langchain.chains import RetrievalQA

# 创建检索器
retriever = vectorstore.as_retriever(search_kwargs={"k": 4})

# 创建问答链
llm = ChatOpenAI(model="gpt-4o-mini", temperature=0)
qa_chain = RetrievalQA.from_chain_type(
    llm=llm,
    retriever=retriever,
    return_source_documents=True,
)

# 提问
result = qa_chain.invoke({"query": "什么是 RAG?"})
print(result["result"])

5.4 手动组装 Prompt 的方式

不依赖封装好的链,也可以手动控制检索与生成的衔接:

python 复制代码
from langchain.prompts import PromptTemplate

# 检索相关文档
docs = retriever.invoke("什么是 RAG?")
context = "\n\n".join([doc.page_content for doc in docs])

# 组装 Prompt
prompt = PromptTemplate.from_template(
    "请基于以下资料回答问题:\n\n{context}\n\n问题:{question}"
)
final_prompt = prompt.format(context=context, question="什么是 RAG?")

# 生成回答
response = llm.invoke(final_prompt)
print(response.content)

6. RAG 的常见挑战与优化方向

6.1 检索质量不佳

  • 症状:召回的文档与问题不相关。
  • 优化:调整切分策略、更换更强的嵌入模型、引入混合检索与重排序。

6.2 上下文被噪声干扰

  • 症状:相关文档混入大量无关内容,模型被带偏。
  • 优化:提高召回精度、压缩上下文、对检索结果做相关性过滤。

6.3 答案缺乏引用来源

  • 症状:用户无法验证回答依据。
  • 优化 :在 Prompt 中要求模型标注引用来源,并返回 source_documents 供前端展示。

6.4 高级 RAG 架构

生产级系统通常演进为更复杂的流水线,包括查询改写、多路召回、重排、以及基于评分的自适应检索等。

7. 总结

RAG 通过"检索 + 生成"的组合,让大语言模型能够访问外部知识库,有效缓解了幻觉问题并支持知识实时更新。构建一个可用的 RAG 系统,核心在于文档切分、向量检索、上下文组装三个环节的精细调优。

对于知识库问答、企业文档助手、智能客服等场景,RAG 是目前落地成本最低、效果最稳定的技术路线之一。建议初学者从 LangChain + Chroma 的最小示例入手,逐步加入混合检索与重排序,再根据业务效果持续迭代。

相关推荐
sel_91 小时前
深度学习损失函数详解:从 MSE、Cross Entropy 到 Dice、Focal、IoU、Contrastive Loss,一文掌握所有常见 Loss
人工智能·深度学习
绘梨衣5471 小时前
AI技术栈全景指南_Prompt_RAG_爬虫_MCP
人工智能·爬虫·prompt
zed_231 小时前
RAG 全链路串起来:一个能答专业问题的问答接口
人工智能
2601_962304911 小时前
把出片接进自动化流水线:2026 年批量 AI 视频生成工具的脚本契约与同类项目对照
运维·人工智能·自动化
知了一笑1 小时前
企业的卷味,组织的AI味
人工智能·ai·ai工作流
实战派K8S&DB2 小时前
如何在内网配置 TiDB 数据库 Agent
数据库·人工智能·分布式·tidb
天远数科2 小时前
零信任架构实战:基于天远身份证OCR构建自动化高并发移动支付网关
人工智能·架构·自动化·ocr
我爱写代码i2 小时前
AI对话绘画数字人源码 - uniapp前端
前端·人工智能·uni-app
这就是佬们吗2 小时前
不写Prompt,写Loop:AI编程的下一场范式迁移
人工智能·prompt·ai编程