← All posts / Tools

Kubernetes 從來就不是正解:Google AX v0.3.0 把 Agent 狀態搬出 etcd、塞進 Redis

Google 開源 agent 編排器 AX 發布 v0.3.0,拆成三個服務並把任務狀態從 Kubernetes CRD 遷移到 Redis Streams——因為 etcd 撐不住數百萬個短生命週期 agent 任務的寫入壓力。

Kubernetes 從來就不是正解:Google AX v0.3.0 把 Agent 狀態搬出 etcd、塞進 Redis

2026 年 9 月 20 日,Google 發布了開源 agent 編排器 AX 的 v0.3.0 版本,幾小時內就衝上 Hacker News 首頁,拿下 481 個讚。吸引目光的不是功能清單,而是一個講得毫不客氣的架構論點——專案自己的設計文件就寫著:Kubernetes 從來不是為了當數百萬個短生命週期 agent 任務的控制平面而設計的,etcd 也吸收不了那種壓力。 AX v0.3.0 就是 Google 給出的具體答案:把 agent 任務狀態完全搬出 Kubernetes,改走 Redis。

Kubernetes 遇上 Agent 會在哪裡壞掉

今天大多數跑 AI agent 的基礎設施團隊第一反應都是上 Kubernetes——熟悉的工具、成熟的生態,排程、健康檢查、滾動部署、自動擴縮,這些原語對微服務來說都非常好用。對那種「跑一下就結束」的 agent,用 pod 或 job 承載也確實合理。

問題出在 agent 數量變大、任務變成長駐型的時候。Kubernetes 把叢集狀態存在 etcd 裡,而 etcd 有硬性的物理限制。AX 的設計文件直白地說:「把數百萬個短生命週期任務存成 Kubernetes CRD,會把 etcd 逼出舒適區(個位數 GB 的儲存上限、寫入速率瓶頸、控制平面退化)。」每一次任務更新、每一次狀態轉移、每一次 checkpoint,都是一筆寫進 etcd Raft log 的紀錄。量小的時候完全無感;到了數百萬個併發 agent 的規模,拖垮的是整個控制平面,而不只是 agent 工作負載本身。

還有第二個結構性錯配:容器是為「持續做事」的服務最佳化的,而 agent 大部分時間在等——等使用者回覆、等工具回應、等下游 API。一個佔著記憶體什麼都不做的容器,照樣在吃運算資源。如果一百萬個 agent 在任一時刻大多處於閒置(通常就是如此),「一個 agent 一個 pod」的模型等於把大部分資源直接浪費掉。

AX v0.3.0 到底改了什麼

這個版本用三層分離同時解決兩個問題。整條流程是:ax apply 打到 ax-server——一個刻意做成無狀態的 gRPC 服務,負責驗證 manifest、持久化、發事件。狀態落在 Redis:task hash、事件流、pub/sub 頻道。然後是一群水平擴展的 ax-controller worker,用 XREADGROUP 從 Redis Streams 消費——consumer group 語意保證可靠投遞:某個 controller 掛掉,它未處理的訊息會重新派給別的實例。要擴容就是加 replica,實例之間不需要任何協調。這條 stream,就是取代 etcd 的調和工作佇列。

這次發布還把 AX 拆成三個服務——API 前端、reconciler、沙箱化 task runner——並提供四個宣告式原語,每個都有完整的 CRUD 加 watch(走 gRPC):

  • Task——工作單位:一個執行中的 agent,含狀態、條件與歷史。SuspendTask 和 ResumeTask 是一等公民 RPC。
  • Workspace——持久的檔案系統上下文,懸置後依然存活,恢復時自動接回。
  • Gateway——每個 workspace 自己的網路出口控制,用明確的 host 白名單,而不是全叢集的 network policy。
  • Model——平台本身要用哪個 LLM、憑證與參數,存成具名物件,換憑證不必重新部署 agent 程式碼。

開發者用的 CLI 刻意做成 kubectl 的手感:ax apply -f task.yaml、ax get tasks、ax watch、ax suspend、ax resume,外加一個很值得注意的 agent 專屬動詞——ax ssh,直接 shell 進執行中的沙箱,盯著 agent 在幹嘛。

Agent Substrate:agent 世界的記憶體分頁

在 controller 之下是 Agent Substrate——真正做運算多工的執行層,也是整個技術棧裡最漂亮的想法。因為 agent 大半輩子都在等待,Substrate 維護的「actor」數量遠多於可用的「worker」。actor 一閒置就會被 checkpoint——RAM 狀態與本地檔案系統快照下來——worker 隨即釋放給別人用。工作一來,指派一個 worker、還原狀態、繼續執行。

結構上,這就是作業系統核心在記憶體壓力下做的分頁(paging):核心不會殺掉閒置的行程,而是把它換出到儲存裝置、需要時再換回來。Substrate 把同樣的原則搬到 agent 層級——邏輯上的 agent 是持久身份,物理上的運算配置則是暫時且共享的。根據 Google Cloud 官方部落格,Substrate 宣稱沙箱密度是標準容器 runtime 的 10 倍、還原延遲低於 500 毫秒、每秒可執行超過 500 次懸置/恢復。這些是廠商自報的數字,沒有公開的基準測試方法學——請當方向參考,不要當定論。

部署之前先看警告

專案對自身成熟度毫不掩飾:README 明講在穩定版之前很可能有重大破壞性變更,文件也說系統尚未 production-ready。真正的開放問題還不少。Redis 現在成了關鍵依賴——Redis 掛掉會影響控制平面裡所有任務狀態,而設計文件尚未說明 Redis 層的複製與故障轉移策略。「atespace」這個命名空間概念還沒有完整文件,大檔案系統快照在規模下的行為也未指定。懸置/恢復機制也有只有上線才會有答案的問題:懸置那一刻,進行中的 tool call 怎麼辦?持有外部 session(瀏覽器狀態、已認證的 API 連線)的 agent 怎麼撐過轉換?

但它依然重要

最直接的啟示是關於 agent 狀態該放哪裡。那些用 Kubernetes job 跑 agent、已經感受到 etcd 壓力的團隊,現在有一套參考架構,可以把狀態搬進佇列式的儲存。Redis Streams 加 consumer group 不是新花樣;把它用在 agent 編排上,才是「別再把 API server 當資料庫用」這件事最有意義的一步。

懸置/恢復 API 的意義比表面更深。因為 SuspendTask 和 ResumeTask 是明確的一等操作,agent 生命週期可以被程式化驅動——碰到速率限制就暫停、配額刷新就恢復、等人類審批就懸置。這和 pod 重啟有本質差異:狀態活過了轉換。

更深層的訊號是架構性的:基礎設施原語正在圍繞 AI 工作負載的行為特徵重新設計,而不是拿為無狀態服務打造的模式硬改。容器模型不會消失,但 AX 主張它不該是 agent 執行層級的葉節點。對一個 v0.3.0、3.9k 星的專案來說,這個論點——附在真實可跑的 Apache-2.0 程式碼上——正是 Hacker News 整個週一都在吵它的原因。