AI智能体设计模式系列(三)—— 并行化模式

并行化模式概述

许多复杂的 Agent 任务涉及多个可同时执行而非顺序执行的子任务。这正是并行化模式变 得至关重要的场景。

并行化涉及并发执行多个组件,包括 LLM 调用、工具使用乃至整个子 Agent。不同于顺序等待每 个步骤完成,并行执行允许独立任务同时运行,从而显著缩短可分解为独立部分的任务的总执行时间。

图1 并行化设计模式

  • 并行化是一种通过并发执行独立任务来提高效率的模式

  • ・ 在涉及等待外部资源(如API调用)的任务中特别有效

  • ・ 采用并发或并行架构会引入显著复杂性和成本,影响设计、调试和系统日志等关键开发环节

  • ・ 像LangChain和GoogleADK这样的框架提供定义和管理并行执行的内置支持

  • ・ 在LangChain表达式语言(LCEL)中,RunnableParallel是并行运行多个可运行对象的关键构造

  • ・ GoogleADK可通过LLM驱动的委托实现并行执行,协调器Agent的LLM识别独立子任务并触发专门

    子 Agent 的并发处理

  • ・ 并行化有助于减少整体延迟,使Agent系统在处理复杂任务时更具响应性

在LangChain表达式语言(LCEL)中,RunnableParallel 是一个用于并行执行多个可运行对象的工具。它允许我们将一个输入同时传递给多个可运行对象(如链、工具、函数等),然后将它们的结果合并到一个字典中。这样,我们可以并行地执行多个任务,从而提高效率。

基本用法:

我们可以通过传递一个字典给 RunnableParallel 来创建它,字典的键是输出结果中的键,值是可运行对象(可以是任何实现了 Runnable 接口的对象,如链、提示模板、模型等)。

示例:

假设我们有两个链,一个用于生成笑话,另一个用于生成总结。我们可以使用 RunnableParallel 同时运行它们。

步骤:

  1. 定义两个可运行对象(这里假设是两个简单的链,但可以是任何可运行对象)。

  2. 使用 RunnableParallel 将这两个链组合起来,并指定输出字典中的键。

  3. 调用组合后的可运行对象。

注意:RunnableParallel 不会保证执行顺序,但会并行执行所有可运行对象。

另外,RunnableParallel 也支持与 RunnableMap 类似的用法,但 RunnableMap 更侧重于将一个输入映射到多个输出,而 RunnableParallel 更强调并行执行。

基本概念

RunnableParallel 允许你将一个输入同时传递给多个可运行对象(链、函数、模型等),并将它们的结果合并成一个字典。

基本用法

python 复制代码
from langchain_core.runnables import RunnableParallel

# 创建并行执行的runnable
parallel_runnable = RunnableParallel({
    "joke": joke_chain,        # 第一个可运行对象
    "summary": summary_chain,   # 第二个可运行对象
    "length": length_func       # 第三个可运行对象(函数)
})

# 执行 - 所有组件并行运行
result = parallel_runnable.invoke("关于AI的笑话")
# 返回: {"joke": "...", "summary": "...", "length": 42}

常见使用场景

1. 并行处理多个任务

python 复制代码
from langchain_core.runnables import RunnableParallel, RunnableLambda

# 定义不同的处理函数
def extract_names(text):
    return extract_name_chain.invoke(text)

def extract_dates(text):
    return extract_date_chain.invoke(text)

def analyze_sentiment(text):
    return sentiment_chain.invoke(text)

# 并行执行
analyzer = RunnableParallel({
    "names": RunnableLambda(extract_names),
    "dates": RunnableLambda(extract_dates),
    "sentiment": RunnableLambda(analyze_sentiment)
})

2. 结合管道使用

python 复制代码
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser

# 创建多个处理链
joke_chain = ChatPromptTemplate.from_template("讲一个关于{topic}的笑话") | model
poem_chain = ChatPromptTemplate.from_template("写一首关于{topic}的诗") | model
summary_chain = ChatPromptTemplate.from_template("总结{topic}") | model

# 并行执行然后合并
parallel = RunnableParallel({
    "joke": joke_chain,
    "poem": poem_chain,
    "summary": summary_chain
})

# 在管道中使用
full_chain = (
    {"topic": lambda x: x} 
    | parallel
    | combine_results_chain
)

3. 收集多个来源的信息

python 复制代码
# 从不同知识库并行检索
retrieval_chain = RunnableParallel({
    "legal_info": legal_retriever,
    "technical_info": technical_retriever,
    "general_info": general_retriever
})

# 使用检索结果生成答案
qa_chain = (
    {"question": lambda x: x, "context": retrieval_chain}
    | prompt
    | model
    | output_parser
)

高级用法

动态配置

python 复制代码
# 根据条件动态选择并行组件
def dynamic_parallel(input_dict):
    config = input_dict.pop("config")
    components = {}
    
    if config.get("extract_entities", True):
        components["entities"] = entity_extractor
    if config.get("classify", True):
        components["classification"] = classifier
        
    return RunnableParallel(components).invoke(input_dict)

错误处理

python 复制代码
from langchain_core.runnables import RunnableConfig

class SafeRunnableParallel(RunnableParallel):
    def invoke(self, input, config=None):
        try:
            return super().invoke(input, config)
        except Exception as e:
            # 处理部分失败的情况
            results = {}
            for key, runnable in self.config["runnables"].items():
                try:
                    results[key] = runnable.invoke(input, config)
                except:
                    results[key] = f"Error processing {key}"
            return results

性能优势

  1. 真正的并行执行:使用异步时,RunnableParallel可以真正并行执行

  2. 减少延迟:对于需要多个独立处理步骤的任务,并行执行可以显著减少总延迟

  3. 资源优化:当不同组件使用不同资源时(CPU/IO),并行执行可以提高利用率

异步支持

python 复制代码
import asyncio

async def process_concurrently():
    parallel = RunnableParallel({
        "chain1": chain1,
        "chain2": chain2,
        "chain3": chain3
    })
    
    # 异步调用
    result = await parallel.ainvoke(input_data)
    return result

实际应用示例

python 复制代码
# 一个完整的文档处理流水线
document_processor = RunnableParallel({
    # 并行提取不同类型的信息
    "summary": summary_extractor,
    "keywords": keyword_extractor,
    "entities": entity_extractor,
    "sentiment": sentiment_analyzer,
    
    # 并行验证不同方面
    "fact_check": fact_checker,
    "grammar_check": grammar_checker,
    "plagiarism_check": plagiarism_checker,
    
    # 并行生成不同格式的输出
    "html": html_generator,
    "markdown": markdown_generator,
    "json": json_generator
})

# 使用
processed = document_processor.invoke(document_text)

RunnableParallel是构建高效、模块化LCEL链的关键工具,特别适合需要同时执行多个独立任务的场景。

结论

并行化模式是通过并发执行独立子任务来优化计算工作流的方法。该模式有效减少整体延迟,在涉及多个模 型推理或对外部服务调用的复杂操作中尤为显著。

不同框架为此模式提供了不同的实现机制。在 LangChain 中,通过 RunnableParallel 等构造显式定义并同 时执行多个处理链。而 Google Agent Developer Kit (ADK) 等框架则通过多 Agent 委托实现并行化,由主协 调器模型将不同子任务分配给可并发操作的专门 Agent。

相关推荐
深情的小陈同学2 小时前
工作学习笔记 —— 支持手机端的添加表单行操作
笔记·学习·ai编程
sky17204 小时前
VectorStoreRetriever 三种搜索类型
python·langchain
草帽lufei4 小时前
LangChain 框架基础知识和核心组件Prompts,Chains
langchain·openai·gemini
重铸码农荣光4 小时前
🤖 用 AI 写 Git Commit Message?我让新手秒变 Git 高手!
langchain·aigc·全栈
倔强的石头_6 小时前
2026 年程序员接单全指南:平台这么多,别再选错了
ai编程
老蒋每日coding6 小时前
AI智能体设计模式系列(一)—— 提示词链
设计模式·ai编程
weixin_462446236 小时前
【原创】使用langchain与MCP 与 Chrome DevTools 打造可调用浏览器工具的 Chat Agent
前端·langchain·chrome devtools
TangGeeA7 小时前
从“工具”到“灵魂”:深度解构 Claude Code 的 Agent、Skills 与 MCP 架构哲学
架构·ai编程