资讯动态

LangChain从零到实战:核心组件、LCEL与Agent编排指南

发布时间:2026/10/27 16:49:51 来源:尧图企业网站定制
提到 LangChain不少同学的第一反应是“又一个大模型套壳框架”。但如果你真的用一段时间就会发现它更像是一个“乐高积木箱”专门用来把大模型、提示词、外部数据和各类工具拼装成真正可用的应用。这半年来我从只会调 API 的“调用工”到能独立搭建带记忆、能联网查资料、会调用工具的多智能体 Demo全靠一点点啃 LangChain 的源码和官方文档。这系列笔记的第一篇我想认认真真聊聊“从零认识 LangChain”——它到底是什么、核心组件有哪些、第一次写代码该走哪条路以及网上那些“LangChain vs Dify vs CrewAI”的争论到底该怎么看。这篇不堆概念只看实际能落地的部分适合刚入门、想搞清 LangChain 定位的同学慢慢看。1. 项目概述LangChain 到底是什么1.1 大模型时代的“胶水层”与编排器LangChain 这个词拆开看是 Lang Chain官方定位是“使用大语言模型构建应用的框架”。我最初的理解是它把大模型LLM包装成可以随意组合的单元让你用一组“链”把提示词、模型、外部数据、工具串起来。但用得深了以后我更愿意把它称作“LLM 应用开发的编排与胶水层”大模型是发动机LangChain 是变速箱和仪表盘——它定义了各类组件之间如何协作、如何流转数据、如何被复用让你不太需要关心底层是 OpenAI 还是本地开源模型。这背后对应的是一个很实际的痛点单个 LLM 调用其实是“无状态、纯文本到纯文本”的映射但现实应用需要复杂流程比如先查数据库、再拼提示词、再调模型、最后格式化输出或者多轮对话时需要记住上下文或者需要决策走哪条分支。用原生代码来做每个项目都要写一套重复逻辑维护成本极高。LangChain 的价值就在这里它把“链式调用状态管理工具调用”这些高频模式抽象成通用组件替你把脏活累活扛了开发者的精力只需投入到真正的业务逻辑上。这个定位对初学者特别重要。因为当你看到网上各种“LangChain 死了”“LangChain 太抽象”的吐槽时如果先清楚它本质是胶水层和编排器就能明白——吐槽者多半是在批评它的 API 演进速度和学习曲线而不是质疑“应用构建需要编排抽象”这件事本身。这也是我写下整个系列笔记的出发点先理解它是什么、解决什么问题再去学怎么用才能不被版本变化的噪声带偏。1.2 它能解决什么问题适合哪些人学习从实际应用场景来说LangChain 最容易帮上忙的是三类事情一是做知识库问答RAG把文档切块、向量化、检索再配合大模型出具回答二是做带工具的智能体比如让模型决定“要不要查天气/要不要调计算器/要不要访问内网文档”从而完成单次 LLM 调用做不到的复合任务三是做业务流的可视化编排把多个模型调用组合成一条流水线支持分支、合并、并行。我的感受是如果你只是想快速调一下大模型的 API 做个小工具直接用 OpenAI SDK 就够了LangChain 属于“锦上添花”但如果你要构建一个稍具规模的应用比如包含数据流转、多轮对话、工具调用、日志追踪的完整服务那 LangChain 的抽象便能让代码结构清晰不少。它最适合的人群有三类正在做 LLM 应用落地的后端开发者、想系统学习智能体编排的 AI 应用工程师以及准备用 Agent 类框架做产品原型的技术决策者。这篇文章虽然是“从零认识”, 但我会尽量带实操视角即便完全没接触过 LangChain 也能跟着步骤走。2. 核心组件与设计思路拆解2.1 六大核心抽象Model、Prompt、Chain、Memory、Agent、IndexesLangChain 最迷人的地方在于它用非常少的几个抽象就覆盖了 LLM 应用背后几乎所有的高频模式。我总结下来核心组件可以分成六类模型Model、提示词Prompt模板、链Chain、记忆Memory、智能体Agent以及索引/向量库Indexes。模型是最底层的引擎LangChain 通过统一接口兼容 OpenAI、Anthropic、百度文心、本地 Ollama 等好处是你写业务代码时可以少关注具体模型厂商的 SDK 差异。提示词模板解决的是“动态拼字符串”的痛点它定义了一个带变量的模板运行时再填充具体内容避免在业务代码里手动拼接 Prompts。链则是串联模型和提示词的最小执行单元比如经典的“提示词 模型 输出解析”就是一个最简链。这也是后来 LangChain 力推 LCELLangChain Expression Language的原因用|符号像 Unix 管道一样把组件串起来直观且天然支持流转和并行。记忆模块用于多轮对话场景存储历史消息并在下一步生成时注入上下文。智能体则让模型具备“决策能力”——它根据用户问题判断该调用哪个工具拿到工具返回值后再决定下一步动作。索引/向量库是 RAG 的基础负责文档加载、切分、向量化并存入向量数据库如 Chroma、FAISS、Pinecone检索时把最相关的片段取出来作为上下文。这六大抽象并不是割裂的它们会在一个应用中协同出现索引提供外部知识提示词把它组织成模型能理解的语言模型生成结果链控制流程流转记忆保留上下文智能体决定是否调用额外工具。把这套骨架先记住后面学任何模块都会觉得有地图可循。2.2 设计逻辑为什么是“链”而不是普通函数封装如果只是“按顺序调用”几个函数那不叫框架写个 Python 脚本也能做。LangChain 之所以把“链”作为一等公民是因为 LLM 应用的执行流往往不是纯线性的有时需要并行处理多个独立任务有时需要根据中间结果动态跳转有时还要嵌入重试、回退、流式输出等逻辑。如果这些都用普通函数硬编码业务代码很快就会被各种控制流淹没。链的设计其实借鉴了 Unix 哲学中的“管道”每个组件实现统一的输入输出协议上一个组件的输出自动成为下一个组件的输入组件的组合方式因此变得非常灵活。LangChain 的 Runnable 协议包含invoke、stream、batch等方法就是这一思想的现代实现它让“链”可以像乐高积木一样被自由拼装、嵌套与并行化。这背后的另一个考量是稳定性与可观测性。把各个步骤抽象成链以后你可以在每个环节插入日志、追踪 token 消耗、设置超时与重试这对生产级应用非常重要。我自己踩过不少“全链路一个函数”的坑——上线前跑得通一旦某段 API 超时或返回非预期格式排查起来非常痛苦。使用链模式之后日志能清楚标出是哪一步“断了”定位问题的时间能少一半。2.3 从旧版到 LCEL现代 LangChain 的核心变化LangChain 过去两年的版本演进堪称剧烈如果你翻到两年前的教程会看到大量LLMChain(prompt..., llm...)的用法而现在官方推荐的是 LCEL 写法直接prompt | llm | output_parser串成一条可执行链。这个变化很关键因为旧版把“链”搞成了一系列难以组合的类而新版用统一的 Runnable 协议让组合、流式、异步都变成内建能力。举个例子在旧版里你想让模型流式输出文本通常得特意去调用llm.stream()但同一个链换到另一个模型厂商流式支持还得单独适配。LCEL 出现以后任何 Runnable 都天然支持.stream()、.invoke()、.batch()不用关心内部实现细节。对于初学者我强烈建议直接学新版 LCEL因为这是 LangChain 所有新功能和教程的基础未来生态也会围绕它扩展。那旧版代码还有必要了解吗说实话偶尔用到老项目维护时还是需要的。但如果你是新项目直接跳过旧 API能在长期上省掉非常多的“改接口”痛苦。我的建议是遇到教程里还在教LLMChain的谨慎参考优先看官方文档中带“Runnable”或“LCEL”字样的章节。3. 从零开始的实操入门3.1 环境准备与依赖安装不管是什么阶段的 LangChain 学习第一步都离不开环境搭建。我个人习惯用 Python 3.10 版本跑 LangChain 生态最省心推荐新建一个虚拟环境避免和系统 Python 打架。核心依赖就两个langchain和对应模型的适配包比如langchain-openai或langchain-anthropic。如果你只想先跑通最小 Demo装这两个就够了。python -m venv .venv source .venv/bin/activate # Windows 用 .venv\Scripts\activate pip install langchain langchain-openai这里有个细节很多人会忽略LangChain 本身是“内核”而不同模型厂商的适配包是独立的。这意味着以后新增模型厂商时不必把整个框架重装一遍只需要单独装对应适配包即可。比如你用本地 Ollama就多装一个langchain-ollama用智谱就装langchain-zhipuai。这种“内核与集成分离”的架构既是 LangChain 生态迅速扩大的原因也是初学者容易困惑的地方——看到教程里装了一堆包时先分清哪些是框架、哪些是模型适配包会清晰很多。3.2 使用 LCEL 构建第一条链安装完成后进入第一个 Demo用 LCEL 构建一条“翻译小助手”链。这个过程会涉及三个核心组件提示词模板、ChatModel 和字符串输出解析器。我用的是langchain-openai中的ChatOpenAI如果你没有 OpenAI 密钥可以换成任何你手头可用的模型但 API 调用参数要以适配包为准。from langchain_openai import ChatOpenAI from langchain_core.prompts import ChatPromptTemplate from langchain_core.output_parsers import StrOutputParser # 1. 定义提示词模板 prompt ChatPromptTemplate.from_messages([ (system, 你是一个专业翻译请把用户输入翻译成英文。), (user, {input}) ]) # 2. 初始化模型这里建议把 temperature 调低一点翻译任务需要确定性 model ChatOpenAI(modelgpt-4o-mini, temperature0.2) # 3. 用一个最简输出解析器保证拿到的是纯字符串 output_parser StrOutputParser() # 4. 用 LCEL 管道符串联起来 chain prompt | model | output_parser # 5. 调用链 result chain.invoke({input: 我爱编程尤其是写能自动处理麻烦事的代码。}) print(result)跑完的预期结果大致是 “I love programming, especially writing code that automates tedious things.”。注意chain.invoke传入的是一个字典它对应提示词模板里定义的{input}变量这个机制就是前面提到的“模板运行时填充”的体现。这条链虽然只有短短几行但背后已经包含了“格式化提示词→调用模型→解析输出”的完整流程。如果你对运行过程好奇可以在链的中间加入.with_config({run_name: translation_chain})LangChain 会自动记录每个步骤的输入输出在 LangSmith 之类的调试工具里一目了然。初学者先不要管太多高级特性先把这条最小链跑通再逐步增加模块你会更容易理解每一步在业务中的价值。3.3 用结构化输出连接真实程序字符串输出对展示来说足够但要对接真实业务系统通常需要模型返回结构化数据如 JSON。LangChain 提供了with_structured_output()方法配合 Pydantic 类可以非常方便地拿到校验过的结构化结果。这一步对“从零认识”阶段的同学可能稍显进阶但我还是建议尽早接触因为它能立刻让 LangChain 从“玩具”变成“生产工具”。from typing import Literal from langchain_core.pydantic_v1 import BaseModel, Field class TranslationResult(BaseModel): translated_text: str Field(description翻译后的文本) tone: Literal[formal, casual] Field(description语气风格) confidence: float Field(description置信度0-1之间) structured_model model.with_structured_output(TranslationResult) structured_chain prompt | structured_model res structured_chain.invoke({input: 帮我翻译今天天气不错适合出门散步。}) print(res.translated_text, res.tone, res.confidence)这里with_structured_output做的事情是把 Pydantic 类的 schema 传给模型让模型按 schema 生成 JSON 并自动完成类型校验。如果模型返回的格式不符合定义框架会直接抛错避免你在下游代码里手写一堆“字段存在性”判断。这种模式在写 API 接口、数据入库、多智能体协作等场景中特别实用。我印象最深的是一个内部知识库问答项目早期直接让模型吐 JSON但模型偶尔会多出或遗漏字段导致下游解析崩溃。换成with_structured_output后这类问题基本消失代码量还减少了一大截。可以说学会结构化输出之后你才真正体会到 LangChain “把模型变成可靠函数”的设计野心。3.4 给链加记忆从无状态到多轮对话第一版链是无状态的你问它“我爱编程”它不会记得上一句。要实现多轮对话就需要引入 Memory记忆机制。LangChain 新版推荐的做法是把聊天历史显式传入提示词模板比如把消息数组构建成System History 当前输入的形式而不是用旧版自动 Memory 类后者内部隐式管理状态在并发场景下容易串戏。from langchain_core.messages import SystemMessage, HumanMessage, AIMessage history [ SystemMessage(content你是一个贴心的助理。), HumanMessage(content我叫小明。), AIMessage(content你好小明很高兴认识你), ] # 再次调用时直接把历史消息和当前问题拼接 messages history [HumanMessage(content我叫什么名字)] response model.invoke(messages) print(response.content)把“显式传历史”和“无状态链”结合起来是我目前觉得工程上最稳妥的记忆方案——每个请求都带上完整上下文天然适合无状态部署、水平扩展和调试。LangChain 社区也提供了很多记忆封装类但我的体会是小项目可以用封装类图省事稍大一点的项目最好还是自己组装消息列表做到“可见即可控”。4. 工具调用与智能体初体验4.1 给模型装“手”定义工具与 Tool 接口LangChain 的智能体能力很大程度上源自“让模型调用工具”这件事。想要让模型调用工具你首先得定义工具。LangChain 里最简洁的方式是把一个普通的 Python 函数加上tool装饰器让它变成模型可感知的工具。from langchain_core.tools import tool tool def get_weather(city: str) - str: 查询指定城市的天气返回温度与风力描述。 # 正常情况下这里应接入真实天气 API if city 北京: return 多云20°C微风 return f{city}晴24°C南风3级 tools [get_weather]对初学者来说这里的要点有两个一是函数的 docstring 会被当作工具描述传给模型模型靠它判断“什么情况该调用这个工具”所以描述要写清楚用途二是函数签名里的参数名和类型很重要模型会按照这些 schema 来填充参数值。我经常把这个过程类比为教实习生你得告诉他“在什么情况下用什么工具、工具需要哪些材料、会得到什么结果”他才能靠谱地干活。4.2 从“工具列表”到“Agent”理解 ReAct 循环有了工具之后怎么让模型自主决定是否调用答案是通过 Agent智能体的 ReAct 循环。ReAct 的思路是模型先思考Reason决定要调哪个工具Action观察工具返回值Observation再思考下一步直到得出最终答案。LangChain 中创建 Agent 的常见写法是使用create_tool_calling_agent针对支持工具调用的模型或create_react_agent通用 ReAct 风格。以最简单的 ReAct 为例你需要准备三样东西模型、工具列表和一个提示词模板模板里定义好 “Question/Thought/Action/Observation” 的格式。from langchain.agents import create_react_agent, AgentExecutor from langchain_core.prompts import PromptTemplate agent_prompt PromptTemplate.from_template( 你可以使用工具来回答问题。 工具列表: {tools} 工具名称: {tool_names} 请按以下格式输出: Thought: 你当前的想法 Action: 要使用的工具名称如果无需工具则写 None Action Input: 工具的输入参数 Observation: 工具返回的结果 ...循环... Final Answer: 最终答案 用户问题: {input} {agent_scratchpad} ) agent create_react_agent(model, tools, agent_prompt) executor AgentExecutor(agentagent, toolstools, verboseTrue) res executor.invoke({input: 北京今天适合穿短袖吗}) print(res[output])agent_scratchpad是 LangChain 自动填充的中间思考记录它会存放模型之前的 Thought/Action/Observation 历史保证多轮推理时上下文不丢失。运行上面的代码你会看到模型输出Thought思考先查天气、Actionget_weather、Action Input北京、Observation多云 20°C、最终判断“建议穿薄外套”。如果把verboseTrue打开运行日志会显示出完整的“思考-行动-观察-答”轨迹这个过程很上瘾——你会觉得模型真的有在“想事情”。4.3 多工具协作与 Agent 决策的艺术真实业务中的 Agent 通常不止一个工具。当工具多起来以后模型的“决策质量”就成了关键。我常用的技巧是尽量让工具职责单一、描述清晰并在描述里加上“何时使用、何时不要使用”的边界。例如get_weather可以写成“仅当用户询问天气时使用不要用于推荐穿搭”。多工具协作时LangChain 会依据模型厂商的工具调用能力来决定是并行还是串行调用。比如 OpenAI 的 function calling 支持一次请求返回多个工具调用LangChain 会在底层解析成多个 ToolMessage 然后再次交给模型。如果你要用本地小模型通常不支持并行工具调用只能靠 ReAct 一步一步来。这也是框架对比中常被忽略的一点不是所有模型都能发挥 Agent 的全部能力选型时要考虑底层模型对工具调用的原生支持度。我自己做过的多工具 Demo 是一个“旅行小助手”它拥有查天气、查汇率、查新闻、生成行程清单四个工具用户只需要用一句话描述需求它会自动安排调用顺序。整个过程跑通后非常有成就感而且代码复用率很高——往工具列表里再塞一个新函数Agent 就能“解锁”一项新技能。5. 生态比较与选型建议LangChain、Dify、CrewAI 怎么选5.1 三类框架的定位差异网上高频出现的对比是“LangChain、Dify、CrewAI 哪个好”我在实际跟项目后得出的结论是这三个框架根本不在同一维度上硬比“哪家强”没有意义关键是弄清楚各自的定位。LangChain 本质是一个开发框架/工具库面向的是会写代码的开发者。它灵活度高能深度定制各类链和智能体逻辑但需要你自己处理部署、前端、数据库等周边系统。Dify 则更像一个 LLM 应用平台/产品它提供可视化工作流编排、内置知识库管理、API 发布管理等能力甚至面向不太写代码的运营和产品人员。CrewAI 专注于多智能体协作强调“角色扮演式的团队”——你定义不同 Agent 的角色、目标和任务让它们像同事一样协同完成复杂工作。从技术角度出发三者可以结合使用用 LangChain 写核心逻辑用 Dify 做产品化界面用 CrewAI 管团队分工。5.2 按项目阶段选择原型期、生产期、团队协作期选型不能只看技术还要看项目阶段和团队构成。我建议按这样来评估如果你在做一个创新原型需要快速验证“这个 Agent 逻辑能否跑通”LangChain 是最佳选择因为它即插即用、组件丰富写代码少但开放度高。如果你已经确定要做成一个面向用户的产品需要管理后台、可视化调试、数据标注、审核流等能力Dify 这类平台能让你免掉很多基础设施工作尤其是在非技术成员也要参与维护的场景下。如果是复杂任务拆解比如“写一份行业研究报告”需要让多个 Agent 分别做资料搜集、数据分析和文案撰写CrewAI 的团队编排效率会更直观。另外要留意成本和锁定效应。用 Dify 这类平台很多逻辑在界面上配置但一旦要做超出平台能力的定制反而更麻烦。用 LangChain代码可控性高但迭代速度依赖你的工程能力。结合我自己的项目经验我现在的标准姿态是小 Demo 和中期项目用 LangChain 快速搭骨架做内部工具或客户产品时后端核心逻辑可以保留 LangChain前端管理界面考虑其他可视化层多角色协作的复杂 Agent 系统才引入 CrewAI 做上层协调。换句话说LangChain 是“地基”其他框架可以理解成“装修公司”它们并不互斥。5.3 避免框架锁定的实用心法框架迭代速度是 LangChain 被诟病最多的点这一风险确实存在。我在文章前面也提到LangChain 的 API 变化相当快如果你把所有业务代码深度绑定到 LangChain 的类上一旦升级大版本可能要重构不少代码。我的经验是建立一个薄薄的门面层把业务代码与框架代码隔离开来。简单来说就是在自己的项目里写一个llm_client.py封装所有模型调用、链构建、智能体创建逻辑业务层只依赖这个门面暴露的几个函数。这样做的好处是即使以后要换掉 LangChain 或者迁移到别的框架你只需要改门面层一个文件而不至于把整个业务逻辑重写。我在一个客服机器人项目中实践过这种方式后来因为模型商优惠政策变动需要更换供应商只改了不到一百行代码就完成了切换团队同事都直呼“这层抽象值回票价”。6. 常见问题与排查技巧实录6.1 运行时报错频繁的几种原因LangChain 版本的频繁迭代加上不同模型适配包的差异初学者在跑代码时几乎都会遇到报错。我把最常遇到的几类问题整理成了速查表方便你对照排查报错现象常见原因解决思路AttributeError: ChatOpenAI object has no attribute ...旧教程代码与新版本 API 不匹配检查 LangChain 版本改用新版属性调用方式ModuleNotFoundError: langchain.llms模型适配包拆分后路径变了从langchain_openai等独立包导入模型类KeyError: input或变量填充失败提示词模板里的变量名和 invoke 传入字典不一致核对模板变量名与字典键名是否完全一致输出解析失败、JSON 格式错误模型返回内容不符合结构化输出 schema使用with_structured_output并配 Pydantic 校验工具调用不触发模型不支持原生 function calling或工具描述不够清晰换用 ReAct Agent 或优化工具描述流式输出无法正常工作LCEL 链中包含不支持 stream 的组件确认所有组件都实现 Runnable 协议经验告诉我遇到报错先看版本号。LangChain 的__version__几乎每隔几周就会变一旦你在一个项目里锁了版本其他项目升级时很可能“殃及池鱼”。建议在项目里用 requirements.txt 或 pyproject.toml 严格固定版本方便复现。6.2 如何高效阅读官方文档与源码LangChain 官方文档的入口非常多初学者最常用的是概念Concepts和教程Tutorials两个板块。我的经验是先快速浏览一遍核心概念再对照教程动手敲代码遇到不理解的组件就去源码里搜定义。源码阅读这条路非常值因为 LangChain 的组件大多是薄封装源码注释也相对清晰直接看Runnable、BasePromptTemplate、BaseChatModel这些基类的实现会帮你省下大量试错时间。6.3 调试利器Verbose、LangSmith 与 tracing调试 Agent 应用时最痛苦的地方在于“模型心里怎么想的”你看不到。这时候首要工具就是把 AgentExecutor 或链的verboseTrue打开它会打印模型每一步的思考、行动和观察记录。另一个更强的手段是接入 LangSmith它是 LangChain 官方可观测性平台开启 tracing 后你会看到一次请求内部的完整调用树包括每次 LLM 调用的输入输出、工具响应、耗时和 token 数。我之前排查一个“Agent 在特定问题下陷入死循环”的 bug靠的就是 LangSmith 的 trace模型反复调用同一个工具但忽略返回结果原来是工具返回值里缺少明确的“终止信号”。修改工具返回内容和提示词边界后死循环自然消失。这类问题如果没有 trace 数据靠猜几乎不可能定位。对初学者我建议把LANGCHAIN_TRACING_V2true和LANGCHAIN_API_KEY配好一开始就养成观测的习惯。6.4 学习路径建议不要一上来就啃 Agent最后聊聊学习路径。我发现很多初学者犯同一个错一上来就搞 Agent、搞 ReAct结果被各种抽象绕晕。更稳的路径是先掌握 Prompt 模板和 Model 调用再用 LCEL 做一条包含输出解析和记忆的链最后才进入 Agent 和工具调用。每一步都把前面的基础吃透再往上叠加。拿我做类比一切复杂应用都是“提示词—链—智能体”三种层次的组合提示词是沟通的语言链是把语言组织成流程智能体是让流程自动决策。把这个层级想清楚LangChain 就会变成一张随手能画出的地图而不是一团乱麻。LangChain 的最佳学习方式永远是手写代码而不是收藏教程。你可以拿它做一个小项目比如个人知识库问答助手、邮件自动分类器或旅行规划师从最小功能开始迭代。框架本身只是工具它背后的设计思想才是真正能在 LLM 应用开发中持续受用的财富。这篇笔记只是系列的第一篇后续我会继续拆解 RAG 落地的完整流程、各种记忆方案在实战中的取舍以及自建 Agent 的踩坑复盘。如果你在跟着实操时遇到什么奇葩报错欢迎留言探讨我会尽量把自己验证过的解法拎出来分享。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑