尽管对语言模型的独立调用很有用,但大多数实际应用都涉及一系列操作。用户的查询可能首先需要被优化,然后传递给模型,最后,模型的输出可能需要被解析并用作另一项任务的输入。链提供了一种结构,可以将这些操作连接成一个统一的整体。本质上,链是一个端到端流程,它接收输入并通过一系列组件处理数据以产生输出。可以将其视为函数组合。如果格式化提示词是一个函数 $f_{提示词}$,调用模型是另一个函数 $f_{模型}$,那么一个简单的链就代表了它们的组合: $$ \text{输出} = f_{模型}(f_{提示词}(\text{输入})) $$ 这种结构使您的应用逻辑清晰且易于管理。您无需编写命令式代码来处理每个步骤,而是定义一个由LangChain执行的声明式序列。基本链的构成最基本的链包含三个部分,您在上一章中已经熟悉它们:提示词模板、模型和输出解析器。PromptTemplate (提示词模板): 接收初始输入变量(例如,一个字典),并将它们格式化为模型所需的提示词值(可以是字符串或消息列表)。Model (模型,即LLM或ChatModel): 接收格式化后的提示词并生成响应(一个文本字符串或一个消息对象)。OutputParser (输出解析器): 接收模型输出并将其转换为更有用的格式,例如JSON或Python对象。此序列代表一个单一的、可重用的逻辑块。下图说明了这一流程,显示了数据在每个步骤中如何转换。digraph G { rankdir=TB; bgcolor="transparent"; node [shape=box, style="rounded,filled", fontname="Arial"]; A [label="输入字典", shape=parallelogram, fillcolor="#e9ecef"]; B [label="提示词模板", fillcolor="#bac8ff"]; C [label="语言模型", fillcolor="#a5d8ff"]; D [label="输出解析器", fillcolor="#96f2d7"]; E [label="结构化输出", shape=parallelogram, fillcolor="#e9ecef"]; A -> B [label=" 变量"]; B -> C [label=" 格式化提示词"]; C -> D [label=" 响应"]; D -> E [label=" 解析数据"]; }标准链通过提示词模板、语言模型和输出解析器来处理输入,以生成结构化数据。链为何是一种不可或缺的结构将应用逻辑组织成链,相比手动编排每次调用,提供了多项优势。标准化: 每个链都暴露出统一的接口。无论一个链执行单次LLM调用还是一个包含十个步骤的流程,您都以相同的方式与其交互。这通常涉及诸如用于单个输入的 invoke() 方法、用于流式输出的 stream() 方法以及用于高效处理多个输入的 batch() 方法。这种一致性简化了构建和测试。模块化和可组合性: 链是自包含且可重用的。一个用于总结文章的链可以是一个更大链中的单一组件,该链首先获取文章,然后总结,最后翻译摘要。这种模块化对于构建精密应用而非创建难以管理的代码来说非常重要。可观察性: 当您运行一个链时,LangChain可以追踪整个执行流程。这使得调试更容易,因为您可以看到序列中每个步骤的精确输入和输出。当我们将介绍LangSmith时,会对此进行详细说明。在LangChain中构建链的标准方式是使用LangChain表达式语言 (LCEL),它使用管道 (|) 运算符来连接组件。这种语法使得数据流直观且易读。一个由提示词、模型和解析器组成的简单链将是这样的:chain = prompt | model | parser这行代码定义了一个完整、可执行的流程。输入首先“通过管道”进入提示词,生成的提示词“通过管道”进入模型,模型的输出“通过管道”进入解析器。在后续部分中,我们将使用这种组合语法来构建我们的第一个链,并学习更高级的顺序模式。