- 大家好,我是同学小张,日常分享AI知识和实战案例
- 欢迎 点赞 + 关注 👏,持续学习,持续干货输出。
- +v: jasper_8017 一起交流💬,一起进步💪。
- 微信公众号也可搜【同学小张】 🙏
本站文章一览:
经过几次的LangChain实战,发现其中最常用的两个封装类:RunnableParallel
和 RunnablePassthrough
。这是LangChain独有的表达式语言(LCEL)中最主要的组件。本文我们来深入学习下这两个组件的原理与使用。
0. 前置推荐阅读
LangChain实战系列:
- 【AI大模型应用开发】【LangChain系列】实战案例1:用LangChain写Python代码并执行来生成答案
- 【AI大模型应用开发】【LangChain系列】实战案例2:通过URL加载网页内容 - LangChain对爬虫功能的封装
- 【AI大模型应用开发】【LangChain系列】实战案例3:深入LangChain源码,你不知道的WebResearchRetriever与RAG联合之力
- 【AI大模型应用开发】【LangChain系列】实战案例4:再战RAG问答,提取在线网页数据,并返回生成答案的来源
LangChain表达式语言(LCEL)介绍:
1. RunnableParallel
1.1 基础使用
官方概念如下:
RunnableParallel can be useful for manipulating the output of one Runnable to match the input format of the next Runnable in a sequence.
RunnableParallel 可用于操作一个Runnable的输出,以匹配序列中下一个Runnble的输入格式。
从下面这段示例代码来理解下官方的解释:
from langchain_community.vectorstores import FAISS from langchain_core.output_parsers import StrOutputParser from langchain_core.prompts import ChatPromptTemplate from langchain_core.runnables import RunnablePassthrough from langchain_openai import ChatOpenAI, OpenAIEmbeddings vectorstore = FAISS.from_texts( ["harrison worked at kensho"], embedding=OpenAIEmbeddings() ) retriever = vectorstore.as_retriever() template = """Answer the question based only on the following context: {context} Question: {question} """ prompt = ChatPromptTemplate.from_template(template) model = ChatOpenAI() retrieval_chain = ( {"context": retriever, "question": RunnablePassthrough()} | prompt | model | StrOutputParser() ) retrieval_chain.invoke("where did harrison work?")
代码中每个 "|"
前后的元素都可看作是一个Runnable
。
其中的 {"context": retriever, "question": RunnablePassthrough()}
就是RunnableParallel
,它的作用就是将输入组成 context
和 question
为key的字典格式,传递给 prompt
。
RunnableParallel 的使用可以有以下三种形式,三种形式等价:
{"context": retriever, "question": RunnablePassthrough()} RunnableParallel({"context": retriever, "question": RunnablePassthrough()}) RunnableParallel(context=retriever, question=RunnablePassthrough())
1.2 并行执行多个Chain
RunnableParallel 可以让我们能够同时执行多个Chain,然后以字典形式返回各个Chain的结果。
from langchain_core.prompts import ChatPromptTemplate from langchain_core.runnables import RunnableParallel from langchain_openai import ChatOpenAI model = ChatOpenAI() joke_chain = ChatPromptTemplate.from_template("tell me a joke about {topic}") | model poem_chain = ( ChatPromptTemplate.from_template("write a 2-line poem about {topic}") | model ) map_chain = RunnableParallel(joke=joke_chain, poem=poem_chain) map_chain.invoke({"topic": "bear"})
以上示例代码中,定义了两个Chain:joke_chain
和 poem_chain
,通过 RunnableParallel
同时执行。
注意 RunnableParallel(joke=joke_chain, poem=poem_chain)
中的key值为 joke
和 poem
,返回的结果中会以这两个值作为每个Chain的key值组织结果。返回结果如下:
{'joke': AIMessage(content="Why don't bears wear shoes?\n\nBecause they have bear feet!"), 'poem': AIMessage(content="In the wild's embrace, bear roams free,\nStrength and grace, a majestic decree.")}
2. RunnablePassthrough
官方解释:
RunnablePassthrough allows to pass inputs unchanged or with the addition of extra keys. This typically is used in conjuction with RunnableParallel to assign data to a new key in the map.
RunnablePassthrough 允许在不改变或添加额外键的情况下传递输入。这通常与RunnableParallel结合使用,将数据分配给映射中的新键。
还是以一个实例代码和输出来看下它怎么用。
from langchain_core.runnables import RunnableParallel, RunnablePassthrough runnable = RunnableParallel( passed=RunnablePassthrough(), extra=RunnablePassthrough.assign(mult=lambda x: x["num"] * 3), modified=lambda x: x["num"] + 1, ) runnable.invoke({"num": 1})
以上代码并行执行了三行代码,其输出结果为:
{'passed': {'num': 1}, 'extra': {'num': 1, 'mult': 3}, 'modified': 2}
(1)第一行代码:passed=RunnablePassthrough()
,直接透传输入:'passed': {'num': 1}
(2)第二行代码:extra=RunnablePassthrough.assign(mult=lambda x: x["num"] * 3)
,除了透传原数据,还加了 mult 的值,通过 assign 函数将两个结果组装输出:'extra': {'num': 1, 'mult': 3}
。
(3)第三行代码:modified=lambda x: x["num"] + 1
,在原值基础上执行+1操作,没使用 assign 函数,因此原数据不组合输出:'modified': 2
3. 参考链接
https://python.langchain.com/docs/expression_language/how_to/map
https://python.langchain.com/docs/expression_language/how_to/passthrough
如果觉得本文对你有帮助,麻烦点个赞和关注呗 ~~~
- 大家好,我是 同学小张,日常分享AI知识和实战案例
- 欢迎 点赞 + 关注 👏,持续学习,持续干货输出。
- +v: jasper_8017 一起交流💬,一起进步💪。
- 微信公众号也可搜【同学小张】 🙏
本站文章一览: