【大语言模型】LangChain LCEL 表达式语言
一、简介
LangChain LCEL 的全称为 LangChain Expression Language 即可直译为 LangChain 表达式。
为了构造更复杂的 LLM 应用并且更为简便快捷的构造 LLM 应用,Langchain 提供了类似"管道"的形式去声明提示词模板(prompt),即用 "|" 来连接各个组件之间的操作。也就是 LCEL 允许开发者将不同的模块进行简单的形式实现串联。语法如下所示:
chain = 提示词板 | 大模型调用 | 输出解析器
二、LCEL的优势
很多人疑惑的一点可能在于明明基于官方的 API 也可以实现请求响应的一系列过程,为何还要多此一举使用 LCEL 呢?
python
import os
# OpenAI提供的python公共库
from openai import OpenAI
import os
os.environ["OPENAI_API_KEY"] = "xxxxxxxxxxxxx" # 将个人token替换到这个位置
os.environ["OPENAI_API_BASE"] = "xxxxxxxxxxxxx"
# 设置OpenAI Token
client = OpenAI(api_key=os.environ.get('OPENAI_API_KEY'), base_url=os.environ.get('OPENAI_API_BASE'))
chat_completion = client.chat.completions.create(
# 声明调用的模型名称
model='gpt-3.5-turbo',
# temperature用来设置大模型返回数据的随机性和创造性,较低的数值返回的数据就更贴近现实。
temperature=0.0,
# 消息内容,可以包含上下文信息,列表数据中的顺序就是对话发生的顺序
messages=[{'role': 'user', 'content': '1+1等于几?'}]
)
print(chat_completion)
# 从返回数据中拿到具体的答案信息
answer = chat_completion.choices[0].message.content
# 打印调试信息
print(answer)
python
tCompletion(id='chatcmpl-AbP4L1ArFNwLSzwRKVh5LrAwP9Pe2', choices=[Choice(finish_reason='stop', index=0, logprobs=None, message=ChatCompletionMessage(content='1+1等于2。', refusal=None, role='assistant', audio=None, function_call=None, tool_calls=None))], created=1733477865, model='gpt-3.5-turbo-0125', object='chat.completion', service_tier=None, system_fingerprint=None, usage=CompletionUsage(completion_tokens=7, prompt_tokens=15, total_tokens=22, completion_tokens_details=CompletionTokensDetails(accepted_prediction_tokens=0, audio_tokens=0, reasoning_tokens=0, rejected_prediction_tokens=0), prompt_tokens_details=PromptTokensDetails(audio_tokens=0, cached_tokens=0)))
1+1等于2。
从以上代码中可以看出以下几个问题:
1.官方提供的主要功能为请求的发送,具体发送的数据 messages 部分需要用户自己组织和维护。
2.返回的数据 response 部分也只是简单的组装了一个结构。有过开发经验的同学都深有感触,如果每次给到的返回信息从结构到内容都是不一样的,作为调用方,则需要编写无数行代码去处理这些异常。
而 LCEL 语法形式使得数据流程清晰,通过 pipeline 的形式,可以清晰地定义数据的流向以及处理的流程,使得代码更易于理解和维护。
三、LCEL 的基本使用
在使用 LCEL 表达式时,需要先了解其中所包含的元素:
|
:连接符Runnable对象
:可执行操作
1、Runnable 对象
Runnable 对象意为可执行操作,每个LCEL表达式都需要runnable 对象以及"|"连接符,使得LCEL 对象可以自动支持这些调用。
其中 Runnable 对象需要包含以下三个接口:
- stream:以流式返回输出结果。
- invoke:基于-个input调用 Runnable。
- batch:基于一个list的input 批量调用 Runnable。
所有的 Runnable 对象都具有共同的属性,即输入架构与输出架构。常见的输入和输出类型如下所示
Component | input Type | output Type |
---|---|---|
Prdmpt | dictonary | prompt Value |
LLM | String, list of messages or Prompt Value | String |
ChatModel | String, list of messages or Prompt Value | ChatMessage |
Retriever | Single String | List of Documents |
Tool | String/Dictonary | Tool dependent |
Output Parser | Output of LLM or ChatModel | Parser dependent |
四、实战实例
python
import os
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI
import os
os.environ["OPENAI_API_KEY"] = "xxxxxxxxxx" # 将个人token替换到这个位置
os.environ["OPENAI_API_BASE"] = "xxxxxxxxxx"
# 1、提示词模板 ->PromptValue
prompt = ChatPromptTemplate.from_template("出给一个关于{goods}的广告宜传语")
# 2、ChatGPT模型调用对象
model = ChatOpenAI()
# 将ChatGPT返回结果转换为字符串的处理器对象
output_parser = StrOutputParser()
# 将三个对象根据使用顺序组合成一个调用链,实现提示词组装、模型调用、结果解析的功能
# 业务流程 提示 调用 解析
chain = prompt | model | output_parser
# 输入提示词模版中的变量部分,调用链会自动完成后续的调用和解析
res = chain.invoke({"goods": "音乐节"})
print(res)
"跟随音乐的节拍,感受心灵的共鸣。音乐节邀您共同享受狂欢,释放激情,感受无限快乐!"