004.链(Chains):构建可组合的工作流

出处:链(Chains):构建可组合的工作流

原作者:怕浪猫


在实际开发中,大模型应用往往不是“单一提示→单一输出”的简单流程,而是需要多步骤联动(如“输入文本→翻译→总结→情感分析”)、多组件协同(提示模板+模型+解析器+工具)。

LangChain 的核心优势之一,就是提供了“链(Chains)”这一核心组件,将多个独立的模块(提示模板、模型、解析器、工具等)串联或组合起来,构建可复用、可扩展的自动化工作流。形象地说,Chain 就像“流水线”,将复杂的大模型任务拆解为多个简单步骤,每个步骤由一个组件负责,最终协同完成完整任务。

1. 什么是 Chain?链式思维的核心

Chain(链)是一个可组合的执行流程,它将多个“执行步骤”(如提示生成、模型调用、输出解析、数据处理)按一定逻辑串联起来,接收输入、依次执行每个步骤,最终输出结果。其核心价值在于“解耦与组合”——将复杂任务拆解为独立模块,再根据需求灵活组合,提升代码的可复用性和可维护性。

1.1. 链式思维的核心:拆解与组合

Chain 的本质是“链式思维”,核心逻辑分为两步:

  1. 拆解:将复杂任务拆解为多个独立的、简单的子任务(每个子任务可由一个组件完成,如提示生成、模型调用、解析);
  2. 组合:将子任务按逻辑顺序组合起来,形成一条完整的执行链,子任务之间自动传递数据(上一个步骤的输出作为下一个步骤的输入)。

举个通俗的例子:做一道“番茄炒蛋”,可拆解为“洗番茄→切番茄→打鸡蛋→炒鸡蛋→炒番茄→混合翻炒→出锅”7 个步骤,每个步骤对应一个“组件”,将这些步骤按顺序组合起来,就形成了一条“番茄炒蛋链”,执行这条链就能自动完成番茄炒蛋。

1.2. Chain 的核心组成与分类

LangChain 中的所有 Chain,都由以下两个核心部分组成:

根据执行逻辑和场景,LangChain 中的 Chain 主要分为以下 5 类(本章重点讲解前 5 类,实战部分综合运用):

2. LLMChain:最简单的调用链

LLMChain 是 LangChain 中最基础、最简单的链,核心作用是将“PromptTemplate(提示模板)”和“LLM/ChatModel(模型)”整合为一个可复用的单元,可选搭配 OutputParser(输出解析器),实现“提示生成→模型调用→输出解析”的一站式执行。

核心场景:单一步骤的任务(如文本生成、简单问答、格式转换),无需多步骤联动,适合作为复杂链的“子链”。

2.1. 基础用法:整合提示模板与模型

步骤:初始化 PromptTemplate、LLM/ChatModel,再用 LLMChain 整合,调用链即可自动完成提示生成和模型调用。

from langchain.chains import LLMChain
from langchain_core.prompts import PromptTemplate
from langchain_openai import ChatOpenAI
from dotenv import load_dotenv
import os

load_dotenv()

# 1. 初始化提示模板
prompt = PromptTemplate(
    template="请为{product}撰写一句宣传语,突出{feature}优势,简洁有力(不超过15字)。",
    input_variables=["product", "feature"]
)

# 2. 初始化模型
chat_model = ChatOpenAI(
    model_name="gpt-3.5-turbo",
    api_key=os.getenv("OPENAI_API_KEY"),
    temperature=0.7
)

# 3. 构建LLMChain(整合提示模板和模型)
llm_chain = LLMChain(
    llm=chat_model,
    prompt=prompt,
    verbose=True  # 开启日志,查看链的执行过程(可选,便于调试)
)

# 4. 调用链(传入输入变量)
result = llm_chain.invoke({"product": "LangChain教程", "feature": "实战导向"})

print("宣传语:", result["text"])

运行结果:宣传语:LangChain实战教程,上手即会!

说明:调用 llm_chain.invoke()时,只需传入提示模板所需的变量,链会自动生成提示、调用模型,返回结果(默认存在"text"键中,对应模型的原始输出)。

2.2. 进阶用法:搭配 OutputParser 解析输出

在 LLMChain 中加入 OutputParser,可实现“提示→模型→解析”的一站式执行,无需手动调用解析器,示例如下(结合 PydanticOutputParser 实现强类型解析):

from langchain.chains import LLMChain
from langchain_core.prompts import PromptTemplate
from langchain_core.output_parsers import PydanticOutputParser
from langchain_openai import ChatOpenAI
from dotenv import load_dotenv
import os
from pydantic import BaseModel, Field

load_dotenv()

# 1. 定义Pydantic模型(用于输出解析)
class AdCopy(BaseModel):
    copy: str = Field(description="宣传语,不超过15字")
    feature: str = Field(description="突出的产品优势")

# 2. 初始化解析器、提示模板、模型
parser = PydanticOutputParser(pydantic_object=AdCopy)
prompt = PromptTemplate(
    template="为{product}撰写宣传语,突出{feature}优势(不超过15字),按要求输出:\n{format_instructions}",
    input_variables=["product", "feature"],
    partial_variables={"format_instructions": parser.get_format_instructions()}
)
chat_model = ChatOpenAI(api_key=os.getenv("OPENAI_API_KEY"), temperature=0.7)

# 3. 构建LLMChain(整合提示、模型、解析器)
llm_chain = LLMChain(
    llm=chat_model,
    prompt=prompt,
    output_parser=parser,
    verbose=True
)

# 4. 调用链,自动解析
result = llm_chain.invoke({"product": "LangChain教程", "feature": "通俗易懂"})

print("解析后的宣传语:", result.copy)
print("突出优势:", result.feature)

运行结果: 解析后的宣传语: 通俗易懂,LangChain 轻松学! 突出优势: 通俗易懂

说明:加入 output_parser 后,链的返回结果不再是字典,而是 Pydantic 模型实例,可直接通过“对象.字段”访问解析后的数据,更简洁、更安全。

2.3. 核心参数与实用技巧

3. SequentialChain:多步骤串行处理

SequentialChain(顺序链)是最常用的复杂链之一,核心逻辑是“多步骤串行执行”——将多个 LLMChain(或其他 Chain)按顺序串联,上一个链的输出作为下一个链的输入,形成线性的执行流程,适合需要多步骤联动的任务(如“翻译→总结→情感分析”“关键词提取→文本生成→格式解析”)。

根据输入输出的传递方式,SequentialChain 分为两种:

3.1. SimpleSequentialChain(简单顺序链)

适用场景:多步骤联动,且每个步骤只有一个输入、一个输出,上一个步骤的输出直接作为下一个步骤的输入。

from langchain.chains import LLMChain, SimpleSequentialChain
from langchain_core.prompts import PromptTemplate
from langchain_openai import ChatOpenAI
from dotenv import load_dotenv
import os

load_dotenv()

# 步骤1:翻译链(英文→中文)
translate_prompt = PromptTemplate(
    template="将以下英文文本翻译为中文,保持原意,简洁流畅:{text}",
    input_variables=["text"]
)
translate_chain = LLMChain(llm=ChatOpenAI(api_key=os.getenv("OPENAI_API_KEY")), prompt=translate_prompt)

# 步骤2:总结链(总结中文文本)
summary_prompt = PromptTemplate(
    template="总结以下中文文本,不超过30字:{text}",
    input_variables=["text"]
)
summary_chain = LLMChain(llm=ChatOpenAI(api_key=os.getenv("OPENAI_API_KEY")), prompt=summary_prompt)

# 构建简单顺序链(串联两个步骤)
simple_sequential_chain = SimpleSequentialChain(
    chains=[translate_chain, summary_chain],
    verbose=True
)

# 调用链(仅传入初始输入text)
result = simple_sequential_chain.invoke("LangChain is a framework for building LLM applications.")

print("最终结果(总结):", result)

运行流程:

  1. 初始输入(英文)→ 翻译链 → 输出中文翻译;
  2. 翻译链的输出 → 总结链 → 输出总结结果; 运行结果:最终结果(总结): LangChain是一个用于构建大语言模型应用的框架。

3.2. SequentialChain(通用顺序链)

适用场景:多步骤联动,且存在多个输入、多个输出,需要灵活控制数据传递(比如某个步骤的输入需要初始输入+上一个步骤的输出)。

from langchain.chains import LLMChain, SequentialChain
from langchain_core.prompts import PromptTemplate
from langchain_openai import ChatOpenAI
from dotenv import load_dotenv
import os

load_dotenv()

# 步骤1:翻译链(英文→中文)
translate_prompt = PromptTemplate(
    template="将英文文本「{english_text}」翻译为中文,目标语言:{target_language}",
    input_variables=["english_text", "target_language"]
)
translate_chain = LLMChain(
    llm=ChatOpenAI(api_key=os.getenv("OPENAI_API_KEY")),
    prompt=translate_prompt,
    output_key="chinese_text"  # 定义输出键,用于传递给下一个链
)

# 步骤2:总结链(总结中文文本,结合用户要求)
summary_prompt = PromptTemplate(
    template="根据用户要求「{summary_requirement}」,总结中文文本「{chinese_text}」",
    input_variables=["summary_requirement", "chinese_text"]  # 输入:用户要求+上一个链的输出
)
summary_chain = LLMChain(
    llm=ChatOpenAI(api_key=os.getenv("OPENAI_API_KEY")),
    prompt=summary_prompt,
    output_key="summary"
)

# 构建通用顺序链
sequential_chain = SequentialChain(
    chains=[translate_chain, summary_chain],
    input_variables=["english_text", "target_language", "summary_requirement"],  # 初始输入
    output_variables=["chinese_text", "summary"],  # 最终输出(可返回中间结果)
    verbose=True
)

# 调用链(传入所有初始输入)
result = sequential_chain.invoke({
    "english_text": "LangChain provides tools for building complex LLM applications.",
    "target_language": "中文",
    "summary_requirement": "简洁明了,不超过20字"
})

print("中文翻译:", result["chinese_text"])
print("总结结果:", result["summary"])

3.3. 实战技巧与注意事项

4. TransformChain:数据预处理与后处理

前面讲解的 LLMChain、SequentialChain,核心是“调用模型”,而实际开发中,我们常常需要对数据进行预处理(如文本清洗、格式转换、关键词提取)或后处理(如结果格式化、数据过滤),这些操作无需调用模型,仅需处理数据。

LangChain 的 TransformChain(转换链)专门用于这类场景——它不调用任何模型,仅接收输入数据,通过自定义函数对数据进行转换,输出处理后的数据,常作为 SequentialChain 的“前置步骤”(预处理)或“后置步骤”(后处理)。

4.1. 核心用法:自定义数据转换函数

TransformChain 的核心是“自定义转换函数”——只需定义一个接收输入字典、返回输出字典的函数,即可构建转换链,示例如下(文本预处理:去除多余空格、换行,统一大小写):

from langchain.chains import TransformChain, SequentialChain, LLMChain
from langchain_core.prompts import PromptTemplate
from langchain_openai import ChatOpenAI
from dotenv import load_dotenv
import os

load_dotenv()

# 1. 定义数据预处理函数(TransformChain的核心)
def text_preprocess(inputs: dict) -> dict:
    """文本预处理:去除多余空格、换行,统一为小写"""
    text = inputs["raw_text"]
    # 处理逻辑
    processed_text = text.strip().replace("\n", " ").replace("  ", " ").lower()
    return {"processed_text": processed_text}

# 2. 构建TransformChain(预处理链)
preprocess_chain = TransformChain(
    input_variables=["raw_text"],  # 输入键
    output_variables=["processed_text"],  # 输出键
    transform=text_preprocess  # 自定义转换函数
)

# 3. 构建LLMChain(文本总结)
summary_prompt = PromptTemplate(
    template="总结以下文本:{processed_text}",
    input_variables=["processed_text"]
)
summary_chain = LLMChain(
    llm=ChatOpenAI(api_key=os.getenv("OPENAI_API_KEY")),
    prompt=summary_prompt,
    output_key="summary"
)

# 4. 串联预处理链和总结链
sequential_chain = SequentialChain(
    chains=[preprocess_chain, summary_chain],
    input_variables=["raw_text"],
    output_variables=["processed_text", "summary"],
    verbose=True
)

# 测试:原始文本(含多余空格、换行、大写)
raw_text = """
  LangChain IS a framework for building LLM applications.
  It provides tools for prompt engineering, output parsing, and chains.
"""
result = sequential_chain.invoke({"raw_text": raw_text})

print("原始文本:", raw_text)
print("预处理后:", result["processed_text"])
print("总结结果:", result["summary"])

运行结果: 预处理后: langchain is a framework for building llm applications. it provides tools for prompt engineering, output parsing, and chains. 总结结果: LangChain 是一个用于构建大语言模型应用的框架,提供提示工程、输出解析和链等工具。

6.4.2 进阶用法:后处理与数据过滤

TransformChain 也可作为后处理步骤,对模型输出的结果进行过滤、格式化,示例如下(过滤总结结果中的冗余词汇,调整格式):

from langchain.chains import TransformChain, SequentialChain, LLMChain
from langchain_core.prompts import PromptTemplate
from langchain_openai import ChatOpenAI
from dotenv import load_dotenv
import os

load_dotenv()

# 步骤1:总结链(生成总结)
summary_prompt = PromptTemplate(
    template="总结以下文本:{text}",
    input_variables=["text"]
)
summary_chain = LLMChain(
    llm=ChatOpenAI(api_key=os.getenv("OPENAI_API_KEY")),
    prompt=summary_prompt,
    output_key="raw_summary"
)

# 步骤2:后处理链(过滤冗余词汇、调整格式)
def summary_postprocess(inputs: dict) -> dict:
    """后处理:去除冗余词汇(如“总的来说”“综上所述”),首字母大写"""
    raw_summary = inputs["raw_summary"]
    redundant_words = ["总的来说", "综上所述", "总而言之"]
    for word in redundant_words:
        raw_summary = raw_summary.replace(word, "")
    # 首字母大写,句末加句号
    processed_summary = raw_summary.strip().capitalize() + "."
    return {"processed_summary": processed_summary}

postprocess_chain = TransformChain(
    input_variables=["raw_summary"],
    output_variables=["processed_summary"],
    transform=summary_postprocess
)

# 串联链
sequential_chain = SequentialChain(
    chains=[summary_chain, postprocess_chain],
    input_variables=["text"],
    output_variables=["raw_summary", "processed_summary"],
    verbose=True
)

# 测试
text = "LangChain是一个用于构建大语言模型应用的框架,支持提示模板、输出解析、链式调用等功能,能帮助开发者快速构建复杂的LLM应用。"
result = sequential_chain.invoke({"text": text})

print("原始总结:", result["raw_summary"])
print("后处理后:", result["processed_summary"])

运行结果: 原始总结: 总的来说,LangChain 是一个支持提示模板、输出解析等功能,能帮助开发者快速构建复杂 LLM 应用的框架。 后处理后: LangChain 是一个支持提示模板、输出解析等功能,能帮助开发者快速构建复杂 llm 应用的框架.

4.3. 实战场景与选型建议

5. RouterChain:条件分支与动态路由

前面讲解的 SequentialChain 是“线性执行”——无论输入是什么,都按固定顺序执行所有步骤。但在实际场景中,我们常常需要根据输入内容的不同,动态选择执行不同的子链,比如:

LangChain 的 RouterChain(路由链)就是为解决这类场景而生——它能根据输入内容,动态判断“应该执行哪个子链”,实现条件分支的自动化执行,就像“路由器”一样,根据输入的“地址”(内容),将请求转发到对应的“子链”。

5.1. 核心组成

RouterChain 的核心由两部分组成,缺一不可:

  1. RouterChain(路由链):负责分析输入内容,判断应该执行哪个子链,返回子链的“路由键”;
  2. DestinationChains(目标子链):多个子链的集合,每个子链对应一个“路由键”,路由链根据路由键选择对应的子链执行。

LangChain 提供了两种常用的 RouterChain:

5.2. 实战示例:LLMRouterChain 动态路由

场景:根据用户输入的需求类型,动态选择执行“翻译链”“总结链”“情感分析链”,示例如下:

from langchain.chains import LLMChain, LLMRouterChain, MultiPromptChain
from langchain_core.prompts import PromptTemplate, ChatPromptTemplate
from langchain_core.runnables import RunnableMap
from langchain_openai import ChatOpenAI
from dotenv import load_dotenv
import os

load_dotenv()

# 1. 定义目标子链(翻译、总结、情感分析)
# 子链1:翻译链
translate_prompt = PromptTemplate(
    template="将以下文本翻译为{target_language}:{text}",
    input_variables=["text", "target_language"]
)
translate_chain = LLMChain(
    llm=ChatOpenAI(api_key=os.getenv("OPENAI_API_KEY")),
    prompt=translate_prompt,
    output_key="result"
)

# 子链2:总结链
summary_prompt = PromptTemplate(
    template="总结以下文本,不超过30字:{text}",
    input_variables=["text"]
)
summary_chain = LLMChain(
    llm=ChatOpenAI(api_key=os.getenv("OPENAI_API_KEY")),
    prompt=summary_prompt,
    output_key="result"
)

# 子链3:情感分析链
sentiment_prompt = PromptTemplate(
    template="分析以下文本的情感倾向(正面/负面/中性),并简要说明原因:{text}",
    input_variables=["text"]
)
sentiment_chain = LLMChain(
    llm=ChatOpenAI(api_key=os.getenv("OPENAI_API_KEY")),
    prompt=sentiment_prompt,
    output_key="result"
)

# 2. 定义目标子链映射(路由键→子链)
destination_chains = {
    "translate": translate_chain,
    "summary": summary_chain,
    "sentiment": sentiment_chain
}

# 3. 定义路由提示(让模型判断输入属于哪种需求,返回对应的路由键)
router_prompt = ChatPromptTemplate.from_template("""
请分析用户输入的需求类型,只能返回以下路由键中的一个,无需其他任何内容:
- translate:翻译需求(需要将文本翻译成其他语言)
- summary:总结需求(需要总结文本内容)
- sentiment:情感分析需求(需要分析文本情感倾向)

用户输入:{text}
""")

# 4. 构建路由链(LLMRouterChain)
router_chain = LLMRouterChain.from_llm(
    llm=ChatOpenAI(api_key=os.getenv("OPENAI_API_KEY")),
    prompt=router_prompt,
    destination_chains=destination_chains,
    verbose=True
)

# 5. 测试不同需求
# 测试1:翻译需求
print("=== 翻译需求 ===")
result1 = router_chain.invoke({"text": "将“LangChain is great”翻译为中文", "target_language": "中文"})
print("结果:", result1["result"])

# 测试2:总结需求
print("\n=== 总结需求 ===")
result2 = router_chain.invoke({"text": "LangChain是一个用于构建大语言模型应用的框架,支持提示模板、输出解析、链式调用等功能。"})
print("结果:", result2["result"])

# 测试3:情感分析需求
print("\n=== 情感分析需求 ===")
result3 = router_chain.invoke({"text": "LangChain使用起来非常方便,极大提升了我的开发效率。"})
print("结果:", result3["result"])

说明:MultiPromptChain 会根据输入内容,匹配最贴合的提示模板(通过 description 判断),自动调用对应的子链执行,简化了路由链的配置。

5.4. 实战建议

6. 使用 LCEL(LangChain Expression Language)重写链

在 LangChain v 0.1 版本之后,官方推荐使用LCEL(LangChain Expression Language,LangChain 表达式语言)来构建和组合链,替代传统的 Chain 类(如 LLMChain、SequentialChain)。LCEL 是一种简洁、灵活的语法,核心优势是“声明式编程”——只需描述“输入→处理步骤→输出”的逻辑,无需手动构建 Chain 类,代码更简洁、更易读、更易扩展。

简单来说,LCEL 用“|”(管道符)将多个组件(提示模板、模型、解析器、转换函数等)串联起来,形成一条完整的链,本质上是对传统 Chain 的简化和优化。

6.1. LCEL 核心语法与优势

1. 核心语法

LCEL 的核心语法是“管道符(|)”,用于串联组件,格式如下:

# 基础格式:输入 → 组件1 → 组件2 → ... → 输出
chain = component1 | component2 | component3

支持的组件类型:PromptTemplate、LLM/ChatModel、OutputParser、TransformChain、自定义函数、其他链,甚至是 Runnable(LangChain 的核心可运行单元)。

2. 核心优势

6.2. 实战示例 1:用 LCEL 重写 LLMChain

传统 LLMChain 的功能(提示模板+模型+解析器),用 LCEL 可简化为一行代码,示例如下:

from langchain_core.prompts import PromptTemplate
from langchain_core.output_parsers import PydanticOutputParser
from langchain_openai import ChatOpenAI
from dotenv import load_dotenv
import os
from pydantic import BaseModel, Field

load_dotenv()

# 1. 定义Pydantic模型、解析器、提示模板、模型
class AdCopy(BaseModel):
    copy: str = Field(description="宣传语,不超过15字")
    feature: str = Field(description="突出的产品优势")

parser = PydanticOutputParser(pydantic_object=AdCopy)
prompt = PromptTemplate(
    template="为{product}撰写宣传语,突出{feature}优势(不超过15字),按要求输出:\n{format_instructions}",
    input_variables=["product", "feature"],
    partial_variables={"format_instructions": parser.get_format_instructions()}
)
chat_model = ChatOpenAI(api_key=os.getenv("OPENAI_API_KEY"), temperature=0.7)

# 2. 用LCEL构建链(管道符串联)
chain = prompt | chat_model | parser

# 3. 调用链
result = chain.invoke({"product": "LangChain教程", "feature": "实战导向"})

print("宣传语:", result.copy)
print("突出优势:", result.feature)

对比传统 LLMChain:无需手动构建 LLMChain 类,用“prompt | chat_model | parser”即可实现相同功能,代码更简洁,逻辑更清晰。

6.3. 实战示例 2:用 LCEL 重写 SequentialChain(多步骤串联)

传统 SequentialChain 的多步骤串联,用 LCEL 可直接用管道符串联多个组件,示例如下(翻译→总结→情感分析):

from langchain_core.prompts import PromptTemplate
from langchain_openai import ChatOpenAI
from dotenv import load_dotenv
import os

load_dotenv()

# 1. 定义各个步骤的组件
# 步骤1:翻译提示+模型
translate_prompt = PromptTemplate(
    template="将以下英文翻译为中文:{text}",
    input_variables=["text"]
)
translate_model = ChatOpenAI(api_key=os.getenv("OPENAI_API_KEY"), temperature=0.5)
translate_chain = translate_prompt | translate_model

# 步骤2:总结提示+模型
summary_prompt = PromptTemplate(
    template="总结以下中文文本,不超过30字:{text}",
    input_variables=["text"]
)
summary_model = ChatOpenAI(api_key=os.getenv("OPENAI_API_KEY"), temperature=0.5)
summary_chain = summary_prompt | summary_model

# 步骤3:情感分析提示+模型
sentiment_prompt = PromptTemplate(
    template="分析以下文本的情感倾向(正面/负面/中性):{text}",
    input_variables=["text"]
)
sentiment_model = ChatOpenAI(api_key=os.getenv("OPENAI_API_KEY"), temperature=0.5)
sentiment_chain = sentiment_prompt | sentiment_model

# 2. 用LCEL串联多步骤(翻译→总结→情感分析)
# 注意:需要用lambda函数传递上一步的输出作为下一步的输入
full_chain = (
    translate_chain
    | lambda x: {"text": x.content}  # 提取翻译结果,作为总结的输入
    | summary_chain
    | lambda x: {"text": x.content}  # 提取总结结果,作为情感分析的输入
    | sentiment_chain
)

# 3. 调用链
result = full_chain.invoke({"text": "LangChain is a powerful framework that makes LLM development easier."})

print("最终情感分析结果:", result.content)

说明:用 lambda 函数提取上一步的输出(x.content,模型输出的内容),并转换为下一步所需的输入格式,实现多步骤的数据传递,比传统 SequentialChain 更灵活。

6.4. 实战示例 3:LCEL 结合 TransformChain(数据预处理)

LCEL 可直接串联 TransformChain(或自定义转换函数),实现“预处理→模型调用→解析”的一站式流程,示例如下:

from langchain_core.prompts import PromptTemplate
from langchain_core.output_parsers import PydanticOutputParser
from langchain_openai import ChatOpenAI
from dotenv import load_dotenv
import os
from pydantic import BaseModel, Field

load_dotenv()

# 1. 定义数据预处理函数(替代TransformChain)
def text_preprocess(inputs: dict) -> dict:
    text = inputs["raw_text"]
    processed_text = text.strip().replace("\n", " ").lower()
    return {"text": processed_text}

# 2. 定义解析器、提示模板、模型
class SummaryResult(BaseModel):
    summary: str = Field(description="文本总结,不超过30字")

parser = PydanticOutputParser(pydantic_object=SummaryResult)
prompt = PromptTemplate(
    template="总结以下文本:{text}\n{format_instructions}",
    input_variables=["text"],
    partial_variables={"format_instructions": parser.get_format_instructions()}
)
chat_model = ChatOpenAI(api_key=os.getenv("OPENAI_API_KEY"), temperature=0.5)

# 3. 用LCEL串联(预处理→提示→模型→解析)
chain = text_preprocess | prompt | chat_model | parser

# 4. 调用链
raw_text = """
  LangChain IS a framework for building LLM applications.
  It provides tools for prompt engineering and output parsing.
"""
result = chain.invoke({"raw_text": raw_text})

print("预处理后文本:", text_preprocess({"raw_text": raw_text})["text"])
print("总结结果:", result.summary)

说明:LCEL 可直接串联自定义转换函数(如 text_preprocess),无需手动构建 TransformChain,进一步简化代码。

6.5. LCEL 核心技巧与注意事项

7. 链的嵌套与复用技巧

在实际开发中,复杂的大模型应用往往需要多个链的协同工作——将一个链作为另一个链的“子链”(嵌套),或复用已有的链(避免重复开发),这是提升开发效率、降低代码冗余的关键技巧。

本节将讲解链的嵌套用法和复用技巧,结合前面所学的 Chain 类和 LCEL,实现更灵活、更可维护的链式工作流。

7.1. 链的嵌套:将链作为子链

链的嵌套核心:将一个完整的链(如 LLMChain、LCEL 链)作为另一个链(如 SequentialChain、RouterChain)的步骤,实现“链中链”的结构,适配复杂任务。

示例:构建“预处理→翻译→总结”三步链,其中“翻译→总结”是一个独立的子链,嵌套到完整链中:

from langchain.chains import SequentialChain, LLMChain
from langchain_core.prompts import PromptTemplate
from langchain_openai import ChatOpenAI
from dotenv import load_dotenv
import os

load_dotenv()

# 1. 定义子链:翻译→总结(用LCEL简化)
translate_prompt = PromptTemplate(
    template="将英文「{text}」翻译为中文:",
    input_variables=["text"]
)
summary_prompt = PromptTemplate(
    template="总结中文文本「{text}」,不超过30字:",
    input_variables=["text"]
)
chat_model = ChatOpenAI(api_key=os.getenv("OPENAI_API_KEY"), temperature=0.5)

# 子链(LCEL构建)
translate_summary_chain = (
    translate_prompt
    | chat_model
    | lambda x: {"text": x.content}
    | summary_prompt
    | chat_model
)

# 2. 定义预处理链(TransformChain)
def text_preprocess(inputs: dict) -> dict:
    text = inputs["raw_text"]
    processed_text = text.strip().replace("\n", " ")
    return {"text": processed_text}

from langchain.chains import TransformChain
preprocess_chain = TransformChain(
    input_variables=["raw_text"],
    output_variables=["text"],
    transform=text_preprocess
)

# 3. 嵌套子链:预处理链 + 翻译总结子链
full_chain = SequentialChain(
    chains=[preprocess_chain, translate_summary_chain],
    input_variables=["raw_text"],
    output_variables=["text"],  # 子链的输出
    verbose=True
)

# 测试
raw_text = """
  LangChain provides a set of tools for building complex LLM applications,
  including prompt templates, output parsers, and chains.
"""
result = full_chain.invoke({"raw_text": raw_text})

print("最终总结结果:", result["text"])