LangChain 从入门到实践:用最小案例理解 RAG 的 5 个核心抽象
2026/7/28 7:47:59 网站建设 项目流程

1. 引言

RAG(Retrieval-Augmented Generation,检索增强生成)是当前大语言模型应用中最热门的架构之一。它通过将外部知识库的检索结果注入到生成过程中,有效缓解了大模型幻觉、知识过时等问题。LangChain 作为最流行的 LLM 应用开发框架,为 RAG 提供了简洁而强大的抽象层。

本文将从零开始,通过一个最小可运行的案例,带你理解 LangChain 中 RAG 的 5 个核心抽象:Document Loaders、Text Splitters、Vector Stores、Retrievers 和 Chains。无论你是刚接触 RAG 的新手,还是想系统梳理 LangChain 概念的开发者,这篇文章都能帮你快速建立完整的认知框架。

2. 环境准备

在开始之前,请确保你的 Python 环境满足以下要求:

  • Python 3.9 或更高版本
  • 安装 LangChain 及相关依赖
pip install langchain langchain-community langchain-openai chromadb

本文使用 OpenAI 的嵌入模型和 Chat 模型,你需要准备一个有效的 API Key:

import os os.environ["OPENAI_API_KEY"] = "your-api-key-here"

3. 核心抽象一:Document Loaders(文档加载器)

Document Loader 是 RAG 管线的第一环,负责从各种来源加载文档并将其转换为 LangChain 统一的Document对象。每个Document包含page_content(文本内容)和metadata(元数据,如来源、作者等)。

LangChain 支持数十种文档加载器,覆盖本地文件、网页、数据库、云存储等场景。下面以最简单的TextLoader为例:

from langchain_community.document_loaders import TextLoader loader = TextLoader("example.txt") documents = loader.load() print(documents[0].page_content[:100]) # 打印前100个字符 print(documents[0].metadata) # 打印元数据

对于更常见的 PDF 或网页场景,可以使用PyPDFLoaderWebBaseLoader

from langchain_community.document_loaders import WebBaseLoader loader = WebBaseLoader("https://example.com/article") documents = loader.load()

4. 核心抽象二:Text Splitters(文本分割器)

加载后的文档通常很长,无法直接送入大模型(受限于上下文窗口)。Text Splitter 负责将长文档切分成语义完整的短片段(chunks),每个 chunk 后续会被向量化并存入向量数据库。

LangChain 提供了多种分割策略,最常用的是RecursiveCharacterTextSplitter,它按优先级依次尝试不同的分隔符(\n\n\n、空格、字符),尽量保持段落和句子的完整性。

from langchain.text_splitter import RecursiveCharacterTextSplitter text_splitter = RecursiveCharacterTextSplitter( chunk_size=500, # 每个 chunk 的最大字符数 chunk_overlap=50, # chunk 之间的重叠字符数,用于保持上下文连贯 separators=["\n\n", "\n", " ", ""] ) chunks = text_splitter.split_documents(documents) print(f"原始文档被切分为 {len(chunks)} 个 chunk")

chunk_size 和 chunk_overlap 的选择:chunk_size 过小会导致语义碎片化,过大则可能超出模型上下文窗口。chunk_overlap 可以缓解边界信息丢失的问题,一般设为 chunk_size 的 10%~20%。

5. 核心抽象三:Vector Stores(向量存储)

切分后的文本片段需要转换为向量(嵌入)并存储,以便后续进行语义检索。Vector Store 就是负责这一环节的抽象。LangChain 支持 Chroma、FAISS、Pinecone、Weaviate 等多种向量数据库。

下面使用 Chroma(本地运行,无需额外服务)来构建向量存储:

from langchain_openai import OpenAIEmbeddings from langchain_community.vectorstores import Chroma embeddings = OpenAIEmbeddings(model="text-embedding-3-small") vectorstore = Chroma.from_documents( documents=chunks, embedding=embeddings, persist_directory="./chroma_db" # 持久化存储路径 ) print("向量存储构建完成,共包含", vectorstore._collection.count(), "个向量")

嵌入模型将文本映射到高维语义空间,语义相近的文本在向量空间中距离更近。这是后续检索的基础。

6. 核心抽象四:Retrievers(检索器)

Retriever 是 RAG 管线的查询接口。当用户提出一个问题时,Retriever 从 Vector Store 中检索出最相关的文档片段,作为上下文提供给大模型。

最简单的用法是将 Vector Store 直接转换为 Retriever:

retriever = vectorstore.as_retriever( search_type="similarity", # 相似度检索 search_kwargs={"k": 3} # 返回最相关的 3 个 chunk ) 测试检索 query = "什么是 RAG?" results = retriever.invoke(query) for i, doc in enumerate(results): print(f"结果 {i+1}: {doc.page_content[:100]}...")

除了基本的相似度检索,LangChain 还支持mmr(最大边际相关性)检索,它在保证相关性的同时增加结果的多样性,避免返回过于相似的片段。

7. 核心抽象五:Chains(链)

Chain 是 LangChain 中最核心的组合抽象,它将上述所有组件串联成一个完整的 RAG 管线。最常用的是RetrievalQA链,它自动完成「检索 → 组装 Prompt → 调用 LLM → 返回答案」的完整流程。

from langchain.chains import RetrievalQA from langchain_openai import ChatOpenAI llm = ChatOpenAI(model="gpt-4o-mini", temperature=0) qa_chain = RetrievalQA.from_chain_type( llm=llm, chain_type="stuff", # 将所有检索结果拼接后一次性送入 LLM retriever=retriever, return_source_documents=True # 返回检索到的原始文档,便于调试 ) 提问 question = "LangChain 中 RAG 的核心抽象有哪些?" response = qa_chain.invoke({"query": question}) print("答案:", response["result"]) print("\n参考来源:") for doc in response["source_documents"]: print(f"- {doc.page_content[:80]}...")

chain_type参数控制检索结果如何送入 LLM:

  • stuff:将所有文档拼接后一次性送入,适合文档量少的情况。
  • map_reduce:先对每个文档单独生成答案,再汇总,适合大量文档。
  • refine:逐个文档迭代优化答案,适合需要逐步推理的场景。
  • map_rerank:对每个文档生成答案并打分,返回最高分结果。

8. 完整最小案例

下面将上述 5 个抽象整合为一个完整的、可直接运行的脚本:

import os from langchain_community.document_loaders import TextLoader from langchain.text_splitter import RecursiveCharacterTextSplitter from langchain_openai import OpenAIEmbeddings, ChatOpenAI from langchain_community.vectorstores import Chroma from langchain.chains import RetrievalQA 1. 加载文档 loader = TextLoader("knowledge.txt") documents = loader.load() 2. 分割文档 text_splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=50) chunks = text_splitter.split_documents(documents) 3. 构建向量存储 embeddings = OpenAIEmbeddings() vectorstore = Chroma.from_documents(chunks, embeddings) 4. 创建检索器 retriever = vectorstore.as_retriever(search_kwargs={"k": 3}) 5. 构建问答链 llm = ChatOpenAI(model="gpt-4o-mini", temperature=0) qa_chain = RetrievalQA.from_chain_type(llm=llm, retriever=retriever) 6. 提问 answer = qa_chain.invoke({"query": "LangChain 是什么?"}) print(answer["result"])

只需替换knowledge.txt为你的知识文档,并配置好 API Key,即可运行一个完整的 RAG 应用。

9. 总结与进阶方向

通过本文的最小案例,我们完整走通了 RAG 的 5 个核心抽象:

  • Document Loaders:从各种来源加载文档。
  • Text Splitters:将长文档切分为语义完整的片段。
  • Vector Stores:将文本片段向量化并存储。
  • Retrievers:根据用户查询检索相关文档。
  • Chains:将上述组件串联为完整的问答管线。

在此基础上,你可以进一步探索以下进阶方向:

  • 多轮对话记忆:结合ConversationRetrievalChain实现带上下文的对话。
  • 多源检索:使用EnsembleRetriever融合多个检索器的结果。
  • 重排序:在检索后使用CrossEncoderReranker对结果重新排序,提升精度。
  • Agent 集成:将 RAG 作为工具集成到 LangChain Agent 中,实现更复杂的推理流程。

RAG 是一个快速发展的领域,LangChain 也在持续迭代。建议你动手运行本文的案例,然后逐步替换组件、调整参数,在实践中加深理解。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询