跳到主要内容

智能体管道中的并行陷阱:扇出为何让延迟更糟

· 阅读需 9 分钟
Tian Pan
Software Engineer

你的智能体管道很慢,于是你把任务拆分给五个并行子智能体。p50 下降了,你把它上线了。三天后,告警响了:一批用户请求超时。你挖进去发现 p99 从 4 秒涨到了 22 秒。单个智能体本身没有任何变化。超时是因为编排层在等最慢的那个——它以 1% 的概率遇到了检索抖动,但现在任何触碰全部五条路径的请求都会遇到这个概率。

这就是并行陷阱:这个模式看起来是显而易见的提速方案,实则以一种伤害真实用户更多的方式重构了延迟分布,p50 的改善远不能弥补 p99 的恶化。在生产基准测试中,单个智能体在 64% 的评估任务上能匹配甚至超过多智能体管道。并行扇出奏效的时候,确实奏效得很干净——但仅限于特定类别的问题。把扇出当作默认选项,才是错误所在。

你没有在计量的协调税

你每增加一条并行分支,都要付出一笔不会出现在分支自身耗时里的代价。随着智能体数量增加,至少有四种隐藏开销会叠加。

上下文合并是第一种。当并行智能体各自产出需要输入到下游步骤的结果时,必须有某个东西把这些输出拼接成连贯的上下文。这个合并步骤并不免费——它本身需要一次 LLM 调用或一次非平凡的 reduce 操作。一个四智能体扇出产出 29,000 个 token 去完成单个智能体 10,000 个 token 就能做到的事,并不意味着运行了 2.9 倍的推理;它运行的推理大致相同,只是包裹了近 3 倍的协调胶水。

结果去重是第二种。并行处理相关子任务的智能体,经常浮现出重叠信息。不去重,下游智能体会被矛盾或冗余的信号搞乱;去重,你又增加了一道有自身延迟且会以微妙方式失败的流程——把在重要细节上存在差异的结果合并掉,或者漏掉需要解决的冲突。

错误聚合延迟是第三种。在顺序管道中,第二步出错会立即中止整个任务。在扇出中,一个分支出错不会阻止其他分支跑完。编排器必须等所有分支完成(或超时)才能决定如何处理不完整的结果集。这段等待时间在任何单条分支的链路追踪中都是不可见的,却实实在在地体现在端到端延迟里。

每步的编排开销是第四种。并行分支之间的每个协调步骤——任务分发、结果收集、路由——都会增加 50 到 200 毫秒。在一个实测的四智能体管道中,总协调开销为 950 毫秒,而实际的并行处理只用了 500 毫秒。开销几乎是它所协调的工作量的两倍。

为什么 p99 的恶化比 p50 的改善更伤人

并行扇出真正的问题不只是增加了开销——它还放大了方差。这是大多数延迟分析都会忽略的概率论论据。

设想五个并行智能体,每个在任意给定请求中都有 1% 的概率运行缓慢。其中至少一个运行缓慢的概率大约是 5%——是单个智能体概率的五倍。当端到端延迟受限于最慢的那条分支时,每条分支中的每个方差来源都直接贡献到尾延迟中。

文本类 AI 应用的行业目标通常是 p50 低于 3 秒、p95 低于 6 秒。在每日百万用户规模下,p99 达到 10 秒意味着每天有一万用户等待超过 10 秒。把 p50 从 2.5 秒降到 1.8 秒,对已经走快路的用户没有任何帮助。把 p99 从 6 秒推到 22 秒,每天都在破坏可量化比例的用户体验。

这就是为什么顺序管道在中位延迟上不如并行管道时,往往在尾延迟上表现更好。顺序管道在每一步只有一个尾方差来源;扇出有 N 个来源,每个都可能触发最坏情况的执行。

阿姆达尔定律在这里适用,而且很残酷

阿姆达尔定律描述了并行化工作负载能获得的理论加速比:最大加速比受限于实际可并行的工作占比。如果你的工作流中有 30% 是本质上串行的——需要先前步骤的输出、需要人工审核、或者依赖中间状态的决策——那么无论添加多少个智能体,并行化其余部分的最大理论加速比大约是 1.4 倍。

在智能体管道中,串行占比往往比看起来更大。每个需要判断的步骤、用上一步的输出来构造提示的步骤、需要结果经过验证才能继续的步骤,都是串行的。规划步骤是串行的,验证步骤是串行的,最终合并是串行的。实践中,大多数智能体工作流中可并行化的部分是 30% 到 50%,这意味着扇出能达到的最大加速比是 2 到 3 倍,而不是一个数量级。

团队在顺序任务上测得 1.6 到 2.2 倍的并行智能体延迟改善——这些数字是真实的,而且大致也是阿姆达尔上限。问题在于,实现这些需要消耗 1.7 到 2.6 倍更多的 token,这是一个必须与延迟收益相权衡的直接成本乘数。在每月 100,000 次执行的规模下,设计不良的并行管道的上下文开销可能把成本从 500 美元推到 50,000 美元。

扇出真正奏效的场景

并行智能体效果好,是在子任务同时满足三个条件时:任务彼此真正独立、不需要共享上下文、且可以基于部分结果得出最终结论。

并行工具调用——同时发出多个 API 调用或搜索查询——是扇出干净获胜的典型例子。任务不共享状态,结果在消费前无需合并,任何单个失败不阻塞其他请求。延迟节省是真实的,协调开销微乎其微。

先解后择的竞争模式——生成多个智能体用不同策略处理同一问题,返回第一个正确答案——在你有一个能低成本确认结果的快速验证器时有效,无需把所有分支跑完。没有这个验证器,你就要为 N 个智能体付费,并合并全部 N 个结果,这几乎总是比一个设计良好的单智能体更慢。

在明确划分领域上的独立报告生成,在分区真正互不相交时有效。如果领域有任何重叠——智能体共享任何上下文、引用彼此的输出、或者需要保持一致性——你只是把协调问题从前期规划移到了下游的对账步骤,而后者通常更难做对。

决策框架

在添加扇出阶段之前,先回答这些问题:

子任务之间存在数据依赖吗? 如果任何子任务在运行之前需要另一个子任务的结果,这两个任务无论你如何架构都是串行的。强行把它们塞进并行结构,只是在等待之上叠加了分发和收集的开销。

最慢分支的 p99 是多少? 你的端到端 p99 被各分支 p99 的最大值所下界。如果任何分支有高方差——由于检索、外部 API 调用或提示复杂性——那个方差就是你管道的尾延迟。

合并步骤的代价是多少? 计算合并所需的 token 数。如果并行分支的输出需要输入另一次 LLM 调用来进行整合,把这笔延迟和成本算进去。很多孤立看起来很快的并行设计,其实藏着一个合并瓶颈。

你的实际串行占比是多少? 标出哪些步骤需要先前输出、哪些真正独立。如果可并行化的工作超不过 50%,你的上限大约是 2 倍,而你要付出协调开销才能到达那里。

当四个答案都有利时,扇出是正确选择。当任何一个答案不利时,配合设计良好的单智能体进行顺序执行,几乎总是在尾延迟和总成本上双双获胜。

生产环境实际的样子

经过验证的生产模式是轮辐式编排,而非对等网格。一个中央编排器路由到专用智能体、收集结果并做合并。各智能体是无状态的,基于独立输入运行。编排器在一处处理错误聚合和部分结果的决策。

驱动网格架构的"编排器即瓶颈"顾虑是真实存在的,但通常为时过早。在大多数生产系统中,编排器的工作是路由和合并,而不是计算——它不会增加有意义的延迟,而集中化使错误处理、链路追踪和调试大幅简化。

最重要的操作纪律,是把每条并行分支视为潜在的 p99 贡献者。每条新的并行路径都需要自己的延迟 SLO、自己的错误预算,以及当该路径超时时编排器该如何应对的明确答案。没有这种纪律的扇出不只会引发延迟问题——还会引发难以诊断的延迟问题,因为慢路径被隐藏在聚合指标看起来正常的并行组里。

从一个强大的单智能体开始。验证专家智能体能提供通才无法提供的信息。量化协调税。然后再扇出——清醒地知道自己买到了什么、付出了什么代价。

Let's stay in touch and Follow me for more thoughts and updates