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。

相关推荐
CCPC不拿奖不改名15 小时前
RAG基础:基于LangChain 的文本分割实战+文本分块
人工智能·python·langchain·知识库·改行学it·rag·向量库
yangminlei15 小时前
使用 Cursor 快速创建一个springboot项目
spring boot·ai编程
冬奇Lab15 小时前
团队宪法:CLAUDE.md 和rule使用技巧与复利模式
人工智能·ai编程
gentle coder16 小时前
【langchain】AI应用开发框架
langchain·llm·rag
Java后端的Ai之路17 小时前
【AI编程工具】-Skills和Rule傻傻分不清?(一文带你读懂)
ai编程·trae·rule·skills
星辰引路-Lefan17 小时前
Antigravity 登录问题及解决方案:Antigravity Tools 账号管理工具详解
ide·ai编程·gemini·antigravity
OPEN-Source17 小时前
大模型实战:把 LangChain / LlamaIndex 工作流接入监控与告警体系
人工智能·langchain·企业微信·rag
重生之我要成为代码大佬19 小时前
LangChain-多任务应用开发
langchain·大模型·agent
HyperAI超神经19 小时前
覆盖天体物理/地球科学/流变学/声学等19种场景,Polymathic AI构建1.3B模型实现精确连续介质仿真
人工智能·深度学习·学习·算法·机器学习·ai编程·vllm
doll ~CJ20 小时前
Large Language Model(LLM)应用开发学习实践(三)
langchain·llm·提示词工程·ai应用