前言
本系列分享前两期分别讲述了
本期分享我们一起来学习LangChain最核心思想------搭建Chains,也就是所谓链式调用的核心方法。顾名思义,LangChain之所以被称为LangChain,其核心概念就是Chain。只要掌握了Chain的搭建方法,我们就掌握了LangChain搭建智能体的核心技巧。
本系列分享是笔者结合自己学习工作中使用LangChain&LangGraph经验倾心编写的,力求帮助大家体系化快速掌握LangChain&LangGraph AI Agent智能体开发的技能!大家感兴趣可以关注笔者掘金账号和系列专栏。更可关注笔者同名微信公众号: 大模型真好玩 , 每期分享涉及的代码均可在公众号私信: LangChain智能体开发获得。
一、LangChain链式调用架构
链式调用位于LangChain三层核心架构中的中间层------工作流API抽象层。Chain翻译成中文就是"链",我们将大模型、相关工具等作为组件,链就是负责将这些组件按照某一种逻辑,顺序组合成一个流水线的方式。比如我们要构建一个简单的问答链,就需要把大模型组件和标准输出组件用链串联起来。下面笔者将通过由易到难的示例向大家介绍常用的链式调用模式:

二、LangChain链搭建代码实战
2.1 尝试搭建一个简单链
第一个示例先尝试搭建一个简单链,将模型"输出结果"过滤为一个纯字符串格式:
python
from langchain.chat_models import init_chat_model
from 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
非常便捷的将一个提示词模板打造为组件,同样以链的形式加入当前流程中:
python
from langchain.chat_models import init_chat_model
from langchain.prompts import ChatPromptTemplate
from 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
)
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
:
python
from langchain.chat_models import init_chat_model
from langchain.prompts import ChatPromptTemplate
from langchain.output_parsers import BooleanOutputParser
model = 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这种结构化信息。
python
from langchain.chat_models import init_chat_model
from langchain_core.prompts import PromptTemplate
from langchain.output_parsers import ResponseSchema, StructuredOutputParser
schemas = [ # 构建结构化数据模板
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()
构建提示词组件,提示词组件的内容可以指定任意占位符。这里我们的占位符是input
和format_instructions
。 prompt.partial(format_instructions=parser.get_format_instructions())
代码中partial()
表示对部分占位符赋值,这里是对format_instructions
变量赋值。parser.get_format_instructions()
则是LangChain自动创建的提示词,我们打印输出一下,正因为这个提示词,LangChain链中大模型才能按我们期望的输出。

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

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

以上复合链的代码如下:
python
from langchain.chat_models import init_chat_model
from langchain_core.prompts import PromptTemplate
from 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
)
# 组合成一个复合 Chain
full_chain = news_chain | summary_chain
# 调用复合链
result = full_chain.invoke({"title": "苹果公司在加州发布新款AI芯片"})
print(result)
执行结果如下:

2.5 自定义组件
相信阅读完上述代码大家会有疑问:如果LangChain没有实现我想要组件的功能该怎么办呀?不用担心,LangChain早预想到了这种情况,提供了开发者自定义可运行节点的功能。
同样是上面的案例,如果我们想在链中设置调试组件该如何编写代码?这就需要用到LangChain的Runnable组件了。 在上述复合链代码中添加:
python
from langchain_core.runnables import RunnableLambda
def debug_print(x):
print('中间结果(新闻正文):', x)
return x
debug_node = RunnableLambda(debug_print)
# 组合成一个复合 Chain
full_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智能体开发 免费获得。