💡

文章摘要

三大 provider 的并行工具调用在 API 行为、延迟收益和错误处理上差异显著。本文从工程决策角度拆解并行 vs 串行的判断框架、跨厂商 API 差异、错误回退策略和生产环境中的延迟优化实践。

1为什么并行工具调用是 Agent 延迟的第四个杠杆

Agent 成本优化的常见杠杆按影响力排列:模型路由(40-70% 节省)、上下文压缩(50-70% token 减少)、prompt 优化。但第四个杠杆——并行工具调用(parallel tool calls)——经常被忽视。

一个典型的 Agent 步骤可能需要查询数据库、调用外部 API、检查用户权限和获取缓存状态。如果串行执行,四个工具调用各 500ms 延迟,总延迟 2000ms。如果并行执行,总延迟约等于最慢的那个调用(~500ms),延迟降低 75%。这个收益在 Agent 循环中被放大——一个 10 步的 Agent 工作流,如果每步有 3 个独立工具,串行总延迟约 15 秒,并行后降到约 5 秒。用户感知从「等半天」变成「基本流畅」。

根据 DeployBase 2026 年 Q1 的基准测试,并行工具调用在 Claude Sonnet 上可将多步 Agent 循环的端到端延迟从 4.8 秒降低到 1.5 秒(三个独立工具同时调用)。OpenAI GPT-4o 的并行调用延迟收益类似,但 API 行为有本质差异:OpenAI 默认启用并行调用,而 Anthropic 需要模型在单次响应中返回多个 tool_use 块。

并行调用不是万能的。当工具之间存在数据依赖(工具 B 的输入来自工具 A 的输出)、共享可变状态(两个工具写同一个数据库行)或需要严格顺序保证(先认证再操作)时,必须强制串行。判断框架的核心问题是:这些工具的输入和输出是否相互独立?

值得注意的是,并行调用的收益不仅来自延迟降低,还来自更好的资源利用率。串行调用时,CPU 和网络连接在等待 I/O 时完全空闲;并行调用时,这些资源被充分利用。对于自托管的 Agent 服务,这意味着同样的硬件可以服务更多并发请求。

图表加载中…

💡 一句话理解

经验法则:如果两个工具调用可以画在 DAG 的同一层(无有向边连接),它们就可以并行。

2三大 Provider 的 API 行为差异

三大 provider 都支持并行工具调用,但 API 协议、默认行为和错误语义存在实质差异。这些差异直接影响你的代码架构——写一套适配层之前,必须理解每个 provider 的行为边界。

OpenAI(GPT-4o / GPT-4o-mini):默认启用并行调用。模型在单次响应中返回多个 tool_calls 数组元素,每个元素有独立的 id。可以通过 parallel_tool_calls=false 显式禁用。根据 OpenAI 官方文档(2026 年更新),结构化输出模式(response_format: { type: "json_schema" })可将 schema 遵循率从 93-95% 提升到接近 100%,但会增加约 100-200ms 延迟OpenAI 的并行调用实现基于 JSON Schema 的严格模式,确保多个工具调用的参数格式一致性。

Anthropic(Claude Opus / Sonnet / Haiku):同样支持并行调用,但协议不同——模型在 content 数组中返回多个 tool_use 块,每个块有独立的 id 和 name。没有显式的 parallel_tool_calls 开关;并行行为由模型自主决定。根据 Anthropic 官方文档(2026 年更新),Claude 在并行调用场景下的延迟方差更低,适合对响应时间可预测性要求高的场景。Anthropic 的工具调用设计强调内容块的灵活性,允许工具调用和文本内容交错出现。

Google Gemini(1.5 Pro / Flash):支持并行函数调用,API 格式更接近 OpenAI。Gemini Flash 的延迟最低(~190ms 首 token),但并行工具调用的 schema 遵循率(85.4%)低于 Claude Sonnet(96.9%)和 GPT-4o(91.2%)。根据 Google AI 官方文档(2026 年更新),Gemini 的并行调用实现与 OpenAI 类似,但在错误处理上有所不同——Gemini 会在单个响应中返回所有成功的调用结果,失败的调用会被标记但不影响其他调用的返回。

根据 OFOX 2026 年的完整指南,跨 provider 的工具调用格式不兼容——OpenAI 用 tool_calls 数组,Anthropic 用 content 块中的 tool_use,Gemini 用 functionCall 数组。这意味着如果你需要多 provider 切换,必须构建适配层。适配层的复杂度不在于协议转换本身,而在于处理各种边界情况:比如 Anthropic 的 tool_use 块可能和文本内容交错出现,而 OpenAI 的 tool_calls 总是独立的数组。

图表加载中…
维度OpenAI GPT-4oAnthropic Claude SonnetGoogle Gemini 1.5 Pro

默认并行

✅ 默认启用

✅ 模型自主决定

✅ 支持

禁用方式

parallel_tool_calls=false

无显式开关

无显式开关

响应格式

tool_calls[] 数组

content[] 中多个 tool_use 块

functionCall[] 数组

Schema 遵循率(并行)

91.2%

96.9%

85.4%

首 token 延迟

~450ms

~480ms

~190ms(Flash)

错误回传

每个 tool_call 独立 tool_call_id

每个 tool_use 独立 id

每个 functionCall 独立 id

结构化输出模式

json_schema 强制模式

无独立模式

无独立模式

⚠️ 常见踩坑

不要假设一个 provider 的并行行为可以直接迁移到另一个。Anthropic 没有 parallel_tool_calls=false 开关——如果你的业务逻辑需要强制串行,必须在应用层自己控制(只发送一个工具定义,或在代码中逐步追加)。

3并行 vs 串行的工程决策框架

并行调用降低延迟,但引入三类风险:竞态条件(race condition)、错误传播放大和结果合并复杂度。生产环境中需要一个清晰的决策框架,而不是凭直觉选择。

第一层判断:数据依赖。如果工具 B 需要工具 A 的输出作为输入,它们必须串行。例如「搜索航班」→「预订航班」——预订需要搜索结果中的航班 ID。

第二层判断:共享状态。两个工具写同一个资源(同一个数据库表、同一个文件、同一个缓存键),即使没有直接数据依赖,也必须串行或使用锁。并行写入同一资源可能导致数据丢失或覆盖。

第三层判断:错误隔离。如果工具 A 失败是否应该阻止工具 B 执行?如果答案是「是」,串行更安全——你可以在 A 失败后立即中止。如果答案是「否」(各工具独立失败不影响其他),并行是更好的选择。

第四层判断:成本约束。并行调用意味着同时消耗多个工具的配额(API rate limit、数据库连接池)。如果某个工具的 rate limit 很紧,并行可能触发限流。

实践中最常见的模式是混合执行:一个 Agent 步骤中,独立的工具并行调用,有依赖的工具串行链接。例如 Agent 同时查询用户信息、订单历史和推荐列表(三个独立调用),然后基于结果生成个性化回复(串行依赖前三个的结果)。

另一个常见的工程陷阱是「伪并行」——代码看起来是并行的,但实际上因为共享连接池或全局锁而退化为串行。例如五个工具调用都使用同一个数据库连接(连接池大小为 1),或者都通过同一个 HTTP client(底层有全局锁)。这种情况下,并行代码的复杂度增加了,但延迟没有改善。排查方法是在每个工具调用前后打时间戳,观察实际执行时间是否重叠。

决策框架的工程实现通常是一个 DAG 调度器:在 Agent 规划阶段,模型输出工具调用列表和依赖关系,调度器构建 DAG 并自动识别可并行的子图。LangGraph 和 AutoGen 等框架已经内置了这种能力。

图表加载中…

4错误处理与回退策略

并行工具调用的错误处理比串行复杂得多。串行模式下,一个工具失败可以立即中止后续步骤。并行模式下,部分工具成功、部分失败是常态,你需要决定如何处理混合结果。

三种主流策略:

策略一:全部成功或全部重试(All-or-Nothing)。任何一个工具失败,整个并行批次重试。适合工具调用幂等且重试成本低的场景。优点是实现简单,缺点是慢工具拖慢整体重试。

策略二:部分成功继续(Partial Success)。成功的工具结果正常传递给下一轮,失败的工具返回错误信息让模型决定下一步。这是 Agent 场景最常用的策略——模型可以基于部分信息继续推理,或者决定重试失败的工具。OFOX 的指南明确指出:「将错误作为工具结果返回,让模型决定下一步。包含清晰的错误描述——模型通常可以用修正的参数重试,尝试替代方案,或向用户解释失败。」

策略三:超时降级(Timeout Fallback)。为并行批次设置总超时时间。超时时,已返回的结果正常处理,未返回的工具标记为超时。适合对外部 API 调用(延迟不可控)的场景。

关键实践:永远不要吞掉错误(silently swallow errors)。Jake's Insights 的分析指出,GPT-4o mini 在复杂嵌套 schema 上的错误率高达 8-12%,而 Claude Sonnet 只有 2-3%。如果你的并行调用包含 3 个工具,使用 GPT-4o mini 时至少一个工具出错的概率约 22-31%——这个概率在生产环境中不可忽视。

错误信息的质量也很重要。不要只返回「Error」或空字符串,而是返回结构化的错误信息:错误类型、错误消息、以及可能的恢复建议。这样模型可以更好地决定下一步行动——是重试、换工具、还是告诉用户。

python
import asyncio
from typing import Any

async def execute_tools_parallel(
    tools: list[dict],  # [{"name": "...", "args": {...}}, ...]
    executor: callable,  # async function(name, args) -> result
    timeout_seconds: float = 30.0,
) -> list[dict]:
    """并行执行工具调用,部分失败时返回混合结果。

    返回格式与 OpenAI tool 结果兼容:
    [{"tool_call_id": "...", "name": "...", "status": "ok"|"error", "result": ...}]
    """
    async def run_one(tool: dict) -> dict:
        try:
            result = await asyncio.wait_for(
                executor(tool["name"], tool["args"]),
                timeout=timeout_seconds,
            )
            return {
                "tool_call_id": tool.get("id", ""),
                "name": tool["name"],
                "status": "ok",
                "result": result,
            }
        except asyncio.TimeoutError:
            return {
                "tool_call_id": tool.get("id", ""),
                "name": tool["name"],
                "status": "error",
                "result": f"Timeout after {timeout_seconds}s",
            }
        except Exception as e:
            return {
                "tool_call_id": tool.get("id", ""),
                "name": tool["name"],
                "status": "error",
                "result": f"{type(e).__name__}: {str(e)}",
            }

    # asyncio.gather 确保所有任务并行启动
    # return_exceptions=False 因为我们已经在 run_one 中捕获了异常
    results = await asyncio.gather(*(run_one(t) for t in tools))
    return list(results)

# 使用示例:将结果回传给模型
# tool_results = await execute_tools_parallel(tool_calls, my_executor)
# messages.append({"role": "tool", "content": json.dumps(tool_results)})

💡 一句话理解

部分成功策略的核心:失败的工具结果也要回传给模型。模型可以决定重试、换工具或告诉用户。吞掉错误会让模型在信息不完整的情况下继续推理,产生幻觉。

5延迟优化的生产实践

并行调用是延迟优化的起点,不是终点。生产环境中还需要考虑 schema 开销、连接池管理和缓存策略。

Schema 开销:每次 API 调用都需要发送工具定义(JSON schema)。根据 Jake's Insights 的分析,一个典型的工具定义约 150-300 tokens。定义 5 个工具,每次 API 调用额外消耗 750-1500 tokens。在 10 轮 Agent 循环中,这是 7500-15000 tokens 的纯开销。以 GPT-4o 的定价($2.50/M input tokens),每轮对话的 schema 开销约 $0.025-$0.04——在 10000 轮对话/月的规模下,这是 $250-$400 的纯 schema 税。

连接池管理:并行调用意味着同时打开多个外部连接。如果你的 Agent 同时调用 5 个数据库查询和 3 个外部 API,需要确保数据库连接池和 HTTP 连接池足够大。连接池耗尽会导致排队等待,反而增加延迟

缓存策略:对于幂等的工具调用(相同输入总是返回相同输出),可以在应用层缓存结果。Agent 场景中,同一个会话内经常重复查询相同的数据(用户信息、配置参数)。工具结果缓存可以将重复调用的延迟从 500ms 降低到 <1ms。

模型选择对延迟的影响:DeployBase 的基准测试显示,对于延迟敏感的单次工具调用(<300ms 响应要求),GPT-4o Mini(~210ms)和 Gemini Flash(~190ms)是更好的选择。对于质量敏感的多步工具链,Claude Sonnet 的并行调用延迟方差更低,端到端更可预测。混合路由策略——简单调用走便宜模型、复杂调用走高质量模型——可以实现 80-90% 的成本降低而几乎不影响准确性。

缓存策略的实施细节:工具结果缓存的键设计很重要。简单的做法是用工具名 + 参数的哈希作为键,但要注意参数顺序和格式的一致性。更高级的做法是语义缓存——识别语义相似的查询(比如「北京天气」和「Beijing weather」),返回相同的缓存结果。这需要嵌入模型的支持,但可以将缓存命中率提升 20-30%。

优化策略延迟收益实施复杂度适用场景

并行工具调用

40-75%

独立工具的组合调用

工具结果缓存

50-99%(命中时)

幂等查询、重复数据获取

Schema 精简

减少 10-20% token 开销

所有场景

模型混合路由

成本降低 80-90%

大规模 Agent 部署

连接池预热

减少冷启动 200-500ms

高并发 Agent 服务

流式工具参数解析

减少首 token 等待

实时交互 Agent

6何时必须强制串行

并行调用不是默认选择。以下场景必须强制串行,即使牺牲延迟

事务一致性:多个工具操作需要原子性(要么全部成功,要么全部回滚)。例如转账操作:扣款和入账必须串行并在同一事务中。并行执行可能导致扣款成功但入账失败的中间状态。

顺序依赖:工具 B 的输入来自工具 A 的输出。这是最常见的串行场景——搜索→筛选→排序→展示,每一步依赖前一步的结果。即使工具本身可以并行执行,数据流的依赖关系强制了执行顺序。

资源锁:多个工具竞争同一个有限资源(同一个数据库行的写锁、同一个文件的独占访问、同一个 API 的 rate limit 配额)。并行访问会导致锁等待或限流,反而比串行更慢。

可观测性要求:需要精确追踪每个工具的执行时间和结果,用于调试或审计。并行调用的时间线交叉,增加了追踪复杂度。在开发和调试阶段,强制串行可以简化问题定位。

成本约束:工具的计费是按调用次数而非延迟。并行调用同时触发多个计费事件,可能在短时间内消耗大量配额。如果预算有限,串行调用可以配合预算检查(每次调用前检查剩余配额)来避免超支。

实践中,大多数 Agent 工作流是混合模式:独立的查询并行,有依赖的操作串行。关键是设计一个清晰的依赖图(DAG),让调度器自动判断哪些可以并行、哪些必须串行。

一个实用的经验法则:如果你的工具定义中没有显式声明依赖关系,默认假设它们是独立的、可以并行的。然后在代码审查中重点检查那些「看起来独立但实际上共享状态」的工具——典型的例子是「读取用户配置」和「更新用户偏好」,它们操作同一个用户记录,即使没有显式的数据依赖,也必须串行。

在生产环境中,建议为每个工具调用添加 trace ID 和 span 时间戳。当并行调用的延迟不符合预期时,这些追踪数据可以快速定位是真正的并行执行,还是因为资源竞争退化为串行。OpenTelemetry 的 Agent instrumentation 库已经支持这种模式。

⚠️ 常见踩坑

一个常见的反模式:为了「看起来快」而把有依赖的工具强行并行。这不会降低延迟——你仍然需要等待所有工具完成才能继续——但会引入竞态条件和数据不一致的风险。并行只适用于真正独立的调用。

7跨 Provider 适配层设计

如果你的 Agent 需要支持多个 provider(生产环境中很常见——主用 Claude,备用 GPT-4o,低成本任务走 Gemini),你需要一个适配层来统一并行工具调用的协议差异。

适配层的核心职责:

统一工具定义格式:将内部的工具定义(名称、参数 schema、描述)转换为各 provider 的格式。OpenAI 和 Gemini 的格式相似(都是 JSON schema 数组),Anthropic 的格式略有不同(tools 数组中每个工具包含 input_schema 而非 parameters)。

统一响应解析:将各 provider 的并行调用响应解析为统一格式。OpenAI 返回 tool_calls[] 数组,Anthropic 返回 content[] 中的多个 tool_use 块,Gemini 返回 functionCall[] 数组。适配层需要提取每个调用的 id、name 和 arguments。

统一结果回传:将工具执行结果转换为各 provider 期望的格式回传。OpenAI 需要 tool 角色的消息带 tool_call_id,Anthropic 需要 tool_result 类型的 content 块带 tool_use_id。

错误处理标准化:各 provider 对工具错误的处理方式不同。适配层需要将 provider 特定的错误格式统一为内部错误格式,然后再转换回 provider 期望的错误回传格式。

LiteLLMLangChain 等框架提供了基础的适配能力,但在并行工具调用的细节处理上往往不够完善。生产级适配层通常需要自己实现,特别是对于错误回传和流式响应的处理。

适配层的测试策略也很重要。由于三个 provider 的 API 行为存在细微差异,你需要一套端到端的集成测试,覆盖以下场景:单工具调用、并行多工具调用工具调用失败、超时处理、以及流式响应中的工具调用。测试数据应该包含真实的工具定义和用户输入,而不是 mock 数据。DeployBase 的基准测试显示,不同 provider 在相同工具定义下的 schema 遵循率差异可达 10-15%,这意味着你的适配层必须处理各种边界情况。

另一个容易被忽视的问题是工具定义的版本管理。当你的工具 API 发生变化时(新增参数、修改参数类型、废弃旧参数),你需要确保三个 provider 的工具定义保持同步。建议使用单一的工具定义源(比如 OpenAPI spec),然后通过代码生成器自动转换为各 provider 的格式。这样可以避免手动维护三份定义导致的版本不一致。

图表加载中…

8参考资料

本文的分析基于以下独立来源:

  1. OFOX.io,「Function Calling Guide: GPT, Claude & Gemini (2026)」,2026-03-12 发布,2026-06-08 更新。覆盖三大 provider 的工具调用 API 差异、并行调用支持和生产实践。
    https://ofox.io/blog/function-calling-tool-use-complete-guide-2026/

  2. DeployBase,「Best LLM for Function Calling: Tool Use Comparison and Benchmarks」,2026-02-24。提供 Berkeley Function Calling Leaderboard Q1 2026 的并行工具调用准确率基准数据。
    https://deploybase.ai/articles/best-llm-for-function-calling-tool-use-comparison

  3. Jake's Insights,「Claude API Tool Use vs OpenAI Function Calling: Latency and Cost」,2026-05-25。分析 schema 开销对成本的影响、延迟基准测试和错误率对比。
    https://jakeinsight.com/ai/2026-05-25-claude-api-tool-use-vs-openai-function-calling-lat/

  4. OpenAI 官方文档(2026 年更新),Function Calling API 规范,定义 parallel_tool_calls 参数和结构化输出模式。
    https://platform.openai.com/docs/guides/function-calling

  5. Anthropic 官方文档(2026 年更新),Tool Use API 规范,描述 tool_use 内容块和并行调用行为。
    https://docs.anthropic.com/en/docs/build-with-claude/tool-use/overview

  6. Google AI 官方文档(2026 年更新),Gemini Function Calling 规范,说明 functionCall 数组和错误处理机制。
    https://ai.google.dev/gemini-api/docs/function-calling

🎯 相关面试题

巩固本篇知识点,备战 AI 岗位面试。