第十三章:RAG(检索增强生成)

学习目标

  • 理解RAG(Retrieval-Augmented Generation)的核心原理与价值
  • 掌握RAG系统的核心组件和工作流程
  • 了解文档切分策略、Embedding模型选择和向量数据库对比
  • 能够使用LangChain构建简单的RAG应用
  • 了解RAG系统的评估方法

前置要求

建议先学习第十一章:大语言模型(LLM)详解,了解LLM的基本原理和使用方法,以便理解RAG如何增强LLM的能力。

什么是RAG?

RAG(Retrieval-Augmented Generation,检索增强生成)是一种将信息检索与大语言模型生成相结合的技术。它先从外部知识库中检索相关信息,再将检索到的信息作为上下文提供给LLM,从而生成更准确、更有依据的回答。

为什么需要RAG?

LLM存在以下局限性,RAG可以有效解决:

  • 知识过时:LLM的训练数据有截止日期,无法获取最新信息
  • 幻觉问题:LLM可能"编造"不存在的信息,RAG通过提供真实文档来减少幻觉
  • 缺乏私有知识:LLM不了解企业内部文档、个人笔记等私有数据
  • 可追溯性差:纯LLM回答无法引用信息来源,RAG可以标注出处

RAG工作流程

RAG 检索增强生成架构流程图
图13-1 RAG完整工作流程:用户提问 → 文档切分与向量化 → 向量数据库检索 → 检索结果作为上下文 → LLM生成带引用的回答
1

文档导入

将PDF、网页、数据库等外部知识导入系统

2

文档切分

将长文档切分为较小的文本块(Chunk)

3

向量化

使用Embedding模型将文本块转换为向量表示

4

存储索引

将向量存入向量数据库,建立索引

5

检索

用户提问时,将问题向量化并在数据库中检索相关文档

6

生成

将检索到的文档作为上下文,交给LLM生成回答

RAG的核心组件

组件 功能 常见选择
文档加载器 读取各种格式的文档(PDF、Word、网页等) LangChain Loaders、LlamaIndex
文本切分器 将长文档切分为适合检索的文本块 RecursiveCharacterTextSplitter
Embedding模型 将文本转换为向量表示 OpenAI、Sentence-BERT、BGE
向量数据库 存储和检索向量 Chroma、Milvus、Pinecone

RAG的优势

  • 减少幻觉:基于真实文档生成回答,提高准确性
  • 知识可更新:只需更新向量数据库中的文档,无需重新训练模型
  • 支持私有数据:可以整合企业内部知识库
  • 可追溯来源:回答可以标注引用的文档来源
  • 成本更低:相比微调,RAG的实现成本更低、速度更快

文档切分策略

文档切分(Chunking)是RAG系统中至关重要的一步,切分策略直接影响检索质量。

切分策略 原理 优点 缺点 适用场景
按段落切分 以段落分隔符(换行、空行)为边界切分 保持语义完整性 段落长度不一,可能过长或过短 结构化文档(文章、报告)
按Token切分 按固定Token数量切分 长度均匀,便于管理 可能切断语义完整的句子 需要精确控制上下文长度
重叠窗口切分 固定长度切分,相邻块之间保留重叠部分 兼顾长度控制和语义完整性 存储冗余,检索结果可能重复 通用场景(推荐)

推荐使用重叠窗口切分,通常设置块大小为500-1000个Token,重叠比例为10%-20%。

Embedding模型选择

模型 开发者 维度 最大长度 多语言支持 特点
text-embedding-3-small OpenAI 1536 8191 较好 效果好、API调用简单、需付费
all-MiniLM-L6-v2 Sentence-BERT 384 256 一般 轻量快速、适合英文
bge-large-zh-v1.5 BAAI (BGE) 1024 512 优秀(中文) 中文效果出色、开源免费
m3e-base Moka (M3E) 768 512 良好(中文) 中文场景常用、开源免费

向量数据库详细对比

数据库 特点 适用场景 是否开源
Pinecone 全托管云服务、无需运维、自动扩展 快速上线、不想管理基础设施的团队 否(商业服务)
Weaviate 支持混合搜索(向量+关键词)、GraphQL API 需要同时支持向量和关键词搜索的场景
Milvus 分布式架构、支持十亿级向量、性能极高 大规模生产环境、海量数据检索
Chroma 轻量级、嵌入式、Python友好、上手极简 开发测试、小规模应用、快速原型
Qdrant Rust编写、高性能、支持过滤、API丰富 高性能需求、需要复杂过滤条件

使用LangChain构建简单RAG

from langchain_community.document_loaders import TextLoader
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_community.embeddings import HuggingFaceEmbeddings
from langchain_community.vectorstores import Chroma
from langchain_community.llms import Ollama
from langchain.chains import RetrievalQA

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

# 2. 切分文档
text_splitter = RecursiveCharacterTextSplitter(
    chunk_size=500,       # 每块最大500个字符
    chunk_overlap=50,    # 块之间重叠50个字符
    separators=["\n\n", "\n", "。", "!", "?", " ", ""]
)
chunks = text_splitter.split_documents(documents)
print(f"文档被切分为 {len(chunks)} 个文本块")

# 3. 初始化Embedding模型
embeddings = HuggingFaceEmbeddings(
    model_name="BAAI/bge-large-zh-v1.5"  # 中文Embedding模型
)

# 4. 创建向量数据库
vectorstore = Chroma.from_documents(
    documents=chunks,
    embedding=embeddings,
    persist_directory="./chroma_db"  # 持久化存储目录
)

# 5. 创建检索器
retriever = vectorstore.as_retriever(
    search_kwargs={"k": 3}  # 检索最相关的3个文本块
)

# 6. 初始化LLM
llm = Ollama(model="qwen2.5:7b")  # 使用本地Ollama运行

# 7. 构建RAG链
qa_chain = RetrievalQA.from_chain_type(
    llm=llm,
    chain_type="stuff",     # 将所有检索结果拼接到一起
    retriever=retriever,
    return_source_documents=True
)

# 8. 提问
question = "什么是机器学习?"
result = qa_chain({"query": question})

print(f"问题:{question}")
print(f"回答:{result['result']}")
print(f"引用来源:{[doc.metadata for doc in result['source_documents']]}")

RAG评估方法

评估RAG系统的质量需要从检索和生成两个维度进行:

评估维度 指标 说明
检索质量 检索准确率(Precision@K) 检索返回的K个文档中,有多少是真正相关的
检索质量 检索召回率(Recall@K) 所有相关文档中,有多少被成功检索到
生成质量 回答相关性 生成的回答是否与问题相关
生成质量 回答忠实度(Faithfulness) 回答是否基于检索到的文档,而非编造
整体质量 端到端准确率 最终回答的正确性和完整性

常用评估框架:RAGAS(RAG Assessment)是一个专门用于评估RAG系统的开源框架,提供上述指标的自动化计算。

本章小结

  1. RAG通过"检索+生成"的范式,将外部知识库与大语言模型结合,有效解决了LLM的知识过时、幻觉和私有数据缺失等问题。
  2. RAG的核心流程包括:文档导入→切分→向量化→存储索引→检索→生成,每个环节都有多种策略和工具可选。
  3. 文档切分推荐使用重叠窗口策略(500-1000 Token,10%-20%重叠),Embedding模型中文场景推荐BGE或M3E。
  4. 向量数据库选择需考虑规模和场景:Chroma适合开发测试,Milvus适合大规模生产,Pinecone适合不想运维的团队。
  5. RAG评估需从检索质量(准确率、召回率)和生成质量(相关性、忠实度)两个维度综合考量。

练习题

  1. RAG系统的主要目的是什么?

    A. 训练更大的语言模型
    B. 让LLM能够利用外部知识库来增强回答
    C. 替代LLM进行文本生成
    D. 加速模型的训练过程

    答案:B。RAG的核心目的是通过检索外部知识来增强LLM的生成能力,使回答更加准确、有依据。

  2. 在RAG系统中,文档切分时使用"重叠窗口"策略的主要好处是什么?

    A. 减少存储空间
    B. 避免在切分边界处丢失上下文信息
    C. 加快检索速度
    D. 减少Embedding的计算量

    答案:B。重叠窗口策略让相邻文本块之间保留部分重叠内容,确保即使关键信息恰好位于切分边界处,也不会被遗漏。

  3. 以下哪个向量数据库最适合快速原型开发和小规模应用?

    A. Milvus
    B. Pinecone
    C. Chroma
    D. Qdrant

    答案:C。Chroma是轻量级、嵌入式、Python友好的向量数据库,非常适合开发测试和小规模应用场景。