[控场AI]
科技前沿· 4 分钟阅读· 2,277 字

OpenAI Agents SDK并行MCP调用变串行?实测与修复

OpenAI Agents SDK并行MCP调用变串行?实测与修复

OpenAI Agents SDK 0.24.0与MCP 2.3.0因历史锁机制导致并行工具调用串行执行,4个3秒调用耗时12秒而非3秒。

本文揭示了OpenAI Agents SDK 0.24.0与MCP 2.3.0中的一个性能问题:通过streamable HTTP连接远程MCP服务器时,多个工具调用被串行执行而非并行。开发者用8行代码复现,4个各需3秒的调用总耗时12秒。根源是MCP 1.x时代引入的按服务器锁机制,在2.x中可能已不需要但尚未移除。GitHub issue #5474已报告但官方未修复。社区提供了非官方变通方法:将`_serialized_session_requests`设为false,可将耗时降至3.1秒,但仅适用于MCP 2.x且为私有属性。文章还提供了自测方法和呼吁社区提供信息以推动修复。

问题现象:并行调用为何变成串行?

最近,有开发者发现OpenAI Agents SDK在调用远程MCP工具时存在性能问题:当模型同时请求多个工具调用时,这些调用并没有并行执行,而是一个接一个地串行处理。以4个各需3秒的工具调用为例,总耗时达到12秒,而非预期的3秒。这个问题在OpenAI Agents SDK 0.24.0和MCP 2.3.0(均为PyPI最新版本)上复现,具体表现为streamable HTTP客户端一次只发送一个请求。

这个问题的隐蔽性在于它不会导致崩溃,只是运行缓慢,因此容易被忽略。如果你在使用MCP 2.x并通过streamable HTTP连接远程MCP服务器,很可能已经遇到了这个问题。

GitHub issue截图

MCP(Model Context Protocol) 是OpenAI于2024年推出的一种开放协议,旨在标准化AI模型与外部工具、数据源之间的连接方式。它允许模型通过统一的接口调用远程服务,例如查询数据库、执行代码或访问API。MCP采用客户端-服务器架构,其中Agents SDK作为客户端,通过HTTP或stdio等传输层与MCP服务器通信。Streamable HTTP是MCP 2.x引入的一种传输方式,支持流式响应和更高效的连接复用,但要求客户端正确处理并发请求。理解MCP的基本架构有助于定位问题:并行调用串行化发生在客户端SDK的请求调度层,而非网络或服务器端。

复现步骤:8行代码揭示瓶颈

为了验证这个问题,开发者进行了一次干净的复现实验。环境使用全新的虚拟环境、Python 3.13.5,并精确安装OpenAI Agents 0.24.0和MCP 2.3.0。无需模型或API密钥,服务器端仅用8行代码实现一个名为slow的工具,该工具睡眠3秒后返回。客户端建立单个连接,同时发起4个对slow的调用,并打印每个调用的完成时间。

运行结果显示,完成时间依次为3秒、6秒、9秒、12秒,总耗时12.1秒,检查失败。这证明调用在单个连接上被逐个排队执行。

客户端打印完成时间

根源分析:历史遗留的锁机制

为什么会出现串行?根源可以追溯到MCP 1.x时代。当时为了应对一个失败请求可能取消其他请求的问题,在PR 2682中引入了一个按服务器粒度的锁。这个锁在MCP 1.x中是合理的,但在0.24.0版本中,它仍然对streamable HTTP生效。在SDK中,每个请求都会经过这个检查,当标志位设为true时,每个请求都会等待锁释放,导致串行执行。

GitHub issue #5474(11月1日报告)指出,MCP 2.x可能已经不需要这个锁了,但OpenAI尚未替换该机制,MCP 2.x方面也未回复。因此,这目前只是报告者的分析,并非官方确认的修复。

issue中关于锁的讨论

按服务器粒度的锁(per-server lock) 是一种同步机制,用于确保同一服务器连接的请求按顺序处理。在MCP 1.x中,由于底层会话管理不够健壮,并发请求可能导致一个请求的失败(如超时或取消)波及同一连接上的其他请求,因此引入此锁来隔离故障。然而,这种锁牺牲了并行性。在MCP 2.x中,协议层面可能已通过改进的流控制和错误处理解决了该问题,但OpenAI Agents SDK仍保留了对旧版行为的兼容逻辑。_serialized_session_requests 标志位正是控制是否启用此锁的开关,默认值为true,导致即使使用streamable HTTP也强制串行。这反映了SDK在向后兼容与性能优化之间的权衡滞后。

官方状态与社区进展

截至11月4日,该issue仍处于开放状态,没有维护者回复,没有修复PR,也没有新版本发布。另一位开发者复现了该问题,还有一位发布了根本原因分析。社区正在等待官方回应。

连接断开导致所有调用失败

临时解决方案:非官方变通方法

目前有一个经过测试的非官方变通方法:在服务器连接后,将_serialized_session_requests属性设置为false。这仅适用于MCP 2.x,且由于是私有属性,任何SDK更新都可能使其失效。在1.x版本上,锁的存在是有原因的,根据issue,如果连接断开,所有进行中的调用会一起失败,因此不建议在1.x上使用。

另一种思路是每次运行使用一个独立连接,但这不会帮助单次运行内的调用并行化,且未经过测试。

应用变通方法后,同样的测试中4个调用在3.1秒内全部完成,总耗时3.1秒,检查通过。重复三次,每次都是3.1秒;而不使用变通方法时,每次都是12.1秒。唯一的变化就是这个标志位,耗时从12.1秒降至3.1秒。

如何判断你是否受影响

你可以用类似的方法自测:创建一个睡眠3秒的工具,同时发起4个调用。如果总耗时约12秒,说明你遇到了这个问题;如果约3秒,则没有。开发者于11月4日复现了该问题。

如果你遇到了,可以在issue下提供你的SDK版本、MCP版本和操作系统信息,帮助社区推动修复。

#OpenAI Agents SDK#MCP#并行调用#串行执行#性能问题#变通方法#streamable HTTP
分享:

相关推荐