在前面几篇文章中,我们已经掌握了LangChain的核心组件:提示词模板、大语言模型、输出解析器。细心的读者可能发现,在使用这些组件时,经常会看到类似 prompt | llm | parser 这样的链式操作。这就是今天重点介绍的LCEL(LangChain Expression Language)表达式。
在平时开发中,经常需要将多个组件组合起来形成完整的处理流程,将上一个组件的输出作为下一个组件的输入,在不使用LCEL表达式之前,就会写出这种代码:使用 invoke() 进行层层嵌套,这就好比早期 JS 中的回调地狱,结构混乱、难以维护,并且出现错误很难判断是哪一步出了问题。- # 1.构建提示词
- prompt = ChatPromptTemplate.from_messages([
- ("system", "你是一个资深文学家"),
- ("human", "请简短赏析{name}这首诗,并给出评价")
- ])
- # 2.创建模型
- llm = ChatOpenAI()
- # 3.创建字符串输出解析器
- parser = StrOutputParser()
- # 4.调用模型返回结果
- result = parser.invoke(
- llm.invoke(
- prompt.invoke({"name": "江雪"})
- )
- )
复制代码 而LCEL让这个过程变得简洁直观,通过管道符号进行连接,可以很轻松地构建出功能强大的AI应用。
文中所有示例代码:https://github.com/wzycoding/langchain-study
一、什么是LCEL表达式
LCEL(LangChain Expression Language)是LangChain框架的表达式语言,它提供了一种声明式的方式来构建复杂的数据处理链。通过LCEL,我们可以使用管道符号 | 将不同的组件连接起来,形成一个完整的数据处理链。
LCEL有以下优点:
1、代码更加简洁:用管道符号连接组件,代码更加简洁易读
2、可任意组合:任意Runnable组件都可以自由组合,构建复杂的处理逻辑
3、统一接口规范:所有Runnable组件都遵循统一的接口规范
4、方便监控与调试:LangChain内置了日志和监控功能,方便调试和优化
下面是使用LCEL表达式的案例:- # 1.构建提示词
- prompt = ChatPromptTemplate.from_messages([
- ("system", "你是一个资深文学家"),
- ("human", "请简短赏析{name}这首诗,并给出评价")
- ])
- # 2.创建模型
- llm = ChatOpenAI()
- # 3.创建字符串输出解析器
- parser = StrOutputParser()
- # 4.构建链
- chain = prompt | llm | parser
- # 5.执行链
- print(f"输出结果:{chain.invoke({'name': '题西林壁'})}")
复制代码 显而易见,LCEL写法更加简洁,而且表达了清晰的数据流向:输入经过提示词模板处理,然后将PromptValue传递给大语言模型,最后将大语言模型输出的Message传递给输出解析器,经过输出解析器解析得到最终结果。
二、什么是Runnable组件
在深入LCEL之前,首先需要理解Runnable接口。Runnable是LangChain中所有可执行组件的基础接口,它定义了组件应该具备的标准方法。前面介绍的LangChain组件如提示词模板、模型、输出解析器等,都实现了Runnable接口,这就是为什么这些组件可以使用管道符进行连接的原因。
在Runnable接口中定义了以下核心方法:
invoke(input):同步执行,处理单个输入,最常用的方法
batch(inputs):批量执行,处理多个输入,提升处理效率
stream(input):流式执行,逐步返回结果,经典的使用场景是大模型是一点点输出的,不是一下返回整个结果,可以通过 stream() 方法,进行流式输出
ainvoke(input):异步执行,用于高并发场景
三、RunnableBranch条件分支
在LangChain中提供了类RunnableBranch来完成LCEL中的条件分支判断,它可以根据输入的不同采用不同的处理逻辑,具体示例如下,在下方示例中程序会根据用户输入中是否包含‘日语’、‘韩语’等关键词,来选择对应的提示词进行处理。根据判断结果,再执行不同的逻辑分支。- import dotenv
- from langchain_core.output_parsers import StrOutputParser
- from langchain_core.prompts import ChatPromptTemplate
- from langchain_core.runnables import RunnableBranch
- from langchain_openai import ChatOpenAI
- # 读取env配置
- dotenv.load_dotenv()
- def judge_language(inputs):
- """判断语言种类"""
- query = inputs["query"]
- if "日语" in query:
- return "japanese"
- elif "韩语" in query:
- return "korean"
- else:
- return "english"
- # 1.构建提示词
- english_prompt = ChatPromptTemplate.from_messages([
- ("system", "你是一个英语翻译专家,你叫小英"),
- ("human", "{query}")
- ])
- japanese_prompt = ChatPromptTemplate.from_messages([
- ("system", "你是一个日语翻译专家,你叫小日"),
- ("human", "{query}")
- ])
- korean_prompt = ChatPromptTemplate.from_messages([
- ("system", "你是一个韩语翻译专家,你叫小韩"),
- ("human", "{query}")
- ])
- # 2.创建模型
- llm = ChatOpenAI()
- # 3.创建字符串输出解析器
- parser = StrOutputParser()
- # 4.构建链分支结构,默认分支为英语
- chain = RunnableBranch(
- (lambda x: judge_language(x) == "japanese", japanese_prompt | llm | parser),
- (lambda x: judge_language(x) == "korean", korean_prompt | llm | parser),
- (english_prompt | llm | parser)
- )
- # 5.执行链
- print(f"输出结果:{chain.invoke({'query': '请你用韩语翻译这句话:“我爱你”。并且告诉我你叫什么'})}")
复制代码 执行结果如下,根据执行结果,执行的是韩语分支。
[code]输出结果:“我爱你”用韩语是:“사랑해” (Saranghae)。我叫小韩,很高兴为你服务!
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |