Paper

论文精读|TAO:面向 LLM Agent 服务的工具感知联合调度

Agent 会话有九成以上的时间在等 CPU 上的工具调用。TAO 用一个按字典序比较的三元组给等待中的会话估值,再用多背包动态规划一次性决定谁上 GPU、上哪台。这篇精读按论文原始数据复现了关键图表,也标出了它没赢的地方。

论文:TAO: Tool-Aware Joint Scheduling for LLM-Based Agentic Serving(arXiv.37230v1,2026 年 10 月) 作者:Shuhuai Li、Shengdong Ye、Dongdong Ge、Jianghao Lin(上海交通大学),Yinyu Ye(斯坦福大学) 许可:CC BY 4.0。文中图 1、图 2 直接引用原图;其余图表由我按论文表格和原图矢量坐标重绘。

一句话

Agent 会话在 GPU 推理和 CPU 工具调用之间来回切换,现有调度器挑会话时既不知道工具什么时候返回,又是一个一个贪心地放。TAO 把"缓存信用、工具是否就绪、上下文长度"按固定优先级排成三元组,再在节点容量约束下对整个等待池做一次动态规划。在论文报告的 12 组设置里,相对每项指标上最好的基线,端到端延迟最多降 26.8%,平均 TTFT 最多降 36.3%,解码吞吐最多升 29.5%。

"最多"两个字要留意:同一组表格里也有 TAO 落后的格子,第 6 节会列出来。

1. 问题:工具调用把推理切成了碎片

SWE-agent、Claude Code 这类 Agent 的一个任务由多轮组成:模型生成工具调用,交给外部 CPU 环境执行(跑测试、编译、检索),拿到结果拼回上下文,再请求下一轮推理。论文把这种部署叫 CGDC(Clustered GPUs with Distributed CPUs):GPU 节点集中提供推理,工具在独立的 CPU/内存预算上运行。

论文图 1 左下角的条形图给了一个数:在他们的负载里,工具调用占了端到端时间的 93.1%,推理只占 6.9%。既然大部分时间 GPU 用不上,调度器就可以在工具边界做会话中断,释放该会话的准入额度,把它放进等待池;工具返回后再做会话重启,挑一个节点重新准入。这套生命周期沿用自 ThunderAgent(Kang et al., 2026),TAO 关注的是"从等待池里挑谁、放哪"。

论文图 1。左:CGDC 场景,外部工具调用在两次 LLM 请求之间留下空档,工具时延占 93.1%。右:现有 evaluate-then-decide 调度器的两个问题,一是评估时忽略工具返回就绪度、用启发式规则合并特征,二是逐个会话做短视的准入和放置决策。
图 1(原图):CGDC 场景与现有调度器的两个缺陷。来源:Li et al., 2026,CC BY 4.0。

现有系统(llm-d、SGLang、Dynamo、ThunderAgent 等)大体是"先评估、后决策",论文认为两步各有一个缺口:

  • 评估:看 KV Cache 亲和性、Token 数、SLO,但不看工具什么时候返回;多个特征靠手调的加权或阈值合成一个分数。
  • 决策:每个会话单独打分、单独路由。几个"短但缓存命中低"的会话可能先占掉容量,把"工具已返回、缓存命中高"的会话挡在外面。

2. 方法总览:用三元组代替加权和

论文图 2。TAO 的 evaluate-then-decide 框架:分布式 CPU 侧提供工具调用的历史耗时,GPU 侧引擎提供缓存观测;会话评估模块为每个会话-节点对构造三元组(衰减后的 KV 缓存信用、二元就绪度、Token 数);决策模块用异步动态规划联合选择并放置等待中的会话,执行前按实时状态重新校验。
图 2(原图):TAO 的两阶段流水线。来源:Li et al., 2026,CC BY 4.0。

设等待池为 PP(被中断的会话加新到达的会话),快照里的 GPU 节点集合为 BB。会话 ii 的准入成本是 wiw_i,节点 bb 的剩余容量是 CbC_b,EE 是允许的会话-节点对。可行域是:

X={x: ∑b∈Bxi,b≤1,∑i∈Pwixi,b≤Cb,xi,b=0 if (i,b)∉E}(1)\mathcal{X}=\left\{x:\ \sum_{b\in B}x_{i,b}\le 1,\quad \sum_{i\in P}w_i x_{i,b}\le C_b,\quad x_{i,b}=0 \text{ if } (i,b)\notin E\right\} \qquad (1)

每个可行的会话-节点对得到一个三元组,目标是按字典序最大化选中三元组之和:

vi,b=(ki,b, ri, ti),x⋆∈arg lexmax⁡x∈X ∑i∈P∑b∈Bxi,b vi,b(2),(3)v_{i,b}=\left(k_{i,b},\ r_i,\ t_i\right),\qquad x^\star\in\operatorname*{arg\,lexmax}_{x\in\mathcal{X}}\ \sum_{i\in P}\sum_{b\in B}x_{i,b}\,v_{i,b} \qquad (2),(3)

三个分量的优先级是固定的:

  1. ki,bk_{i,b},衰减后的缓存信用。命中前缀直接省掉 Prefill,所以排第一;但它随暂停时间快速衰减。
  2. ri∈{0,1}r_i\in\lbrace 0,1\rbrace,工具返回就绪度。第一项衰减到打平之后,由它区分"马上要回来"和"还早"的会话。
  3. tit_i,累积 Token 数。前两项都打平时偏向上下文更长的会话;它占的容量更大,这笔账由后面的 DP 去算。

用字典序而不用加权和,好处是不用调权重:不同量纲的特征不会互相抵消。代价是表达力变窄,第一项只要差一点点,后两项就完全不起作用。TAO 靠下一节的衰减和取整来缓解这一点。

3. 两个信号:缓存信用怎么衰减,工具什么时候回来

3.1 缓存信用的时间衰减

会话因工具调用暂停时,它在节点 bb 上留下的前缀不会一直在:其他请求在跑,引擎会按自己的策略驱逐 KV 块。论文在 DeepSeek-V4 Flash(2 节点 × 4 H100)的轨迹上统计了"暂停多久之后,下一次请求还能命中多少缓存",也就是图 3。

图 3 复现:暂停时长与缓存保留率(DeepSeek-V4 Flash,2 节点 × 4 H100)
暂停 4 到 44 秒时,缓存保留率的分箱中位数在 91% 到 99% 之间;暂停 87 秒及以上时中位数降到 0。 叠加的调度信用曲线按 100 × 2^(−τ/h) 衰减,默认半衰期 h = 10 秒。0%25%50%75%100%10 s100 s1 000 s下一次请求前的暂停时长(对数轴)
分箱中位数(95% 区间) 论文的描述性拟合 调度信用 2−τ/h

数据点按论文原图的矢量坐标还原。拖动滑块只改变调度器的折算曲线,不改变实测数据。

TAO 对观测到的缓存信用 ki,b0k^{0}_{i,b} 按暂停时长打折,并对结果取整:

ki,b(t)=ki,b0 2−τi,b/h,τi,b=max⁡(0, t−ti,bobs)(4)k_{i,b}(t)=k^{0}_{i,b}\,2^{-\tau_{i,b}/h},\qquad \tau_{i,b}=\max\left(0,\ t-t^{\mathrm{obs}}_{i,b}\right) \qquad (4)

论文取 h=10h=10 秒。这里有一个容易读错的地方:hh 不是对缓存保留率的拟合。论文明确说半衰期是调度参数,和轨迹拟合出的时间常数是两回事。对比一下就清楚了:暂停 44 秒时实测中位数还有 91.4%,而 h=10h=10 的信用只剩 2−4.4≈4.7%2^{-4.4}\approx 4.7\%。

我的理解是,衰减在这里的作用主要是让出优先级:信用很快被压低、取整后打平,第二项 rir_i 才有机会起作用。滑块拉到 60 秒能看到,衰减变慢后,第一项会在更长时间里独占排序。论文没有报告 hh 的敏感性实验,取 10 秒是怎么定的,正文没有交代。

另外,图 3 的中位数不是平滑下降的:44 秒以内都在 90% 以上,87 秒之后直接归零,中间那两个分箱的 95% 区间覆盖了 0 到 96%。"指数衰减"是描述性拟合,真实形状更像一个阈值。

3.2 工具返回就绪度

TAO 要回答"这个会话的工具会不会在接下来 HH 秒内返回"。论文取 H=1H=1 秒,和调度周期一致。信号按可信度依次取:

  1. 工具接口直接暴露的进度或截止时间,例如 Claude Code 的 Monitor 事件、OpenCode 的 Bash 超时信息;
  2. 从命令里解析出的 sleep N;
  3. 按结构化工具名统计的历史耗时;没有该工具的历史就用全局历史,再没有就用 5 秒默认值。

历史估计用了一个经验 Bernstein 形式的保守上界(附录 A,Maurer & Pontil 2009),δ=0.2\delta=0.2:

D^f=dˉf+2sf2log⁡(3/δ)nf+3Rflog⁡(3/δ)nf(nf≥2)(8)\widehat{D}_f=\bar{d}_f+\sqrt{\frac{2s_f^2\log(3/\delta)}{n_f}}+\frac{3R_f\log(3/\delta)}{n_f}\qquad (n_f\ge 2) \qquad (8)

减去已执行时间 ei(t)e_i(t) 得到剩余时间 d^i(t)=max⁡{0, D^f−ei(t)}\hat d_i(t)=\max\lbrace 0,\ \widehat D_f-e_i(t)\rbrace。二元信号 ri(t)r_i(t) 的规则是:

  • 工具已经完成,直接置 1,优先于任何预测;
  • 预测完成时间落在 t+Ht+H 以内,且预测时间戳在 30 秒内刷新过,置 1;
  • 预测时间已过但工具还没回来,只给一个临时的探针机会,不会一直占着"就绪"。

论文自己也说,这个上界是调度启发式,不保证单次调用的覆盖率。实际效果看附录数据:在 10,967 次完成的工具调用上,最终预测的平均绝对误差是 0.410 秒,82.9% 的误差在 0.5 秒以内,也就是半个调度周期。

4. 决策:多背包动态规划,加一层异步

4.1 为什么贪心不够

拿到每个会话-节点对的三元组后,最直接的做法是按分数从高到低往节点里塞。问题在于各会话的 wiw_i 差别很大,缓存命中又强烈依赖节点。局部看合理的一步,可能把一个节点的剩余空间切碎,或者占掉某个只在特定节点上有大量缓存的会话的位置。附录 H 给了两个重建的真实快照,下面按原图坐标重画。

图 10 复现:同一快照下的缓存信用(DeepSeek-V4 Flash,32 workers 回放)
(a) 短任务优先 + 亲和贪心缓存信用 13,624 tokenNode 1P143P1371.4k 命中P896.4k 命中P1235.8k 命中上限 51.3k剩余 8.5kNode 2P10920.5kP11121.6k上限 62.2k剩余 20.1k(b) TAO 动态规划缓存信用 16,791 token(+23.2%)Node 1P143P1371.4k 命中P1098.8k 命中P1116.6k 命中上限 51.3k剩余 1.5kNode 2P8916.2kP12318.9k上限 62.2k剩余 27.1k010203040506070准入权重(千 token)

浅色是会话占用的准入权重,深色是其中能复用的缓存。同一个会话在两种方案里颜色相同。

图 10 里,贪心先把较短的 P89、P123 放进 Node 1,于是 P109(在 Node 1 上有 8.8k 命中)和 P111(6.6k 命中)只能去没有缓存的 Node 2。DP 反过来安排,两边总的剩余安全空间相同,缓存信用从 13,624 增加到 16,791,多 23.2%。

图 11 复现:同一快照下的准入数量(DeepSeek-V4 Flash,32 workers 回放)
(a) 短任务优先 + 亲和贪心准入 6 个,缓存信用 10,397Node 11953.7k1936.2k1896.6k1877.0k上限 37.8k剩余 14.3kNode 21904.7k1887.3k上限 27.2k剩余 15.2k未准入17721.0k两个节点的剩余空间都放不下(b) TAO 动态规划准入 7 个,缓存信用 14,949Node 11896.6k1877.0k17721.0k上限 37.8k剩余 3.2kNode 21953.7k1904.7k1936.2k1887.3k上限 27.2k剩余 5.3k010203040准入权重(千 token)

方块宽度是准入权重(含每会话 512 token 预留)。虚线框是没能准入的会话。

图 11 是准入数量的例子。贪心先把四个短会话塞进 Node 1,两个节点各剩约 14k 和 15k,都放不下约 21k 的会话 177,只准入 6 个;DP 把 195、193 挪到 Node 2,在 Node 1 腾出整块空间,准入 7 个。

这两张图是精选的例子。论文第 4.3 节给了更全面的统计:在 23 个有多个候选会话的快照里,DP 在 6 个(26.1%)上改进了字典序目标,其余 17 个和贪心结果相同;算上单候选的情况,35 个快照里改进了 6 个(17.1%)。多数时候 DP 和贪心给出同一个答案,差距来自少数快照。

4.2 动态规划

令 Δ\Delta 为容量量子,离散化后会话成本 wˉi=⌈wi/Δ⌉\bar w_i=\lceil w_i/\Delta\rceil,节点容量 Cˉb=⌊Cb/Δ⌋\bar C_b=\lfloor C_b/\Delta\rfloor。Dj(s)D_j(s) 表示只考虑前 jj 个会话、各节点已用容量为向量 ss 时能达到的最大字典序价值:

Dj(s)=lexmax⁡{Dj−1(s), lexmax⁡b eligible[Dj−1(s−wˉjeb)+uj,b]}(7)D_j(s)=\operatorname*{lexmax}\left\lbrace D_{j-1}(s),\ \operatorname*{lexmax}_{b\ \text{eligible}}\left[D_{j-1}(s-\bar w_j e_b)+u_{j,b}\right]\right\rbrace \qquad (7)

状态是多维的,节点一多就会爆。论文的两个工程处理:缓存等价的节点合并成 g≤mg\le m 个容量维度;设状态预算,超了就退回 BFD(best-fit-decreasing)。

4.3 异步求解与重验证

为了不阻塞调度主循环,DP 在独立的异步 worker 里对时刻 ss 的冻结快照求解,得到计划 xsx_s。在时刻 tt 应用前做重验证:被选中会话的状态签名变了就丢弃整个计划;否则只应用当前实时容量允许的最长可行前缀 yty_t。

论文给了相对于"在 tt 时刻重新求最优"的损失上界:

max⁡x∈XtΔUt(x)−Ut(yt) ≤ As,t+2ϵs,t+Ts,t(10)\max_{x\in\mathcal{X}_t^\Delta}U_t(x)-U_t(y_t)\ \le\ A_{s,t}+2\epsilon_{s,t}+T_{s,t} \qquad (10)

As,tA_{s,t} 是可行域变化带来的新机会,ϵs,t\epsilon_{s,t} 是规划期间的价值漂移,Ts,tT_{s,t} 是重验证截断造成的损失。这个界是有条件的:若每个计划最多 KK 个分配、单个分配的价值漂移有界,并进一步假设漂移随时间线性增长 ηs,t≤L(t−s)\eta_{s,t}\le L(t-s),漂移项才变成 2KL(t−s)2KL(t-s)。论文特别指出,二元就绪度的跳变不满足这个假设,需要单独留余量。所以它更适合理解为"规划越新鲜,损失越小"的定性保证,而不是可以直接代入的数。

开销数据在附录 Table 9。我把它摘成下表,因为原 HTML 里"单次 DP 仅需 0.551.59 ms""回退仅 3%8%"的说法只取了部分列:

设置 Workers 求解均值 求解 P95 调度工作占运行时间 BFD 回退 计划丢弃
DeepSeek-V4 Flash,TP4 × 2 16 0.55 ms 0.55 ms < 0.001% 0% 0%
32 1.48 ms 2.08 ms 0.005% 0% 0%
64 12.50 ms 88.84 ms 0.297% 5.24% 0.37%
Qwen3-32B,TP2 × 4 96 0.56 ms 0.62 ms 0.003% 3.06% 0%
128 1.04 ms 2.43 ms 0.077% 6.74% 0.14%
160 1.59 ms 3.68 ms 0.112% 8.98% 0.18%

摘要里"低于运行时间 0.12%"指的是 Qwen 四副本那一组。DeepSeek 64 workers 时求解均值到了 12.5 ms,P95 接近 90 ms,调度工作占比约 0.3%,仍然很小,但已经不是"亚毫秒"。并发越高,回退到 BFD 的比例也越高。

5. 实验设置

  • 模型与硬件:DeepSeek-V4 Flash(2 节点 × 4 H100),Qwen3-32B(4 节点 × 2 H100,4 副本),GLM-4.7(单节点 8 × H100,TP8)。
  • 负载:SWE-bench Lite(SWE-Lite,用 mini-SWE-agent 驱动);DeepSeek 另跑 Terminal-Bench 2.0(用 Claude Code 驱动);Qwen 与 GLM 另跑 SWE-verified。GLM 每次运行 300 个任务。
  • 基线:Dynamo(KV 感知调度)、vLLM 调度器配 Round-Robin(RR)或 Cache-Aware(CA)路由、ThunderAgent(按 Token 数排序 + BFD 放置)。
  • 指标:任务端到端平均延迟、平均 TTFT、解码吞吐。

6. 主要结果

下表是论文 Table 1 和 Table 2 的全部数据,每列最好的值加粗,最后一行是 TAO 相对该列最优基线的变化,负值标红。

DeepSeek-V4 Flash · SWE-Lite2 nodes with 4 × 4\times H100 per node

调度器16 workers32 workers64 workers
Latency (s) ↓TTFT (s) ↓Decode (tok/s) ↑Latency (s) ↓TTFT (s) ↓Decode (tok/s) ↑Latency (s) ↓TTFT (s) ↓Decode (tok/s) ↑
Dynamo122.00.146874.1152.30.1761393.3269.80.3511548.5
vLLM Scheduler w/ RR122.80.177888.5158.80.2171145.6290.70.5081299.8
vLLM Scheduler w/ CA116.00.183889.6150.40.2261256.1253.20.4101561.3
ThunderAgent123.60.379796.2215.72.708961.8407.27.447969.0
TAO (Ours)113.30.135935.0142.30.1531477.5185.40.2242021.5
相对最优基线+2.4%+7.4%+5.1%+5.4%+13.3%+6.0%+26.8%+36.3%+29.5%

DeepSeek-V4 Flash · Terminal-Bench2 nodes with 4 × 4\times H100 per node

调度器16 workers32 workers64 workers
Latency (s) ↓TTFT (s) ↓Decode (tok/s) ↑Latency (s) ↓TTFT (s) ↓Decode (tok/s) ↑Latency (s) ↓TTFT (s) ↓Decode (tok/s) ↑
Dynamo536.61.371494.9579.61.252651.2688.51.315760.7
vLLM Scheduler w/ RR342.50.306820.8375.20.4991071.1467.40.5821597.5
vLLM Scheduler w/ CA304.80.319723.9394.70.3311146.4393.10.3871654.1
ThunderAgent361.10.336876.1380.11.4021053.0391.61.0101376.5
TAO (Ours)298.20.239798.6333.60.2641161.4376.60.3241551.4
相对最优基线+2.2%+21.7%-8.8%+11.1%+20.3%+1.3%+3.8%+16.2%-6.2%

Qwen3-32B · SWE-Lite4 nodes with 2 × 2\times H100 per node

调度器96 workers128 workers160 workers
Latency (s) ↓TTFT (s) ↓Decode (tok/s) ↑Latency (s) ↓TTFT (s) ↓Decode (tok/s) ↑Latency (s) ↓TTFT (s) ↓Decode (tok/s) ↑
Dynamo821.62.0982074.6857.47.9241203.71203.717.2081239.4
vLLM Scheduler w/ RR775.35.1091400.6975.411.1791359.81088.016.6451433.3
vLLM Scheduler w/ CA811.65.3391614.7881.111.7071456.41179.318.3041285.4
ThunderAgent716.32.0512104.9839.38.7052036.31028.516.2091712.4
TAO (Ours)634.71.8271996.8829.47.9072051.81031.014.5541827.6
相对最优基线+11.4%+10.9%-5.1%+1.2%+0.2%+0.8%-0.2%+10.2%+6.7%

Qwen3-32B · SWE-verified4 nodes with 2 × 2\times H100 per node

调度器96 workers128 workers160 workers
Latency (s) ↓TTFT (s) ↓Decode (tok/s) ↑Latency (s) ↓TTFT (s) ↓Decode (tok/s) ↑Latency (s) ↓TTFT (s) ↓Decode (tok/s) ↑
Dynamo736.81.9851862.81041.910.4411820.91286.222.4691667.8
vLLM Scheduler w/ RR777.65.0821931.3933.312.5861804.51244.524.2211091.0
vLLM Scheduler w/ CA816.25.7311522.61016.514.2631670.91264.423.1991619.8
ThunderAgent699.82.3962184.9911.110.5002045.91202.221.6081993.6
TAO (Ours)642.01.3922354.7933.79.0922128.61094.317.6192087.2
相对最优基线+8.3%+29.9%+7.8%-2.5%+12.9%+4.0%+9.0%+18.5%+4.7%

GLM-4.7 · SWE-Liteone node with 8 × 8\times H100 (TP8)

调度器96 workers128 workers160 workers
Latency (s) ↓TTFT (s) ↓Decode (tok/s) ↑Latency (s) ↓TTFT (s) ↓Decode (tok/s) ↑Latency (s) ↓TTFT (s) ↓Decode (tok/s) ↑
Dynamo2870.321.677290.53779.241.865287.84786.759.548262.2
vLLM Scheduler w/ RR2687.820.927310.83633.839.502294.64391.053.588272.5
vLLM Scheduler w/ CA2606.519.553318.73435.837.665308.04314.556.326297.3
ThunderAgent999.67.014773.31360.414.243731.11747.023.345668.9
TAO (Ours)887.76.777869.61261.914.103813.71476.220.066805.9
相对最优基线+11.2%+3.4%+12.5%+7.2%+1.0%+11.3%+15.5%+14.1%+20.5%

GLM-4.7 · SWE-verifiedone node with 8 × 8\times H100 (TP8)

调度器96 workers128 workers160 workers
Latency (s) ↓TTFT (s) ↓Decode (tok/s) ↑Latency (s) ↓TTFT (s) ↓Decode (tok/s) ↑Latency (s) ↓TTFT (s) ↓Decode (tok/s) ↑
Dynamo3164.626.761286.24545.352.588256.68217.186.008163.6
vLLM Scheduler w/ RR2938.223.967292.74136.047.930269.86149.571.452214.6
vLLM Scheduler w/ CA2928.624.505300.33935.746.963284.95989.571.239220.9
ThunderAgent1146.112.590691.51533.318.516688.31846.526.045683.6
TAO (Ours)951.77.752856.81243.915.281858.11548.321.943839.1
相对最优基线+17.0%+38.4%+23.9%+18.9%+17.5%+24.7%+16.2%+15.7%+22.8%

几点我觉得值得单独说:

  • 26.8% / 36.3% / 29.5% 来自同一格:DeepSeek-V4 Flash、SWE-Lite、64 workers。这一格的对照是各列最好的基线:延迟和吞吐比的是 vLLM w/ CA,TTFT 比的是 Dynamo。同一行 16 workers 时,三项只有 2.4%、7.4%、5.1%。
  • TAO 不是每格都赢。54 格里有 5 格落后:Terminal-Bench 16 和 64 workers 的解码吞吐分别低 8.8% 和 6.2%;Qwen SWE-Lite 96 workers 的解码吞吐低 5.1%、160 workers 的延迟高 0.2%;Qwen SWE-verified 128 workers 的延迟高 2.5%。论文正文点名了最后一处。
  • GLM-4.7 上传统基线差很多:Dynamo 与两个 vLLM 配置的延迟是 TAO 的 2.7 到 5.3 倍。这一组里真正可比的是 ThunderAgent:在 SWE-verified 上,TAO 相对它延迟降 16.2–18.9%、TTFT 降 15.7–38.4%、吞吐升 22.8–24.7%;在 SWE-Lite 上幅度小一些,TTFT 在 128 workers 时只降了 1.0%。

图 4 是 GLM-4.7 在 SWE-Lite、160 workers 下的运行过程:

图 4 复现:运行中请求数随时间变化(GLM-4.7,SWE-Lite,160 workers,TP8)
五个调度器都从约 158 个运行中请求开始。TAO 在 60.0 分钟跑完 300 个任务,中段并发保持在约 40 到 75 之间; ThunderAgent 在 70.9 分钟跑完,约 1970 秒处从 28 跳到 122;vLLM w/ CA、vLLM w/ RR 与 Dynamo 分别在 164.3、176.8 和 189.4 分钟跑完。04080120160030 min60 min90 min120 min150 min180 min距该次运行第一个客户端请求的时间

曲线从论文原图的矢量路径提取后做了简化(容差约 1 个请求)。完成时间取自原图图例。

TAO 在 60.0 分钟跑完全部任务,ThunderAgent 70.9 分钟,其余三个基线在 164 到 189 分钟之间。按论文的解释,区别在中段:TAO 在有限容量下持续、平稳地准入新会话,并发维持在约 40 到 75;ThunderAgent 在约 1,970 秒处从 28 个运行中请求跳到 122 个,之后才回落。

论文附录 D 也提醒,这些曲线是自然运行的结果,各次运行生成的轨迹不同。我在正文和附录里没有找到主表的重复次数或方差,所以个位数百分比的差异要谨慎看待。

7. 消融:哪个组件贡献最大

Table 4,DeepSeek-V4 Flash、SWE-Lite、32 workers:

配置 解码吞吐 (tok/s) 缓存命中 TTFT 均值 工具返回到首 Token 暂停等待
完整 TAO 1417.97 96.31% 0.154 s 0.203 s 0.972 s
去掉缓存信用 1398.35 96.24% 0.157 s 0.209 s 1.028 s
去掉就绪度 1363.06 96.16% 0.161 s 0.227 s 1.067 s
两者都去掉 1373.51 96.24% 0.182 s 0.213 s 1.025 s
用 ThunderAgent 的暂停排序 1355.20 96.20% 0.162 s 0.226 s 1.025 s
用 BFD 代替 DP 1233.72 96.05% 0.195 s 0.235 s 1.081 s
  • DP 的贡献最大:换成 BFD,吞吐下降 13.0%,TTFT 从 0.154 秒升到 0.195 秒。
  • 缓存信用的衰减贡献很小:吞吐只差 1.4%,命中率只差 0.07 个百分点。
  • 两项都去掉,吞吐反而比只去掉就绪度高一点(1373.51 对 1363.06),TTFT 则更差。论文没有解释,这类差距可能就在运行噪声范围内。

附录 G 加长了工具返回时延(额外 1–5 秒、2–10 秒、4–20 秒)。时延越长,就绪度改变 DP 计划的比例越高:从 1.65% 升到 3.94%,再到 7.93%。用回放里已知的真实耗时代替历史预测(Oracle),在 2 倍时延时 makespan 只再降 2.24%,说明历史预测已经足够好。不过这组实验每格只跑了一次,论文自己也注明了是探索性的。

8. 我的看法

值得借鉴的地方

  • 字典序加衰减,用来代替手调权重。很多网关路由写成 score = w1 * cache + w2 * load + w3 * wait,换个负载权重就得重调。TAO 用固定优先级,让第一项随时间衰减、取整后打平,把排序权自然交给第二项。思路简单,可以直接搬到别的多信号调度里。
  • "异步求解快照 + 应用前校验 + 截取可行前缀 + 超时回退"这套组合,是把精确组合优化放进在线调度的一个稳妥做法。表里能看到它的代价:并发上去后回退率到了 9%,但不会卡住主循环。
  • 和 Agentic RL 的 rollout 很像。多轮 Agent RL 的 rollout 阶段本身就是 CGDC:大量轨迹卡在容器编译和单测上。把就绪度和联合准入放进 RL 框架的 rollout 调度器,可能缓解长尾轨迹拖慢整个 step 的问题。这是我的推测,论文没有做 RL 场景的实验。

需要留意的地方

  • 收益集中在高并发、容量紧张的设置;低并发时和最强基线只差几个百分点,个别格子还落后。
  • 消融显示主要收益来自 DP 放置,而第 4.3 节统计 DP 只在约四分之一的多候选快照里改变了结果。两者合起来看,收益来自少数关键决策,这也解释了为什么低并发时差距很小。
  • h=10h=10 秒、H=1H=1 秒、δ=0.2\delta=0.2 这些参数都是给定值,没有敏感性分析;主表也没有方差。