当前位置: 首页 > news >正文

LangChain 核心链式组件对比:从 SequentialChain 到 LCEL

本文档旨在详细解析 LangChain 中用于构建顺序工作流的三种核心方式:

  1. SimpleSequentialChain (简单顺序链)
  2. SequentialChain (通用顺序链)
  3. LCEL 管道符 | (现代链式表达式)

我们将首先分别介绍它们的概念,然后通过一个统一的编程示例,展示它们各自的实现方式和差异,并深入讲解其中用到的关键组件。


1. 组件介绍

1.1 SimpleSequentialChain (简单顺序链)

概念:
这是最基础的顺序链,如同一个简单的“接力赛”。第一个链执行完毕后,将其单个字符串输出直接作为第二个链的单个输入,以此类推。

核心特点:

  • 单入单出: 链条中的每一个子链都必须只有一个输入和一个输出。
  • 最终输出: 整个 SimpleSequentialChain 只返回最后一个链的输出结果。
  • 无中间状态: 你无法获取中间步骤产生的任何结果。
  • 适用场景: 用于非常简单、线性的任务,例如:主题 -> 标题 -> 关于标题的推文

1.2 SequentialChain (通用顺序链)

概念:
这是一个更强大、更灵活的顺序链,可以看作一个拥有共享上下文的“工厂流水线”。它能处理包含多个输入和输出的子链。

核心特点:

  • 多入多出: 子链可以拥有多个输入和输出。
  • 共享上下文 (Memory): SequentialChain 维护一个包含所有步骤输入和输出的字典。后续的链可以从这个字典中获取任何它所需要的变量。
  • 访问中间结果: 你可以访问并返回流程中任何一步的输出结果。
  • 显式定义: 需要通过 input_variables, output_variables, 和 output_key 等参数来精确控制数据流。
  • 适用场景: 绝大多数需要分解步骤、并且后一步需要前一步结果的复杂任务。

1.3 LCEL 管道符 | (LangChain Expression Language)

概念:
这是 LangChain 当前及未来推荐的链构建方式,其核心是 Runnable 协议和管道符 |。它允许你像拼接“乐高积木”一样,将各种组件(提示、模型、解析器、函数等)自由地组合在一起。

核心特点:

  • 简洁直观: 语法非常简洁,a | b 的意思就是将 a 的输出作为 b 的输入。
  • 高度灵活: 任何实现了 Runnable 接口的对象都可以被链接,包括普通的 Python 函数,这提供了极大的灵活性。
  • 强大的数据流控制: 通过字典和 RunnablePassthrough 等工具,可以轻松实现比 SequentialChain 更复杂的数据流管理。
  • 原生高级功能: 天然支持**流式(Streaming)、异步(Async)和批量(Batch)**调用,无需额外配置。
  • 透明可调试: 链的内部结构清晰,易于调试和可视化。
  • 适用场景: 所有新项目。它是构建任何类型链(无论是简单还是复杂)的黄金标准。

2. 统一任务场景

我们将用以下这个任务来对比三种实现方式:

  1. 初始输入: 一个技术主题(例如:“人工智能”)。
  2. 第一步: 根据该主题,生成一个吸引人的中文博客标题。
  3. 第二步: 根据生成的标题,为这篇博客写一段简短(2-3句话)的摘要。
  4. 最终输出: 同时得到生成的标题摘要

注意: SimpleSequentialChain 由于其局限性,无法直接完成“同时输出两项结果”的任务。为了演示,我们将让它完成一个类似的、但只返回最终结果的线性任务。

3. 完整代码示例与组件讲解

以下是完整的 Python 代码,演示了如何用三种方式解决上述问题。

# 安装必要的库
# pip install langchain langchain-openai python-dotenvimport os
from dotenv import load_dotenv# --- 1. 环境与基础组件设置 ---
# 加载 .env 文件中的环境变量 (OPENAI_API_KEY)
load_dotenv()# 导入 LangChain 相关模块
from langchain_openai import ChatOpenAI
from langchain.prompts import PromptTemplate
from langchain.chains import LLMChain, SimpleSequentialChain, SequentialChain
from langchain_core.output_parsers import StrOutputParser
from langchain_core.runnable import RunnablePassthroughprint("--- 基础组件初始化 ---")
# 初始化大语言模型 (LLM)
# 这是所有链的“大脑”,负责根据提示生成文本。
# 我们选择 gpt-4o 模型,并设置 temperature=0.7 以增加一些创造性。
llm = ChatOpenAI(model="gpt-4o", temperature=0.7)# 初始化输出解析器 (Output Parser)
# 它的作用是将LLM返回的原始输出(通常是一个 AIMessage 对象)转换成更易于处理的格式,比如纯字符串。
# 在 LCEL 中非常常用。
output_parser = StrOutputParser()# --- 2. SimpleSequentialChain 示例 ---
# 由于它只能返回最终结果,我们调整任务为:主题 -> 标题 -> 关于标题的推文
print("\n--- 示例1: SimpleSequentialChain ---")# a. 第一个链:生成标题
prompt_title = PromptTemplate.from_template("给我一个关于技术主题 '{topic}' 的吸引人的中文博客标题。"
)
chain_title = LLMChain(llm=llm, prompt=prompt_title)# b. 第二个链:根据标题写推文
prompt_tweet = PromptTemplate.from_template("为这篇博客文章写一条推文,标题是:'{title}'" # 注意这里的输入变量名'title'是随意的,因为SimpleSequentialChain会自动传递
)
chain_tweet = LLMChain(llm=llm, prompt=prompt_tweet)# c. 组装简单顺序链
# 它会自动将 chain_title 的输出作为 chain_tweet 的输入
simple_chain = SimpleSequentialChain(chains=[chain_title, chain_tweet], verbose=True)# 运行并打印结果
print("运行 SimpleSequentialChain...")
simple_result = simple_chain.invoke("人工智能在医疗领域的应用")
print("\n[SimpleSequentialChain 最终输出]:")
print(simple_result)# --- 3. SequentialChain 示例 ---
# 这个可以完美解决我们的原始任务:同时返回标题和摘要
print("\n--- 示例2: SequentialChain ---")# a. 第一个链:生成标题 (带 output_key)
# output_key 是关键,它定义了此链输出结果在共享上下文中的键名。
chain_title_seq = LLMChain(llm=llm,prompt=prompt_title,output_key="blog_title" # 指定输出的键为 'blog_title'
)# b. 第二个链:生成摘要
# 它的 input_variables 必须是上一个链的 output_key。
prompt_summary = PromptTemplate.from_template("根据这篇博客的标题 '{blog_title}',写一段2-3句话的简短摘要。"
)
chain_summary_seq = LLMChain(llm=llm,prompt=prompt_summary,output_key="blog_summary" # 指定输出的键为 'blog_summary'
)# c. 组装通用顺序链
# 在这里,我们精确地控制输入和输出
full_sequential_chain = SequentialChain(chains=[chain_title_seq, chain_summary_seq],input_variables=["topic"], # 定义整个流程的初始输入变量output_variables=["blog_title", "blog_summary"], # 定义整个流程最终要返回的变量verbose=True
)# 运行并打印结果
print("运行 SequentialChain...")
seq_result = full_sequential_chain.invoke({"topic": "人工智能在医疗领域的应用"})
print("\n[SequentialChain 最终输出]:")
print(seq_result)# --- 4. LCEL 管道符 | 示例 ---
# 这是解决该任务的现代、推荐方式
print("\n--- 示例3: LCEL 管道符 | ---")# a. 定义第一个处理步骤 (LCEL 风格)
# 这里的 chain_title_lcel 是一个 Runnable 对象
chain_title_lcel = prompt_title | llm | output_parser# b. 定义第二个处理步骤 (LCEL 风格)
# 这里的 chain_summary_lcel 也是一个 Runnable 对象
chain_summary_lcel = prompt_summary | llm | output_parser# c. 使用 RunnablePassthrough.assign 组装流水线
# 这是 LCEL 中管理上下文、构建复杂数据流的核心技巧。
# .assign() 的作用是:并行或串行地运行一些 Runnable,然后将它们的结果添加到(或覆盖)输入的字典中。
lcel_chain = RunnablePassthrough.assign(# 第一步:运行标题链,并将结果存入 'blog_title' 键。# 输入的字典(包含'topic')会自动传递给 chain_title_lcel。blog_title=chain_title_lcel
).assign(# 第二步:运行摘要链,并将结果存入 'blog_summary' 键。# 此时输入的字典已经包含了 'topic' 和 'blog_title',chain_summary_lcel 会自动找到它需要的 'blog_title'。blog_summary=chain_summary_lcel
)# 运行并打印结果
print("运行 LCEL 链...")
lcel_result = lcel_chain.invoke({"topic": "人工智能在医疗领域的应用"})
print("\n[LCEL 链最终输出]:")
print(lcel_result)

4. 关键组件详细讲解

在上面的代码中,我们用到了以下几个核心组件:

  1. ChatOpenAI:

    • 作用: LangChain 对 OpenAI 聊天模型(如 GPT-3.5, GPT-4, GPT-4o)的封装。它是执行语言理解和生成任务的“大脑”。
    • 关键参数: model 用于指定模型版本, temperature 用于控制生成文本的随机性(0最确定,2最随机)。
  2. PromptTemplate:

    • 作用: 提示词模板。它允许你创建一个包含动态变量的、可复用的提示词结构。
    • 关键参数: template 是包含占位符(如 {topic})的字符串, input_variables 是一个列表,定义了所有占位符的名称。
  3. LLMChain:

    • 作用: 这是 LangChain 经典的链实现,也是最基础的链之一。它将一个 PromptTemplate 和一个 LLM 绑定在一起。
    • 工作流程: 接收输入变量 -> 使用 PromptTemplate 格式化成最终提示词 -> 将提示词发送给 LLM -> 返回 LLM 的输出。
    • output_key: 在 SequentialChain 中至关重要,它为该链的输出命名,以便后续的链可以引用它。
  4. SimpleSequentialChain / SequentialChain:

    • 作用: 如前所述,它们是“容器”链,用于将多个子链按顺序组合起来。
    • 关键参数: chains 是一个按执行顺序排列的子链列表。input_variablesoutput_variables (仅 SequentialChain) 用于定义整个工作流的公共接口。
  5. StrOutputParser (String Output Parser):

    • 作用: 一个简单的输出解析器,是 LCEL 中非常常用的组件。它的功能是将模型输出(可能是复杂对象)转换成一个简单的字符串。
    • 为何需要: 在 LCEL 中,prompt | llm 的直接输出是一个 AIMessage 对象。通过 | output_parser,我们可以直接得到干净的文本,方便后续处理或直接使用。
  6. RunnablePassthrough.assign:

    • 作用: 这是 LCEL 中实现类似 SequentialChain 共享上下文功能的核心工具
    • 工作原理: 它接收一个字典作为输入,然后并行或串行地运行你提供给它的其他 Runnable(比如我们例子中的 chain_title_lcel)。最后,它将这些 Runnable 的结果作为新的键值对,添加到原始的输入字典中,并返回这个更新后的字典。
    • 为何强大: 这种机制让你能够像搭积木一样,一步步地丰富你的数据上下文,非常灵活和强大。

总结: 从 SequentialChain 到 LCEL 的演进,体现了 LangChain 从声明式、类封装的设计哲学,向量更简洁、更灵活、功能更强大的函数式组合范式的转变。对于所有新项目,强烈建议直接学习和使用 LCEL。


文章转载自:

http://Yfu782UR.hskLc.cn
http://gd1riqnH.hskLc.cn
http://TkVCNJgL.hskLc.cn
http://QXhJ6svs.hskLc.cn
http://TbNWPMeW.hskLc.cn
http://REHxbkCl.hskLc.cn
http://Jp75AlvD.hskLc.cn
http://2EctyUDt.hskLc.cn
http://S0HzZyzq.hskLc.cn
http://ansKUooz.hskLc.cn
http://CB7iXXGE.hskLc.cn
http://YOMZK60o.hskLc.cn
http://E3OXyo6D.hskLc.cn
http://34Ax6kzG.hskLc.cn
http://IPphi6xu.hskLc.cn
http://2WSXZ0Nd.hskLc.cn
http://1FZ8O1R7.hskLc.cn
http://2DMwnZZS.hskLc.cn
http://PRo53cDA.hskLc.cn
http://DVmPoG8c.hskLc.cn
http://yDiaoJ8a.hskLc.cn
http://asXXpMxI.hskLc.cn
http://GbVR1UG3.hskLc.cn
http://JUlpe1Jm.hskLc.cn
http://jeLs3quG.hskLc.cn
http://3ymLa6sP.hskLc.cn
http://RS23ekgd.hskLc.cn
http://pfiFktgn.hskLc.cn
http://e0Lnc0IS.hskLc.cn
http://DGwsF3jh.hskLc.cn
http://www.dtcms.com/a/359994.html

相关文章:

  • 想学怎么写网站怎么办?初学者专用! (HTML+CSS+JS)
  • 【大语言模型 32】Constitutional AI:自我改进的对齐方法
  • TJA1445学习笔记(二)
  • Python入门教程之类型判别
  • Qt Core 之 QString
  • 响应式编程框架Reactor【7】
  • React Hooks useMemo
  • JVM学习总结
  • docker中的命令(四)
  • 大话 IOT 技术(3) -- MQTT篇
  • 机器视觉学习-day19-图像亮度变换
  • 【模型训练篇】VeRL分布式基础 - 框架Ray
  • 分布式相关
  • 正则表达式 Python re 库完整教程
  • 如何用熵正则化控制注意力分数的分布
  • 让你的App与众不同打造独特品牌展示平台
  • Scikit-learn Python机器学习 - 类别特征提取- OneHotEncoder
  • 编写Linux下usb设备驱动方法:disconnect函数中要完成的任务
  • 【数学建模学习笔记】异常值处理
  • RAG(检索增强生成)技术的核心原理与实现细节
  • 【Unity开发】Unity核心学习(三)
  • macos自动安装emsdk4.0.13脚本
  • 在Ubuntu系统上安装和配置JMeter和Ant进行性能测试
  • 基于SpringBoot + Vue 的宠物领养管理系统
  • 【Spring Cloud微服务】7.拆解分布式事务与CAP理论:从理论到实践,打造数据一致性堡垒
  • ANR InputDispatching TimeOut超时判断 - android-15.0.0_r23
  • 拆分TypeScript项目的学习收获:处理编译缓存和包缓存,引用本地项目,使用相对路径
  • 配置 Kubernetes Master 节点不可调度的标准方法
  • 【51单片机】【protues仿真】基于51单片机音乐喷泉系统
  • 记录测试环境hertzbeat压测cpu高,oom问题排查。jvm,mat,visulavm