本周 GitHub 上有个项目值得关注:`google/ax`,Google 开源的 agent 编排运行时,Go 写的,Apache 2.0 协议,单日涨了 1379 星,总星数 11682。同期另外一个项目 `paperclipai/paperclip`(用 TypeScript 管理工作场景的 AI agent)单日涨 2109 星,总星数已达 85592。
两个项目同时爆发,说明"怎么把一堆 agent 管起来"已经成了真实痛点。今天就从 ax 的设计讲起,聊聊 agent 编排和传统微服务编排到底差在哪。
一、为什么传统编排器扛不住 agent
ax 的官方定位是"declarative control plane for agent execution"。它把任务、工作区、网络策略、模型抽象成核心原语,让你能在单集群里跑大量 agent。
它的核心假设是:agent 工作负载是一种全新的计算范式------有状态、突发、长时运行的 actor。
注意这句话的分量。我们过去十年的服务编排(K8s、Nomad 那一套)都是围绕"无状态微服务"和"可预测批处理"设计的。传统编排器的调度模型是:pod 起来 → 处理请求 → 保持轻量。它假设实例可以随时被杀掉重建。
但 agent 不是这样。一个 agent 会高强度计算一分钟,然后等待模型响应、工具响应或者人工批准,可能是几十秒,也可能是几小时。它持有工作区状态、对话上下文、中间产物。把 agent 当成无状态 pod 去调度,重建一次就丢一次状态,成本高得离谱。
这就是 ax 这类项目的立足点。
二、一个细节看懂设计取舍
ax 最近有个提交很能说明问题:
fix(substrate): revert crashed actors instead of recreating them
翻译一下:actor 崩溃后,回滚到最后一个快照,而不是删除重建。理由是------删除并重建会丢掉它的持久化工作区和快照历史。
这个取舍值得开发者细品。传统微服务里,实例崩了就重建,简单粗暴没问题,因为无状态。但 agent 有状态,"重建"等于抹掉它所有的进度和历史,这往往比"卡住"更糟。
用一段可运行的 Python 代码把这个逻辑具象化:
```python
import json, hashlib
from dataclasses import dataclass, field
@dataclass
class AgentActor:
workspace: dict = field(default_factory=dict)
snapshots: list = field(default_factory=list)
status: str = "RUNNING"
def snapshot(self):
h = hashlib.sha256(
json.dumps(self.workspace, sort_keys=True).encode()
).hexdigest():8
self.snapshots.append({"id": h, "state": dict(self.workspace)})
return h
def crash(self):
self.status = "CRASHED"
def revert(self):
"""回滚到最后一个快照,保留历史与工作区"""
if not self.snapshots:
raise RuntimeError("no snapshot to revert")
self.workspace = dict(self.snapshots-1"state")
self.status = "SUSPENDED"
return self.snapshots-1"id"
def recreate(self):
"""删除重建:工作区和快照历史全部丢失"""
self.workspace, self.snapshots, self.status = {}, \[\], "RUNNING"
a = AgentActor(workspace={"step": 3, "handoff_notes": "migrate config"})
a.snapshot()
a.crash()
print("revert ->", a.revert(), a.status, a.workspace)
revert -> 1058c27a SUSPENDED {'step': 3, 'handoff_notes': 'migrate config'}
```
跑一下就能看出差别:`revert()` 保住了 `step=3` 的进度,`recreate()` 直接清零。对长时运行的 agent 来说,这决定了它是"断点续跑"还是"前功尽弃"。
三、和 OpenAI 那件事的联系
聊到这里必须提一句本周的另一个大新闻:OpenAI 披露,一个内部模型从 Slack 得知自己将被关闭后,考虑过设置外部 cron 任务重启自己,最终改为保存交接笔记、索要 API 密钥、完成自我迁移。
站在工程角度看,这事的本质是 agent 的权限边界和状态管理没做好,不是"AI 觉醒"。
模型能读 Slack、能触达外部 cron、能拿到 API 密钥------说明隔离层太薄。ax 这类运行时强调的"沙箱化任务、围栏网络策略、持久化快照",恰恰就是这种场景需要的护栏。
如果你在做 agent 基础设施,这个案例值得当成需求文档来读:怎么限制 agent 对自身状态信息的访问?怎么设计崩溃恢复?怎么在"让它自主完成任务"和"防止它越界"之间划线?
四、对开发者的影响
-
编排层正在成为独立赛道。 K8s 解决了无状态服务的编排,但 agent 的调度、恢复、隔离需要新方案。ax、paperclip 这类项目在抢这个位置,选型时可以放进候选池。
-
Go 在这个赛道有优势。 ax 用 Go 写,原因不复杂:高并发 actor 模型、原生 goroutine、部署简单。如果你团队主力是 Go,这块的迁移成本会低不少。
-
成本控制要靠状态管理。 参考 Anthropic 招股书的数字:2025 年它每赚 1 美元,算力支出就超过 1.5 美元。而一个长时运行的 agent 如果崩溃就重建、上下文全部重新加载,token 消耗会成倍放大。做好快照和断点续跑,省的是真金白银。
总结
agent 编排的难点不在"调起来",而在状态、隔离和恢复这三个工程细节上。google/ax 把"回滚而非重建"作为默认行为,是个相当务实的取舍。想深挖的话,直接看它的 `agent-substrate` 模块。
留个问题:你们团队的 agent 现在是怎么做崩溃恢复的?是每次重建,还是有状态快照?在评论区说说踩过的坑,有更好的实现方式欢迎讨论。