为什么框架在规模化时会停滞
大多数 agent 框架建模的是单次运行:一个 LLM 循环调用工具、向记录追加内容,并在满足停止条件时终止。这种抽象对于 notebook 来说足够,但在生产环境中具有误导性。生产系统不是一次运行;而是许多并发运行在争夺同样的稀缺资源——模型速率限制、工具并发、检索带宽,以及盯着队列的运维人员的注意力。框架的职责是描述一次运行。系统的职责是决定哪些运行发生、以什么顺序发生,以及以谁为代价。
这些是调度问题,几十年前就已经为容器解决了。准入控制决定一个请求是被接受、排队还是拒绝。配额限制租户可以消耗的资源。抢占取消低优先级工作,为高优先级工作腾出空间。背压将过载向上游传播,而不是吸收它直到某个环节崩溃。这些概念没有一个是 Kubernetes 首创的,但 Kubernetes 给了它们一套工程师已经理解的词汇和 API 表面。
这种趋同在工具链中已经可见。Google 开源的 AX 编排器是一个信号:业界正在把 agent 协调当作控制平面问题,而不是提示词问题。真正有趣的工程不是用于描述 agent 的新 DSL;而是决定它们何时运行的调度器。
映射控制原语
从容器编排到 agent 编排的映射不是隐喻。它是结构性的,而且有用。
准入控制
当一次运行被提交时,调度器会预测其成本:预期 token 消耗、按类别划分的工具调用次数,以及挂钟时长。如果预测超出该租户或集群的剩余预算,运行就会被拒绝或排队。预测不需要精确;它需要保守且廉价。一个简单的机制是根据提示词大小、声明的工具集,以及每个工具类别的历史乘数,得出每次运行的成本估算。调度器将该估算与令牌桶进行比较。如果桶是空的,运行就等待。
这与 Kubernetes 准入 webhook 拒绝一个请求内存超过命名空间允许值的 pod 是同样的逻辑。区别在于资源是不可互换的:花在失败运行上的 token 就没了,而带有外部副作用的工具调用无法被撤销。
配额

配额在派发之前执行,而不是之后。一个租户有三个预算:每个窗口的 token、每个窗口按类别划分的工具调用,以及并发运行数。调度器在准入时检查这三者。如果任何一个耗尽,运行就排队而不是启动。这是刻意无聊的,而且它是防止一个租户的失控循环饿死其他所有租户的最有效机制。
代价是延迟。严格的配额会让一次运行等待,即使集群还有空闲容量,因为配额是按租户而不是全局的。另一种方案——带公平份额权重的全局调度——更高效,但也更难推理。大多数团队应该从硬配额开始,只有在有数据时才放宽。
抢占
抢占是框架很少实现、而生产系统最终会需要的原语。当一个高优先级运行需要一个当前被低优先级运行持有的工具时,调度器可以取消低优先级运行并释放该工具。被取消的运行会被重新排队,而不是丢失。
抢占强大且危险。只有当被抢占的运行可以从检查点恢复而不重复副作用时,它才是安全的。这个条件并不总是满足,这就是为什么抢占应该是最后引入的原语,而不是第一个。
哪些东西无法迁移
agent 运行的三个属性打破了到 pod 的干净映射。
agent 运行不是无状态的。 pod 可以被杀死并重新调度,因为它的状态存在于卷或数据库中。agent 运行的状态存在于它的记录、工具调用历史和工作记忆中。检查点必须捕获这三者,而恢复必须对已经调用过的工具保持幂等。这是真实的工程成本,也是抢占并非免费的原因。
工具调用有外部副作用。 在工具调用中途取消运行并不会撤销该调用。一笔支付、一张工单、一封邮件、一次数据库写入——这些都会持续存在。因此,抢占

可观测性必须捕获轨迹。 容器编排器关心退出码和资源使用。agent 编排器关心决策序列:调用了哪个工具、用什么参数、返回了什么,以及运行为什么走了那个分支。退出码可观测性是不够的,因为一次运行可以成功退出,却做了错误的事。调度器应该为每次运行发出结构化的轨迹记录,而该记录应该是调试的单位,而不是日志行。
一条迁移路径
团队不需要在第一天就采用完整的调度器。这条路径是渐进的、可逆的。
第一步:为每次运行发出调度记录。 在任何强制执行之前,让系统描述自己。每次运行发出包含优先级、预算估算、依赖关系和工具类别的记录。这是可观测性,不是控制,而且是安全的。它还会产生设定非任意配额所需的数据。
第二步:在抢占之前引入配额。 配额是可逆的:达到限制的租户会等待,而限制可以提高。抢占是不可逆的:被取消的运行可能已经造成了副作用。先引入配额,测量队列行为,然后才考虑对可安全取消的那部分运行进行抢占。
第三步:把调度器当作成本与策略交汇的唯一位置。 如果准入逻辑在 API 网关、配额逻辑在 worker、优先级逻辑在提示词里,就没有人能回答一次运行为什么等待。集中决策使系统可审计,使策略变更可测试。调度器成为拥有“这次运行为什么没有启动?”这个答案的组件。
诚实的权衡
调度器会增加延迟和一个新的故障域。每次运行都要付出准入检查的代价,而调度器中的一个 bug 可能让整个集群停摆。框架通过没有控制平面来避免这一点;它们把问题推给运维人员。对于小系统来说,这是一个合理的选择。当并发运行、租户或工具类别的数量使人工仲裁变得不可能时,它就不再合理。到那时,选择不是框架与调度器之间;而是显式调度器与散落在重试逻辑、速率限制处理和 on-call 判断中的意外调度器之间。
显式调度器更难构建,但更容易运维。这就是权衡。对于生产中的 agent 集群,它是正确的选择。
封面照片:panumas nikhomkhai / Pexels。
