核心要点
LCEL = LangChain Expression Language,声明式组合链路的方式
用管道符 | 把多个 Runnable 串接,输出自动作为下一步输入
统一接口:每个链都自动获得 invoke / batch / stream 及异步 ainvoke 等
内置能力:流式输出、并行执行、异步、重试与 fallback、与 LangSmith 可观测
取代旧的硬编码 Chain 类,成为 2026 LangChain 推荐写法
标准回答
LCEL(LangChain Expression Language)是 LangChain 用来声明式拼装链路的表达式语言,核心是用管道把一个个 Runnable 组合起来。
基本概念
LangChain 把提示模板、模型、输出解析器、检索器、自定义函数等都统一抽象成 Runnable 接口。LCEL 用管道符 | 把它们串联:上一步的输出自动成为下一步的输入,例如 prompt | model | output_parser 就声明了"填模板 → 调模型 → 解析输出"的完整流程。这是声明式的"描述要做什么",而不是命令式地手写每一步调用与传参。
核心优势
- 统一接口:任何用 LCEL 组合出的链都自动实现一组标准方法——
invoke(单条同步)、batch(批量)、stream(流式逐块返回)以及对应的异步版ainvoke/abatch/astream。换链不换调用方式。 - 天然流式:只要链路里的环节支持流式,整条链就能逐 token 流式输出,无需额外改写,对聊天体验至关重要。
- 并行与异步:用 RunnableParallel 可并行执行多个分支(如同时检索多个数据源),整体延迟取决于最慢分支而非串行累加;异步接口天然支持高并发。
- 重试与 fallback:可为任意环节配置自动重试、超时和备用模型/备用链,主模型失败时优雅降级,提升健壮性。
- 可观测:与 LangSmith 深度集成,每个 Runnable 步骤的输入输出、耗时、token 都可追踪,便于调试与评估。
为什么取代旧 Chain
早期 LangChain 提供大量硬编码的 Chain 类(如 LLMChain),它们封装死板、难以自由组合、流式与异步支持不一致。LCEL 用统一的 Runnable 协议 + 管道组合,把这些能力一次性、可组合地提供出来,因此 2026 年官方推荐用 LCEL 组合 Runnable,而非继续使用旧的具体 Chain 子类。
常见误区
⚠️ 常见踩坑
以为 LCEL 只是语法糖;它的真正价值是统一 Runnable 接口后"免费"获得流式、批量、异步、并行、重试与可观测——这些都不需要你为每条链单独实现。
追问
追问 1:LCEL 里如何并行执行多个步骤、又如何把变量透传下去?
并行用 RunnableParallel(也可直接用字典字面量声明多个键),多个分支同时执行、结果按键汇总,整体延迟取决于最慢分支。透传或重组输入常用 RunnablePassthrough,它把上游输入原样传下去或与新计算结果合并,典型场景是 RAG 中一边检索文档、一边把原始问题保留,再一起喂给提示模板。
追问 2:一个 LCEL 链怎么实现流式输出,整条链都能流式吗?
调用链的 stream/astream 方法即可逐块拿到结果。能否真正逐 token 流式取决于链路中每个环节是否支持流式:LLM 通常支持,因此 prompt | model 可以流式;但若末端接了一个需要拿到完整输出才能工作的解析器(如严格 JSON 解析),流式会被该环节"阻断"成等待完整结果。设计时应把阻断式步骤尽量后置或改造。
追问 3:怎么给 LCEL 链加上失败重试和备用模型?
Runnable 提供 with_retry 配置自动重试(可设次数与退避),with_fallbacks 配置一组备用 Runnable:当主环节抛错时按顺序尝试备用,例如主模型限流或超时就切换到备用模型或更便宜的模型。这样无需在业务代码里手写 try/except 和切换逻辑,健壮性以声明方式内建在链里。
🔗 相似问题
同一考点的不同问法,面试官可能换着问,一起刷更稳
没找到想看的面试题?把你想看的告诉我们 →
延伸学习
按主题分类的相关资源,便于系统复习