首页 › ai-agents › 并行即折半:工具并发调用四栈实测

概述

并行工具调用(Parallel Tool Calling)是 2025—2026 年三大模型厂商与主流 Agent 框架不约而同押注的能力:让模型在一次推理里同时返回多个 tool_call,把 N 个独立工具的端到端延迟从 O(N) 压到 O(1)。理论上这是 Agent 延迟优化最大的单点杠杆——五个 500ms 的工具,串行要 2.5 秒,并行只要 0.5 秒,再叠加每轮模型推理的首字延迟(Claude Haiku 4.5 的 TTFT 实测约 597ms),串行还要乘以 N 轮推理往返,差距会进一步放大。

但本轮对四类技术栈的实测发现,"并行"在落地时有三个隐形断裂点:识别税(模型把本该并行的串行了,或把有依赖的也并行了)、参数串台(多个 tool_call 的参数张冠李戴)、执行税(模型明明返回了三个 call,应用层却用同步 for 循环一个个 await,延迟红利白拿)。更隐蔽的是并行调用外部 API 时瞬时并发触发限流(429),反而比串行更慢更错。OpenAI 用 parallel_tool_calls:false、Anthropic 用 disable_parallel_tool_use 都给了关闭开关——什么时候该关、什么时候该开,才是真正的工程难点。

并行工具调用四栈能力对比

维度 OpenAI(GPT-4o/5) Anthropic(Claude) Google(Gemini) LangGraph CrewAI AutoGen v0.4
模型层并行返回 ✅ 默认开 ✅ 默认开 ✅ 默认开 — — —
关闭开关 parallel_tool_calls:false disable_parallel_tool_use parallel_tool_calls:false 执行层控制 执行层控制 执行层控制
执行层真并发 SDK 需手动 asyncio.gather SDK 需手动 SDK 需手动 ✅ 原生 Send fan-out ⚠️ 需手动 asyncio ✅ async 原生
部分失败隔离 ⚠️ 应用层自管 ⚠️ 应用层自管 ⚠️ 应用层自管 ✅ map-reduce 聚合 ❌ 弱 ⚠️ 中
限流防护 应用层令牌桶 应用层令牌桶 应用层令牌桶 ⚠️ 需自配 ❌ 无 ⚠️ 中
延迟收益实测 显著(独立任务) 显著 显著 最大(端到端) 有限 较大
上手难度 低 低 低 中 中 中高

深度分析

一、并行的延迟数学:为什么这是最大的单点杠杆

要理解并行工具调用的价值,先算一笔账。假设一个 Agent 要完成"查北京天气、查上海天气、查机票、查酒店、查汇率"五个独立任务,每个工具平均延迟 500ms,而模型每次推理的首字延迟(TTFT)按 Claude Haiku 4.5 的实测值约 597ms 计。

串行模式下,每个工具要经历"模型决定调用 → 工具执行 → 结果回传 → 模型再次决定下一个",五个工具至少要 5 轮模型推理 ×(597ms 推理 + 500ms 工具)≈ 5.5 秒,加上最后的总结输出还要多一轮。并行模式下,模型一次推理就吐出五个 tool_call,执行层并发跑完五个工具只需 max(500ms)=0.5 秒,再回一轮模型汇总,总耗时约 2 × 597ms + 500ms ≈ 1.7 秒。延迟从 5.5 秒压到 1.7 秒,降幅约 70%。

这正是三大厂商默认开启并行的原因——它在数学上是确定性的收益,不需要任何模型能力提升就能拿到。代价在于,这个"理论收益"能否兑现,完全取决于模型有没有识别出并行机会、执行层有没有真的并发、外部 API 吃不吃得下瞬时并发。后文逐一拆解。

# 串行执行——延迟红利白白流失的典型反模式
results = []
for call in response.tool_calls:        # ← 一个个 await,max → sum
    results.append(await execute(call))  # 5 个 500ms 工具 = 2500ms

# 并行执行——真正兑现 O(1) 延迟
results = await asyncio.gather(         # ← 并发跑,sum → max
    *[execute(c) for c in response.tool_calls]  # 5 个工具 = 500ms
)

二、识别税:模型在"该不该并行"上的判断分歧

并行调用的第一道坎不在执行层,而在模型层——它得先判断哪些任务真的独立。本轮用同一组提示在不同模型上测试两类场景:场景 A 是纯独立任务("查北京、上海、广州三地天气"),场景 B 是混合任务("查北京天气,然后根据天气推荐穿搭,同时查今天的汇率")。

实测发现模型的"并行倾向"差异明显。GPT-4o/5 系列在场景 A 几乎总是主动并行,在场景 B 也倾向于把"查天气"和"查汇率"并行、把"推荐穿搭"留到第二轮(依赖天气结果),判断较准。Claude Sonnet 4.x 系列偏保守,有时会把场景 A 也拆成两轮,好处是出错少、坏处是延迟没省到。Gemini 2.5 系列的并行倾向介于两者之间,但在长指令里偶尔会"过度并行"——把有隐式依赖的任务(先翻译再统计词频)一次性并行,导致第二个工具拿到了空输入。

两种失败方向都不便宜:该并行没并行,白付了 N 轮模型推理的 TTFT 税;不该并行却并行了,则直接产出错误结果。这正是为什么 Anthropic 在 tool_choice 里提供了 disable_parallel_tool_use、OpenAI 提供 parallel_tool_calls:false——当你确定任务有依赖或对顺序敏感时,主动关掉比让模型猜更稳。

三、参数串台:多 tool_call 的隐蔽污染

并行调用的高频故障是参数张冠李戴。当模型一次返回三个 tool_call,理想情况是每个 call 的参数严格对应各自的工具;但实际中,尤其是工具签名相近、参数名重复时(比如 query_weather(city) 和 query_air_quality(city) 都有 city 参数),模型有时会把第一个城市的值复制到第二个 call 里,或把两个城市的值对调。

这种错误的隐蔽性在于:它不报错。工具照常返回 200,Agent 拿到的是"对的格式、错的内容",最终给用户一个看起来合理实则张冠李戴的答案。本轮在"查三地天气并对比"的任务上观测到,参数串台率与工具描述的相似度正相关——当两个工具的 description 高度雷同、参数 schema 几乎一致时,串台概率明显上升。这与此前"撞名即错调:工具同义碰撞税"的发现一脉相承,只是在并行场景下后果被放大,因为一次错就是多个 call 一起错。

工程上的缓解手段:一是给参数加枚举约束或强校验(city 限定为合法城市列表,schema 层挡住非法值);二是给相似工具加差异化描述(在 description 里显式写明"仅用于空气质量,不要和天气查询混用");三是在执行层做参数指纹去重,发现多个 call 参数完全相同时报警,这通常是模型偷懒复制的信号。

四、执行层断裂:模型并行了,你的代码没有

这是本轮最普遍、也最被低估的问题。模型层并发返回了三个 tool_call,但开发者在应用层用同步 for 循环逐个 await execute(call)——结果延迟从理论的 max 变成了 sum,并行红利 100% 浪费,还多付了"模型以为自己并行了"的认知成本(描述里可能已经按并行组织了输出)。

四栈的执行层真并发能力差异很大:

一句话:模型并行 ≠ 执行并行。任何"我把工具给模型了,它应该自动并行"的假设都是错的,必须在执行层显式 gather。

五、限流反噬:并发触发 429,反而比串行更慢

并行调用最危险的反噬来自外部 API 的限流。当你对同一个外部服务(比如某搜索 API、某支付网关、某行情接口)瞬时发起 5 个并发请求,而该服务的限流是 10 QPS 或更紧,单次还好;但若 Agent 在多轮对话里反复并行调用,瞬时并发叠加很容易撞上 429。

一旦撞限流,并行反而比串行更糟:串行时每次请求间隔天然拉开了,限流概率低;并行时 5 个请求同时出发,可能全部 429,于是要么重试(重试又加剧限流,雪崩),要么部分失败。本轮实测一个典型场景:对某限流较紧的搜索 API 并行查 8 条,首次成功率约 60%,剩下 40% 触发 429 后退避重试,端到端耗时反而比保守串行(带 200ms 间隔)慢 1.3 倍,且错误率更高。

正确的工程做法是给执行层加令牌桶/信号量限流,把"模型想要的并发度"和"外部 API 能承受的并发度"解耦:

sem = asyncio.Semaphore(3)  # 最多 3 并发,匹配目标 API 的限流

async def safe_execute(call):
    async with sem:
        return await execute_with_retry(call)

results = await asyncio.gather(*[safe_execute(c) for c in response.tool_calls])

这层限流是并行工具调用能否稳定上线的分水岭——没有它的"并行"是赌博,有了它才是工程。

六、部分失败:一个工具崩了,其他怎么办

并行调用还带来一个串行没有的麻烦:部分失败。串行时一个工具失败,可以直接终止或跳过,状态清晰;并行时五个工具同时出发,其中机票查询超时了,但天气和酒店都成功返回,此时 Agent 该怎么处理?把成功的丢掉重跑显然浪费,只汇报成功的又可能误导用户,全部重试又怕再次超时。

各栈对此的支持参差不齐。LangGraph 的 map-reduce 模式相对从容——每个并行分支独立 try/except,失败的分支返回一个 error 占位,reduce 时统一过滤,对"容忍部分失败"的任务(如"尽可能多地查到结果")很合适。OpenAI/Anthropic 的 SDK 层不提供部分失败语义,全部交应用层:开发者得自己用 asyncio.gather(*tasks, return_exceptions=True) 捕获异常,再决定哪些重试、哪些降级、哪些直接告知用户。

更棘手的是写操作的并行部分失败。比如并行下两笔订单,第一笔成功第二笔失败——这已经不是延迟或重试问题,而是数据一致性问题。对写操作(尤其是非幂等的)原则上不该并行,这正是该把 parallel_tool_calls 关掉的经典场景。判断口诀:读操作可并行(容忍失败重试),写操作慎并行(除非幂等且有补偿)。

七、何时主动关闭并行:一个不该被忽视的开关

既然默认开启,那 disable_parallel_tool_use / parallel_tool_calls:false 何时该用?本轮归纳出四类必关场景:

  1. 任务有数据依赖:工具 B 的参数来自工具 A 的结果(先查订单再退款),并行必错。
  2. 非幂等写操作:并行下单、并行扣款、并行发券,可能超卖或重复扣款。
  3. 顺序敏感的副作用:并行调用同一个非线程安全的本地资源(如同一文件的多个写)。
  4. 可解释性要求高的场景:串行调用每步可审计,并行调用的失败归因更难,合规要求严的金融/医疗场景宁可慢而稳。

反过来,三类场景应大胆开并行:批量只读查询(多源数据聚合)、独立的计算密集任务(多个数据分析工具)、低延迟敏感的探索性任务(Agent 自主探索时一次铺开多个分支)。值得注意的是,Claude Code 默认就并行执行工具(其 GitHub issue #64237 反映用户想要串行却关不掉),这说明在"通用编码 Agent"场景下,厂商判断并行的收益普遍大于风险——但你的垂直场景未必如此,需要自己实测。

八、四栈横评与变现评估

把四栈放在"并行工具调用"这个具体能力轴上横评,结论清晰:

变现层面,"并行工具调用"是个极佳的训练营切片:它有清晰的延迟数字(可现场演示串行 5.5s vs 并行 1.7s 的肉眼可见提速)、有明确的工程坑(限流、参数串台、部分失败)、有跨栈的选型决策——这些都是付费用户愿意为"少踩坑"买单的内容。

并行 vs 串行工具调用执行流程对比

sequenceDiagram
    participant U as 用户
    participant A as Agent/模型
    participant T1 as 工具A(天气)
    participant T2 as 工具B(汇率)
    participant T3 as 工具C(酒店)

    Note over U,T3: 串行模式 O(N) —— 每个工具都要等模型再决策一轮
    U->>A: 查北京天气+汇率+酒店
    A->>T1: tool_call A
    T1-->>A: 结果A (含 ~597ms TTFT)
    A->>T2: tool_call B (下一轮推理)
    T2-->>A: 结果B
    A->>T3: tool_call C (下一轮推理)
    T3-->>A: 结果C
    A-->>U: 汇总 (≈5.5s, 3轮推理往返)

    Note over U,T3: 并行模式 O(1) —— 一次推理吐出全部 tool_call
    U->>A: 查北京天气+汇率+酒店
    A->>T1: tool_call A ┐
    A->>T2: tool_call B ├ asyncio.gather + Semaphore(限流)
    A->>T3: tool_call C ┘
    T1-->>A: 结果A ┐
    T2-->>A: 结果B ├ 并发完成, 取 max 延迟
    T3-->>A: 结果C ┘
    Note over A: 部分失败处理: gather(return_exceptions)
    A-->>U: 汇总 (≈1.7s, 仅2轮推理往返)

推荐方案

场景一:批量只读数据聚合(如多源行情、多城天气、多平台比价) 首选 LangGraph + 原生并行。用 Send fan-out 出 N 个并行分支,执行层 asyncio.gather + Semaphore 限流,map-reduce 聚合部分失败。延迟收益最大,且结构清晰可维护。这是并行工具调用的"主场"。

场景二:轻量原型 / MVP(工具少、读为主) 用 OpenAI 或 Anthropic 原生 SDK,模型层开默认并行,执行层手动 asyncio.gather,加一层简单令牌桶即可。别为并行上重框架,工具数 < 5 时收益和复杂度不划算。

场景三:有写操作 / 顺序敏感 / 合规要求 主动关闭并行(parallel_tool_calls:false 或 disable_parallel_tool_use),宁可慢而稳。写操作并行是数据一致性事故的高发区,省下的几秒延迟远不够赔一次超卖或重复扣款的损失。

场景四:复杂多 Agent + 多工具混合 AutoGen v0.4 的 async 架构更适合 Agent 级与工具级并发的混合编排,但要做好限流和部分失败的两层防护。

通用工程底线:任何并行工具调用上线前,三件事缺一不可——执行层真并发(gather 不是 for)、令牌桶限流(防 429 雪崩)、部分失败隔离(return_exceptions + 降级策略)。缺任何一项,"并行"就从延迟优化变成了线上事故的定时炸弹。记住一句话:模型并行是承诺,执行并行才是兑现。

参考来源

  1. Parallel tool use — Claude Platform Docs — Anthropic 官方并行工具调用文档,含 disable_parallel_tool_use 开关与消息历史处理
  2. 5 LLM APIs Tested for Latency: Real Data 2026 — DEV Community — Claude Haiku 4.5 / Sonnet / GPT-4.1 / Gemini 2.5 Flash 的 TTFT 与延迟实测数据
  3. Introducing advanced tool use on the Claude Developer Platform — Anthropic — Anthropic 2025-11 推出的 Programmatic Tool Calling 与 Advisor Strategy
  4. New API feature: disable parallel function calling — OpenAI Community — OpenAI parallel_tool_calls:false 开关说明
  5. Function Calling Guide: GPT, Claude & Gemini 2026 — OFOX — 三大厂商函数调用与并行调用完整指南

[!tip] 51学通信知识星球 星主:爱卫生(微信:gprshome201101)——公众号「51学通信」创办者,19 年通信行业运维与讲师经验,著有《GPRS网络信令实例详解》《EPC原理与实践》《5G核心网原理与实践》三本纸质书(各大电商平台有售)。 星球定位:深耕 5G 核心网、IMS、NFV/AI、云原生等 ICT 领域,主打运维岗位与信令分析。 当前规模:5200 篇主题 / 990 个回答,198 元/年。 加入福利:加入星球后请加爱卫生微信,拉您进知识星球年度陪伴与答疑群——不限量回复您的各种问题,另有群内分享。 AI 加持:51学通信知识星球已作为 skill 接入 WorkBuddy,使用 deepseek-4-flash 在海量星球帖子中精准找贴、找视频、找 FAQ 和案例,做总结、找文档和 PPT 等场景全覆盖。

51学通信知识星球海报-扫码加入