/ RAG  大模型  LangChain  向量数据库  检索增强生成  Embedding  AI应用  Python 

大模型RAG检索增强生成实战:从原理到落地的完整开发指南


封面

一、什么是 RAG?为什么它如此重要

RAG(Retrieval-Augmented Generation,检索增强生成)是一种将信息检索与大语言模型生成能力相结合的技术架构。传统大模型存在两个核心痛点:知识截止日期(训练数据有时效性)和幻觉问题(模型会编造不存在的事实)。RAG 通过在生成前先从外部知识库检索相关内容,将其作为上下文传入模型,从根本上缓解了这两个问题。

RAG 的典型应用场景包括:

  • 企业内部知识问答系统(对接公司文档、Wiki、FAQ)

  • 智能客服(实时检索产品手册、政策文件)

  • 代码助手(检索私有代码库和文档)

  • 医疗/法律等专业领域问答(检索权威文献库)

二、RAG 核心架构与工作流程

一个完整的 RAG 系统由以下几个核心组件构成:

  • 文档加载器(Document Loader):支持 PDF、Word、Markdown、网页等多种格式

  • 文本分块器(Text Splitter):将长文档切分为合适的片段(Chunk)

  • Embedding 模型:将文本转换为高维向量表示

  • 向量数据库(Vector Store):存储和检索向量,常用 Chroma、Milvus、Pinecone

  • 检索器(Retriever):根据用户查询找出最相关的文档片段

  • 生成器(Generator):将检索结果与问题拼接成 Prompt 调用 LLM 生成答案

工作流程如下:用户提问 → 查询向量化 → 向量数据库相似度检索 → 拼接 Prompt → LLM 生成答案 → 返回结果。

三、关键技术选型与优化策略

RAG 系统的效果很大程度上取决于以下几个关键决策:

3.1 文档分块策略

分块大小直接影响检索精度与召回率。经验值:chunk_size=512~1024 tokens,chunk_overlap=50~100 tokens。对于结构化文档,建议按段落或标题层级分块;对于代码文档,按函数或类分块效果更好。

3.2 Embedding 模型选择

  • 中文场景优先考虑:BAAI/bge-large-zh-v1.5、text2vec-large-chinese

  • 多语言场景:multilingual-e5-large

  • OpenAI API:text-embedding-3-large(效果最佳但有成本)

3.3 检索优化

  • 混合检索:结合向量检索(语义)和 BM25 检索(关键词),用 RRF 融合排序

  • 重排序(Reranker):用 cross-encoder 模型对 Top-K 结果重新打分

  • 查询扩展:对用户查询进行改写或生成多个子查询

四、Python 实战:用 LangChain 构建 RAG 系统

下面是一个基于 LangChain + Chroma + OpenAI 的完整 RAG 示例:

from langchain.document_loaders import PyPDFLoader, DirectoryLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.embeddings import HuggingFaceEmbeddings
from langchain.vectorstores import Chroma
from langchain.chains import RetrievalQA
from langchain.llms import OpenAI

# 1. 加载文档
loader = DirectoryLoader('./docs', glob='**/*.pdf', loader_cls=PyPDFLoader)
documents = loader.load()
print(f"加载了 {len(documents)} 个文档页面")

# 2. 文本分块
text_splitter = RecursiveCharacterTextSplitter(
    chunk_size=512,
    chunk_overlap=64,
    separators=["\n\n", "\n", "。", "!", "?", " "]
)
chunks = text_splitter.split_documents(documents)
print(f"切分为 {len(chunks)} 个文本块")

# 3. 创建 Embedding 模型(使用本地模型,无需 API key)
embeddings = HuggingFaceEmbeddings(
    model_name="BAAI/bge-large-zh-v1.5",
    model_kwargs={"device": "cuda"},  # 有 GPU 时使用
    encode_kwargs={"normalize_embeddings": True}
)

# 4. 构建向量数据库
vectorstore = Chroma.from_documents(
    documents=chunks,
    embedding=embeddings,
    persist_directory="./chroma_db"
)
vectorstore.persist()
print("向量数据库构建完成")

# 5. 构建检索链
retriever = vectorstore.as_retriever(
    search_type="mmr",  # 最大边际相关性,减少冗余
    search_kwargs={"k": 5, "fetch_k": 20}
)

# 6. 构建 QA 链
qa_chain = RetrievalQA.from_chain_type(
    llm=OpenAI(temperature=0),
    chain_type="stuff",
    retriever=retriever,
    return_source_documents=True,
    verbose=True
)

# 7. 问答
result = qa_chain({"query": "请解释产品的退款政策"})
print("答案:", result["result"])
print("来源文档:", [doc.metadata for doc in result["source_documents"]])

上述代码涵盖了完整的 RAG 流水线。在生产环境中,建议将向量数据库替换为 Milvus 或 Weaviate 以支持更大规模数据。

五、常见问题与解决方案

在实际落地过程中,RAG 系统经常遇到以下问题:

  • 检索不准确:优先检查 Embedding 模型是否与文档语言匹配,考虑加入混合检索和 Reranker

  • 答案幻觉仍然存在:在 Prompt 中明确要求模型只基于检索内容回答,无信息时说"不知道"

  • 响应速度慢:向量检索建议使用 HNSW 索引;Embedding 计算可异步或缓存

  • 上下文窗口超限:控制检索数量(Top-K=3~5),或使用 Map-Reduce / Refine chain

  • 文档更新同步:建议设计增量更新机制,使用文档 hash 判断是否需要重新 Embedding

RAG 并非银弹,它更适合"知识密集型"场景。对于逻辑推理、数学计算等任务,Fine-tuning 或 Tool Use 可能是更好的选择。随着 LLM 上下文窗口不断增大(如 Gemini 1M token),未来 RAG 的架构形态也会持续演进,但其核心价值——让模型获取实时、可靠、私有知识——将长期存在。

发布评论

热门评论区: