深入浅出LangChain AI Agent智能体开发教程(三)—LangChain核心概念“链”

前言

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

本期分享我们一起来学习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)

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

  1. 通过PromptTemplate.from_template()构建提示词组件,提示词组件的内容可以指定任意占位符。这里我们的占位符是inputformat_instructions
  2. prompt.partial(format_instructions=parser.get_format_instructions())代码中partial()表示对部分占位符赋值,这里是对format_instructions变量赋值。parser.get_format_instructions()则是LangChain自动创建的提示词,我们打印输出一下,正因为这个提示词,LangChain链中大模型才能按我们期望的输出。
  1. 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 的设计初衷在于:

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

3.3 LCEL的核心组成

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

  1. Runnable 接口

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

    • .invoke(input):同步调用
    • .stream(input):流式生成
    • .batch(inputs):批量执行
  2. 管道运算符 |

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

    复制代码
    prompt | model | parser

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

  3. PromptTemplate 与 OutputParser

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

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

四、总结

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

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

相关推荐
SoFlu软件机器人9 分钟前
飞算科技:以原创技术为翼,赋能产业数字化转型
人工智能·科技
alex888610 分钟前
万界星空科技锂电池MES解决方案
运维·人工智能·科技·5g·能源·创业创新·制造
mwq3012323 分钟前
如何写出好用的提示词?——从原理到实操,以“减肥食谱”为例全解析
人工智能
88号技师24 分钟前
2025年一区SCI-回旋镖气动椭圆优化算法Boomerang Aerodynamic Ellipse-附Matlab免费代码
开发语言·人工智能·算法·matlab·优化算法
胖哥真不错28 分钟前
基于MATLAB的极限学习机ELM的数据回归预测方法应用
人工智能·matlab·数据挖掘·回归·项目实战·数据回归预测·极限学习机elm
亚马逊云开发者29 分钟前
从分析到优化:Amazon Q CLI 助力 EKS 网络调用链剖析与运维实践
人工智能
AI扶我青云志1 小时前
“hidden act“:“gelu“在bert中作用
人工智能·深度学习·bert
聚客AI1 小时前
🤖Cherry Studio+ MCP实现文件自由操控的奥秘
人工智能·llm·mcp
都叫我大帅哥1 小时前
Python Typing 模块中的 Type:全面深入指南
python
都叫我大帅哥1 小时前
LangChain向量嵌入:从入门到面试的全方位指南
python·langchain