一、什么是 LCEL?
LCEL 全称 LangChain Expression Language ,即 LangChain 表达式语言,是 LangChain 提供的一种声明式语法,用于以简洁、优雅的方式构建 Chain(链)。
二、核心语法
LCEL 的核心是 | 管道操作符,语法灵感来源于 Linux 管道命令,将多个组件串联起来,数据从左到右依次流转:
python
chain = prompt | model | output_parser
result = chain.invoke({"topic": "AI"})
三、与传统写法的对比
传统写法(旧版)
python
from langchain.chains import LLMChain
chain = LLMChain(llm=model, prompt=prompt)
result = chain.run("AI")
LCEL 写法(新版)
python
chain = prompt | model | StrOutputParser()
result = chain.invoke({"topic": "AI"})
相比之下,LCEL 写法更加简洁直观,且具备更多内置能力。
四、完整使用示例
python
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
# 1. 定义各组件
prompt = ChatPromptTemplate.from_template("请介绍一下{topic}")
model = ChatOpenAI(model="gpt-3.5-turbo")
parser = StrOutputParser()
# 2. 用 | 组合成 Chain
chain = prompt | model | parser
# 3. 调用
result = chain.invoke({"topic": "人工智能"})
print(result)
五、核心优势
| 特性 | 说明 |
|---|---|
| 🔄 流式输出 | 原生支持 stream(),实时返回结果 |
| ⚡ 异步支持 | 原生支持 ainvoke()、astream() |
| 🔀 并行执行 | 使用 RunnableParallel 并发运行多个任务 |
| 📦 批量处理 | 原生支持 batch(),一次处理多条输入 |
| 🔍 可观测性 | 自动集成 LangSmith,方便链路追踪与调试 |
| 🔁 重试/回退 | 支持 .with_retry()、.with_fallbacks() 提升稳定性 |
🔄 流式输出(Streaming)
流式输出允许模型边生成边返回,而不是等全部生成完再返回,大幅提升用户体验。
python
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
prompt = ChatPromptTemplate.from_template("写一篇关于{topic}的文章")
model = ChatOpenAI(model="gpt-3.5-turbo")
parser = StrOutputParser()
chain = prompt | model | parser
# 流式输出,逐字打印
for chunk in chain.stream({"topic": "人工智能"}):
print(chunk, end="", flush=True)
输出效果如下,模型会逐字实时返回,而非等待全部生成完毕:
人 工 智 能 是 ...(逐字实时输出)
适用场景:聊天对话界面、长文本生成等需要实时反馈的场景。
⚡ 异步支持(Async)
LCEL 原生支持异步调用,适合在 FastAPI、异步爬虫 等异步框架中使用,避免阻塞主线程。
python
import asyncio
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
prompt = ChatPromptTemplate.from_template("用一句话介绍{topic}")
model = ChatOpenAI(model="gpt-3.5-turbo")
chain = prompt | model | StrOutputParser()
async def main():
# 异步单次调用
result = await chain.ainvoke({"topic": "机器学习"})
print(result)
# 异步流式输出
async for chunk in chain.astream({"topic": "深度学习"}):
print(chunk, end="", flush=True)
asyncio.run(main())
适用场景:Web 服务接口、需要高并发的后端服务。
🔀 并行执行(Parallel)
使用 RunnableParallel 可以同时执行多个子链,最终合并结果,节省总耗时。
python
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
from langchain_core.runnables import RunnableParallel
model = ChatOpenAI(model="gpt-3.5-turbo")
parser = StrOutputParser()
# 定义两个不同的子链
summary_chain = (
ChatPromptTemplate.from_template("用100字总结:{text}") | model | parser
)
keyword_chain = (
ChatPromptTemplate.from_template("提取5个关键词:{text}") | model | parser
)
# 并行执行
parallel_chain = RunnableParallel({
"摘要": summary_chain,
"关键词": keyword_chain,
})
result = parallel_chain.invoke({"text": "LangChain 是一个用于构建 LLM 应用的框架..."})
print(result)
两个子链会同时执行,最终合并输出:
python
{
"摘要": "LangChain 是一个强大的 LLM 应用构建框架...",
"关键词": "LangChain、LLM、框架、链式调用、Agent"
}
适用场景:需要同时从多个角度处理同一份输入,如同时生成摘要、翻译、关键词等。
📦 批量处理(Batch)
batch() 方法支持一次性处理多条输入,内部自动并发执行,比循环调用效率更高。
python
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
prompt = ChatPromptTemplate.from_template("用一句话介绍{topic}")
model = ChatOpenAI(model="gpt-3.5-turbo")
chain = prompt | model | StrOutputParser()
# 一次性处理多条输入
results = chain.batch([
{"topic": "Python"},
{"topic": "JavaScript"},
{"topic": "Rust"},
{"topic": "Go"},
])
for r in results:
print(r)
输出结果:
erlang
Python 是一种简洁易学的高级编程语言...
JavaScript 是一种广泛用于 Web 开发的脚本语言...
Rust 是一种注重安全性和性能的系统编程语言...
Go 是 Google 开发的一种高效并发编程语言...
适用场景:批量处理文档、批量翻译、批量分类等任务。
🔍 可观测性(LangSmith 追踪)
LCEL 自动集成 LangSmith,无需额外代码即可记录每一步的输入输出、耗时、Token 消耗等信息。
python
import os
# 配置环境变量即可自动开启追踪
os.environ["LANGCHAIN_TRACING_V2"] = "true"
os.environ["LANGCHAIN_API_KEY"] = "your_langsmith_api_key"
os.environ["LANGCHAIN_PROJECT"] = "my-lcel-project"
# 之后正常调用链,自动记录追踪信息
chain.invoke({"topic": "AI"})
配置完成后,LangSmith 面板将自动记录以下信息:
bash
[LangSmith 追踪面板]
├── Chain 总耗时: 1.23s
├── Prompt 渲染结果: "请介绍一下 AI"
├── Model 输出: "AI 是人工智能的缩写..."
├── Token 消耗: 输入 15 tokens,输出 120 tokens
└── 总费用: $0.0002
适用场景:开发调试、性能监控、问题排查、成本分析。
🔁 重试与回退(Retry & Fallback)
重试(with_retry)
当调用失败时(如网络超时),自动重试,提升服务稳定性。
python
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
model = ChatOpenAI(model="gpt-3.5-turbo")
# 设置最多重试 3 次
model_with_retry = model.with_retry(
stop_after_attempt=3, # 最多重试 3 次
wait_exponential_jitter=True # 指数退避 + 随机抖动
)
chain = ChatPromptTemplate.from_template("介绍{topic}") | model_with_retry | StrOutputParser()
result = chain.invoke({"topic": "AI"})
回退(with_fallbacks)
当主模型失败时,自动切换到备用模型,保证服务可用性。
python
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
# 主模型(优先使用 GPT-4)
primary_model = ChatOpenAI(model="gpt-4")
# 备用模型(GPT-4 失败时降级到 GPT-3.5)
fallback_model = ChatOpenAI(model="gpt-3.5-turbo")
# 设置回退策略
model_with_fallback = primary_model.with_fallbacks([fallback_model])
chain = (
ChatPromptTemplate.from_template("介绍{topic}")
| model_with_fallback
| StrOutputParser()
)
result = chain.invoke({"topic": "AI"})
print(result)
执行逻辑如下:
markdown
调用 GPT-4
├── 成功 → 返回结果 ✅
└── 失败 → 自动切换 GPT-3.5-turbo → 返回结果 ✅
适用场景:生产环境容灾、多模型降级策略、API 限流处理。
六、常用组件
LCEL 提供了一系列内置的 Runnable 组件,满足不同场景需求:
python
from langchain_core.runnables import (
RunnableParallel, # 并行执行多个子链
RunnablePassthrough, # 直接透传输入数据
RunnableLambda, # 将自定义函数包装为 Runnable
)
# 示例:并行执行两个子链
chain = RunnableParallel({
"summary": prompt1 | model | parser,
"keywords": prompt2 | model | parser,
})
七、总结
LCEL 是 LangChain 推荐的现代化链式构建方案,其核心价值可以概括为以下三点:
- 简洁性 :用
|管道符串联组件,代码直观易读- 灵活性:支持顺序、并行、条件等多种组合方式
- 生产级能力:内置流式、异步、批量、重试等特性,开箱即用
无论是快速原型开发还是生产环境部署,LCEL 都是构建 LangChain 应用的首选方式。