LangChain 从入门到实践:用最小案例理解 RAG 的 5 个核心抽象

LangChain 从入门到实践:用最小案例理解 RAG 的 5 个核心抽象 1. 引言RAGRetrieval-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 Keyimport os os.environ[OPENAI_API_KEY] your-api-key-here3. 核心抽象一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 或网页场景可以使用PyPDFLoader或WebBaseLoaderfrom 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_size500, # 每个 chunk 的最大字符数 chunk_overlap50, # 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(modeltext-embedding-3-small) vectorstore Chroma.from_documents( documentschunks, embeddingembeddings, persist_directory./chroma_db # 持久化存储路径 ) print(向量存储构建完成共包含, vectorstore._collection.count(), 个向量)嵌入模型将文本映射到高维语义空间语义相近的文本在向量空间中距离更近。这是后续检索的基础。6. 核心抽象四Retrievers检索器Retriever 是 RAG 管线的查询接口。当用户提出一个问题时Retriever 从 Vector Store 中检索出最相关的文档片段作为上下文提供给大模型。最简单的用法是将 Vector Store 直接转换为 Retrieverretriever vectorstore.as_retriever( search_typesimilarity, # 相似度检索 search_kwargs{k: 3} # 返回最相关的 3 个 chunk ) 测试检索 query 什么是 RAG results retriever.invoke(query) for i, doc in enumerate(results): print(f结果 {i1}: {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(modelgpt-4o-mini, temperature0) qa_chain RetrievalQA.from_chain_type( llmllm, chain_typestuff, # 将所有检索结果拼接后一次性送入 LLM retrieverretriever, return_source_documentsTrue # 返回检索到的原始文档便于调试 ) 提问 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参数控制检索结果如何送入 LLMstuff将所有文档拼接后一次性送入适合文档量少的情况。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_size500, chunk_overlap50) 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(modelgpt-4o-mini, temperature0) qa_chain RetrievalQA.from_chain_type(llmllm, retrieverretriever) 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 也在持续迭代。建议你动手运行本文的案例然后逐步替换组件、调整参数在实践中加深理解。