langchain(七)表达式 LCEL
介绍
LCEL是LangChain 表达式语言(LangChain Expression Language)的简称。使用LCEL可以快速将各种链组合到一起,那链又是啥呢?
在LangChain里只要实现了Runnable接口,并且有invoke方法,都可以成为链。实现了Runnable接口的类,可以拿上一个链的输出作为自己的输入。


区别
不使用LCEL
不使用LCEL时,代码写起来是,各种invoke满天飞。比如这样:
final_prompt = prompt.invoke({"book_introduction": book_introduction,
"parser_instructions": output_parser.get_format_instructions()})
response = model.invoke(final_prompt)
result = output_parser.invoke(response)
使用LCEL
使用LCEL时,代码简洁,并且表达力强许多,比如这样:
chain = prompt | model | output_parser
ret = chain.invoke({"book_introduction": book_introduction,
"parser_instructions": output_parser.get_format_instructions()})
LangChain表达式语言,或者LCEL,是一种声明式的方式,可以轻松地将链条组合在一起。 LCEL从第一天开始就被设计为支持将原型放入生产中,不需要改变任何代码,从最简单的“提示+LLM”链到最复杂的链(我们已经看到人们成功地在生产中运行了包含数百步的LCEL链)。以下是你可能想要使用LCEL的一些原因:
流式支持 当你用LCEL构建你的链时,你可以得到最佳的首次到令牌的时间(输出的第一块内容出来之前的时间)。对于一些链,这意味着例如我们直接从LLM流式传输令牌到一个流式输出解析器,你可以以与LLM提供者输出原始令牌相同的速率得到解析后的、增量的输出块。
异步支持 任何用LCEL构建的链都可以通过同步API(例如在你的Jupyter笔记本中进行原型设计时)以及异步API(例如在LangServe服务器中)进行调用。这使得可以使用相同的代码进行原型设计和生产,具有很好的性能,并且能够在同一台服务器中处理许多并发请求。
优化的并行执行 无论何时,你的LCEL链有可以并行执行的步骤(例如,如果你从多个检索器中获取文档),我们都会自动执行,无论是在同步接口还是异步接口中,以获得最小可能的延迟。
重试和回退 为你的LCEL链的任何部分配置重试和回退。这是一种使你的链在大规模下更可靠的好方法。我们目前正在努力为重试/回退添加流式支持,这样你就可以在没有任何延迟成本的情况下获得增加的可靠性。
访问中间结果 对于更复杂的链,通常在最终输出产生之前就能访问中间步骤的结果是非常有用的。这可以用来让最终用户知道正在发生什么,甚至只是用来调试你的链。你可以流式传输中间结果,它在每个LangServe服务器上都可用。
输入和输出模式 输入和输出模式为每个LCEL链提供了从你的链的结构中推断出来的Pydantic和JSONSchema模式。这可以用于验证输入和输出,是LangServe的一个重要部分。
无缝的LangSmith跟踪集成 随着你的链变得越来越复杂,理解在每一步究竟发生了什么变得越来越重要。 使用LCEL,所有步骤都会自动记录到LangSmith,以实现最大的可观察性和可调试性。
无缝的LangServe部署集成 任何用LCEL创建的链都可以使用LangServe轻松部署。
例子
import os
from dotenv import load_dotenv
from langchain_openai import ChatOpenAI
from pydantic import SecretStr
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate
load_dotenv()
llm = ChatOpenAI(
base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
model="qwen-plus",
api_key=SecretStr(os.environ["DASHSCOPE_API_KEY"]),
)
# 2. 提示词模板
prompt_template = ChatPromptTemplate.from_messages([
("user", "{text}") # 用户输入占位符
])
# 3. 结果解析器
parser = StrOutputParser()
# 4. 构建调用链(补充LLM实例)
chain = prompt_template | llm | parser
# 5. 调用链并输出结果
result = chain.invoke({"text": "你是谁?"})
print(result)
请注意这行代码,我们使用LCEL将不同的组件组合成一个单一的链条:
chain = prompt_template | llm | parser
| 符号类似于 unix 管道操作符,它将不同的组件链接在一起,将一个组件的输出作为下一个组件的输入。
在这个链条中,用户输入被传递给提示模板,然后提示模板的输出被传递给模型,然后模型的输出被传递给输出解析器。让我们逐个组件地看一下,以真正理解发生了什么。
LCEL 强调组件之间的职责明确,Prompt 只负责模板化输入,Parser 只负责格式化输出,Model 只负责推理。
LCEL 是 LangChain 在 2024 年末引入的一项重要特性,标志着从传统 Agent 架构向“声明式、组合式”开发范式的转变。它不仅让开发者能以更清晰的方式组织 LLM 工作流,也大大提高了系统的可维护性与可测试性。
更多推荐


所有评论(0)