ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

AX开源框架:用声明式YAML编排十亿级Agent生产任务

AX开源框架:用声明式YAML编排十亿级Agent生产任务

开头先从我自己的一件事说起。之前做一个多 Agent 协作项目,几十个 Agent 同时跑,我写了个调度脚本,跑了几天就开始四处冒烟:某个 Agent 超时卡死,另一个把共享状态写到同一个 key,还有一次模型接口返回变慢导致整个队列雪崩。调试的时候我就在想,这年头谁还自己写脚本管理几十个进程啊?容器有 Kubernetes,Agent 怎么就没有类似的东西?结果没过多久,Google 真的推出了一个叫AX的开源项目,定位就是"Kubernetes for Agents",用声明式 YAML 编排十亿级的 Agent 任务。

这个项目解决的事情其实非常朴素:当你的 Agent 从"跑个 Demo"变成"跑生产任务集群"时,你需要像 K8s 管理容器一样,用一套统一的控制面来管理部署、伸缩、状态、调度、回滚和审计。而不是靠一堆 shell 脚本、环境变量、临时数据库表硬凑。

如果你正在做 AI Agent 相关的开发,或者你是技术负责人、平台工程师,关注 Agent 规模化落地,那这篇文章会非常有用。我会先拆解 AX 为什么值得被叫做 "Kubernetes for Agents",再带你看它的两层架构、声明式 YAML 到底能编排什么,然后给一个可操作的配置示例,最后聊聊我在阅读它源码和文档后最关注的三个可靠性设计:扩展策略、回滚机制和安全审计。

1. 为什么需要"给 Agent 准备的 Kubernetes":从容器编排到 Agent 编排

先达成一个共识:单个 Agent 很好写,难的是让几千、几万个 Agent 稳定地协作。

Kubernetes 之所以成功,不只是因为"能跑容器",而是因为它提供了一套声明式的资源管理哲学:你告诉它期望状态(desired state),它负责让实际状态趋近期望状态。扩容、缩容、滚动升级、故障自愈,都是这套哲学在不同场景下的体现。

AX 做的正是这套体系在 AI Agent 领域的镜像。标题里说的"用声明式 YAML 编排十亿级 Agent 任务",关键在于两个词:声明式和编排。

1.1 声明式资源管理对 Agent 意味着什么

以容器为例,你在 Deployment 里写上replicas: 5,K8s 就会保证有 5 个 pod 在跑。多了它帮你杀掉,少了它帮你拉起。

Agent 也一样。你有没有遇到过这种情况:一个 Agent 任务因为网络抖动或模型接口 5xx 挂掉了,你需要手动重启、重试、补偿;或者早上业务量上来,需要把某个 Agent 的并发数从 2 调到 10,然后半夜还得记得调回来。

命令式脚本搞不定这些,因为命令式只描述"现在做什么",不描述"应该处于什么状态"。AX 的 YAML 配置描述的是 Agent 任务集群的期望状态:

  • 预期运行多少个实例(副本数)
  • 用什么基础模型 API
  • 什么条件下允许接收新任务
  • 失败后是重试还是回退给人
  • 工具访问范围有哪些

然后由 AX 的运行时(Runtime)持续协调实际状态。你不关心它内部怎么调度的,你只关心你声明的目标有没有被收敛。

1.2 十亿级任务背景下:手写 while 循环撑不住的时候

我相信很多团队最初的 Agent 引入是从一个while循环开始的:读消息、调 LLM、执行工具、返回结果。这在一两个场景里够用,但一旦进入生产环境,问题会以指数形式爆发:

  • 并发控制:同时几百个任务请求打到模型 API,没有限流和排队,分分钟被限速。
  • 状态管理:每个任务的状态、上下文、中间步骤,你存 Redis 还是数据库?TTL 设多少?谁来清理?
  • 故障恢复:节点宕机、模型超时、工具调用失败,任务队列里的消息怎么重新分配?
  • 灰度发布:你更新了 Agent 的系统提示词,结果效果反而不如旧版本,怎么快速回到上一个稳定版本?

当任务规模走向 "十亿级"(无论是调用量级还是 Agent 实例数级),这些问题不可能靠人工或脚本解决。AX 做的事情,就是在这些点位上提供标准化的答案,就像 K8s 在容器调度领域做过的那样。

2. AX 的核心:应用层与分布式层的分离

刚开始看 AX 文档时,会被它拆成两层的结构迷惑。但细想之后,我觉得这个设计是整套系统的灵魂:它把"Agent 自己的逻辑"和"Agent 运行的环境"彻底解耦了。

AX 的架构可以简单理解为两部分:

  • 应用层:负责 Agent 自己的状态、设备、运行逻辑,以及它们之间的协作协议。它不关心底层基础设施。
  • 分布式层:负责把多个 Agent 设备连接到跨网络的 Zone 中,实现网络拓扑、调度和副本分发。

打个比方:应用层是你的程序代码,分布式层是承载代码的操作系统加网络。你只需要关注前者怎么写,后者交给运行时管理。

2.1 应用层:ZIT 协议、Device 与 Runnable

AX 的 Agent 模型建立在ZIT(Zone-to-Zone)协议之上。这套协议定义了多个 Agent 设备(Device)如何在同一个 Zone 网络中注册、发现、通信和协作。Zone是 AX 中跨网络的协调单元,它的命名方式类似域下的主机名(如mycompany.product1.prod),既能表达归属,又能限定通信边界。

一个典型的 Agent 设备由两部分组成:

  • Device:Agent 的运行时载体,负责承载 Runnable 对象,并管理 Agent 的生命周期。你可以理解为"Agent 进程"。
  • Runnable:实际的业务逻辑单元,可能是模型调用、工具调用、消息识别、意图分类等。

这个分离设计很关键。它意味着你的 Agent 逻辑是以单元(Runnable)形式存在的,可以被组合、被复用、被编排,而 Device 只是承载它们的底座。就像容器镜像和 Pod 的关系:镜像描述内容,Pod 负责运行。

使用 AX 模型时,Device 会绑定一个应用端点地址(API 前缀),同时暴露一组内置端点。对于用户而言,真正面向用户的 Agent(也许是前端页面,也许是对话接口)是一个包含名称、回复规则、可执行动作的对象。剩下的事情就交给运行时。

2.2 分布式层:单机模式与集群模式

AX 的分布式层最值得讲的,是它支持单机模式和集群模式两种拓扑,而且切换成本很低。因为 Device 本身的模型是一致的,区别只在于"网络边界在哪里"。

单机模式下,所有 Device 运行在一个进程中,Zone 网络退化为本地进程内网络。适合开发调试、CI 跑测试、小规模部署。

集群模式下,多个 Device(可能分布在不同机器、不同数据中心)通过 ZIT 协议建立 Zone 网络,形成真正的分布式拓扑。此时 AX 可以提供跨节点的副本调度、容错转移和横向伸缩。

这让我想到 Kubernetes 的minikube和正式集群的差别——本地先跑通,再上集群。AX 保留了这种渐进式体验,避免了"本地能跑、生产不能跑"的鸿沟,因为配置模型是一致的。

3. 声明式 YAML 到底能编排什么:任务、状态与人的回退

标题强调"声明式 YAML",那我们就必须盯着 YAML 看。AX 用 YAML 描述一类 Agent 应用的所有边界条件,而不是只描述代码入口。

3.1 一个 Agent 配置的核心字段与心智模型

我根据 AX 的编排模型,把 YAML 配置拆成几个核心区块:

区块说明对应 K8s 视角
id/name应用的唯一标识与显示名称metadata.name
conversation.requires判定会话是否进入 Agent 的前置条件Pod 的 readinessProbe
conversation.can_start允许开始的时间窗口与状态约束replicas 与调度条件
intro对话开场白(自然语言接口)容器的 command 启动参数
context静态上下文提示语ConfigMap 挂载
runtime.app.base_api模型/内部 API 端点配置image + env

拿一个实际配置来理解:假设我要做一个"客服分类 + 判断是否为老客户"的 Agent 应用,其中一个 Runnable 的职责是"判断是否需要人工介入"。YAML 里会有一段:

id: cs-classifier name: 客户意图分级代理 conversation: requires: - user_intent_exists can_start: if: user.segment == "vip" intro: | 你好,我是前端客服分级助手,可以协助识别你的需求。 context: | 你是一个客户意图分类器。请根据用户会话判断: - 如果用户表达投诉,优先转人工。 - 如果用户仅咨询,输出自动回复建议。 runtime: app: base_api: "https://south-1.ai-infra.example.internal/api/"

这段配置声明了:只有当用户输入现实存在且用户属于 VIP 分群时,该 Agent 才会开始工作。而 "context" 里的规则,是 Agent 每轮思考时的背景上下文。

你可能会问:这么一段 YAML 和直接在代码里写 prompt 有什么区别?区别在于——AX 能让这些配置被版本化、灰度化和回滚。你的 Agent 行为不再藏在代码里,而是变成显式的可管理资源。调整一个提示词、改一个分类逻辑,不需要重新编译和发布整个服务,只需要更新这份 YAML。

3.2 "老机器人"与主动回退:人的介入成为一等公民

这是整个 AX 里我觉得最符合生产现实的设计:它把"回退给人"也做成了 Agent 的一个可编排步骤,而不是一个异常分支。

很多 Agent 框架里,人工介入被当成异常路径处理:识别到"置信度不足"就抛异常,然后系统报错。真正在生产里,人工介入是常态,关键在于介入得及时、流程要可追溯。

AX 支持可回退的 Agent(rollback-able agent),它的核心是固定/动态场景结合。固定部分由conversation.requires决定:只有满足条件,Agent 才会开始回复。动态部分由运行时动态评估:当 Agent 遭遇超出工具边界、无法置信的场景,运行时会把对话回退给人(或者另一个更高级的 Agent)。

这种设计的价值,我在做客服机器人时体会尤其深。用户说"我要退款",Agent 能懂;用户说"我刚收到一条短信,说我银行卡被冻结,让我点击链接转账验资",Agent 若是工具边界不足却硬答,就危险了。有边界、有回退,Agent 才是可靠的生产组件。把这个做成配置而非代码,团队里非资深开发者也能做维护。

4. 从配置到运行:跑通一个可回滚的 Agent 任务

理论讲了一堆,上实操。以下是我自己在本地跑通一个 AX Agent 应用的完整思路,你可以当作踩坑前的路线图。

提示:以下示例基于 AX 当前公开文档的典型使用模式,具体命令以你拉取到的版本为准。

4.1 安装与初始化

首先克隆 AX 仓库并安装 AX CLI:

git clone https://github.com/google/AX.git cd AX make install-or-tools # 如果本地缺 OR 工具 pip install -e .

本地模式我推荐 UniprocessorRuntime,即单进程模型。确认默认运行时:查看ax/agent/core/config/env_config.py,把默认运行时改为合适的本地版本。

如果是从 Docker 镜像方式启动,类似:

docker run -d -p 8780:8780 -v $(pwd)/config:/app/config ax-agent:latest --runtime uniprocessor

4.2 编写 Agent 应用配置文件

在config/下建一个 YAML 文件,描述你的第一个 Agent。以"根据用户意图调用不同 API"为例:

id: app-hotel-cs name: 酒店客服座席助手 conversation: requires: user_intent: true can_start: if: user.session.is_authenticated intro: "我是酒店客服助手,可以帮你处理预订、退货和投诉。" context: | 你的职责: - 用户咨询订单状态时,调用订单查询工具。 - 用户表达投诉时,以道歉开头,并转人工。 - 如果用户要求退款,先核对订单状态,再给出可操作指引。 runtime: app: base_api: "http://localhost:8080/v1/" run: pool_size: 4 timeout_seconds: 30 tool_scope: allowlist: - "get_order_status" - "create_refund_request" denylist: - "delete_order"

这段配置做了几件事:

  • 声明该 Agent 只在"已认证 + 有用户意图"的会话中启动。
  • 定义了系统上下文,决定了 Agent 回答策略。
  • 通过tool_scope.allowlist/denylist限定了 Agent 可调工具集,这属于安全边界。

类似我们给 K8s Pod 设置 networkPolicy 和 seccomp——不是限制自由,而是让 Agent 在受控边界内发挥。

4.3 使用 API 与分类器触发应用

AX 不仅支持对话场景,还支持以 API 形式触发应用。配置好 Agent 后,你可以通过 REST 或分类器来启动:

curl -X POST http://localhost:8780/api/v1/apps/app-hotel-cs/run \ -H "Content-Type: application/json" \ -d '{"conversation_id": "conv_001", "user_id": "u_502", "message": "我要查一下订单 O20240101 的状态"}'

如果 Agent 判定该请求可以直接处理,它会走工具调用链;如果 Context 里的上下文不够判断,或者请求的消息落在工具边界外,响应体里就会出现rollback: true、handoff: human这类标记。你在上层系统把这个标记转成"人工坐席接管事件"即可。

AX 内置的 API 应用和分类器应用形态,覆盖了"服务端点 + 意图识别"的组合。这也是很多生产场景的核心需求:不是所有输入都进 LLM 对话,先分类,再决定交给哪个 Agent 处理。

4.4 观察运行日志与状态

运行成功后,AX 会在控制台或日志里输出具体调度的信息(类似 K8s 的 event 输出):

  • 哪台 Device 接管了这个请求;
  • Runnable 执行耗时;
  • 工具调用是否命中 allowlist;
  • 结果是否触发回退;
  • 用户反馈是否在可感知的审计日志中落痕。

这部分内容在生产中极其重要:当业务方说"刚才有个 Agent 答错了",你要能在几秒内给出完整链路。AX 的自主运行(autonomous run)+ 审计日志,正好把这条链留了下来。

5. 规模化背后的可靠支撑:前滚、回滚、扩缩容与安全审计

最后一个部分,说点作为平台工程师最关心的东西。项目标题说 AX 是为"十亿级任务"设计的,这不是靠一张 YAML 就能达成的。真正的底气在于下面几个机制。

5.1 "快速回滚":Agent 行为回归的救命通道

Agent 应用和普通代码有一个巨大差异:普通代码出错是明确的报错,Agent 出错是"看起来不错但回答得很烂"。这种错往往不是上线时发现,而是被用户骂了几天才发现。

因此 Agent 平台必须有版本回溯能力。AX 的前滚/回滚机制,类似 K8s 的滚动更新:你声明新配置,系统逐渐把旧实例切到新配置;如果效果不符合预期(准确率下降、投诉率上升),一条命令把整个集群的 Agent 行为回退到上个稳定版本。

这比缓存一份 prompt 文件要有意义得多。因为回滚的不只是 prompt,还包括运行参数、上下文、工具权限、API 版本。所有被编排的内容一起回到旧状态。

具体回到 config 层面,你可以在版本控制里维护配置文件的历史版,在发布平台把它们打成环境版本。AX 的 Rolling / Non-Rolling 部署策略(滚动与非滚动)在这里对应 K8s 的 Recreate 与 RollingUpdate,非滚动适合本地小规模,滚动适合生产大规模。你自己按集群规模选择。

5.2 扩缩容逻辑:动态适配任务洪峰

"十亿级"不致于靠编排模式硬撑,还必须能水平扩容。我对 AX 的期望是:当队列长度、请求延迟指标达到阈值时,它可以动态增加 Runnable 的执行副本,或调度到更多 Device 上。缩容同理,避免资源浪费。

这在部署场景中的落地方式:你的 Agent 应用构建为可横向扩展的单位,运行时托管到多个节点。需要扩时,复制 Device 与调度策略即可。这与 K8s 的 HPA(水平Pod自动扩缩)思路一致——关注资源指标,而非手动改副本数。

对普通团队,这降低了 Agent 平台化的门槛:你不需要自己写流量分发和动态扩缩容组件,把配置交给 AX 就好。

5.3 安全与合规:工具白名单与审计日志

最后,Agent 光聪明不够,还得"听话"。AX 在安全模型上把这块当成一等公民来做:

  • 工具白名单/黑名单:Agent 只能调用明确允许的工具,降低工具误用风险。
  • 审计日志:所有 Action、工具调用、用户消息、模型输出都要被记录。
  • Chat / Autopilot / 分类器不同的交互模式,也会对安全边界产生约束(比如 Autopilot 自主运行的权限可以更严格)。

这块设计让我想到 Kubernetes 的 RBAC + AuditPolicy:平台不阻止你做任何事,但它会保证每件事都被记录、被控制。对于金融、客服、医疗这类强合规领域,没有这套机制,AI Agent 几乎没有上生产的可能。

5.4 托管模式还是自托管?

AX 的另一个贴心之处是提供两种交付方式:

  • 托管版本:Google 提供托管平台,用户直接使用控制面和 API,适合不想运维基础设施的团队。
  • 自托管:完全开源,自己部署,适合对数据主权和隔离有硬性要求的场景(比如企业内部私有化部署)。

我倾向于建议:技术验证阶段用托管版快速跑通,安全合规、数据敏感度高的场景斟酌自托管。两套模式可以让一个项目在概念验证到生产部署之间平滑切换,不会因为平台绑定而被卡死。毕竟,一个开源系统最大的竞争力,是你随时可以把它搬到自己掌控的基础设施上。

写在最后的一些实话

我接触 AX 这个过程里最大的感触,不是它帮我省了多少行代码,而是它让我开始用"资源管理"的思路重新看待 Agent。以前我考虑的是一个 Agent 怎么写提示词、怎么调工具;现在我会先想,这个 Agent 的边界在哪、它处于什么期望状态、失败了怎么回退。这种思维转变,可能才是 "Kubernetes for Agents" 带给我最大的价值。

如果你手头只有一两个 Agent,暂时不需要 AX 这种重量级编排,自己写点状态管理完全够用。但如果你正在做一个平台,需要让多个 Agent 长期稳定地服务业务,我建议你花一个周末把 AX 文档过一遍,跑通一个 YAML 示例。Kubernetes 当年也是从一个简单的容器编排器起步,最后成为云原生的事实标准。Agent 编排这个领域,AX 正在走同一条路。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进