学习记录01——LCEL

3 阅读2分钟

LCEL 的全称是 LangChain Expression Language,翻译过来就是 LangChain 表达式语言。

简单说,LCEL 是 LangChain 提供的一种声明式语言,专门用来把多个组件串成一条链。你之前问的那行代码里的 | (管道符),就是它最核心的语法。


为什么需要 LCEL?

在没有 LCEL 之前,要用 LangChain 搭一条链,通常得这么写:

# 传统写法 (SequentialChain 等)
chain = SequentialChain(
    chains=[prompt_chain, llm_chain, parser_chain],
    input_variables=["input"],
    output_variables=["result"]
)

这种写法有几个痛点:

  • 不直观:非得套一层 SequentialChain,没法一眼看出数据是怎么流的。
  • 难组合:想在中间加个处理步骤,得改一大片代码。
  • 功能受限:想用异步、流式、批量处理,得自己写一大堆代码。

而用 LCEL,只需要:

chain = prompt | llm | parser

数据流向一目了然,从左到右,清晰无比。


LCEL 的核心玩法就是 | 管道符

这个 | 是 LangChain 重载过的,它的作用就一个:把前一个组件的输出,传给下一个组件当输入

chain = component_1 | component_2 | component_3

执行的时候等价于:

output_1 = component_1.invoke(input)
output_2 = component_2.invoke(output_1)
result = component_3.invoke(output_2)

所有实现了 Runnable 协议的对象(比如 ChatPromptTemplateChatOpenAI、各种 Parser)都能用 | 自由连接。


LCEL 带来的四大好处

  1. 天然支持异步:不用你额外写代码,直接就有 chain.ainvoke()chain.astream() 可以用。
  2. 天然支持流式:同样,chain.stream() 开箱即用。
  3. 天然支持批量chain.batch() 自动并行处理多个输入。
  4. 可观测性一流:所有 LCEL 链都能无缝接入 LangSmith 做调试和追踪。

举个例子,对比一下

假设你要搭一个“生成冷笑话并翻译成中文”的链。

不用 LCEL:

from langchain.chains import LLMChain, TransformChain, SequentialChain

# 得显式定义每一步的 Chain
generate_chain = LLMChain(prompt=...)
translate_chain = LLMChain(prompt=...)
chain = SequentialChain(chains=[generate_chain, translate_chain], ...)

用 LCEL:

generate_prompt = ChatPromptTemplate.from_template("讲一个关于{topic}的冷笑话")
translate_prompt = ChatPromptTemplate.from_template("把下面内容翻译成中文:\n{text}")

chain = (
    generate_prompt | llm | StrOutputParser() |
    (lambda joke: {"text": joke}) | translate_prompt | llm | StrOutputParser()
)

总结一下,LCEL 就是 LangChain 的“官方流水线语法”,核心就是 | 管道符,让你可以像搭乐高一样把各个组件拼起来,代码简洁、功能强大、维护方便。