LangChain表达式语言(LCEL)原理
这种管道操作符的底层实现基于 Runnable 协议 和 运算符重载 的设计模式
...
final_prompt = ChatPromptTemplate.from_messages(
[
few_shot_prompt,
("human", "{input}"), #这里的human是用户的输入。chain.invoke({"input": "xxxx"}) 里面的input
]
)
final_prompt
print(final_prompt)
chain = final_prompt | llm
response = chain.invoke({"input": "艾米需要4分钟才能爬到滑梯顶部,她花了1分钟才滑下来,水滑梯将在15分钟后关闭,请问在关闭之前她能滑多少次?"})
print(response.content)
看看上面的例子:
如果是 0.1 的版本是这么实现的
chain = LLMChain(final_prompt,llm)
response = chain.invoke({"input": "艾米需要4分钟才能爬到滑梯顶部,她花了1分钟才滑下来,水滑梯将在15分钟后关闭,请问在关闭之前她能滑多少次?"})
print(response.content)
从原理上看就是第一个组件执行结果作为第二个组件的输入。
底层原理
1. 运算符重载 (| 的实现)
当使用 | 操作符时,LangChain 通过 Python 的 __or__ 方法重载机制,将两个组件连接成一个新的 可运行序列 (RunnableSequence)。
# 伪代码示例
class Runnable:
def __or__(self, other):
return RunnableSequence(self, other)
这意味着以下两行代码是等价的:
chain = final_prompt | llm
chain = RunnableSequence(final_prompt, llm)
2. 输入输出处理流程
当调用 chain.invoke({"input": ...}) 时,执行流程如下:
步骤 1 - 执行提示模板
# final_prompt 是一个 ChatPromptTemplate 实例
messages = final_prompt.invoke({"input": "问题内容..."})
# 输出格式示例:
# [
# SystemMessage(content="你是一个助手..."),
# HumanMessage(content="艾米需要4分钟...")
# ]
步骤 2 - 传递到 LLM
# llm 是一个 ChatOpenAI 实例
response = llm.invoke(messages)
# 输出格式示例:
# AIMessage(content="艾米可以滑3次...")
3 组件的类型预先定义
所有 LangChain 组件(称为 Runnable)都有明确的输入输出类型定义,这些类型通过 Python 的 类型注解 和 LangChain 的 Pydantic 模型 实现。
核心类型示例
| 组件类型 | 输入类型 | 输出类型 |
|---|---|---|
ChatPromptTemplate |
Dict[str, Any] |
List[BaseMessage] |
ChatOpenAI (LLM) |
List[BaseMessage] |
AIMessage |
StrOutputParser |
AIMessage |
str |

浙公网安备 33010602011771号