掘金 人工智能 07月22日 10:28
深入浅出LangChain AI Agent智能体开发教程(三)—LangChain核心概念“链”
index_new5.html
../../../zaker_core/zaker_tpl_static/wap/tpl_guoji1.html

 

本文深入浅出地讲解了LangChain的核心概念——“链”(Chain)的搭建与应用。通过由易到难的示例,包括简单链、带提示词模板的链、结构化解析链以及复合链,详细展示了如何利用LangChain Expression Language (LCEL) 的管道符“|”将模型、提示词模板、输出解析器等组件串联起来,构建高效的AI Agent。文章还介绍了如何自定义组件以及LCEL的设计理念和核心组成,为读者快速掌握LangChain开发奠定了基础。

💡 **LangChain链式调用架构**:LangChain的核心思想在于“链”,即将大模型、工具等组件按照特定逻辑顺序组合成流水线。这种链式调用是LangChain三层核心架构中工作流API抽象层的重要组成部分,通过“|”符号连接不同组件,实现模块化和流程化。

🔧 **链的搭建与组件应用**:文章通过代码实战演示了如何搭建基础链(如连接模型和字符串输出解析器),以及如何集成提示词模板(如ChatPromptTemplate)和各种结构化解析器(如BooleanOutputParser、StructuredOutputParser)来处理模型输出。这些解析器能够将模型输出转换为布尔值、JSON等结构化数据,极大地提高了数据处理的效率和准确性。

🔗 **复合链与自定义组件**:LangChain支持将已有的链作为组件嵌套到新的链中,形成复杂的复合链,例如先生成新闻内容再提取摘要。此外,LangChain还提供了自定义组件的功能(如使用RunnableLambda将Python函数转换为可运行节点),允许开发者根据需求扩展框架能力,增加了灵活性。

🚀 **LCEL的表达范式**:LangChain Expression Language (LCEL) 是LangChain专为大语言模型应用开发设计的表达语言,它采用“函数式管道风格”将提示词模板、语言模型、输出解析器等组件组合起来。LCEL通过“|”符号清晰地呈现数据流路径,支持.invoke()、.stream()、.batch()等统一的运行接口,并强调组件的模块化和职责分离,使得模型调用流程更易于构建、管理和维护。

📈 **实战与未来展望**:通过对简单链、复合链、自定义节点链的实战操作,以及对LCEL核心概念的阐述,读者能够初步掌握搭建LangChain智能体的核心技巧。文章预告了下一期将通过全栈项目展示LangChain在多轮对话网站开发中的应用,展现了LangChain在AI Agent开发领域的强大潜力和实用性。

前言

本系列分享前两期分别讲述了

本期分享我们一起来学习LangChain最核心思想——搭建Chains,也就是所谓链式调用的核心方法。顾名思义,LangChain之所以被称为LangChain,其核心概念就是Chain。只要掌握了Chain的搭建方法,我们就掌握了LangChain搭建智能体的核心技巧。

本系列分享是笔者结合自己学习工作中使用LangChain&LangGraph经验倾心编写的,力求帮助大家体系化快速掌握LangChain&LangGraph AI Agent智能体开发的技能!大家感兴趣可以关注笔者掘金账号和系列专栏。更可关注笔者同名微信公众号: 大模型真好玩, 每期分享涉及的代码均可在公众号私信: LangChain智能体开发获得。

一、LangChain链式调用架构

链式调用位于LangChain三层核心架构中的中间层——工作流API抽象层。Chain翻译成中文就是“链”,我们将大模型、相关工具等作为组件,链就是负责将这些组件按照某一种逻辑,顺序组合成一个流水线的方式。比如我们要构建一个简单的问答链,就需要把大模型组件和标准输出组件用链串联起来。下面笔者将通过由易到难的示例向大家介绍常用的链式调用模式:

二、LangChain链搭建代码实战

2.1 尝试搭建一个简单链

第一个示例先尝试搭建一个简单链,将模型“输出结果”过滤为一个纯字符串格式:

from langchain.chat_models import init_chat_modelfrom langchain_core.output_parsers import StrOutputParser # 导入标准输出组件model = init_chat_model(    model="Qwen/Qwen3-8B",    model_provider="openai",    base_url="https://api.siliconflow.cn/v1/",    api_key="", #你注册的硅基流动api_key)# 搭建链条,把model和字符串输出解析器组件连接在一起basic_qa_chain = model | StrOutputParser()# 查看输出结果question = "你好,请你介绍一下你自己。"result = basic_qa_chain.invoke(question)print(result)

上图是以上代码执行结果,可以看到此时的result不再是包含模型各种调用信息的AIMessage对象,而是纯粹的模型响应的字符串结果。这里用到的StrOutputParser()实际上就是用于构成LangChain中一个链条的一个对象,其核心功能是用于处理模型输出结果。同时我们也发现LangChain中搭建链的方法十分简单,只需将不同组件通过|符号串联即可。

2.2 加入提示词模板创建链

接下来尝试为简单的链流程增加一个提示词模板,可以借助ChatPromptTemplate非常便捷的将一个提示词模板打造为组件,同样以链的形式加入当前流程中:

from langchain.chat_models import init_chat_modelfrom langchain.prompts import ChatPromptTemplatefrom langchain_core.output_parsers import StrOutputParsermodel = init_chat_model(    model="Qwen/Qwen3-8B",    model_provider="openai",    base_url="https://api.siliconflow.cn/v1/",    api_key="", #你注册硅基流动api_key)prompt_template = ChatPromptTemplate([    ("system", "你是一个乐意助人的助手,请根据用户的问题给出回答"),    ("user", "这是用户的问题: {topic}, 请用 yes 或 no 来回答")])# 直接使用模型 + 输出解析器bool_qa_chain = prompt_template | model | StrOutputParser()# 测试question = "请问 1 + 1 是否 大于 2?"result = bool_qa_chain.invoke({'topic':question})print(result)

当我们调用指令跟随能力较强的大模型时,借助提示词模板即可实现相应的结构化输出。

2.3 结构化解析器

LangChain中一个基础的链一般由如下三部分构成,分别是提示词模板大模型结构化解析器。智能体开发人员通过提示词让大模型输出结构化的字符串,然后通过结构化解析器将字符串解析为指定对象。流程如下:

我们上文使用的StrOutputParser仅仅是一种最简单的结构化解析器,LangChain中常用的核心结构化解析器功能如下:

解析器名称功能描述类型
BooleanOutputParser将LLM输出解析为布尔值基础类型解析
DatetimeOutputParser将LLM输出解析为日期时间基础类型解析
EnumOutputParser解析输出为预定义枚举值之一基础类型解析
RegexParser使用正则表达式解析LLM输出模式匹配解析
RegexDictParser使用正则表达式将输出解析为字典模式匹配解析
StructuredOutputParser将LLM输出解析为结构化格式结构化解析
YamlOutputParser使用Pydantic模型解析YAML输出结构化解析
PandasDataFrameOutputParser使用Pandas DataFrame格式解析输出数据处理解析
CombiningOutputParser将多个输出解析器组合为一个组合解析器
OutputFixingParser包装解析器并尝试修复解析错误错误处理解析
RetryOutputParser包装解析器并尝试修复解析错误错误处理解析
RetryWithErrorOutputParser包装解析器并尝试修复解析错误错误处理解析
ResponseSchema结构化输出解析器的响应模式辅助类

下面使用BooleanOutputParser()改变上述代码,将yes or no的输出转化为True or False

from langchain.chat_models import init_chat_modelfrom langchain.prompts import ChatPromptTemplatefrom langchain.output_parsers import BooleanOutputParsermodel = init_chat_model(    model="Qwen/Qwen3-8B",    model_provider="openai",    base_url="https://api.siliconflow.cn/v1/",    api_key="", # 你注册的硅基流动 api key)prompt_template = ChatPromptTemplate([    ("system", "你是一个乐意助人的助手,请根据用户的问题给出回答"),    ("user", "这是用户的问题: {topic}, 请用 yes 或 no 来回答")])# 直接使用模型 + 输出解析器bool_qa_chain = prompt_template | model | BooleanOutputParser()# 测试question = "请问 1 + 1 是否 大于 2?"result = bool_qa_chain.invoke({'topic':question})print(result)

BooleanOutputParser()的用法比较简单,大家用的更多的是StructedOutputParser从文档中提取指定的类似Json这种结构化信息。

from langchain.chat_models import init_chat_modelfrom langchain_core.prompts import PromptTemplatefrom langchain.output_parsers import ResponseSchema, StructuredOutputParserschemas = [ # 构建结构化数据模板    ResponseSchema(name="name", description="用户的姓名"),    ResponseSchema(name="age", description="用户的年龄")]parser = StructuredOutputParser.from_response_schemas(schemas) # 根据模板生成解析器model = init_chat_model(    model="Qwen/Qwen3-8B",    model_provider="openai",    base_url="https://api.siliconflow.cn/v1/",    api_key="", # 你注册的硅基流动api_key)prompt = PromptTemplate.from_template(    "请根据以下内容提取用户信息,并返回 JSON 格式:\n{input}\n\n{format_instructions}") # 这是另一种使用占位符的提示词模板表示方式chain = (    prompt.partial(format_instructions=parser.get_format_instructions())     | model    | parser)result = chain.invoke({"input": "用户叫李雷,今年25岁,是一名工程师。"}) # 输入input, format_instructions前面已经赋值print(result)

以上代码有如下几个关键点:

    通过PromptTemplate.from_template()构建提示词组件,提示词组件的内容可以指定任意占位符。这里我们的占位符是inputformat_instructionsprompt.partial(format_instructions=parser.get_format_instructions())代码中partial()表示对部分占位符赋值,这里是对format_instructions变量赋值。parser.get_format_instructions()则是LangChain自动创建的提示词,我们打印输出一下,正因为这个提示词,LangChain链中大模型才能按我们期望的输出。

    parser解析器可以自动将大模型输出提取成json格式,上述代码的执行结果如下:

2.4 复杂链搭建

链不但可以将不同的组件组织起来。不同的链又可以作为组件被其它的链串联起来(世界就是巨大的套娃),下面我们就来尝试创建一条复合链:第一个子链负责生成新闻内容,第二个子链负责生成新闻摘要,结构如下:

以上复合链的代码如下:

from langchain.chat_models import init_chat_modelfrom langchain_core.prompts import PromptTemplatefrom langchain.output_parsers import ResponseSchema, StructuredOutputParser# 第一步:根据标题生成新闻正文news_gen_prompt = PromptTemplate.from_template(    "请根据以下新闻标题撰写一段简短的新闻内容(100字以内):\n\n标题:{title}")model = init_chat_model(    model="Qwen/Qwen3-8B",    model_provider="openai",    base_url="https://api.siliconflow.cn/v1/",    api_key="", # 你注册的硅基流动api_key)# 第一个子链:生成新闻内容news_chain = news_gen_prompt | model# 第二步:从正文中提取结构化字段schemas = [    ResponseSchema(name="time", description="事件发生的时间"),    ResponseSchema(name="location", description="事件发生的地点"),    ResponseSchema(name="event", description="发生的具体事件"),]parser = StructuredOutputParser.from_response_schemas(schemas)summary_prompt = PromptTemplate.from_template(    "请从下面这段新闻内容中提取关键信息,并返回结构化JSON格式:\n\n{news}\n\n{format_instructions}")# 第二个子链:生成新闻摘要summary_chain = (    summary_prompt.partial(format_instructions=parser.get_format_instructions())    | model    | parser)# 组合成一个复合 Chainfull_chain = news_chain | summary_chain# 调用复合链result = full_chain.invoke({"title": "苹果公司在加州发布新款AI芯片"})print(result)

执行结果如下:

2.5 自定义组件

相信阅读完上述代码大家会有疑问:如果LangChain没有实现我想要组件的功能该怎么办呀?不用担心,LangChain早预想到了这种情况,提供了开发者自定义可运行节点的功能。

同样是上面的案例,如果我们想在链中设置调试组件该如何编写代码?这就需要用到LangChain的Runnable组件了。在上述复合链代码中添加:

from langchain_core.runnables import RunnableLambdadef debug_print(x):    print('中间结果(新闻正文):', x)    return xdebug_node = RunnableLambda(debug_print)# 组合成一个复合 Chainfull_chain = news_chain | debug_node | summary_chain# 调用复合链result = full_chain.invoke({"title": "苹果公司在加州发布新款AI芯片"})print(result)

RunnableLambda将python函数转换为可运行节点。转化后的节点可以像任何其它Runnable一样组合并与LangChain链无缝集成。(特别注意: RunnableLambda适合非流式输出,如果要流式输出请使用RunnableGenerator python.langchain.com/api_referen…)。

看到这里,大家基本了解了LangChain链的核心原理,我们离使用LangChain快速开发出一个智能问答机器人项目也不远了~

三、LCEL简述

在上述代码中|符号被我们广泛使用,大家可能会想问:“Python语言里面这个符号的用法好像也不是链呀,在这里为什么可以把各个组件串起来呢?”

其实这是LangChain专门为现代大语言模型应用开发的一种全新表达范式,被称为LCEL(LangChain Expression Language) 。它不仅简化了模型交互的编排过程,还增强了组合的灵活性和可维护性。

3.1 LCEL的定义

LCEL,全称为LangChain Expression Language,是一种专为 LangChain 框架设计的表达语言。它通过一种链式组合的方式,允许开发者使用清晰、声明式的语法来构建语言模型驱动的应用流程。简单来说,LCEL 是一种“函数式管道风格”的组件组合机制,用于连接各种可执行单元(Runnable)。这些单元包括提示模板、语言模型、输出解析器、工具函数等。

3.2 LCEL的设计目的

LCEL 的设计初衷在于:

    模块化构建:将模型调用流程拆解为独立、可重用的组件。逻辑可视化:通过语法符号(如管道符 |)呈现出明确的数据流路径。统一运行接口:所有 LCEL 组件都实现了 .invoke().stream().batch() 等标准方法,便于在同步、异步或批处理环境下调用。脱离框架限制:相比传统的 Chain 类和 Agent 架构,LCEL 更轻量、更具表达力,减少依赖的“黑盒”逻辑。

3.3 LCEL的核心组成

LCEL的核心组成有如下三点:

    Runnable 接口

    LCEL 的一切基础单元都是 Runnable 对象,它是一种统一的可调用接口,支持如下形式:

      .invoke(input):同步调用.stream(input):流式生成.batch(inputs):批量执行

    管道运算符 |

    这是 LCEL 最具特色的语法符号。多个 Runnable 对象(也就是我们说的组件)可以通过 | 串联起来,形成清晰的数据处理链。例如:

    prompt | model | parser

    表示数据将依次传入提示模板、模型和输出解析器,最终输出结构化结果。

    PromptTemplate 与 OutputParser

    LCEL 强调组件之间的职责明确,Prompt 只负责模板化输入,Parser 只负责格式化输出,Model 只负责推理。

以上就是我们今天分享的全部内容~

四、总结

本期分享我们讲解了LangChain的核心概念——“链”,由易到难搭建了LangChain简单链、复合链和自定义节点链,同时了解了LangChain提示词模板和结构化解析器的基本用法。在实战代码案例中让大家感受到了LangChain LCEL语法设计的简洁性和实用性,大家学完本期内容初步具备了搭建简易LangChain智能体的能力,下一期分享我们将手把手带大家完成一个全栈项目——LangChain搭建多轮对话网站,大家一起期待一下吧!

本系列分享预计会有20节左右的规模,保证大家看完一定能够掌握LangChain&LangGraph的开发能力,大家感兴趣可关注笔者掘金账号和专栏,更可关注笔者的同名微信公众号:大模型真好玩, 本系列分享的全部代码均可在微信公众号私信笔者: LangChain智能体开发 免费获得。

Fish AI Reader

Fish AI Reader

AI辅助创作,多种专业模板,深度分析,高质量内容生成。从观点提取到深度思考,FishAI为您提供全方位的创作支持。新版本引入自定义参数,让您的创作更加个性化和精准。

FishAI

FishAI

鱼阅,AI 时代的下一个智能信息助手,助你摆脱信息焦虑

联系邮箱 441953276@qq.com

相关标签

LangChain 链式调用 LCEL AI Agent 智能体开发
相关文章