LangChain有两个重要的概念:LangChain表达式(LCEL) 、组件。我们使用组件,构建整个RAG应用中各种点单的操作,然后使用LCEL将这些组件进行连接,按照一定顺序运行,最终实现我们的目的。相关概念可在这里进一步理解。
Runnable
LCEL通过简洁的形式调用各类组件,实现方式是使用|
串联所有实现了Runnable
接口的组件。简而言之,LangChain的所有组件均实现了Runnable
接口,通过LCEL的方式进行相连,然后按照顺序执行每个组件,最终得到结果。
概念
Runnable
是LangChain中的一个抽象接口,凡是实现这个接口的均代表一个可执行单元,可通过标准化方法执行,处理并生成输出。其涉及目标是:
- 统一接口,为不同的组件提供统一的调用方式;便于LCEL调用,组合完成复杂任务;支持同步、异步、流式、批量调用等适合各种场景。
核心方法
invoke
:同步单个调用
ainvoke
:异步单个调用,适合高并发场景
stream
:流式调用
batch
:同步批量调用
abatch
:异步批量调用
LangChain提供的常见的Runnable实现
RunnableSequence
例子:
from langchain_core.runnables import RunnableSequencefrom langchain_core.output_parsers import StrOutputParser# chain_of_sequence_v1 = RunnableSequence(prompt, llm, StrOutputParser())# template_chain = prompt | llm# chain_of_sequence_v2 = RunnableSequence(first=template_chain, last=StrOutputParser())chain = prompt | llm | StrOutputParser()chain.invoke({"input":"你好"})
RunnableSequence
有三个参数:first
,middle
,last
,可以赋值实现了Runnable
的组件,或者一个链。RunnableSequence
等价于常用符号|
。
RunnableParallel
例子:
from langchain_core.runnables import RunnableParallelsystem_prompt_of_parallel = "你是一个非常棒的助手,能根据用户的问题给出精准的回答。。"prompt_1 = ChatPromptTemplate( [ ("system", system_prompt_of_parallel), ("human", "请讲一个关于{object}的冷笑话。"), ])prompt_2 = ChatPromptTemplate( [ ("system", system_prompt_of_parallel), ("human", "请详细介绍{object}。"), ])chain_1 = prompt_1 | llm | StrOutputParser()chain_2 = prompt_2 | llm | StrOutputParser()chain_of_parallel = RunnableParallel({"chain_1":chain_1, "chain_2":chain_2})print(chain_of_parallel.invoke({"object":"苹果"}))
RunnableParallel
的作用是,将两条链并行执行,并根据每条链的key
输出对应的回答。并行执行后,也可以按照key
取到对应的值,并执行后续操作。如对chain_of_parallel
进行改造如下:
from langchain_core.runnables import RunnableParallel,RunnableLambdasystem_prompt_of_parallel = "你是一个非常棒的助手,能根据用户的问题给出精准的回答。。"prompt_1 = ChatPromptTemplate( [ ("system", system_prompt_of_parallel), ("human", "请讲一个关于{object}的冷笑话。"), ])prompt_2 = ChatPromptTemplate( [ ("system", system_prompt_of_parallel), ("human", "请详细介绍{object}。"), ])prompt_3 = ChatPromptTemplate( [ ("system", system_prompt_of_parallel), ("human", "评价一下 \n\n {chain_1} \n\n这个冷笑话怎么样,并且判断一下 \n\n {chain_2} \n\n 描述是否准确"), ])chain_1 = prompt_1 | llm | StrOutputParser()chain_2 = prompt_2 | llm | StrOutputParser()chain_3 = prompt_3 | llm | StrOutputParser()chain_of_parallel = RunnableParallel({"chain_1":chain_1, "chain_2":chain_2}) | RunnableLambda(lambda x: {"chain_1":x["chain_1"], "chain_2":x["chain_2"]}) | chain_3print(chain_of_parallel.invoke({"object":"苹果"}))
上述代码可实现,在并行执行的链后,提取执行结果,并进一步对执行结果处理。
RunnablePassthrough
RunnablePassthrough
是构建链式任务时直接传递输入数据或上下文,同时支持附加额外数据以增强后续处理能力。
例子:
from langchain_core.runnables import RunnablePassthroughsystem_prompt_of_passthrough = "你是一个非常棒的助手,能根据用户的问题给出精准的回答。。"prompt_of_passthrough = ChatPromptTemplate( [ ("system", system_prompt_of_parallel), ("human", "请讲一个关于{object}的冷笑话。"), ])chain_of_passthrough = RunnablePassthrough() | llm | StrOutputParser()# chain_of_passthrough_1 = RunnablePassthrough.assign(object=RunnableLambda(lambda x:"西瓜"))| prompt_of_passthrough | StrOutputParser()chain_of_passthrough.invoke({"object":"苹果"})
需要注意的是,RunnablePassthrough.assign()
可以修改后添加参数,如chain_of_passthrough_1
所示,其中assign
函数的参数为key=func
,key
为需要修改或新增参数的key,func
为修改或新增的参数的函数。
RunnableLambda
可以将Python函数包装成为Runnable
的实现,应用于链中。
例子:
from langchain_core.runnables import RunnableLambdachain_of_lambda = RunnableLambda(lambda x:x["object"])| StrOutputParser()# chain_of_lambda_v2 = (lambda x:x["object"]) | StrOutputParser()chain_of_lambda_v2.invoke({"object":"苹果"})
此处使用lambda
函数作为例子,也可以使用def
定义的python函数。另外需要说明的,在链中出现的函数,即使是没有使用RunnableLambda
进行包装,链的底层也会自动将其进行包装。
RunnableBranch
例子:
from langchain_core.runnables import RunnableBranchdefault_branch = (lambda x:"这个是default_branch") | StrOutputParser()chain_of_branch_1 = (lambda x:"这个是chain_of_branch_1") | StrOutputParser()chain_of_branch_2 = (lambda x:"这个是chain_of_branch_2") | StrOutputParser()chain_of_branch = RunnableBranch( (lambda x:x == 1,chain_of_branch_1), (lambda x:x == 2,chain_of_branch_2), default_branch)chain_of_branch.invoke({"object":"苹果"})
根据条件选择执行不同的 Runnable
分支。
RunnableWithMessageHistory
添加对话历史管理和多轮对话跟踪,具体用法详见:这里
核心组件
- 提示词模板(Prompt Templates):用于动态生成提示词;大语言模型(LLMs):提供统一的对外访问API链(Chains):将多个简单操作组合执行,实现复杂功能记忆功能(Memory):记录对话内容,实现多轮对话Agent:大模型自主决策执行、动态调用工具
除了上述核心组件外,还有许多其他组件,如:检索器(Retrievers)、向量存储(Vector Store)、工具(tools)等,不一一列举,均可在这里找到。
原文地址:https://www.cnblogs.com/AfroNicky/p/18922644