引言
"Agent 是一种全新的工作负载:它们不是无状态的微服务,也不是跑到完成就结束的批处理任务。"
这是"一天一个开源项目"系列的第 228 篇。今天的项目是 AX(仓库地址 google/ax)。
当团队开始批量运行 AI Agent 时,很快会发现一个尴尬的事实:现有的调度基础设施都不太合身。Kubernetes 的 Pod 模型假设工作负载是无状态服务或跑批任务,但 Agent 会积累状态、需要严格的沙箱隔离、要频繁调用模型 API 和工具服务器,而且一旦没人盯着,很容易在一个循环里把 Token 预算烧穿。传统的 CI/CD 或批处理平台,同样没有为"暂停一个 Agent 再原地恢复""SSH 进沙箱看它在干什么"这类需求设计过。
AX 是 Google 开源的一个"高吞吐、声明式的 Agent 编排运行时",目标是在单个集群里运行数十亿次自主 Agent 工作负载。如果你用过 Kubernetes,ax 的操作体验会非常熟悉——apply、get、describe、watch、delete,一套 kubectl 风格的命令行,只是调度对象换成了 Agent 任务。它构建在 Agent Substrate 之上做沙箱化执行,自己专注于声明式编排这一层。
11,600+ Stars,560 Forks,Apache-2.0 协议,由 Google 主导开发,目前仍在 Alpha 阶段,核心概念和协议还在快速迭代,项目本身也明确警告"稳定版之前可能会有重大breaking change"。
你将学到什么
- AX 的三个核心原语:
Task、Workspace、Model,分别解决什么问题 - 为什么 Agent 工作负载需要一种"既非无状态服务、也非批处理任务"的新调度模型
- AX 与 Agent Substrate 的分层关系:编排层 vs 沙箱执行层
- 控制面架构:为什么用 Redis + Streams 而不是直接把 Task 存成 Kubernetes CRD
ax suspend/ax resume/ax ssh背后的沙箱生命周期设计
前置知识
- 熟悉 Kubernetes 的基本概念(Pod、CRD、
kubectl操作习惯) - 了解容器化部署和沙箱隔离的基本原理
- 可选:了解 MCP(Model Context Protocol)的基本概念
项目背景
项目简介
AX 的官方定位是"Google 的开放 Agent 编排运行时"(Google's open agentic orchestration runtime)。项目 README 开篇就给出了一个精炼的操作描述:"声明一个带工作区和模型规格的 Agent 任务。AX 把它放进沙箱、接好工作区,并帮你大规模运行。"这句话点出了整个项目的分工——AX 自己不做沙箱隔离和执行,而是把这部分工作交给底层的 Agent Substrate,自己专注于"声明式定义任务、大规模调度、生命周期管理"这一层。
项目文档里有一段话很直接地解释了为什么现有工具不够用:"Agent 是一种新的工作负载。它们既不是无状态的微服务,也不是跑到完成就结束的批处理任务。它们会积累状态,需要严格的隔离,要调用模型 API 和工具服务器,而且如果没人看着,可能在一个循环里烧钱。"AX 给出的答案是三个可以声明式描述的小原语,而不是试图用一个大而全的框架去建模 Agent 的全部行为。
团队与项目信息
- 所属组织:google
- 协议:Apache License 2.0
- 主语言:Go
- 依赖底座:Agent Substrate(沙箱化 Actor 执行环境)
- 官网:agentexecutor.io
- 状态:Alpha,核心概念和协议仍在迭代中,明确警告可能有重大 breaking change
项目数据
- ⭐ GitHub Stars:11,600+
- 🍴 Forks:560
- 📄 协议:Apache-2.0
- 🐛 Open Issues:48
- 📅 创建时间:2026-03
主要功能
解决什么问题
在通用调度平台上跑 Agent 工作负载的困境:
Kubernetes Pod 模型 → 假设工作负载是无状态服务或跑批任务
↑ Agent 会积累状态、需要严格隔离、频繁调用外部模型 API
↑ 没有"暂停并原地恢复"的原生支持
↑ 没有"SSH 进去看 Agent 在干什么"的调试通道
↑ 每次运行都要重新克隆仓库、接工具、配 MCP Server,冷启动成本高
AX 的做法:
三个声明式原语:Task(沙箱化执行单元)+ Workspace(预热好的工作环境)
+ Model(集群级的模型配置)
↓
用 ax apply -f task.yaml 一次性声明整套任务
↓
ax watch / ax ssh / ax suspend / ax resume 提供 K8s 风格的可观测与生命周期管理
↑ 底层沙箱隔离交给 Agent Substrate,AX 专注编排这一层使用场景
-
大规模运行自主编码/运维 Agent
- 每个 Agent 任务作为一个独立沙箱运行,能声明它需要的 Git 仓库、MCP 服务器、工具集,适合"给一堆仓库分别派一个 Agent 去修 Bug"这类批量场景
-
需要长时间运行、可暂停恢复的 Agent 工作流
- 通过
ax suspend/ax resume,Agent 的状态可以被 checkpoint 并在之后原地续跑,不需要为"长任务如何省资源"单独设计逻辑
- 通过
-
需要调试和观察 Agent 实际行为的开发场景
ax ssh可以直接进入正在运行的沙箱查看文件系统、跑命令,不用只能干等日志输出
-
需要统一管理模型凭据和配置的多团队场景
Model作为集群级资源声明,轮换密钥、切换模型版本只需要一次ax apply,而不是在每个 Agent 的环境变量里挨个改
快速开始
前置条件:
# 需要一个已安装 Agent Substrate 的 Kubernetes 集群
kubectl get svc api -n ate-system # 确认 Substrate 的 Control API 已就绪安装 CLI:
go install github.com/google/ax/cmd/ax@latest部署控制面:
make deploy AX_IMAGE_REPO=<your-registry>用一份 YAML 声明工作区和任务:
# task.yaml
apiVersion: ax.io/v1alpha1
kind: Workspace
metadata:
name: golang
spec:
git:
- repo: https://github.com/golang/go.git
branch: "my-fix"
---
apiVersion: ax.io/v1alpha1
kind: Task
metadata:
name: test
spec:
workspaces:
- name: golang
goal: "Ensure that Go tool chain is available and is built from source"
debug: true # 允许 ax ssh 进入沙箱应用并观察:
ax apply -f task.yaml
ax watch task test
ax ssh test -- ls -al /workspace核心特性
1. 三个正交的声明式原语
| 原语 | 解决什么 |
|---|---|
| Task | 在隔离沙箱中运行不受信任的 Agent 代码,附带 CPU/内存限制 |
| Workspace | 预先接好 Git 仓库、MCP 服务器、技能包,让每个 Agent"热启动" |
| Model | 声明平台自身使用哪个 LLM,凭据来自 Kubernetes Secret |
2. kubectl 风格的 CLI
ax apply、ax get、ax describe、ax watch、ax delete,加上 Agent 特有的 ax ssh、ax suspend、ax resume。跟着活跃的 kubectx 上下文走,切集群时 ax 会自动解析并隧道连接到对应集群的控制面。
3. Task 的最小化设计哲学
Task 被设计成"足够小"的单元——一个 Agent 的生命周期里会做计划、委派、重试、拆分任务,AX 不试图对这个行为建模,而是提供一个创建、隔离、暂停、丢弃成本都很低的原语,由 Agent 自己去组合出任意数量的 Task。一个 Task 可以是整个任务本身,也可以是 Agent 拆解问题后生成的一大片任务树的根节点——无论哪种情况,每个节点都拿到同样的沙箱、同样的生命周期、同样的工具链。
4. Workspace 的目标驱动引导
Workspace 绑定可以带一个 goal——一句描述任务需要什么环境的自然语言。首次启动时,Runner 会把这个目标交给一个 Agent 去完成环境搭建(比如安装某个工具链或依赖),这样任务自己的命令启动时环境已经是就绪状态。
5. 集群级模型资源
把模型配置声明成集群资源,而不是散落在每个 Agent 的环境变量里,意味着轮换密钥、锁定新模型版本、调整生成参数只需要一次 ax apply。AX 自身的组件(比如根据 goal 规划 Workspace 的过程)同样读取 Model 资源。
6. 暂停/恢复与 SSH 调试
ax suspend 会 checkpoint Actor 状态并暂停任务;ax resume 让它原地续跑。ax ssh 需要任务显式声明 spec.debug: true 才能连接——因为它开放的是任意进程执行和文件访问权限,默认关闭是一个明确的安全设计。
项目优势
| 对比项 | 直接用 Kubernetes 跑 Agent | 自建 Agent 编排逻辑 | AX |
|---|---|---|---|
| 状态模型契合度 | 差,Pod 假设无状态或跑批 | 视自建程度而定 | 专为 Agent 的"积累状态+需要暂停恢复"设计 |
| 大规模调度 | etcd 存储 CRD,百万级任务会顶到瓶颈 | 需要自己解决 | 用 Redis + Streams 支撑十亿级任务目标 |
| 环境预热 | 需要自己写 initContainer 逻辑 | 需要自己实现 | Workspace 原语声明式搞定 |
| 调试通道 | 只能看日志/exec | 需要自己实现 | ax ssh 内置,权限默认关闭 |
| 模型配置管理 | 散落在各处 | 需要自己封装 | Model 作为集群资源统一管理 |
为什么选择这个项目?
- Google 主导开发,已经在思考"十亿级 Agent 任务"这种规模问题,架构决策(Redis 而非 etcd)是针对这个规模做的
- 操作心智模型直接复用 Kubernetes 经验,
kubectl用户几乎零上手成本 - 明确的分层设计——AX 专注编排,沙箱执行交给 Agent Substrate,职责边界清晰
项目详细剖析
为什么不直接把 Task 存成 Kubernetes CRD
这是 AX 架构里一个很值得琢磨的决定。项目文档直接给出了理由:"把数百万个短生命周期任务存成 Kubernetes CRD,会把 etcd 推到它不擅长的区域——个位数 GB 的存储上限、写入速率瓶颈、控制面性能下降。"
AX 的解法是把状态存进 Redis,用 Redis Streams 作为 API Server 和一组水平扩展的 Controller 之间的工作队列:
ax apply -f task.yaml
│
▼
ax-server(无状态 gRPC API)
│
写入并发布事件
│
▼
Redis(Task Hash + Event Streams + PubSub)
│
XREADGROUP(消费流)
│
▼
ax-controller(水平扩展的 Worker 池)
│
gRPC 调用
│
▼
Agent Substrate(沙箱执行)这个选择说明 AX 团队从一开始就没打算把自己套进"一切皆 CRD"的 Kubernetes 心智模型,而是只借用了它的操作体验(apply/get/watch),底层存储引擎则换成了更适合高频短生命周期对象的方案。这是一种务实的取舍:用户感知到的交互方式不变,但后端为真实的规模需求重新设计。
Task 的"小而可组合"设计
AX 对 Task 的设计哲学值得单独展开。很多编排系统会试图对"一个完整的 Agent 工作流"建模——比如定义 DAG、定义步骤依赖。AX 反其道而行之:它拒绝对 Agent 的内部行为(计划、委派、重试、拆分)建模,只提供一个原子的、廉价的执行单元,让 Agent 自己决定怎么组合。
这个设计的好处是灵活性——一个 Task 既可以是全部工作,也可以是一整棵任务树的根节点,AX 不需要理解树的结构,每个节点拿到的都是同样的沙箱和同样的生命周期原语。代价是:任务之间的依赖关系、数据传递,需要 Agent 自己或上层工具去管理,AX 不提供内置的工作流编排语义。
Workspace 的目标驱动引导机制
Workspace.spec.goal 是一个不算常见的设计:它不是直接描述"要装什么依赖",而是一句自然语言描述的环境目标(比如"确保 Go 工具链可用,并且是从源码构建的"),交给沙箱启动时的一个 Agent 去解读和执行。
这个设计把"环境搭建"这件本来需要写脚本、写 Dockerfile 的机械工作,变成了一个可以用自然语言描述、由 Agent 完成的动态过程。文档里提到的 Roadmap 显示,这个方向还会继续深化——"动态 Agentic 环境策划"计划让这个引导过程能自动检查仓库内容、解析工具链、从注册表里发现相关的 MCP Server 和技能,而不只是执行一句写好的目标描述。
沙箱生命周期:Runner 作为 PID 1 的常驻角色
每个任务容器里,ax-task-runner 作为 PID 1 启动,承担的职责比单纯"启动命令"复杂得多:加载 Task 和 Workspace 规格、在端口 80 启动一个元数据与 Guest 管理守护进程、首次运行时按绑定顺序准备每个 Workspace(克隆仓库、配置技能路径,如果有 goal 就交给 Agent 完成)、最后才启动 spec.command 作为子进程并持续监督。
关键的一点是:Runner 在命令退出后仍然作为 PID 1 存活,这意味着即使 Agent 的主命令已经跑完,元数据服务器仍然在响应,ax ssh 依然可用。这个设计让"调试一个已经结束的任务"成为可能,而不是任务一结束容器就整个消失。
与 Agent Substrate 的分层关系
AX 自己不做沙箱隔离,而是把这部分完全委托给 Agent Substrate——一个专门负责 Atespace 供应、Actor 创建与激活、Worker 分配的底层系统。AX 的 Controller 通过 gRPC 调用 Substrate 的 Control API 来驱动任务朝目标状态演进。这种分层意味着 AX 专注在"声明式编排语义"和"大规模调度"这两件事上,把"如何安全隔离一个不受信任的进程"这个更底层、更难做对的问题留给专门的项目去解决——这也是为什么 AX 的 Roadmap 里花了大量篇幅描述与 Substrate 的 Actor 架构如何演进(迁移到新 Actor API、拆分 Workspace 初始化为独立 Actor、最小权限策略、空闲检测自动挂起等)。
项目地址与资源
官方资源
- 🌟 GitHub:https://github.com/google/ax
- 🌐 官网:https://agentexecutor.io
- 📄 协议:Apache License 2.0
- 🐛 Issue Tracker:GitHub Issues
相关资源
- Agent Substrate —— AX 底层依赖的沙箱化执行环境
- Agent Substrate Guest Services —— 支撑
ax ssh的进程/文件系统服务 - Model Context Protocol —— Workspace 中集成的工具协议标准
总结与展望
核心要点回顾
- 三个正交原语覆盖 Agent 编排的核心需求:Task 负责隔离执行,Workspace 负责环境预热,Model 负责集群级模型配置管理
- 复用 Kubernetes 的操作心智模型,但重新设计了存储后端:用 Redis + Streams 替代 etcd,是为十亿级短生命周期任务规模量身定制的取舍
- 不对 Agent 行为建模,只提供廉价可组合的执行单元:Task 足够小,由 Agent 自己决定如何拆分、委派、重试
- 明确的分层架构:AX 专注声明式编排,沙箱隔离委托给 Agent Substrate,职责边界清晰
- 仍处于 Alpha 阶段:核心概念和协议还在快速演进,生产落地前需要关注 breaking change
适合谁
- 需要大规模运行自主 Agent 工作负载的团队:尤其是任务量级已经超出手写脚本管理范围的场景
- 已经在用 Kubernetes、熟悉其运维心智模型的团队:
kubectl式的操作体验几乎零迁移成本 - 需要暂停/恢复长时间运行 Agent、或需要调试通道观察 Agent 实际行为的场景
- 愿意接受 Alpha 阶段项目风险、想提前介入设计和贡献的开发者
一句话评价
AX 没有试图重新发明 Agent 应该怎么"思考",而是先把"怎么在集群里安全、大规模地跑这些会积累状态的新工作负载"这道基础设施题解好。
欢迎访问 PrimeSkills —— 一个精心策划的 AI Agent 与技能市场,所有内容均经过真实企业级工作流验证。没有噱头,只有真正有效的东西。
更多实用知识和有趣产品,欢迎访问我的个人主页