一万个 Agent 同时在线,需要一万个 Worker 吗?长任务系统的容量题
Agent Runtime 工程 · 工程面试系列 05/05
面试官把问题从“写一个 Agent Loop”改成“一万个 Agent 同时跑,有的十几分钟才结束”。最容易脱口而出的答案是:上队列,Worker 横向扩容。但扩到多少?有多少 Agent 正在等待模型响应,多少在等浏览器,多少在等用户确认?这些状态的成本完全不同。没有先定义“同时在线”,一万个既可能很轻,也可能轻易耗尽下游配额。
这里沿用 API 文档兼容性报告的示例。假设每个任务需要模型推理、读取规范、运行可选的浏览器或测试工具,部分任务还会停下来等人补充范围。下面的数字是容量算例;本文没有跑过一万并发,也没有实测延迟或成本指标。
把长任务拆成能移交的短步骤
不要让 Web 请求从接收任务一直等到报告完成。入口先持久化运行 ID、任务版本和初始状态,再返回 ID。客户端可以轮询,也可以用 SSE 订阅状态;事件带序号,断线后从上次位置补读,最终状态以持久层为准。
提交任务 ─→ 运行状态 / 事件 ─→ 调度器 ─→ 按资源类型排队
↑ ↑ ├→ 模型调用池
│ │ ├→ 浏览器池
客户端订阅或查询 │ └→ 代码/读取工具池
└──────── 步骤结果、事件与下一步 ─────┘
每次 Worker 领的是有界步骤。等待用户、定时器或外部回调时,将运行置为等待状态并归还 Worker;达到可运行条件后再排队。等待异步响应仍可能占用下游并发额度或网络连接,需要由相应资源池计量。浏览器会话如果必须跨多个步骤保留,也不能免费计入“休眠”:它需要独立租约、空闲回收策略,或按业务需要保存可恢复材料。
步骤不必拆得太碎。几个毫秒内完成的内存变换无需全部过队列,可以按恢复边界、资源池边界和调度公平性切分。上一步完成和下一步派发如果分两次独立写入,进程崩溃可能让任务卡在中间。可以用同一事务写入待发送事件,再通过幂等消费应对重复投递。
容量先算需求,再对照真实限额
假设十分钟内有 10,000 个活跃运行,每个在这十分钟内平均调用 6 次模型,且请求近似均匀:
模型请求速率:10,000 × 6 ÷ 600 秒 = 100 请求/秒
如果平均每次占用 4 秒,平均在途请求数约为 100 × 4 = 400
如果每次输入加输出平均 3,000 token,约为 18,000,000 token/分钟
三行的用途不同:请求速率用于对照 RPM,在途数用于考虑连接、并发和超时,token 吞吐用于对照计费与限额。总 token 的算术示例不能替代服务商计量规则,例如输入与输出分开限额、按预估 token 预扣,或按项目计量。稳定平均值也不是峰值。一批任务同一时间起跑,或在上游限流后同步重试,瞬时请求量都会更高。并发池配置要结合峰值分布、延迟、实际配额和压测。
另一个容易漏掉的条件:上面的 10,000 是十分钟内的活跃运行,并非每秒新到一万个。如果入口到达率长期高于实际服务速率,队列会持续积压。扩 Worker 不能提高已耗尽的模型配额,此时应做背压、延迟非紧急任务,或按明确的产品规则降级。
公平调度和重试,是容量管理的一部分
同一租户提交五千个大任务时,不能让其他租户的小任务全堵在队尾。可以按租户设并发额度,再按优先级和等待时长调度。模型、浏览器、代码执行分别限流;浏览器池吃满时,纯文本任务仍可继续。高成本任务在入队前估算资源,执行中扣除实际预算,超过上限返回可解释的暂停或失败状态。
对 429 或可安全重试的短暂网络错误,采用指数退避与随机抖动,并遵守上游给出的 Retry-After;永久权限错误应结束该步骤。还要限制每次运行及每种依赖的重试总量,避免一万个任务各自把故障放大三倍。对于有副作用的工具,按幂等和对账语义区分“失败可以重试”和“结果未知不能盲重试”。
队列租约可以帮助 Worker 宕机后重新派发,但不能让旧 Worker 自动消失。租约过期后的重复领取、晚到结果、用户取消,都应由运行版本、动作幂等键和条件写入处理。客户端看见进度停顿不能据此推断任务失败,最终状态要可查。
面试追问:上线第一天,你看哪些指标?
先看最老排队任务的年龄、分阶段的 p95 等待与执行时长、依赖侧 429 和重试放大、每租户运行中数量,以及成功、取消、失败的比例。再用运行 ID 关联步骤、模型和工具日志,区分“排队慢”和“模型响应慢”。如果队列长度大但年龄低,可能只是正常突发;如果年龄持续上升而模型配额打满,继续增加 Worker 就不会解决瓶颈。
可用假模型与假浏览器分别模拟正常流量、流量突发和某一依赖持续故障,验证租户公平、取消能阻止后续步骤、重试不越过预算、故障不拖垮其他池。之后用小规模真实流量校准延迟、配额与成本。面试回答可以从一句话开始:“我先拆活跃任务、可运行步骤和下游在途请求,然后按资源和租户做调度、限流与背压。”再拿算例解释为什么一万个运行不等于一万个常驻 Worker。
参考:AWS Builders’ Library:Avoiding insurmountable queue backlogs;AWS Builders’ Library:Timeouts, retries, and backoff with jitter;OpenTelemetry Traces。
更多推荐



所有评论(0)