在 LangChain 中,RunnableMapRunnableParallel都是用来处理多个并行任务的工具,但它们在用途、设计目的和使用方式上有显著的区别。

为了帮你清晰理解它们的差异,我们从以下几个方面进行对比:


一、基本概念

名称

类型

用途简述

RunnableMap

映射类(Mapping)​

用于对输入数据的每个键值对,分别运行不同的 Runnable,即对输入中的每个字段调用不同的链或工具,返回一个映射(dict)结果。

RunnableParallel

并行执行类

用于同时运行多个 Runnable(或链)​,这些 Runnable 通常共享同一个输入,目的是并行调用多个工具/链并合并结果

🧠 简单记忆:

  • RunnableMap​:对输入中的每个字段,用不同的逻辑/链去处理​ → 映射不同处理逻辑到不同字段。

  • RunnableParallel​:将多个链/工具并行执行,通常这些链都使用相同的输入,然后合并它们的输出。


二、类来源(LangChain 版本相关)

  • 这两个类通常来自:

    from langchain_core.runnables import RunnableMap, RunnableParallel

    在较新的 LangChain 版本中(尤其是基于 langchain-core的版本),它们是核心组件。

⚠️ 注意:在非常旧的 LangChain 版本中,可能没有直接暴露这两个名字,或者它们可能以不同方式实现(比如通过 dict输入或自定义组合)。


三、RunnableMap 详解

✅ 用途:

  • 你对输入数据中的每个字段(key)想要应用不同的 Runnable(或函数/链)​

  • 相当于对输入字典的每个 key-value,使用不同的处理逻辑,最终返回一个新的字典,其中每个 key 对应处理后的结果。

🧩 工作方式:

  • 接收一个 ​Dict[str, Runnable]​,即:每个 key 对应一个 Runnable。

  • 输入也是一个字典,RunnableMap 会将输入中的每个字段交给对应的 Runnable 处理

  • 输出也是一个字典,结构与输入类似,但 value 是经过各个 Runnable 处理后的结果。

📌 示例:

from langchain_core.runnables import RunnableMap
from langchain_core.messages import HumanMessage
from langchain_community.llms import ChatOpenAI  # 或其他 LLM

# 假设有两个简单的处理逻辑(可以是 RunnableLambda 或 LLM Chain)
def process_name(data):
    return f"Processed Name: {data['name'].upper()}"

def process_age(data):
    return f"Processed Age: {int(data['age']) + 1}"

# 构造 RunnableMap
runnable_map = RunnableMap({
    "processed_name": lambda x: process_name(x),  # 或者直接用 RunnableLambda
    "processed_age": lambda x: process_age(x),
})

# 输入
input_data = {"name": "alice", "age": "30"}

# 调用
output = runnable_map.invoke(input_data)

print(output)
# 输出类似:
# {
#   'processed_name': 'Processed Name: ALICE',
#   'processed_age': 'Processed Age: 31'
# }

🎯 重点:​每个字段(name, age)由不同的函数/逻辑处理,但输入是同一个字典,你可以根据字段名选择处理哪个字段。​

你也可以使用 RunnableLambda或实际的 Chain 对象作为值。


四、RunnableParallel 详解

✅ 用途:

  • 你希望同时运行多个 Runnable(或工具/链)​,这些 Runnable ​都接收相同的输入,并且你想要并行地调用它们,然后合并它们的输出结果

  • 类似于并发调用多个 API / 工具 / 模块,然后汇总结果。

🧩 工作方式:

  • 接收一个 ​Dict[str, Runnable]​,每个 key 是输出结果中的字段名,value 是对应的 Runnable。

  • 所有 Runnable 都接收相同的输入,然后并行执行​(在支持异步/并发的环境下)。

  • 返回一个合并的字典,key 是你在 RunnableParallel 中定义的字段名,value 是对应 Runnable 的输出。

📌 示例:

from langchain_core.runnables import RunnableParallel
from langchain_core.messages import HumanMessage
from langchain_community.llms import ChatOpenAI  # 或其他 LLM

# 假设我们有两个独立的 Chain 或工具(这里用 Lambda 模拟)
chain_a = RunnableLambda(lambda x: f"A处理结果: {x['query']} - A")
chain_b = RunnableLambda(lambda x: f"B处理结果: {x['query']} - B")

# 构建 RunnableParallel
parallel = RunnableParallel({
    "result_a": chain_a,
    "result_b": chain_b,
})

# 输入
input_data = {"query": "今天天气怎么样?"}

# 调用
output = parallel.invoke(input_data)

print(output)
# 输出类似:
# {
#   'result_a': 'A处理结果: 今天天气怎么样? - A',
#   'result_b': 'B处理结果: 今天天气怎么样? - B'
# }

🎯 重点:​多个链/工具都用同一个输入(比如用户的 query),并行执行,返回各自的结果,并合并为一个大的字典。​


五、RunnableMap vs RunnableParallel 对比表

特性

RunnableMap

RunnableParallel

目的

对输入中的每个字段使用不同的处理逻辑

并行运行多个 Runnable,通常共享同一个输入

输入

一个字典,通常包含多个字段

一个字典(通常是统一的输入,如 user query)

Runnable 分配方式

每个字段(key)对应一个 Runnable,处理该字段

每个 key 是输出字段名,value 是一个 Runnable,都用相同输入

输出

一个字典,key 与输入字段对应,value 是处理结果

一个字典,key 是你定义的(如 result_a),value 是对应 Runnable 的输出

典型使用场景

输入数据有多个部分,需要对每部分做不同处理

同时调用多个工具/模型/链,比如同时查知识库 + 调用 LLM + 搜索

是否并行执行

不一定(取决于具体实现,通常是顺序)

通常是设计为可以并行(尤其在异步环境下)

类比

类似于对字典的每个字段 apply 不同函数

类似于并发调用多个服务,合并结果


六、什么时候用哪一个?

场景

推荐使用

我有一个输入字典,里面的每个字段(如 name, age, location)需要用不同的逻辑处理,比如对 name 做大写,对 age 做 +1

✅ ​RunnableMap

我有一个输入(如用户的问题),希望同时做多件事情​:比如同时调用一个搜索工具、调用一个 LLM、调用一个数据库,然后汇总所有结果

✅ ​RunnableParallel

我想把多个独立的功能模块组合起来,并行执行,提升效率

✅ ​RunnableParallel

我想对输入中的不同部分定制不同处理,比如对字段 A 用 Chain A,字段 B 用 Chain B

✅ ​RunnableMap


七、高级用法:组合使用

在实际的复杂工作流中,你可能会 ​同时使用 RunnableParallel 和 RunnableMap,比如:

  • 先用 RunnableParallel同时调用多个工具获取信息,

  • 然后用 RunnableMap对返回的多个结果做进一步处理。

或者:

  • RunnableMap对输入的不同字段预处理,

  • 再用 RunnableParallel并发调用多个下游任务。


八、总结一句话

Runnable

一句话解释

RunnableMap

对输入字典的每个字段,使用不同的处理逻辑,返回处理后的字段映射。适合字段级定制处理

RunnableParallel

将多个 Runnable 并行运行,通常使用相同的输入,返回合并的多个结果。适合多任务并发执行


九、附加提示

  • 在 ​LangChain Graph(如 Agent 图、Workflow)​​ 中,这两个工具也经常被用来构建节点之间的逻辑流。

  • 如果你使用的是 ​LangChain v0.1.x 或更早,可能没有直接的 RunnableMapRunnableParallel,而是通过字典 + 自定义组合实现类似功能。

  • 在 ​LangChain 0.2.x 及之后(基于 langchain-core)​,这两个是官方推荐的标准组件,功能清晰、组合灵活。


🔗 ​


Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐