FEATURED · 精选文章

LangChain入门指南:从零构建大语言模型应用与RAG系统

发布时间 / 2026/8/13 23:36:34
来源 / 创域科博编辑部
栏目 / 资讯中心
LangChain入门指南:从零构建大语言模型应用与RAG系统 1. 从零开始为什么你需要LangChain如果你最近在折腾大语言模型不管是OpenAI的GPT系列还是开源的Llama、Qwen大概率会碰到一个头疼的问题这些模型本身很强大但怎么把它们真正用起来做成一个能解决实际问题的应用比如你想让模型帮你读公司内部的PDF文档并回答问题或者做一个能自动分析用户反馈并生成周报的智能助手。这时候你发现光靠调用模型的API远远不够你需要处理文档加载、文本分割、向量化存储、对话历史管理、复杂逻辑编排等一系列“脏活累活”。LangChain就是为解决这些“脏活累活”而生的。它不是另一个大模型而是一个框架一个专门用来构建基于大语言模型的应用的“脚手架”。你可以把它想象成乐高积木的基础底板而各种大模型、工具、数据源就是上面的积木块。LangChain提供了一套标准化的接口和组件让你能像搭积木一样快速、灵活地将这些模块组合成一个功能完整的AI应用。我最初接触LangChain时也被它繁杂的概念搞得有点晕——Chain、Agent、Tool、Memory、Retrieval……但真正用起来才发现它的设计思想非常清晰标准化和组合化。它把LLM应用开发中那些通用的、重复性的工作抽象成了组件你不需要每次都从零开始写文件解析、写缓存逻辑、写提示词模板。更重要的是它让你能专注于业务逻辑本身而不是陷在工程细节里。所以这篇快速入门的目标很明确不搞长篇大论的理论直接带你上手用最短的时间理解LangChain的核心概念并亲手搭建两个最实用的应用场景——一个简单的问答链和一个带检索增强的文档问答系统。你会发现原来让AI“干活”可以这么简单。2. 环境准备与核心概念扫盲2.1 快速搭建你的开发环境工欲善其事必先利其器。开始之前我们需要一个干净的Python环境。我强烈建议使用conda或venv来创建独立的虚拟环境避免包版本冲突。# 使用conda创建环境如果你安装了Anaconda或Miniconda conda create -n langchain-demo python3.10 conda activate langchain-demo # 或者使用venv python -m venv langchain-demo source langchain-demo/bin/activate # Linux/Mac # 或 .\langchain-demo\Scripts\activate # Windows接下来安装LangChain。这里有个小细节LangChain社区非常活跃核心库拆分为多个包以保持轻量。对于入门我们主要安装langchain-core核心接口、langchain标准集成组件和langchain-community第三方工具集成。pip install langchain langchain-core langchain-community为了连接大模型我们还需要安装对应模型的SDK。本文将以OpenAI的API为例因为它最通用、最稳定。你需要在 OpenAI平台 获取一个API密钥。pip install openai设置环境变量将你的API密钥安全地配置进去。不要在代码里硬编码密钥。# Linux/Mac export OPENAI_API_KEY你的-api-key-here # Windows (PowerShell) $env:OPENAI_API_KEY你的-api-key-here注意对于生产环境请使用.env文件配合python-dotenv库或使用密钥管理服务绝对不要将密钥提交到代码仓库。2.2 五分钟理解六个核心概念LangChain的概念不少但入门只需抓住最关键的六个。我用最直白的话解释一下模型 I/O (Model I/O)这是和LLM对话的“出入口”。主要包括Prompt Templates提示词模板可复用的提示词框架比如“请用{style}的风格总结以下内容{text}”。它把变量和固定结构分开方便管理和迭代。Language Models语言模型就是LLM本身比如GPT-4、Claude等。LangChain提供了统一的调用接口。Output Parsers输出解析器LLM的输出是文本但程序需要结构化的数据如JSON、列表。输出解析器帮你把非结构化的文本“翻译”成程序能懂的结构。检索 (Retrieval)让模型能访问“外部知识”的核心。当模型自身的知识不够或已过时你需要从你自己的文档、数据库里找信息喂给它。这通常涉及文档加载器从PDF、网页、数据库等地方把文档读进来。文本分割器把长文档切成模型能“消化”的小块。向量存储将文本块转换成向量一组数字并存储起来便于后续快速查找相似内容。检索器根据用户问题从向量存储里找出最相关的文本块。链 (Chains)这是LangChain的灵魂。一个链就是把多个组件模型、提示词、工具等按特定顺序组合起来完成一个更复杂的任务。比如“加载文档 - 分割 - 检索 - 生成答案”就是一个链。最简单的链是LLMChain就是一个“提示词 模型”的组合。代理 (Agents)如果说“链”是预设好的流水线那“代理”就是有自主决策能力的智能体。代理可以访问“工具”比如搜索、计算、查数据库并根据用户的目标自己决定先做什么、后做什么甚至调用哪个工具。它让AI应用从“自动化”走向了“智能化”。记忆 (Memory)让对话有“上下文”。普通的API调用是无状态的你问“我叫什么名字”它根本不知道你是谁。记忆组件负责保存和管理对话历史让模型能记住之前说过的话实现多轮对话。回调 (Callbacks)相当于应用的“日志和监控系统”。你可以通过回调在链执行的各个阶段开始、结束、出错插入自定义逻辑用于日志记录、流式输出、性能监控等对调试和优化非常有用。理解了这些我们就可以开始动手了。接下来的部分我们会把这些概念变成具体的代码。3. 第一个LangChain应用构建智能问答链让我们从一个最简单的“链”开始直观感受LangChain的工作方式。我们将创建一个根据公司名称生成宣传口号的链。3.1 初始化模型与提示词首先我们需要导入必要的模块并初始化一个LLM对象。这里我们使用OpenAI的gpt-3.5-turbo模型它性价比高响应速度快。from langchain_openai import ChatOpenAI from langchain_core.prompts import ChatPromptTemplate # 初始化聊天模型。temperature控制创造性越高答案越随机。 llm ChatOpenAI(modelgpt-3.5-turbo, temperature0.7)接下来创建一个提示词模板。注意我们使用的是ChatPromptTemplate它是为聊天模型设计的可以处理系统消息、用户消息等多种角色。# 定义一个提示词模板 prompt_template ChatPromptTemplate.from_messages([ (system, 你是一位资深的品牌营销专家。), (user, 请为一家名为{company_name}的{industry}公司构思一句朗朗上口、突出{core_value}核心价值的宣传口号。) ])这个模板里包含了三个变量company_name公司名、industry行业和core_value核心价值。我们可以用不同的值填充它生成不同的提示词。3.2 组装并运行你的第一个链现在我们把提示词模板和模型“链”起来。在LangChain中最简单的链就是LLMChain。from langchain.chains import LLMChain # 创建链 slogan_chain LLMChain(llmllm, promptprompt_template) # 运行链传入变量 result slogan_chain.invoke({ company_name: 绿源科技, industry: 新能源, core_value: 可持续创新 }) print(result[text]) # 输出模型生成的口号运行这段代码你可能会得到类似“绿动未来源创无限——绿源科技驱动可持续新纪元”这样的输出。看我们只用了几行代码就完成了一个可配置、可复用的AI小应用。实操心得temperature参数很重要。对于需要确定性答案的任务如代码生成、数据提取设为0或0.1对于需要创造性的任务如起名、写文案可以设为0.7-0.9。一开始不妨多试试不同值观察输出效果。3.3 深入解析链的调用与流式输出上面我们用了invoke方法这是同步调用。LangChain还支持异步调用ainvoke这在Web服务中非常有用。此外如果你想看到模型一个字一个字生成答案的过程即流式输出可以使用stream方法。# 异步调用 (适用于FastAPI等异步框架) # async def generate_slogan(): # result await slogan_chain.ainvoke(...) # return result # 流式输出 for chunk in slogan_chain.stream({company_name: 快达物流, industry: 物流, core_value: 极速可靠}): if text in chunk: print(chunk[text], end, flushTrue) # 逐词打印流式输出能极大提升用户体验让用户感觉响应更快。在Web应用中你可以通过Server-Sent Events (SSE) 将每个chunk实时推送给前端。4. 进阶实战打造你的专属知识库问答机器人简单的问答链只能利用模型的内置知识。但在实际工作中我们往往需要让模型回答关于特定、私有文档的问题比如公司制度、产品手册、技术文档等。这就是检索增强生成RAG的用武之地也是LangChain最强大的场景之一。4.1 RAG流程全景图一个典型的RAG应用分为“索引”和“查询”两个阶段索引阶段将你的文档库处理成模型可查询的格式。加载文档 - 分割文本 - 文本向量化 - 存入向量数据库。查询阶段回答用户问题。将用户问题向量化 - 从向量库检索相关文本片段 - 将片段和问题组合成提示词 - 发送给LLM生成答案。下面我们一步步实现它。4.2 文档加载与处理从原始文件到文本块假设我们有一个product_manual.pdf的产品手册。首先我们需要安装处理PDF的库。pip install pypdf # 一个轻量级的PDF解析库然后使用LangChain的文档加载器来读取它。from langchain_community.document_loaders import PyPDFLoader # 加载PDF文档 loader PyPDFLoader(./product_manual.pdf) documents loader.load() print(f加载了 {len(documents)} 页文档。) # 每页是一个Document对象包含page_content文本和metadata如页码。加载后的文档可能很长直接塞给LLM会超出上下文限制且包含大量无关信息。因此我们需要进行文本分割。这里使用RecursiveCharacterTextSplitter它会尝试按字符如换行、句号、空格递归地分割尽量保持语义段落完整。from langchain.text_splitter import RecursiveCharacterTextSplitter text_splitter RecursiveCharacterTextSplitter( chunk_size500, # 每个文本块的最大字符数 chunk_overlap50, # 块之间的重叠字符数避免上下文断裂 separators[\n\n, \n, 。, , , , , ] # 分割优先级 ) split_docs text_splitter.split_documents(documents) print(f文档被分割成 {len(split_docs)} 个文本块。)注意事项chunk_size没有黄金标准。太小会丢失上下文太大会降低检索精度并增加LLM成本。对于通用文档500-1000是个不错的起点。chunk_overlap设置重叠可以防止一个完整的句子被拦腰截断通常设为chunk_size的10%-20%。4.3 向量化与存储构建文档的“记忆”文本分割后我们需要将它们转换成向量即嵌入并存储到向量数据库中。这里我们使用Chroma一个轻量级、易上手的开源向量数据库。同时我们需要一个嵌入模型来生成向量。OpenAI的text-embedding-ada-002是业界标杆我们用它来演示。pip install chromadb langchain-openaifrom langchain_openai import OpenAIEmbeddings from langchain_community.vectorstores import Chroma # 初始化嵌入模型 embeddings OpenAIEmbeddings(modeltext-embedding-ada-002) # 将分割后的文档转换为向量并持久化存储到本地目录 ./chroma_db vectorstore Chroma.from_documents( documentssplit_docs, embeddingembeddings, persist_directory./chroma_db # 指定持久化目录 ) # 如果需要后续加载可以使用 Chroma(persist_directory./chroma_db, embedding_functionembeddings)这个过程可能会消耗一些时间取决于文档数量和大小。Chroma会将向量数据存储在本地下次启动应用时可以直接加载无需重新计算。4.4 组装检索链从提问到答案存储完成后我们就可以构建检索链了。LangChain提供了一个高级抽象RetrievalQA它把检索、提示、生成打包成了一个链。from langchain.chains import RetrievalQA # 从已存在的向量库创建检索器 retriever vectorstore.as_retriever( search_typesimilarity, # 相似度搜索 search_kwargs{k: 3} # 返回最相关的3个文本块 ) # 创建RetrievalQA链 qa_chain RetrievalQA.from_chain_type( llmllm, # 使用之前定义的LLM chain_typestuff, # 最常用的类型将所有检索到的文档“塞”进提示词 retrieverretriever, return_source_documentsTrue, # 返回源文档便于追溯答案来源 verboseTrue # 打印详细日志调试时非常有用 ) # 现在开始提问吧 question 这款产品的主要安全特性是什么 result qa_chain.invoke({query: question}) print(答案, result[result]) print(\n--- 来源文档 ---) for i, doc in enumerate(result[source_documents]): print(f\n片段 {i1}: {doc.page_content[:200]}...) # 打印前200字符当你运行这段代码时RetrievalQA链会执行以下操作用嵌入模型将你的问题转换成向量。在向量数据库中搜索与问题向量最相似的3个文本块。将这些文本块和你的问题一起填充到一个预设的提示词模板中。将完整的提示词发送给LLM生成最终答案。返回答案和来源文档。chain_typestuff是最直接的方式但如果检索到的文档总长度超过LLM的上下文窗口就会出错。对于超长文档可以考虑map_reduce或refine等更复杂的链类型它们会对文档进行分步处理。5. 避坑指南与效能优化在实际使用中你肯定会遇到各种问题。下面是我踩过的一些坑和总结的优化技巧。5.1 检索效果不佳可能是这里出了问题你可能会发现有时候机器人给出的答案不准确或者根本没用到你文档里的信息。别急着怪模型大概率是检索环节出了问题。问题1检索不到相关内容检查点search_kwargs{“k”: n}中的n是否太小可以尝试增加到5或10。检查点文本分割的chunk_size是否合适如果块太大一个块里包含多个不相关主题会稀释关键信息的向量表示。尝试减小chunk_size到300-400。检查点嵌入模型是否匹配不同模型生成的向量空间不同。确保索引和查询时使用同一个嵌入模型。问题2答案胡编乱造幻觉检查点提示词是否明确要求模型“基于给定上下文回答”可以在RetrievalQA中自定义prompt加入强约束例如“请严格仅根据以下上下文信息回答问题。如果上下文没有提供足够信息请直接说‘根据已知信息无法回答该问题’。上下文{context} 问题{question}”检查点开启return_source_documentsTrue并仔细核对模型生成的答案是否真的来源于你提供的片段。很多时候幻觉是因为模型自行补充了知识。问题3回答冗长或跑题调整LLM参数降低temperature如设为0.1让答案更确定、更简洁。优化提示词在系统消息中明确要求“回答应简洁、精准不超过三句话”。5.2 成本与性能优化技巧使用商业API成本是需要考虑的因素。以下是一些省钱的技巧缓存嵌入结果文档的嵌入向量一旦生成就不会变可以永久缓存。使用CacheBackedEmbeddings可以避免重复计算相同内容的嵌入大幅节省成本和时间。选择合适的模型不是所有任务都需要GPT-4。对于简单的信息提取、总结gpt-3.5-turbo完全够用且便宜一个数量级。对于嵌入text-embedding-3-small比ada-002更便宜且性能更好。限制上下文长度严格控制chunk_size和检索返回的块数k。送入LLM的令牌数越少费用越低速度也越快。异步处理对于批量处理文档或同时服务多个用户请求使用异步调用ainvoke,astream可以显著提高吞吐量。5.3 调试利器LangSmith当链变得复杂时调试会变得困难。LangChain官方推出了一个强大的平台——LangSmith。它可以可视化地追踪每一次链的调用查看每一步的输入输出精确找到问题出在哪个环节是检索没找到还是提示词没写好还是模型理解错了。虽然它是商业服务但提供了免费额度。对于学习和调试复杂应用强烈建议注册使用。只需设置几个环境变量你的所有链调用就会自动记录到LangSmith仪表盘。export LANGCHAIN_TRACING_V2true export LANGCHAIN_API_KEY你的-langsmith-api-key export LANGCHAIN_PROJECT你的项目名6. 从链到智能体探索更自主的AI掌握了链和RAG你已经能解决80%的问题。但有时候用户的需求不是一次问答就能解决的可能需要多步推理、调用外部工具如搜索、计算器、数据库。这时候就需要请出智能体Agent。智能体的核心思想是“思考-行动-观察”循环。它有一个目标一套可用的工具Tools和一个决定使用哪个工具的“大脑”通常是LLM。6.1 创建一个简单的数学计算代理让我们创建一个能使用Python解释器进行复杂数学计算的代理。from langchain.agents import create_react_agent, AgentExecutor from langchain import hub from langchain_community.tools import Tool from langchain_experimental.tools import PythonREPLTool # 1. 定义工具 python_repl_tool PythonREPLTool() # 一个安全的Python代码执行工具 # 可以将多个工具包装在一起 tools [ Tool( namePython_REPL, funcpython_repl_tool.run, description用于执行数学计算或数据操作的Python代码解释器。输入必须是有效的Python代码。 ) ] # 2. 从LangChain Hub拉取一个高效的提示词模板ReAct格式 prompt hub.pull(hwchase17/react) # 3. 创建智能体 agent create_react_agent(llm, tools, prompt) # 4. 创建代理执行器 agent_executor AgentExecutor(agentagent, toolstools, verboseTrue, handle_parsing_errorsTrue) # 5. 运行代理 result agent_executor.invoke({ input: 请计算圆周率π的平方根并求出其结果与自然常数e的差值。 }) print(result[output])运行这段代码你会看到verboseTrue模式下代理详细的思考过程Thought: 我需要计算π的平方根和e的值然后求差。这需要数学计算我应该使用Python_REPL工具。Action: 调用Python_REPL工具输入代码import math; sqrt_pi math.sqrt(math.pi); diff sqrt_pi - math.e; print(diff)。Observation: 工具执行后返回的结果一个数字。Thought: 我得到了计算结果现在可以给出最终答案了。Final Answer: 输出最终答案。6.2 代理与链的核心区别通过这个例子你可以清晰感受到链和代理的区别链是确定性的流程。你预先定义好步骤检索-生成它就会按部就班执行。适合流程固定、目标明确的任务。代理是目标导向的决策者。你只告诉它目标“解这个数学题”并提供工具。它自己规划步骤、选择工具、执行并迭代直到达成目标。适合需要多步推理、条件判断或工具调用的复杂任务。选择使用链还是代理取决于你的应用场景是否需要这种自主规划和工具使用的能力。对于大多数文档问答、内容生成、数据提取任务链已经足够。当你需要AI与外部世界动态交互时代理才是更好的选择。7. 常见问题与解决方案速查在学习和项目开发中以下是我被问得最多的一些问题Q1: LangChain和LangGraph、LlamaIndex有什么区别LangChain是一个全面的应用构建框架提供了模型I/O、检索、链、代理、记忆等全套组件强调灵活组合。LangGraph是LangChain团队推出的一个库用于构建有状态、多参与者的复杂工作流。它用图Graph的概念来编排多个链或代理特别适合需要循环、分支、并行等复杂控制流的场景。你可以理解为LangChain是乐高积木LangGraph是拼装复杂乐高模型的说明书。LlamaIndex更专注于数据索引和检索这一环节在RAG的数据连接、索引结构、高级检索策略上做得非常深入。它常与LangChain结合使用用LlamaIndex做强大的数据层用LangChain做应用编排层。Q2: 我的提示词怎么写效果都不好怎么办提示词工程是门实践科学。除了遵循清晰、具体、提供示例等基本原则外一个实用的技巧是使用Few-Shot示例。在提示词模板中提供一两个输入输出的例子能极大地引导模型理解你的格式和意图要求。LangChain的FewShotPromptTemplate可以方便地实现这一点。Q3: 向量检索速度慢怎么优化首先确保你的向量数据库支持索引如Chroma的HNSW。其次可以考虑量化使用更短的向量如从1536维降到768维牺牲极少精度换取速度和存储空间。预过滤在向量检索前先用元数据如文档类型、日期过滤掉大量不相关文档缩小搜索范围。升级硬件向量检索是计算密集型CPU优化或使用GPU能大幅提升速度。Q4: 如何将LangChain应用部署为API服务最常用的方式是结合FastAPI。将你的链或代理封装成FastAPI的端点。注意处理好异步调用、请求超时、错误处理和API密钥管理。对于生产环境还需要考虑限流、监控和日志。from fastapi import FastAPI from pydantic import BaseModel app FastAPI() # ... 初始化你的qa_chain ... class QueryRequest(BaseModel): question: str app.post(/ask) async def ask_question(request: QueryRequest): result await qa_chain.ainvoke({query: request.question}) return {answer: result[result]}Q5: 代码里出现LangChainDeprecationWarning怎么办LangChain更新很快API常有变动。警告信息通常会告诉你应该改用哪个新方法。务必查看警告指向的文档链接。保持依赖包更新到较新版本并定期检查官方迁移指南是避免兼容性问题的最好方法。走到这里你已经掌握了LangChain最核心的部件和思想。从定义一个简单的提示词链到构建一个能理解私有知识的RAG系统再到创建一个能自主使用工具的智能体这套工具链极大地降低了LLM应用开发的门槛。我个人的体会是初期不要追求大而全从一个明确的小需求切入用最简单的链实现它看到效果后再逐步迭代、增加复杂度。遇到问题多查官方文档现在中文社区资料也越来越丰富多在实践中调试。记住LangChain是帮你提效的脚手架而不是束缚你的枷锁当你熟悉了它的模式后完全可以按自己的业务需求灵活定制和扩展。
RELATED — 相关阅读

相关资讯

LATEST — 最新资讯

最新发布

TODAY — 本日精选

新闻

WEEKLY — 本周精选

新闻

MONTHLY — 本月精选

新闻