Langchain学习笔记(十一):Chain构建与组合技巧

news2025/12/14 16:54:09

:本文是Langchain框架的学习笔记;不是教程!不是教程!内容可能有所疏漏,欢迎交流指正。后续将持续更新学习笔记,分享我的学习心得和实践经验。

前言

在LangChain的发展过程中,API设计经历了重要的演进。从0.1.17版本开始,传统的Chain类(如LLMChain、SequentialChain等)被标记为已弃用,官方推荐使用更现代的LCEL(LangChain Expression Language)和管道符(|)语法。本文将详细对比新旧两种方式,帮助大家理解这一重要变化


1. Chain的基本概念与版本变化

1.1 什么是Chain?

Chain(链)是LangChain中用于连接多个组件的核心抽象。想象一下工厂的流水线,每个工作站负责一个特定的任务,产品从一个工作站传递到下一个工作站,最终完成整个生产过程。Chain就是这样的概念:

  • 输入处理:接收用户的原始输入

  • 中间处理:通过多个步骤对数据进行转换和处理

  • 输出生成:产生最终的结果

Chain的核心价值在于:

  1. 模块化设计:将复杂的AI任务分解为多个简单的步骤

  2. 可重用性:每个组件都可以在不同的场景中重复使用

  3. 可维护性:便于调试、测试和优化单个环节

  4. 灵活组合:可以根据需求灵活组合不同的处理步骤


1.2 版本演进的背景

为什么要从传统Chain迁移到LCEL?

传统的Chain类虽然功能强大,但存在一些局限性:

  • 性能瓶颈:无法充分利用并行处理能力

  • 语法复杂:需要创建多个类实例,代码冗长

  • 功能限制:不支持流式处理和高级组合模式

  • 维护困难:复杂的继承关系增加了维护成本

LCEL(LangChain Expression Language)的优势:

  • 直观语法:使用管道符(|)连接组件,类似Unix管道

  • 高性能:原生支持并行、批处理和流式处理

  • 类型安全:更好的类型提示和错误检查

  • 易于调试:清晰的数据流向,便于问题定位


1.3 新旧版本对比表

功能旧版本(已弃用)新版本(推荐)说明
基础链LLMChainprompt | llm最基础的提示词+模型组合
顺序链SequentialChainchain1 | chain2 | chain3按顺序执行多个处理步骤
执行方法chain.run()chain.invoke()单次执行链的方法
批量执行chain.apply()chain.batch()批量处理多个输入
异步执行chain.arun()chain.ainvoke()异步执行,提高并发性能
流式执行不支持chain.stream()实时流式输出,改善用户体验



2. LLMChain的新旧版本对比

2.1 LLMChain的作用和意义

LLMChain是LangChain中最基础、最常用的链类型。它的作用是将提示词模板(Prompt Template)与大语言模型(LLM)连接起来,形成一个完整的处理单元。

LLMChain的核心功能

  1. 模板化输入:使用提示词模板,支持变量替换

  2. 模型调用:自动调用指定的大语言模型

  3. 输出处理:可选的输出解析和格式化

  4. 错误处理:统一的错误处理机制

使用场景:

  • 文本生成(如写作助手、内容创作)

  • 问答系统(基于提示词的简单问答)

  • 文本分析(情感分析、关键词提取等)

  • 格式转换(如JSON生成、代码生成)


2.2 基础用法对比

旧版本写法(已弃用)

from langchain_ollama import ChatOllama
from langchain.chains import LLMChain  # 已弃用
from langchain.prompts import PromptTemplate

llm = ChatOllama(
    base_url=OLLAMA_BASE_URL,
    model=MODEL_NAME,
    temperature=0.1  # 降低温度以获得更确定性的回答
)

prompt_template = PromptTemplate(
    input_variables=["topic"],
    template="请为我写一篇关于{topic}的简短介绍,大约100字左右。"
)

# 构建LLMChain(已弃用)
llm_chain = LLMChain(
    llm=llm,
    prompt=prompt_template,
    verbose=True
)

# 使用链(已弃用的方法)
result = llm_chain.run(topic="人工智能")  # 弃用警告
print(result)

新版本写法(推荐)

from langchain_core.prompts import PromptTemplate
from langchain_ollama import ChatOllama
from langchain_core.output_parsers import StrOutputParser

OLLAMA_BASE_URL = "http://192.168.0.118:11434"
MODEL_NAME = "deepseek-r1:1.5b"

llm = ChatOllama(
    base_url=OLLAMA_BASE_URL,
    model=MODEL_NAME,
    temperature=0.1  # 降低温度以获得更确定性的回答
)

prompt_template = PromptTemplate(
    input_variables=["topic"],
    template="请为我写一篇关于{topic}的简短介绍,大约100字左右。"
)

# 使用管道符构建链(推荐)
chain = prompt_template | llm | StrOutputParser()

# 使用invoke方法执行(推荐)
result = chain.invoke({"topic": "人工智能"})
print(result)

# 新版本支持的其他执行方式
# 批量执行
results = chain.batch([
    {"topic": "人工智能"},
    {"topic": "机器学习"}
])
print(results)

新版本的优势解析:

  • 管道符语法:prompt_template | llm | StrOutputParser() 清晰地表达了数据流向

  • 输出解析器:StrOutputParser() 确保输出为字符串格式

  • 批量处理:batch() 方法可以高效处理多个输入

  • 类型安全:更好的类型提示,减少运行时错误


2.3 带输出解析器的高级用法

输出解析器的作用

输出解析器(Output Parser)是LangChain中用于处理模型输出的重要组件。它的主要作用包括:

  1. 格式化输出:将模型的原始输出转换为结构化数据

  2. 类型转换:确保输出符合预期的数据类型

  3. 验证检查:验证输出是否符合预定义的格式要求

  4. 错误处理:处理格式不正确的输出

新版本写法

from langchain_core.prompts import PromptTemplate
from langchain_ollama import ChatOllama
from langchain.output_parsers import CommaSeparatedListOutputParser

OLLAMA_BASE_URL = "http://192.168.0.118:11434"
MODEL_NAME = "deepseek-r1:1.5b"

llm = ChatOllama(
    base_url=OLLAMA_BASE_URL,
    model=MODEL_NAME,
    temperature=0.1  # 降低温度以获得更确定性的回答
)

# 新版本
output_parser = CommaSeparatedListOutputParser()

list_prompt = PromptTemplate(
    template="列出5个关于{topic}的关键词,用逗号分隔。\n{format_instructions}",
    input_variables=["topic"],
    partial_variables={"format_instructions": output_parser.get_format_instructions()}
)

# 使用管道符连接解析器
chain = list_prompt | llm | output_parser

keywords = chain.invoke({"topic": "机器学习"})
print(f"关键词列表: {keywords}")
print(f"类型: {type(keywords)}")

3. SequentialChain

3.1 SequentialChain的概念和作用

SequentialChain(顺序链)是用于按顺序执行多个处理步骤的链类型。它的核心思想是将复杂的任务分解为多个简单的子任务,然后按照特定的顺序依次执行。

SequentialChain的特点:

  1. 步骤化处理:将复杂任务分解为多个简单步骤

  2. 数据传递:前一个步骤的输出作为后一个步骤的输入

  3. 模块化设计:每个步骤都是独立的,便于测试和维护

  4. 灵活组合:可以根据需要调整步骤的顺序和组合

适用场景:

  • 内容创作流程:大纲生成 → 内容写作 → 格式优化

  • 数据分析流程:数据收集 → 数据清洗 → 分析报告

  • 产品开发流程:需求分析 → 方案设计 → 实施计划

  • 客户服务流程:问题识别 → 解决方案 → 回复生成


3.2 简单顺序链

简单顺序链的特点:

  • 每个步骤只有一个输入和一个输出

  • 前一步的输出直接作为后一步的输入

  • 适合线性处理流程

新版本写法

from langchain_core.prompts import PromptTemplate
from langchain_ollama import ChatOllama
from langchain_core.output_parsers import StrOutputParser

OLLAMA_BASE_URL = "http://192.168.0.118:11434"
MODEL_NAME = "deepseek-r1:1.5b"

llm = ChatOllama(
    base_url=OLLAMA_BASE_URL,
    model=MODEL_NAME,
    temperature=0.1  # 降低温度以获得更确定性的回答
)

# 新版本
outline_prompt = PromptTemplate(
    input_variables=["topic"],
    template="为主题'{topic}'创建一个详细的文章大纲,包含3-5个主要部分。"
)

article_prompt = PromptTemplate(
    input_variables=["outline"],
    template="根据以下大纲写一篇简短的文章:\n{outline}"
)

# 使用管道符构建顺序链
writing_chain = (
        outline_prompt
        | llm
        | StrOutputParser()
        | (lambda outline: {"outline": outline})
        | article_prompt
        | llm
        | StrOutputParser()
)

final_article = writing_chain.invoke({"topic": "可持续发展"})
print(final_article)

3.2 复杂顺序链

复杂顺序链的特点:

  • 支持多个输入和输出变量

  • 可以在处理过程中保留和传递多个数据

  • 支持并行处理某些步骤

  • 适合复杂的业务逻辑

新版写法

from langchain_core.prompts import PromptTemplate
from langchain_ollama import ChatOllama
from langchain_core.output_parsers import StrOutputParser
from langchain_core.runnables import RunnablePassthrough, RunnableParallel

OLLAMA_BASE_URL = "http://192.168.0.118:11434"
MODEL_NAME = "deepseek-r1:1.5b"

llm = ChatOllama(
    base_url=OLLAMA_BASE_URL,
    model=MODEL_NAME,
    temperature=0.1  # 降低温度以获得更确定性的回答
)

# 新版本
analysis_prompt = PromptTemplate(
    input_variables=["product_name", "product_description"],
    template="产品:{product_name}\n描述:{product_description}\n请分析产品特点:"
)

slogan_prompt = PromptTemplate(
    input_variables=["product_name", "product_analysis"],
    template="产品:{product_name}\n分析:{product_analysis}\n请创建3个营销标语:"
)

# 使用RunnableParallel和管道符构建复杂链
product_marketing_chain = (
        RunnablePassthrough.assign(product_analysis=analysis_prompt | llm | StrOutputParser()) | RunnableParallel(
    product_analysis=lambda x: x["product_analysis"], marketing_slogans=slogan_prompt | llm | StrOutputParser()
)
)

result = product_marketing_chain.invoke({
    "product_name": "智能语音助手",
    "product_description": "基于AI技术的智能语音助手"
})

print("产品分析:", result["product_analysis"])
print("营销标语:", result["marketing_slogans"])

核心组件解析:

  1. RunnablePassthrough.assign()

    • 作用:在保留原有输入的基础上,添加新的字段
    • 这里添加了 product_analysis 字段,包含产品分析结果
  2. RunnableParallel()

    • 作用:并行执行多个任务,提高处理效率
    • 同时输出产品分析和营销标语两个结果

处理流程:

  1. 输入处理:接收产品名称和描述
  2. 产品分析:生成产品特点分析,并保留原始输入
  3. 并行输出:同时生成最终的分析结果和营销标语



4. RouterChain

4.1 RouterChain的概念和作用

RouterChain(路由链)是一种智能分发机制,它可以根据输入内容的特征,自动选择最合适的处理路径。就像交通路口的智能信号灯,根据不同方向的车流量来调整信号,RouterChain根据不同类型的输入来选择最佳的处理方式。

RouterChain的核心价值:

  1. 智能分类:自动识别输入内容的类型或意图
  2. 专业处理:为不同类型的问题提供专门的处理逻辑
  3. 提高效率:避免用通用方法处理所有问题
  4. 提升质量:专业化处理通常能获得更好的结果

典型应用场景:

  • 智能客服系统:根据问题类型路由到不同的处理模块

  • 内容分类处理:技术问题、商业问题、创意问题分别处理

  • 多语言支持:根据语言类型选择对应的处理器

  • 难度分级:简单问题快速回答,复杂问题深度分析


4.2 基础路由链

路由逻辑的设计思路:

  1. 关键词匹配:通过关键词识别问题类型
  2. 专业模板:为每种类型设计专门的提示词模板
  3. 默认处理:为无法分类的问题提供通用处理方式

新版写法

from langchain_core.prompts import PromptTemplate
from langchain_ollama import ChatOllama
from langchain_core.output_parsers import StrOutputParser
from langchain_core.runnables import RunnableBranch

OLLAMA_BASE_URL = "http://192.168.0.118:11434"
MODEL_NAME = "deepseek-r1:1.5b"

llm = ChatOllama(
    base_url=OLLAMA_BASE_URL,
    model=MODEL_NAME,
    temperature=0.1  # 降低温度以获得更确定性的回答
)

# 新版本
tech_prompt = PromptTemplate(
    template="你是技术专家。请回答:{input}",
    input_variables=["input"]
)

business_prompt = PromptTemplate(
    template="你是商业顾问。请回答:{input}",
    input_variables=["input"]
)

default_prompt = PromptTemplate(
    template="请回答:{input}",
    input_variables=["input"]
)


# 使用RunnableBranch实现路由逻辑
def route_question(x):
    question = x["input"].lower()
    if any(keyword in question for keyword in ["代码", "编程", "技术", "开发"]):
        return "tech"
    elif any(keyword in question for keyword in ["商业", "市场", "销售", "管理"]):
        return "business"
    else:
        return "default"


router_chain = RunnableBranch(
    (lambda x: route_question(x) == "tech", tech_prompt | llm | StrOutputParser()),
    (lambda x: route_question(x) == "business", business_prompt | llm | StrOutputParser()),
    default_prompt | llm | StrOutputParser()
)

result = router_chain.invoke({"input": "如何优化Python代码性能?"})
print(result)

核心组件详解:

  1. route_question() 函数:

    • 作用:分析输入问题,判断问题类型
    • 逻辑:通过关键词匹配来识别问题领域
    • 返回:问题类型标识(tech/business/default)
  2. RunnableBranch:

    • 作用:根据条件选择不同的处理分支
    • 结构:(条件函数, 处理链) 的元组列表
    • 默认:最后一个参数作为默认处理分支
  3. 专业化提示词:

    • tech_prompt:以技术专家身份回答技术问题
    • business_prompt:以商业顾问身份回答商业问题
    • default_prompt:通用回答模式



总结

LangChain从传统的Chain类向LCEL的迁移代表了框架设计理念的重要演进:

  • API设计更现代化:管道符语法更直观,符合现代编程习惯

  • 性能更优秀:原生支持并行、批处理和流式处理

  • 功能更强大:更灵活的组合方式,更好的调试工具

  • 维护性更好:代码更简洁,逻辑更清晰

虽然旧版本的Chain类仍然可用,但建议在新项目中使用LCEL语法,在现有项目中逐步迁移。这不仅能享受到新版本的性能优势,还能确保代码的长期可维护性

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2404372.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Windows平台RTSP/RTMP播放器C#接入详解

大牛直播SDK在Windows平台下的RTSP、RTMP播放器模块,基于自研高性能内核,具备极高的稳定性与行业领先的超低延迟表现。相比传统基于FFmpeg或VLC的播放器实现,SmartPlayer不仅支持RTSP TCP/UDP自动切换、401鉴权、断网重连等网络复杂场景自适应…

从 JDK 8 到 JDK 17:Swagger 升级迁移指南

点击上方“程序猿技术大咖”,关注并选择“设为星标” 回复“加群”获取入群讨论资格! 随着 Java 生态向 JDK 17 及 Jakarta EE 的演进,许多项目面临从 JDK 8 升级的挑战,其中 Swagger(API 文档工具)的兼容性…

使用 Coze 工作流一键生成抖音书单视频:全流程拆解与技术实现

使用 Coze 工作流一键生成抖音书单视频:全流程拆解与技术实现(提供工作流) 摘要:本文基于一段关于使用 Coze 平台构建抖音爆火书单视频的详细讲解,总结出一套完整的 AI 视频自动化制作流程。内容涵盖从思路拆解、节点配…

【发布实录】云原生+AI,助力企业全球化业务创新

5 月 22 日,在最新一期阿里云「飞天发布时刻」,阿里云云原生应用平台产品负责人李国强重磅揭晓面向 AI 场景的云原生产品体系升级,通过弹性智能的一体化架构、开箱即用的云原生 AI 能力,为中国企业出海提供新一代技术引擎。 发布会…

LabVIEW主轴故障诊断案例

LabVIEW 开发主轴机械状态识别与故障诊断系统,适配工业场景主轴振动监测需求。通过整合品牌硬件与软件算法,实现从信号采集到故障定位的全流程自动化,为设备维护提供数据支撑,提升数控机床运行可靠性。 ​ 面向精密制造企业数控机…

计算机组成与体系结构:补码数制二(Complementary Number Systems)

目录 4位二进制的减法 补码系统 🧠减基补码 名字解释: 减基补码有什么用? 计算方法 ❓为什么这样就能计算减基补码 💡 原理揭示:按位减法,模拟总减法! 那对于二进制呢?&…

C#使用MindFusion.Diagramming框架绘制流程图(2):流程图示例

上一节我们初步介绍MindFusion.Diagramming框架 C#使用MindFusion.Diagramming框架绘制流程图(1):基础类型-CSDN博客 这里演示示例程序: 新建Windows窗体应用程序FlowDiagramDemo,将默认的Form1重命名为FormFlowDiagram. 右键FlowDiagramDemo管理NuGet程序包 输入MindFusio…

【物联网-ModBus-RTU

物联网-ModBus-RTU ■ 优秀博主链接■ ModBus-RTU介绍■(1)帧结构■(2)查询功能码 0x03■(3)修改单个寄存器功能码 0x06■(4)Modbus RTU 串口收发数据分析 ■ 优秀博主链接 Modbus …

Java应用10(客户端与服务器通信)

Java客户端与服务器通信 Java提供了多种方式来实现客户端与服务器之间的通信,下面我将介绍几种常见的方法: 1. 基于Socket的基本通信 服务器端代码 import java.io.*; import java.net.*;public class SimpleServer {public static void main(String…

Python_day47

作业:对比不同卷积层热图可视化的结果 一、不同卷积层的特征特性 卷积层类型特征类型特征抽象程度对输入的依赖程度低层卷积层(如第 1 - 3 层)边缘、纹理、颜色、简单形状等基础特征低高,直接与输入像素关联中层卷积层&#xff08…

如何在mac上安装podman

安装 Podman 在 macOS 上 在 macOS 上安装 Podman 需要使用 Podman 的桌面客户端工具 Podman Desktop 或通过 Homebrew 安装命令行工具。 使用 Homebrew 安装 Podman: (base) ninjamacninjamacdeMacBook-Air shell % brew install podman > Auto-updating Hom…

小黑一层层削苹果皮式大模型应用探索:langchain中智能体思考和执行工具的demo

引言 小黑黑通过探索langchain源码,设计了一个关于agent使用工具的一个简化版小demo(代码可以跑通),主要流程: 1.问题输入给大模型。 2.大模型进行思考,输出需要执行的action和相关思考信息。 3.通过代理&…

阿里云ACP云计算备考笔记 (4)——企业应用服务

目录 第一章 企业应用概览 第二章 云解析 1、云解析基本概念 2、域名管理流程 3、云解析记录类型 4、域名管理 ① 开启注册局安全锁 ② 域名赎回 第二章 内容分发网络CDN 1、CDN概念 2、使用CDN前后对比 3、使用CDN的优势 4、阿里云CDN的优势 5、配置网页性能优化…

ARM SMMUv3简介(一)

1.概述 SMMU(System Memory Management Unit,系统内存管理单元)是ARM架构中用于管理设备访问系统内存的硬件模块。SMMU和MMU的功能类似,都是将虚拟地址转换成物理地址,不同的是MMU转换的虚拟地址来自CPU,S…

hadoop集群datanode启动显示init failed,不能解析hostname

三个datanode集群,有一个总是起不起来。去查看log显示 Initialization failed for Block pool BP-1920852191-192.168.115.154-1749093939738 (Datanode Uuid 89d9df36-1c01-4f22-9905-517fee205a8e) service to node154/192.168.115.154:8020 Datanode denied com…

浏览器工作原理05 [#] 渲染流程(上):HTML、CSS和JavaScript是如何变成页面的

引用 浏览器工作原理与实践 一、提出问题 在上一篇文章中我们介绍了导航相关的流程,那导航被提交后又会怎么样呢?就进入了渲染阶段。这个阶段很重要,了解其相关流程能让你“看透”页面是如何工作的,有了这些知识,你可…

|从零开始的Pyside2界面编程| 用Pyside2打造一个AI助手界面

🐑 |从零开始的Pyside2界面编程| 用Pyside2打造一个AI助手界面 🐑 文章目录 🐑 |从零开始的Pyside2界面编程| 用Pyside2打造一个AI助手界面 🐑♈前言♈♈调取Deepseek大模型♈♒准备工作♒♒调用API♒ ♈将模型嵌入到ui界面中♈♈…

pikachu靶场通关笔记20 SQL注入03-搜索型注入(GET)

目录 一、SQL注入 二、搜索型注入 三、源码分析 1、渗透思路1 2、渗透思路2 四、渗透实战 1、渗透准备 2、SQL注入探测 (1)输入百分号单引号 (2)万能注入语句 3、获取回显列orderby 4、获取数据库名database 5、获取…

产品笔试专业名词梳理

目录 产品常识 四种常见广告形式 贴片广告 中插广告 信息流广告 横幅广告 BAT和TMD BAT TMD 付费渗透率 蓝海市场、红海市场 蓝海市场 红海市场 竞品研究 SWOT分析 SWOT分析的核心目的: SWOT分析的优点: SWOT分析的局限与注意事项&…

【前端】es6相关,柯里化

0. 严格模式 严格模式的概念从ES6引进。通过严格模式,可以在函数内部选择进行较为严格的全局或局部的错误条件检测。 MDN中严格模式的描述 严格模式通过抛出错误来消除了一些原有静默错误严格模式修复了一些导致 JavaScript引擎难以执行优化的缺陷:有时…