欢迎光临
我们一直在努力

RAG检索增强生成从入门到实战教程

什么是RAG(检索增强生成)?

RAG(Retrieval-Augmented Generation,检索增强生成)是2023年以来大语言模型应用中最重要的一项技术架构。它通过将外部知识检索与语言模型生成能力相结合,有效解决了大模型”幻觉”问题、知识时效性问题以及私有知识无法接入等核心痛点。

简单来说,RAG的工作流程分为三个阶段:检索(Retrieve)→ 增强(Augment)→ 生成(Generate)。当用户提出一个问题时,系统首先从知识库中检索出相关文档片段,然后将这些片段作为上下文信息与原始问题一起拼接到提示词中,最后交给大模型生成回答。这种方式让大模型在回答时有了”参考书”可查,而不是完全依赖自己的参数记忆。

与传统的微调(Fine-tuning)方案相比,RAG具有几个显著优势:无需重新训练模型即可引入新知识、知识更新只需修改向量数据库、部署成本低、可解释性强。正因为这些优势,RAG已经成为企业构建知识问答系统、智能客服、文档分析等应用的首选方案。

RAG架构示意图

RAG核心技术组件详解

一个完整的RAG系统由多个核心组件构成,每个组件都有多种实现选择。下面我们来逐一解析。

1. 文档解析与分块(Chunking)

文档解析是RAG系统的第一道工序。原始文档可以是PDF、Word、HTML、Markdown等各种格式。常用的解析工具有:

  • Unstructured.io:支持多种文档格式的解析,安装简单,社区活跃
  • PyMuPDF(fitz):PDF解析速度最快的库之一
  • LangChain文档加载器:提供了50+种文档加载器,开箱即用
  • LlamaParse:专为RAG优化的文档解析服务,对表格和图片有很好的支持

文档分块是影响检索质量的关键因素。常见的分块策略包括:

策略名称 分块方式 适用场景
固定大小分块 按字符数/Token数切分 通用场景,实现简单
递归分块 按段落→句子→子句逐级切分 Markdown、代码文档
语义分块 使用嵌入模型检测语义边界 高质量场景,计算成本较高
Agent式分块 LLM自主决定切分位置 极端复杂文档

在实践中,推荐使用递归分块+重叠窗口的组合策略。LangChain的 RecursiveCharacterTextSplitter 是最常用的实现,默认按 “\n\n” → “\n” → ” ” → “” 的层级进行切分,配合适当的chunk_size(通常500-1500字符)和chunk_overlap(10%-20%)参数。

2. 向量化与嵌入(Embedding)

将文本转化为向量是RAG系统的核心步骤。高质量的嵌入模型直接决定了检索的准确率。2024年以来,嵌入模型的发展集中在以下几个方向:

  • BGE系列(BAAI):BGE-M3支持多语言、多粒度,是目前最广泛使用的开源嵌入模型
  • E5系列(微软):在大规模文本匹配数据上训练,英文场景表现优异
  • OpenAI Embeddings:text-embedding-3-small/large,API调用方便但需付费
  • Jina Embeddings:支持长达8192 Token的输入,适合长文档
  • 智源M3E:国产中文嵌入模型,中文场景性价比高

一个实用的嵌入函数示例:

from sentence_transformers import SentenceTransformer
import numpy as np

# 加载BGE中文嵌入模型
model = SentenceTransformer(BAAI/bge-large-zh-v1.5)

def get_embedding(text: str) -> list:
    """为输入文本生成向量嵌入"""
    # BGE模型建议在查询前添加指令前缀
    return model.encode(text, normalize_embeddings=True).tolist()

# 批量处理文档片段
chunks = ["文档第一段内容...", "文档第二段内容..."]
embeddings = model.encode(chunks, normalize_embeddings=True)
print(f"向量维度: {embeddings.shape[1]}")  # 输出: 1024

3. 向量数据库

向量数据库负责存储和检索嵌入向量。市面上的向量数据库选择非常丰富:

数据库 部署方式 索引算法 适用规模
Chroma 嵌入式 HNSW 小规模 <100万
FAISS 嵌入式 IVF+HNSW 中规模 <1000万
Milvus 分布式 IVF_FLAT/HNSW 大规模 亿级
Qdrant 单机/分布式 HNSW 中大规模
PGVector PostgreSQL插件 IVFFlat/HNSW 中等规模

对于个人开发者和小团队,Chroma 是最友好的选择,它无需单独部署服务,可以嵌入到Python应用中直接使用。对于生产环境,MilvusQdrant 提供了更好的性能和可靠性。

完整RAG应用实战:搭建知识问答系统

接下来,我们从头搭建一个完整的RAG知识问答系统。这个系统将读取本地Markdown文档,构建向量索引,并基于用户提问检索相关文档生成回答。

环境准备

pip install langchain langchain-community chromadb sentence-transformers
pip install openai  # 或其他LLM提供商的SDK

Step 1: 文档加载与分块

from langchain_community.document_loaders import DirectoryLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter

# 加载文档目录中的所有Markdown文件
loader = DirectoryLoader(
    "./knowledge_base/",
    glob="**/*.md",
    show_progress=True
)
docs = loader.load()

# 递归分块
text_splitter = RecursiveCharacterTextSplitter(
    chunk_size=1000,
    chunk_overlap=200,
    separators=["\n## ", "\n### ", "\n\n", "\n", " ", ""]
)
chunks = text_splitter.split_documents(docs)
print(f"文档分块完成,共 {len(chunks)} 个片段")

Step 2: 构建向量索引

from langchain_community.embeddings import HuggingFaceBgeEmbeddings
from langchain_community.vectorstores import Chroma

# 配置BGE嵌入模型
model_name = "BAAI/bge-small-zh-v1.5"
model_kwargs = {"device": "cpu"}
encode_kwargs = {"normalize_embeddings": True}

embeddings = HuggingFaceBgeEmbeddings(
    model_name=model_name,
    model_kwargs=model_kwargs,
    encode_kwargs=encode_kwargs
)

# 创建Chroma向量存储(自动持久化到磁盘)
vectorstore = Chroma.from_documents(
    documents=chunks,
    embedding=embeddings,
    persist_directory="./chroma_db"
)
vectorstore.persist()
print("向量索引构建完成!")

Step 3: 实现检索增强生成

from langchain.chains import RetrievalQA
from langchain_openai import ChatOpenAI

# 初始化LLM
llm = ChatOpenAI(
    model="gpt-4o-mini",  # 也可替换为DeepSeek、GLM等其他模型
    temperature=0.1,  # 低温度保证回答的确定性
)

# 创建检索QA链
qa_chain = RetrievalQA.from_chain_type(
    llm=llm,
    retriever=vectorstore.as_retriever(
        search_type="similarity",
        search_kwargs={"k": 4}  # 检索最相似的4个片段
    ),
    return_source_documents=True,
    verbose=True
)

# 测试问答
question = "什么是RAG架构?它的主要优势是什么?"
result = qa_chain.invoke({"query": question})

print(f"回答: {result[result]}\n")
print("参考来源:")
for doc in result["source_documents"]:
    print(f"  - {doc.metadata.get(source, unknown)}")

代码和数据流示意图

RAG系统的高级优化技巧

基础RAG可以工作,但在实际生产环境中往往面临各种挑战。下面介绍一些经过验证的优化策略。

1. 混合检索(Hybrid Search)

纯向量检索在某些场景下效果不佳,比如精确匹配(产品型号、日期)和稀有词检索。混合检索结合了向量相似度检索关键词检索(BM25),兼顾语义理解和精确匹配。

from langchain.retrievers import BM25Retriever, EnsembleRetriever

# 关键词检索器
bm25_retriever = BM25Retriever.from_documents(chunks)
bm25_retriever.k = 4

# 向量检索器
vector_retriever = vectorstore.as_retriever(
    search_kwargs={"k": 4}
)

# 集成检索器(加权合并结果)
ensemble_retriever = EnsembleRetriever(
    retrievers=[bm25_retriever, vector_retriever],
    weights=[0.3, 0.7]  # BM25权重0.3,向量检索权重0.7
)

2. 重排序(Re-ranking)

初步检索返回的Top-K结果中,前面的结果不一定最相关。引入重排序模型对检索结果进行二次排序,可以显著提升最终答案质量。

from langchain.retrievers import ContextualCompressionRetriever
from langchain.retrievers.document_compressors import CrossEncoderReranker
from langchain_community.cross_encoders import HuggingFaceCrossEncoder

# 加载交叉编码器重排序模型
reranker = HuggingFaceCrossEncoder(model_name="BAAI/bge-reranker-v2-m3")

compressor = CrossEncoderReranker(
    model=reranker,
    top_n=3  # 保留最相关的3个片段
)

compression_retriever = ContextualCompressionRetriever(
    base_compressor=compressor,
    base_retriever=vectorstore.as_retriever(search_kwargs={"k": 10})
)

3. 查询重写(Query Rewriting)

用户原始查询往往不够精确,直接检索效果差。让LLM将用户问题重写为更适合检索的形式,可以大幅提升召回率。

from langchain.prompts import PromptTemplate

rewrite_prompt = PromptTemplate.from_template(
    """给定用户问题,生成3个不同角度的搜索查询,用于从技术文档库中检索相关信息。
每个查询应该覆盖问题的不同侧面。

用户问题: {question}

搜索查询(每行一个):"""
)

def rewrite_queries(question: str) -> list[str]:
    """将用户问题重写为多个搜索查询"""
    llm = ChatOpenAI(model="gpt-4o-mini", temperature=0.3)
    result = llm.invoke(rewrite_prompt.format(question=question))
    queries = [q.strip() for q in result.content.split("\n") if q.strip()]
    return queries[:3]

4. RAPTOR:分层摘要检索

RAPTOR(Recursive Abstractive Processing for Tree-Organized Retrieval)是2024年提出的创新方案。它通过对文档片段进行递归摘要,构建一棵多层次的摘要树。检索时,系统同时搜索底层片段和高层摘要,从而兼顾细节和概览。

这种方法特别适合处理长篇文档或书籍——当用户问”整本书的核心思想是什么”这类宏观问题时,高层摘要能直接提供答案,而不需要拼接多个片段。

常见RAG评估指标与工具

构建RAG系统后,如何评估它的质量?行业常用的评估指标包括:

指标 说明 评估维度
Hit Rate 检索结果中包含正确答案的比例 检索质量
MRR 正确答案在检索结果中的平均排名倒数 检索排序
Faithfulness 生成回答是否忠实于检索到的上下文 生成质量
Answer Relevancy 回答是否与用户问题相关 生成质量
Context Precision 检索结果中相关文档的比例 检索质量

推荐使用 RAGAS(RAG Assessment)框架来自动化评估过程:

pip install ragas

from ragas import evaluate
from ragas.metrics import (
    faithfulness,
    answer_relevancy,
    context_precision,
    context_recall
)

# 准备评估数据集
dataset = {
    "question": ["什么是RAG?", "向量数据库有哪些?"],
    "answer": [result_1, result_2],
    "contexts": [[context_1], [context_2]],
    "ground_truth": ["预期答案1", "预期答案2"]
}

scores = evaluate(dataset, metrics=[
    faithfulness,
    answer_relevancy,
    context_precision,
    context_recall
])
print(scores)

RAG vs 微调:如何选择?

很多开发者在面对业务需求时经常困惑:该用RAG还是微调(Fine-tuning)?其实二者并非对立关系,而是互补的技术路线。

选择RAG的场景:

  • 知识频繁更新:产品文档、新闻资讯、法律法规等
  • 需要引用原文:合规审查、学术研究、医疗诊断
  • 处理大量私有数据:企业内部知识库、客户聊天记录
  • 资源有限:不需要昂贵的GPU进行训练

选择微调的场景:

  • 需要模仿特定输出风格:客服话术、代码规范
  • 改善模型基础能力:推理能力、数学计算
  • 降低延迟:无需额外检索步骤

在实际工程中,RAG + 微调的组合方案往往能取得最佳效果。先用微调让模型掌握特定领域的输出格式和基本知识,再用RAG补充最新的私有信息。这套组合在2024年微软的《AI Transformation Guide》中被强烈推荐。

总结与学习资源

RAG作为大模型落地应用的关键技术,已经成为每位AI工程师必须掌握的技能。本文从基本原理出发,逐步深入到完整的代码实现和高级优化技巧,希望为读者提供一条清晰的学习路径。

如果你想进一步深入学习,以下免费资源非常值得推荐:

  • LangChain官方教程:langchain.com/docs — 最完整的RAG框架文档
  • LlamaIndex教程:docs.llamaindex.ai — 专注于RAG的高级框架
  • DeepLearning.AI RAG专项课程:与LangChain/LlamaIndex作者合作,免费试听
  • Pinecone RAG入门指南:免费电子书,含大量代码示例
  • Hugging Face NLP课程:huggingface.co/learn — 涵盖嵌入模型和检索技术

记住,构建优秀的RAG系统没有银弹。关键在于理解业务场景、选择合适的组件组合,并通过持续评估迭代优化。希望本文能成为你RAG学习之旅的起点!

【本站文章皆为原创,未经允许不得转载】:汤不热吧 » RAG检索增强生成从入门到实战教程
分享到: 更多 (0)