LangChain核心组件-链chains

链可以将提示词模板、模型包装器和输出解析器串起来,将模型输入输出整合在一个链中操作,它利用提示模板格式化输入,将格式化后字符串传递给LLM模型,并返回LLM的输出

LCEL链

LCEL,用声明式的方法来链接LangChain组件,所有可以被链起来的组件,如:大语言模型、检索器、提示词模板等都支持:stream(流式响应)、invoke(接受输入返回输出)、batch(接受批量输入返回输出列表),其最终组成的链使用也是调用这三个方法

如何链式运行可运行对象

关于LangChain表达式的一点是,任何两个可运行对象可以“链式”组合成序列。前一个可运行对象的 .invoke() 调用的输出作为输入传递给下一个可运行对象。这可以使用管道操作符 (|) 或更明确的 .pipe() 方法来完成,二者效果相同。
生成的 RunnableSequence 本身就是一个可运行对象,这意味着它可以像其他任何可运行对象一样被调用、流式处理或进一步链式组合。以这种方式链式运行可运行对象的优点是高效的流式处理(序列会在输出可用时立即流式输出),以及使用像LangSmith这样的工具进行调试和追踪。

管道操作符: |

mport getpass
import os

os.environ["OPENAI_API_KEY"] = getpass.getpass()

from langchain_openai import ChatOpenAI
# 给出model
model = ChatOpenAI(model="gpt-4o-mini")

from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate
# 给出prompt
prompt = ChatPromptTemplate.from_template("tell me a joke about {topic}")
# 加上解析器组成管道LCEL
chain = prompt | model | StrOutputParser()

#提示和模型都是可运行的,提示调用的输出类型与聊天模型的输入类型相同,因此我们可以将它们链在一起。然后我们可以像调用其他可运行的那样调用结果序列:
chain.invoke({"topic": "bears"})

==>
"Here's a bear joke for you:\n\nWhy did the bear dissolve in water?\nBecause it was a polar bear!"

.pipe() 方法

from langchain_core.runnables import RunnableParallel

composed_chain_with_pipe = (
RunnableParallel({"joke": chain})
.pipe(analysis_prompt)
.pipe(model)
.pipe(StrOutputParser())
)

composed_chain_with_pipe.invoke({"topic": "battlestar galactica"})

可简写

composed_chain_with_pipe = RunnableParallel({"joke": chain}).pipe(
analysis_prompt, model, StrOutputParser()
)

其它方法

RunnableLambda: LangChain组件未提供的功能,需要自定义函数,且该函数需要加入链作为流一部分,则需要用

RunnableParallel/RunnableMap: 把组件链起来,且多个任务能够同时执行

RunnablePassthrough: 允许在LangChain的链中传递数据
1.确保数据保持不变,直接用于后续步骤的输入,常用于链第一个位置,用于接收用户的输入(也可以用在中间位置,则用于接收上一步的输出)
2.允许通过assign对数据增强再后续处理

RunnableWithMessageHistory: 大模型是无状态的,无法记住每次聊天的对话内容,所以提供了自动会话历史管理组件