ThunderAgent: A Simple, Fast and Program-Aware Agentic Inference System

发表时间: 2026-02 · arXiv:2602.13692 (Georgia Tech / CMU / Stanford)

文章标题: ThunderAgent: 一个简单、快速且程序感知的 Agentic 推理系统
作者/机构: Hao Kang∗1, Ziyang Li∗2, Xinyu Yang∗3, Weili Xu∗4, Yinfang Chen4, Junxiong Wang5, Beidi Chen3, Tushar Krishna1, Chenfeng Xu5, and Simran Arora5 (1佐治亚理工学院 2独立研究员 3卡内基梅隆大学 4伊利诺伊大学厄巴纳-香槟分校 5Together AI)

A1 主要贡献

大型语言模型(LLM)正被用于驱动复杂的多轮 Agentic 工作流。现有系统通过松散地组装独立组件(如 vLLM 推理引擎和 Kubernetes 工具编排器)来运行 Agentic 推理。这些系统在处理涉及多个 LLM 和工具请求的 Agentic 工作流时,是基于单个请求进行调度和资源分配的,缺乏对整个工作流的端到端认知。这导致了 KV 缓存和工具执行环境管理的次优问题。

核心问题与研究目标
随着 Agentic 工作流的规模化和自主化,系统的整体效率更多地取决于持续吞吐量而非尾部延迟。然而,现有 Agentic 推理系统存在三大挑战,导致吞吐量不佳:
1. KV 缓存颠簸 (KV cache thrashing):在工具执行期间,系统会过早地驱逐 KV 缓存,当工具调用完成后,系统需要重新预填充(re-prefill)以恢复其交互历史,这极大地增加了端到端延迟并降低了吞吐量。
2. 跨节点内存不平衡 (Cross-node memory imbalance):现有引擎为了最大化 KV 缓存命中率,会将同一 Agentic 工作流的所有请求固定到单个节点。但由于工作流的上下文长度会不可预测地快速增长,导致某些节点内存耗尽,而其他节点仍处于低利用率状态。
3. 工具生命周期无感知 (Tool lifecycle obliviousness):系统无法判断何时释放和准备工具执行所需的环境和资源,导致未使用的沙箱和 API 服务器持续占用磁盘空间和网络端口,最终引发资源耗尽和系统故障。

为应对这些挑战,本文提出了 ThunderAgent,一个快速、简单且程序感知的 Agentic 推理系统。

创新点
1. 程序抽象 (Program abstraction):将 Agentic 工作流抽象为“Agentic 程序”。这是一个跨越多个模型调用和工具执行的持久化一级调度单元,向运行时暴露语义状态(如标识符、执行阶段、调度状态、Token 总数和工具资源)。这种抽象将调度与执行后端(如 vLLM/SGLang)解耦。
2. 程序感知调度器 (Program-aware scheduler):将 Agentic 推理调度视为一个约束优化问题,目标是最小化重计算和缓存开销,最大化预填充和解码吞吐量。为此引入了两个关键机制:
* 状态感知暂停 (State-aware pausing):当后端出现内存压力时,选择性地暂停处于“行动”状态(即正在调用工具)的工作流,为处于“推理”状态的程序保留内存,避免次优的 KV 缓存驱逐。
* 动态迁移 (Dynamic migration):通过让所有数据并行(DP)节点共享一个全局的程序感知等待队列,实现 Agentic 程序在节点间的迁移,以缓解内存不平衡。

  1. 程序感知工具资源管理 (Program-aware tool resource management):通过跟踪执行依赖关系,ThunderAgent 将 I/O 密集型的环境初始化与 LLM 推理过程重叠。对于已完成的程序,实现了一个生命周期感知的垃圾回收器,利用程序终止信号回收 Docker 沙箱、网络端口等工具资源,防止资源泄漏。


图 1: ThunderAgent 与先前的 Agent 推理系统在并行工作流数量(即批处理大小)增加时的性能比较。我们在一个 8×H100 GPU 集群上评估了在 SWE-Bench Lite 上服务 SWE-Agent 的 GLM-4.6 MoE 模型(图 a 和 b),以及 SWE-Agent、OpenHands 和 ToolOrchestra(图 c)。结果显示:(a) 当前推理系统在大批量下无法保持高吞吐量。(b) 吞吐量下降主要是由低 KV 缓存命中率引起的,这增加了端到端请求延迟。(c) ThunderAgent 通过减少 KV 缓存颠簸和管理工具执行资源的生命周期,实现了比先前推理系统更高的吞吐量。

A3 背景知识与关键挑战

2. 背景知识

当前 Agentic 工作流的系统属性。当前的 Agentic 工作流在生成过程中交替进行推理和行动。在每个步骤 t,Agent 接收一个观察 $o_t \in O$ 并产生一个输出 $e_t = (\ell_t, a_t) \in L \times A$,其中 $\ell_t$ 表示思考, $a_t$ 表示行动。我们将步骤 t 的累积上下文定义为 $c_t = (o_1, e_1, \ldots, o_t)$,它捕获了 Agentic 工作流的交互历史。在给定 $c_t$ 的条件下, $e_t$ 从策略 $\pi(e_t|c_t)$ 中采样。此工作流保持两种持久状态:(i) GPU 内存,其中 $c_t$ 的 KV 缓存作为工作流的内存。由于轨迹是增量增长的,$c_{t+1}$ 将 $c_t$ 作为前缀进行扩展,理论上可以在步骤之间实现近乎完全的 KV 缓存重用。(ii) 工具环境,其中在 t=1 时初始化的外部资源(如沙箱或数据库连接)必须在整个执行过程中保持一致和可访问。这些状态依赖性要求对 Agentic 推理轨迹有一个程序级别的视图,从而使系统能够协调异构资源并管理长期运行工作流的状态。然而,现有的推理系统将每个思考 $\ell_t$ 和行动 $a_t$ 视为独立的、无状态的请求。

现有 Agentic 推理系统。先前的工作主要集中于优化 Agentic 推理中的单个组件,包括 LLM 推理引擎或工具编排器(附录 A.1, A.2),但很少有工作为跨 GPU、CPU 和远程资源的 Agentic 工作流提供端到端优化。Autellix 将多轮 Agentic 工作流建模为纯 GPU 程序,并在一个中央进程表中跟踪累积的 GPU 执行时间【13,Autellix: An efficient serving engine for llm agents as general programs,2025】。然而,它忽略了工作流的局部性,允许并发工作流激进地驱逐其他工作流的 KV 缓存,在重负载下引发 KV 缓存颠簸。Continuum 是另一个为多轮 Agentic 工作流设计的近期服务系统【11,Continuum: Efficient and robust multi-turn llm agent scheduling with kv cache time-to-live,2025】。它采用生存时间(TTL)机制将 KV 缓存固定在 HBM 中,以减轻工具执行期间的上下文颠簸。然而,它未能解决 KV 缓存驱逐问题。首先,大多数工具的执行时间不可预测(例如 ToolOrchestra 中的远程模型 API【18】,代码 Agent 中的编译器,以及计算机使用 Agent 的 Web 应用【35】)。由于不正确的 TTL 估计,这类不可预测的工具在 Continuum 中会引发严重的颠簸以及被困的 KV 缓存内存。此外,一旦运行中工作流的解码内存超过 GPU 限制,系统也会抢占并驱逐固定的 KV 缓存。这导致了图 1a 中所示的不可避免的颠簸和相应的吞吐量下降。这些局限性凸显了对一个简单、快速的 Agentic 推理系统的需求。


图 2: 当前 Agentic 推理系统内存不平衡和工具资源管理问题的演示。我们使用 GLM 4.6 模型在两个 8×H100 GPU 节点上,通过 vLLM + Kubernetes 评估 OpenHands RL rollout 在 SWEBench-Lite 上的表现。观察结果显示:(a) 在 90 分钟的 rollout 测试中,当应用 vLLM 的 KV 感知路由器时,最大内存不平衡可达 51%。(b) 未能对工具执行环境进行垃圾回收,导致资源使用量逐渐超过系统容量。(c) 随着并行工作流数量的增加,平均工具执行环境准备时间迅速增长。

3. 现有 Agentic 推理系统中的挑战

本节将 vLLM 与 Kubernetes 的组合作为多轮 Agentic 推理的代表性基线进行剖析,并综合其关键的低效之处。这些已识别的局限性无法通过更换推理引擎(如 TensorRT 或 SGLang)或工具编排器来解决,而是需要新的程序感知抽象。默认情况下,我们在两个 8×H100 GPU 节点上使用 GLM 4.6 模型进行 OpenHands RL rollout。

KV 缓存颠簸。Agentic 工作流在执行期间表现出很高的理论 KV 缓存重用率。然而,在现有的 LLM 服务系统中,每一步都被视为一个独立的、无状态的请求。在高并发下,这种请求级别的调度导致 KV 缓存在工具执行期间被频繁驱逐,以容纳新到达的请求,从而导致重复的驱逐和重新预填充,我们称之为 KV 缓存颠簸。如图 1b 所示,随着并行工作流数量的增加,这种颠簸会加剧。由此导致的缓存命中率下降会引发频繁且代价高昂的重新预填充,即在工具完成后必须重新计算整个历史记录。与无颠簸设置相比,这种冗余使每个请求的端到端延迟显著增加高达 7.14 倍,导致严重的吞吐量下降。

跨节点内存不平衡。当前跨数据并行(DP)节点路由请求的策略也是次优的。现有的多轮调度器【21, 33】贪婪地将请求分配给具有最高 KV 缓存局部性的目标 DP 节点,以最大化缓存重用。然而,该策略忽略了节点间内存负载可能变得不平衡的事实。例如,vLLM 中的 KV 感知路由器【21,KV-aware Routing — vLLM Production Stack Documentation,2025】将来自同一 Agentic 工作流的所有请求发送到同一节点。由于不同工作流可能表现出高度异构的 KV 占用和执行生命周期,该策略常常导致节点间严重的内存不平衡,某些节点过载而其他节点利用率很低。类似地,SGLang 中的前缀感知路由器贪婪地将工作负载路由到具有匹配前缀的节点以最大化缓存命中。由于 Agentic 系统的提示在工作流之间是相同的,该策略会将几乎所有请求发送到同一节点,而让其他节点闲置。如图 2a 所示,在 Agentic RL rollout 的 90 分钟快照期间,两个 DP 节点之间的内存使用差异在超过 37 分钟的时间里超过 20%,峰值不平衡达到 51%。

工具生命周期无感知。当前的 Agentic 推理系统没有将外部工具编排器的生命周期与 LLM 推理引擎同步,导致工具编排器端出现静默的资源浪费和延迟开销。如图 2b 所示,总磁盘空间消耗随处理的工作流数量线性增加,最终超过系统容量。这是因为当工作流完成时,未使用的资源(例如,已完成工作负载的 Docker 镜像)没有被回收。这种低效的垃圾回收导致了长期 Agentic 推理的致命系统不稳定性。此外,我们观察到大多数 Agentic 工作负载在启动多轮轨迹之前需要准备环境。例如,编码 Agent 需要拉取 docker、安装相关包和构建仓库。如图 2c 所示,这个准备时间是昂贵的,并且随着并行工作负载数量(即批处理大小)的增加而增加。如果 LLM 推理引擎需要等到环境完全准备好,这个开销将延长推理系统的端到端延迟。

A2 方法细节


图 3: ThunderAgent 概览。我们展示了调度状态和内存管理之间的转换。ThunderAgent 每隔 Δt 时间周期性地查询每个数据并行后端的状态。在这里,后端 #1 触发了颠簸,而后端 #3 利用率不足。所有后端共享的全局等待队列随后暂停并将正在行动的程序 #2 回收到队列中,同时释放正在推理的程序 #6 和 #9,以停止后端 #1 的 KV 缓存颠簸并减少后端 #3 的内存不平衡。

基于第 3 节的发现,我们提出了 ThunderAgent,一个用于高吞吐量 Agentic 推理的程序感知系统。我们在 4.1 节中对 Agentic 程序进行建模,它作为我们调度的主要抽象。4.2 节形式化了一个成本模型来指导我们的系统设计。基于这些基础,我们在 4.3 节详细介绍了我们的 KV 缓存调度策略,在 4.4 节介绍了工具资源管理策略。

Table 1: Agentic 程序的符号总结。每个程序实例由其身份、执行阶段、工具环境、资源占用和在 ThunderAgent 中的调度状态来表征。

4.1 程序抽象

Agentic 程序的定义。Agentic 程序是一个基本的抽象,它封装了 Agentic 工作流的逻辑执行流和系统级依赖。我们正式将一个 Agentic 程序 P 定义为一个元组:

其中 ID 代表唯一的全局标识符。c 表示上下文中的 Token 数量,对应于活动执行期间的 KV 缓存内存占用。T 跟踪程序使用的工具环境集合,当没有程序再需要它们时,可以进行垃圾回收。L、τ 和 s 分别表示节点位置、执行阶段和调度状态,有助于程序级的 KV 缓存颠簸减少和跨节点转移。一个元数据示例在图 3 的右侧展示。ThunderAgent 通过与 OpenAI 风格的端点接口,直接包装现有的 LLM 引擎和工具编排器。程序 ID 使系统能够区分来自不同 Agentic 工作流的请求。我们在附录 B 中详细阐述了将 ThunderAgent 与现有推理服务集成的简便性。

4.2 成本模型

时空积(STP)成本模型。在多轮 Agentic 推理期间,只有用于活动预填充和解码的资源对系统的有效吞吐量有贡献,而重计算、已用容量和空闲缓存则构成资源浪费。我们将其包含在一个 GPU 资源消耗的成本模型中,该模型将有效成本与非生产性使用分离开。我们采用时空积(STP)【1,A study of replacement algorithms for a virtual-storage computer,1966,IBM Systems Journal】作为我们的主要度量,定义为内存占用在处理时间上的积分。一个处理阶段 x 期间的 STP 成本形式化为:

其中 $t_x$ 是处理过程 x 的持续时间。由于内存使用量 $M_x(t)$ 可以直接通过 LLM 中使用的 KV 缓存 Token 数量来量化,我们将成本模型定义为 Token 数量对时间的积分。

成本分解。Agentic 推理的总成本包括五个不同的部分:解码、预填充、重计算、未使用容量和空闲缓存。我们明确区分了用于工具执行结果的增量预填充与对历史交互的重计算,后者由于需要重新计算被驱逐的完整上下文的 KV 缓存而导致成本显著更高。形式上,这产生了以下成本分解:
在这个分解中,$Cost_{decode}$ 和 $Cost_{prefill}$ 代表对推理吞吐量有贡献的有效工作。其余项是浪费的系统开销:$Cost_{recompute}$ 源于 KV 缓存颠簸(第 3.1 节);$Cost_{unused}$ 反映了数据并行(DP)推理后端副本间的内存不平衡(第 3.2 节);而 $Cost_{caching}$ 是在外部工具执行期间持有内存时累积的(第 3.3 节)。

4.3 调度策略

优化目标。基于上述成本模型,我们调度策略的优化目标是最小化非生产性开销部分:$Cost_{recompute}$、$Cost_{unused}$ 和 $Cost_{caching}$,从而最大化吞吐量。

4.3.1 通过程序感知等待队列减少重计算和缓存成本

引入程序感知等待队列。如第 3.1 节和图 1b 所述,KV 缓存颠簸是吞吐量下降的主要瓶颈。为解决此问题,系统必须通过明确控制活动程序的数量来最小化 $Cost_{recompute}$。ThunderAgent 通过引入一个程序感知的等待队列来实现这一点。我们的系统利用此队列调度程序执行,根据它们的 Token 长度 c 和执行阶段 τ 决定哪个程序应在 GPU 中执行,哪个应被换出。在这里,我们使用两个基本操作来形式化调度器行为:Restore 和 Pause。

Restore 和 Pause 操作
* Restore:此操作将一个程序接纳到活动执行中。给定一个程序 $P = \langle ID, c, T, L, \tau, s \rangle$,其中 $s = \text{Paused}$ 且 $L = \emptyset$,Restore(P) 将 P 分配给一个有可用容量的后端 L' 并更新状态:

* Pause:此操作将一个程序从活动执行中移除。给定一个程序 $P = \langle ID, c, T, L, \tau, s \rangle$,其中 $s = \text{Active}$,Pause(P) 将 P 从其后端解绑,释放其 KV 缓存以供抢占,并更新状态:

基于这两个操作,我们接下来介绍我们的调度策略以最小化 KV 缓存颠簸。

周期性颠簸检测。第 4.1 节中的程序抽象为我们提供了行动中程序的 KV 缓存大小。这在请求级系统中是不可用的(如第 3 节所述)。我们将 DP 后端 L 的颠簸条件定义为程序内存需求超过总容量的状态:

其中 $C_{total}$ 表示后端 L 的 KV 缓存池的固定 Token 容量。在解码期间,Agentic 工作流的上下文长度 $c_p$ 迅速增长,即使没有新请求到达,也可能在执行中途触发内存颠簸。与仅在工作流到达时检查是否接纳的基线调度器(如 Continuum)不同,我们实现了一个周期性监视器,以固定间隔 $\Delta t$ 评估内存使用情况,从而可以抢先检测和缓解由上下文增长引起的内存压力。当 KV 缓存颠簸即将发生时,ThunderAgent 调用 Pause 操作暂停活动程序并释放内存大小 $\Delta C = \sum_{p \in L} c_p - \lambda_{max} \cdot C_{total}$,直到总内存使用量降至限制 $\lambda_{max} \cdot C_{total}$ 以下。相反,当后端有可用空间时,即 $\sum_{p \in L} c_p < \lambda_{min} \cdot C_{total}$,ThunderAgent 通过 Restore 从等待队列中恢复暂停的程序,确保恢复的程序使总内存低于 $\lambda_{max} \cdot C_{total}$。这里,$\lambda_{max}$ 和 $\lambda_{min}$ 分别表示内存使用的高水位和低水位线,共同形成一个稳定我们调度的滞后窗口。在实践中,我们将这两个值都设置为 1,因为程序间共享的提示隐式地保留了足够的内存缓冲区。

时间衰减机制。通过这种程序级的周期性容量检查,ThunderAgent 可以保证在行动阶段为活动程序保留内存,从而不会发生 KV 缓存颠簸。然而,代价是当程序进行长时间的工具执行时,行动中程序占用的 GPU 内存是空闲的。为了平衡缓存成本与重计算成本,我们在颠簸检查中加入了一个时间衰减机制,该机制逐步降低行动中程序 Token 的有效权重。这使得调度器在内存压力上升时可以驱逐长时间空闲的缓存,而不是无限期地持有它们:

具体来说,$t_q$ 是程序 q 在当前步骤的工具执行时间。$f(t)$ 是一个旨在平衡 $Cost_{caching}$ 和 $Cost_{recompute}$ 的时间衰减函数。通过随时间动态降低行动中程序的有效内存优先级,$f(t)$ 鼓励调度器驱逐保持空闲的缓存。在 E.1 节中,我们证明当工具执行延迟满足无记忆属性时(即剩余执行时间与已用时长无关),最优的衰减函数 $f(t)$ 呈指数衰减形式。

通过最短优先驱逐最小化重计算成本。在上述驱逐和恢复条件下,处理颠簸的剩余问题是确定要暂停哪些活动程序的子集,以最小化重计算成本。我们证明,驱逐具有最小 KV 缓存大小的程序可以得到最优解,详细证明见 E.2 节。
引理 4.1 (二次重计算成本):给定一个上下文长度为 $c_i$ 的程序 $P_i$,重新预填充其 KV 缓存所产生的重计算成本与 $c_i$ 成二次方关系,即:

定义 4.1 (驱逐优化问题):基于引理 4.1,给定所需的内存释放量 $\Delta C$,调度器旨在选择一个程序子集 S 进行驱逐,使得释放的容量满足约束,同时最小化总重计算成本。该优化问题形式化如下:

目标函数通过选择较小的 $c_i$ 来严格最小化。因此,ThunderAgent 的策略是贪婪地暂停和驱逐具有最短上下文长度的程序。我们将其正式证明推迟到附录 E.3。

调度评分函数。基于这些分析,我们在调度器中采用以下分数来恢复和暂停程序:
PROTECTED_IMAGE_25____PROTECTED_IMAGE_26
其中,指示函数 $I(\cdot)$ 强制程序执行状态 $(\tau)$ 的优先级高于上下文长度。这两种机制都遵循最短优先策略以最小化重计算成本。然而,状态指示器 $I$ 确保调度器优先暂停“行动中”(Acting)的程序,从而通过回收缓存内存来最小化 $Cost_{caching}$,同时优先恢复“推理中”(Reasoning)的程序以最大化 $Cost_{decode} + Cost_{prefill}$。

4.3.2 通过全局程序感知等待队列减少内存不平衡

全局等待队列设计。第 3.1 节和图 2a 强调了节点间的内存不平衡会引入显著的 $Cost_{unused}$,导致尽管其他节点有足够的内存容量,程序仍不必要地被暂停。为此,ThunderAgent 将所有后端副本的等待队列统一为一个全局的程序感知等待队列。该设计的关键动机是,$Cost_{unused}$ 仅在暂停的程序保留在等待队列中而某些副本有空闲内存时才会产生。此外,一旦一个程序被暂停,其 KV 缓存被假定为已驱逐,使其重计算成本与节点无关。这使我们能够在不牺牲 KV 缓存局部性的情况下改善跨节点内存平衡。恢复策略与负载均衡而非严格的 KV 感知路由对齐,使暂停的程序可以被分派到任何有可用内存容量的副本。因此,全局队列将未使用成本限制在每个节点在 $\Delta t$ 周期内的 $C_{unused} < c_{min} \cdot \Delta t^1$ 以内,其中 $c_{min}$ 代表暂停程序中的最小 Token 长度。ThunderAgent 中的调度策略和全局等待队列的概览如图 3 所示。

4.4 工具资源管理

钩子式垃圾回收。我们实现了生命周期钩子,将工具资源的持久性与 Agentic 程序的调度状态 s 严格耦合。当一个程序状态变为“已终止”(Terminated)时,收集器会立即触发一个拆卸序列,系统地回收沙箱、网络套接字和计算槽位。图 2b 中的活动磁盘使用情况表明,我们的资源管理策略有效地防止了过多资源的累积,使磁盘内存消耗在一段时间内保持近乎恒定。

异步环境准备。初始化工具执行环境(例如,启动 Docker 容器并安装依赖项)所涉及的延迟可能成为瓶颈。为解决此问题,ThunderAgent 监视全局等待队列;当一个高优先级程序(高 $S_{restore}$)接近恢复阈值时,系统会在分配 GPU 内存之前异步恢复其执行环境。这项技术有效地隐藏了初始化开销,显著减少了像编码 Agent 和科学 Agent 这样工具调用繁重的工作负载的端到端延迟,如图 2c 所示。

A4 实验

实验环境

  1. 基准和工作流:

    • 编码 Agent 服务: 在 SWEBench-Lite【9】数据集上部署 OpenHands【23】和 mini-SWEAgent【27】。OpenHands 是重初始化工作流(每个沙箱磁盘占用 >10GB),mini-SWEAgent 是轻量级工作流(≈2GB)。
    • 其他 Agent 服务: 在 HLE-Bench【15】上应用 ToolOrchestra【18】,在 ScienceAgentBench【3】上应用 OpenHands。这些工作流涉及由外部 API 调用和复杂科学模拟驱动的可变延迟。
    • RL Rollout: 在两个 8×H100 节点上,使用相同的模型、工作流和样本进行 RL rollout。
  2. 模型和部署:

    • 模型: GLM-4.6 (355B)【20】和 Qwen-3 (235B)【26】。
    • 硬件: 在 8×H100 节点上,模型被量化为 FP8 并使用张量并行(TP=8)进行部署。ToolOrchestra 使用 Qwen3-8B(FP16 精度)部署在一台 RTX 5090 上。
    • 部署架构: LLM 推理引擎运行在 GPU 集群上,而 Agent 的 Docker 环境被卸载到专用的 CPU 集群。
  3. ThunderAgent 配置:

    • 超参数: 调度周期 $\Delta t = 5$s,优先级衰减函数 $f(t) = 2^{-t}$。
    • 后端引擎: 使用 vLLM 作为 LLM 推理引擎。
    • 度量标准: 使用“每分钟步数”(steps per minute)作为吞吐量指标,一步包括工作流的一个推理和行动周期。
  4. 基线技术:

    • vLLM (Inference): 广泛采用的请求感知 LLM 推理引擎,作为无状态的基线。
    • Continuum (Inference): 当前最先进的多轮 Agentic 工作流系统,通过预测工具执行时长并固定 KV 缓存来缓解颠簸。
    • vLLM + SGLang Gateway (Distributed Rollout): 用于大规模分布式 RL Rollout 的领先解决方案,通过增强跨节点内存平衡和 KV 缓存命中率来优化分布式推理。

实验结果

5.2 服务评估结果

高并发下的高吞吐量。图 4 显示,在高并发水平(例如 96 个并行程序)下,ThunderAgent 的吞吐量显著优于基线,相比 vLLM 实现了 1.48–3.58 倍的加速,相比 Continuum 实现了 1.17–3.31 倍的加速。这得益于其程序感知调度器,该调度器维持了近乎最优的 KV 缓存命中率(对于 Mini-SWE-Bench 和 OpenHands 接近 100%,见图 5 a, b, d, e),并实现了环境的异步准备。相比之下,Continuum 在高并发下性能下降,其 KV 缓存命中率从 >90% 降至 ≈60%,因为当内存不足时,不同程序的请求会相互竞争导致 KV 缓存颠簸。

对高并发的鲁棒性。即使并行工作流数量超出 GPU 内存限制,ThunderAgent 仍能保持最大可实现吞吐量。如图 4 所示,ThunderAgent 的吞吐量保持稳定,而基线系统在工作负载超过内存限制后会经历严重的吞吐量崩溃。这种自动适应最大可用容量的能力对于现实世界的稳健部署至关重要。

对确定性和随机性工具执行的鲁棒性。ThunderAgent 不仅在工具模式确定的工作流中表现出色(图 4 a, b, d, e),在高度随机的条件下也同样优越(图 4 c, f)。这源于其动态的程序感知等待队列策略。vLLM 缺乏为行动中程序保留内存的机制,导致频繁重计算。Continuum 则静态保留内存并错误预测工具执行时间,导致在长且不可预测的工具调用中产生高昂的 $Cost_{recompute}$ 或 $Cost_{caching}$。ThunderAgent 通过时间衰减函数 $f(t)$ 平衡了这两者,优先保留短工具调用的 KV 缓存,同时抢先暂停长工具调用的程序以防内存浪费。如图 5 (右) 所示,尽管在随机设置下 ThunderAgent 的 KV 缓存命中率低于 Continuum,但通过确保 GPU 的有效利用,它实现了更高的吞吐量。


图 4: 服务评估结果。ThunderAgent 在三个模型、四个 Agentic 工作流和三个数据集上显著优于 vLLM 和 Continuum。对于工具调用时间可预测的工作流(a, b, d, e),ThunderAgent 的性能比 vLLM 和 Continuum 高出 2.43-3.56 倍。对于工具执行时间随机的工作流(c, f),ThunderAgent 仍然实现了最佳的吞吐量性能。


图 5: KV 缓存命中率统计。在工具调用时间可预测的情况下(a, b, d, e),ThunderAgent 实现了近乎最优(≈100%)的命中率;而在工具执行时间随机的情况下(c, f),它动态地用命中率换取更少的空闲缓存。与 vLLM 和 Continuum 相比,它也实现了更高的 KV 缓存命中率。

5.3 Rollout 评估结果

在双节点 H100 集群上使用 GLM4.6 进行的 RL rollout 评估(持续 3 小时)显示,ThunderAgent 保持了有效的可扩展性,相比 vLLM + Gateway 基线,吞吐量提升了 1.79–3.92 倍,使其对于内存密集型的分布式 RL 工作负载非常高效。

Table 2: ThunderAgent 在 2×H100 节点上使用 GLM-4.6 进行的 rollout (N=144)

5.4 消融研究

端到端延迟分解。图 6a 分解了 OpenHands rollouts 的平均端到端延迟。吞吐量的提升主要源于预填充和解码延迟的减少。此外,工具资源管理策略(第 4.4 节)贡献了约 10% 的延迟改进,同时节省了 4.2 倍的磁盘内存。

对 $\Delta t$ 和 $f(t)$ 的消融。研究了检测周期 $\Delta t$ 和衰减函数 $f(t) = x^{-t}$ 的敏感性。图 6b 显示,在使用 GLM4.6 模型和 mini-SWEAgent 的离线服务中,ThunderAgent 在不同参数设置下均保持高吞吐量,证明了其方法的鲁棒性。增加 $\Delta t$ 可能会降低 KV 缓存命中率并减少吞吐量,因为颠簸可能在检测间隔中发生。增加 $f(t)$ 中的 x 会导致对行动中程序更激进的驱逐,这是用重计算成本来换取缓存成本的降低,这会因为过早驱逐工具执行时间短的行动中程序而降低吞-吐量。


图 6: 端到端延迟分解和 ThunderAgent 参数敏感性的消融研究。

A5 结论

本文介绍了 ThunderAgent,一个基于程序级抽象构建的快速、简单的 Agentic 系统,该抽象在每个 Agentic 工作流的整个生命周期中跟踪元数据。ThunderAgent 利用该程序抽象进行运行时调度和资源管理。具体来说,ThunderAgent 动态地在 GPU 节点间调度程序执行,以减轻 KV 缓存颠簸和内存不平衡,同时管理工具资源以防止资源泄漏。实验结果表明,ThunderAgent 在服务方面比以前的系统性能高出 1.48–3.58 倍,在 RL rollouts 方面高出 1.79–3.92 倍。

A6 附录

A. 与先前工作的扩展比较

A.1 KV 缓存优化多层 KV 缓存管理。为缓解 GPU 内存压力,像 Pensieve【28】、Continuum【11】、Strata【25】和 ShadowKV【19】等系统利用硬件内存层次结构(GPU HBM、CPU DRAM 和 NVMe SSD)进行 KV 缓存管理。这些分层缓存机制通过将不活动的 KV 状态卸载到低层存储并在请求恢复时将其预取回 GPU 来减轻瞬时抢占。然而,这些方法的实际效率从根本上受到设备和主机内存之间跨层带宽的限制。在图 7a 中,当使用 mini-SWEAgent 框架【27】服务 GLM-4.6 模型【20】时,频繁的换入换出操作带来的延迟惩罚抵消了内存容量的好处,导致在重度 Agentic 工作负载下吞吐量严重下降。分布式 KV 缓存管理。分布式管理 Agentic 状态给 KV 缓存驱逐和抢占策略带来了显著的复杂性。虽然 BanaServe【6】和 LMCache【12】等系统支持跨 DP 节点的 KV 缓存传输,但它们在大批量 Agentic 服务和 rollout 中的性能常受限于有限的互连带宽。Agentic 工作流中强烈的程序内依赖性需要在没有程序级管理的情况下频繁进行状态传输,这很容易在服务或 rollout 期间使网络饱和。为绕过这些带宽瓶颈,vLLM KV-aware router【21】和 SGLang Model Gateway【33】等标准推理系统采用 KV 感知路由策略,根据前缀局部性或会话 ID 将请求固定到特定节点。然而,这些方法缺乏在 DP 节点间动态迁移活动程序状态的能力,导致集群中严重的内存利用不平衡和总吞吐量下降,如图 2a 所示。

A.2 KV 缓存优化扩展实验结果KV 缓存卸载实验。我们使用 LMcache【12】研究了 KV 缓存卸载作为解决容量限制的潜在方案。理论上卸载可以利用 CPU 或 SSD 存储扩展有效内存空间,但我们的 vLLM + LMcache 实现揭示了一个关键瓶颈:PCIe 带宽不足以支持 Agentic 工作负载固有的高频上下文切换和大容量数据传输。如图 7a 所示,这导致了严重的吞吐量下降。预填充-解码(PD)分离实验。我们还探索了 PD 分离【34】,这是聊天机器人服务的标准优化。然而,当应用于上下文持续增长的 Agentic 工作负载时,PD 分离反而加剧了颠簸。通过将集群划分为仅预填充和仅解码的节点,可用于处理预填充的有效 HBM 池比统一架构小得多。这种内存碎片化导致系统在更低的并发水平下就达到容量极限并触发颠簸,如图 7b 所示。这些结果表明,通用的架构优化无法替代主动管理工作集的以程序为中心的调度器。

A.3 扩展 Agentic 工作流异构资源分配与调度。为了大规模编排多轮 Agent-环境交互,MegaFlow【31】、RollArt【5, 22】、AgentRL【30】和 VerlTool【8】等近期系统将模型推理与环境执行解耦。虽然这些框架通过专门服务有效扩展了环境并发性,但它们表现出粗粒度分离的固有局限性。通过将推理引擎和工具执行器视为孤立的黑盒,这些系统缺乏统一的资源管理,无法将 KV 缓存生命周期与环境执行相协调。没有程序级的细粒度调度,基于分离的方法在 Agentic 工作负载中浪费了 KV 缓存的重用潜力,导致吞吐量次优。


图 7: KV 缓存卸载和预填充-解码(PD)分离的消融研究

B. 系统可移植性与接口抽象

B.1 中间件架构与统一接口。ThunderAgent 作为一个程序感知的运行时层,通过程序级抽象在 Agent 控制流和后端推理引擎之间进行协调。调度器根据抽象的 ProgramState(见表 3a)和后端缓存容量视图(见表 4)来控制程序状态转换。同时,每个程序只与端点绑定,不依赖于具体的后端实现。

B.2 为何程序 ID 很重要。虽然标准会话 ID 用作路由标签,但我们的系统使用程序 ID 来检查工作流元数据。这种可见性至关重要:它允许调度器区分有效的工具等待时间与空闲会话,从而实现基于会话的基线无法支持的智能抢占策略。

B.3 低开销采用 ThunderAgent。图 8 显示,采用 ThunderAgent 仅需将程序 ID 附加到请求(包括 LLM 推理和工具执行),并在程序结束时发送带有程序 ID 的显式释放信号。程序 ID 为每个请求标记其所属的程序实例以进行调度,而释放信号允许 ThunderAgent 在程序终止后回收每个程序的资源。所有其他请求字段和 OpenAI 风格的 API 接口保持不变。

仅推理后端 (例如, vLLM/SGLang)

使用 ThunderAgent


图 8: 使用 ThunderAgent 仅需三处改动。

Table 3: 程序状态和状态定义。

(a) ProgramState 字段。
(b) ProgramStatus 语义。

Table 4: BackendState 的关键字段。

C. 工具执行时间的可变性

工具执行时间的不可预测性。实际的 Agent 工具调用难以表征且通常不可预测。在某些以代码为中心的场景中(如使用 SWE-agent 或 OpenHands 服务 SWE-Bench),工具延迟相对稳定。然而,在更广泛和现实的场景中(如使用 ToolOrchestra 服务 HLE-Bench),工作负载更依赖于远程服务工具(表 5),使得工具执行时间多变且难以预测。这种波动性主要源于 Agent 运行时之外的因素,如网络抖动、后端负载、排队延迟和速率限制。我们在图 9 中凭经验证实了这种行为。对于远程服务工具(和一些执行工具),中位数和尾部百分位数之间的差距很大:p95 和 p99 远高于中位数,尾部可以延伸到数十甚至数百秒。这表明在这些设置中,工具延迟缺乏稳定的中心趋势;相反,重尾行为占主导地位,使得工具延迟预测在实践中本质上是脆弱的。

现有方法的局限性。鉴于工具执行的不可预测性,低估会浪费固定的缓存容量,同时仍会触发过早的 KV 驱逐,导致恢复时发生颠簸。相反,高估可能导致不必要地驱逐本应固定的程序 KV 缓存。即使工具运行时间完全可预测,像 continuum【11】这样的现有方法仍使用静态的、基于阈值的规则来决定是否固定 KV 缓存。相比之下,ThunderAgent 构建了一个完整的成本建模框架,并动态地权衡 $Cost_{recompute}$ 和 $Cost_{caching}$。

Table 5: 工具类别。

PROTECTED_IMAGE_27____PROTECTED_IMAGE_28
图 9: 工具执行时间分布。工具执行时间表现出高可变性且难以预测。

D. KV 缓存命中率统计与解读

成本权衡。在我们的成本分解方程(3)中,Agentic 服务的吞吐量损失主要来自非生产性开销:由颠簸引起的 KV 重计算($Cost_{recompute}$)和外部工具执行期间的空闲 KV 缓存($Cost_{caching}$)。当工具调用时间短且可预测时,$Cost_{caching}$ 很小,因此避免颠簸是主要矛盾:更高的 KV 缓存命中率通常意味着更少的重预填充和更高的吞吐量。然而,当工具执行时间高度可变时(见附录 C),基于 TTL 的调度器最终可能会为长工具调用固定 KV。虽然这可以减少 $Cost_{recompute}$ 并提高 KV 缓存命中率,但它同时会增加 $Cost_{caching}$ 并降低吞吐量。这有助于解释为什么尽管 continuum【11】实现了更高的 KV 缓存命中率,但在工具密集型工作负载上表现不佳(图 4, 5)。

ThunderAgent的自适应策略。ThunderAgent 通过明确平衡缓存和重计算来适应这些情况。ThunderAgent 在 4.3 节中为行动中程序引入了一个时间衰减函数 $f(t)$,以权衡 $Cost_{caching}$ 和 $Cost_{recompute}$;我们在附录 E.1 中严格推导了 $f(t)$ 的最优函数形式。通过逐步降低长时间空闲的行动中程序的有效内存优先级,调度器会驱逐它们的 KV 缓存以减少空闲缓存成本,同时控制重计算,从而在实践中产生更好的吞吐量(图 4)。

E. 扩展理论分析

E.1 时间衰减函数的证明
假设 E.1 (不可预测的工具执行时间):对于行动中程序,我们假设调度器无法可靠预测给定程序的工具返回时间。因此,衰减函数 f 应仅以时间同质的方式依赖于已流逝的行动时间 t。
假设 E.2 (边界条件):我们假设时间衰减函数 $f : [0, \infty) \rightarrow (0, 1]$ 满足:

定理 E.1 (可接受的时间衰减函数):在假设 E.1 和 E.2 下,我们容量检查函数(公式 7)的可接受时间衰减函数 f 必须采用以下形式之一:连续时间下的指数函数 $f(t) = e^{-\lambda t}$ (其中 $\lambda > 0$),或离散滴答时间下的几何函数 $f(k) = x^{-k}$ (其中 $x > 1$)。
证明概要:该证明首先将假设 E.1 暗示的时间同质性形式化为 $f(t+\Delta) = f(t)\phi(\Delta)$。通过设置 $t=0$ 并使用边界条件 $f(0)=1$,得到 $\phi(\Delta) = f(\Delta)$,从而得出乘法半群方程 $f(t+\Delta) = f(t)f(\Delta)$。对于连续时间,取对数后得到柯西函数方程 $h(t+\Delta) = h(t) + h(\Delta)$,其中 $h(t) = \ln f(t)$。在有界条件下,其唯一解为线性函数 $h(t)=ct$,即 $f(t)=e^{-\lambda t}$。对于离散时间,该方程变为 $f(k+n)=f(k)f(n)$,其解为几何形式 $f(k)=\gamma^k$ 或 $f(k)=x^{-k}$。

E.2 重计算 STP 成本的证明
根据 4.2 节的定义,STP 重计算成本为:

其中瞬时成本 $c_i(t)$ 与解码步骤成正比(即 $c_i(t) \propto t$)。这是因为分块预填充在每次迭代中处理恒定数量的 KV 对,导致累积计算随时间线性增加。因此,对积分求值得到 $Cost_{recompute} \propto t^2_{recompute}$。鉴于 $t_{recompute} = c_i \times T_{decode}/\text{chunk}$,其中 $T_{decode}$ 和块大小都是常数,因此 $Cost_{recompute} \propto c_i^2$。

E.3 最小化重计算 STP 成本的证明
问题定义:选择一个暂停程序的子集 S 进行驱逐,使得总回收内存 $\sum_{i \in S} c_i \geq \Delta C$,同时最小化总重计算成本 $J(S) = \sum_{i \in S} c_i^2$。
定理:最小化 $J(S)$ 的最优策略是严格选择具有最小上下文长度 $c_i$ 的程序。
证明概要(交换论证):假设最优集 $S^*$ 不是最短程序的集合,这意味着存在一个“长”程序 $p_{long} \in S^*$ 和一个“短”程序 $p_{short} \notin S^*$,使得 $c_{short} < c_{long}$。由于平方函数的凸性,我们有 $(c_{short} + (c_{long}-c_{short}))^2 = c_{long}^2 > c_{short}^2 + (c_{long}-c_{short})^2$。这意味着将一个大的驱逐目标分解为较小的部分会严格减少平方和。因此,如果用一个大程序来满足内存约束,可以通过将其换成一个或多个总容量相同但更小的可用程序来严格降低成本。通过迭代应用这种交换,成本函数 $J(S)$ 单调递减,直到 S 完全由具有最小可用上下文长度的程序组成时达到全局最小值。因此,最短优先策略是全局最优的。

F. 端到端延迟分析

尽管我们在第 1 节中指出,对于自主 Agent 和 Agentic RL rollout,程序级延迟(整个工作流生成所用时间)远比每步的端到端延迟重要,但我们在此比较了 ThunderAgent 与 vLLM 和 Continuum 的平均每步延迟。图 10 显示,无论是在低并行度还是高并行度下,当在单个 H100 上使用 GLM4.6 和 Qwen3 235B 配合 mini-SWEAgent 和 Openhands 时,ThunderAgent 的性能都显著优于 vLLM 和 Continuum。基线系统看似通过切换行动中程序来改善端到端延迟,但实际上是通过引发严重的 KV 缓存颠簸来延迟所有正在运行的程序的延迟。


图 10: 端到端延迟比较