從養蝦到蓋 Agent OS:拆解 Anthropic Managed Agents 的腦手解耦架構與本地復刻實踐

managed-agents-cover

我同時開著5個 Claude Code 視窗。一個跑編碼、一個專責 Code Review、一個寫測試、一個守著 lint、最後一個是我自己用來貼錯誤訊息的「人肉訊息佇列」。一旦哪個窗口的上下文被壓縮,記憶就掉了一截;一旦某個容器跑歪,我得手動把整個目錄掃過去重來。

直到 2026 年 4 月 8 日,Anthropic 在 engineering 部落格悄悄丟出一篇文章 ,標題叫做 Scaling Managed Agents: Decoupling the brain from the hands。我讀完那個下午就明白:所謂的「蜂群 Agent」不是要靠工程師硬刻 harness 把模型框起來,而是要把腦、手、記憶徹底拆開,再讓編排者像 RTOS 一樣調度。這篇文章接下來會帶你一路走過:那篇部落格到底在說什麼、Managed Agents 的四個齒輪怎麼咬合、Memory Store 為什麼是真正的「腦」、我怎麼用一週復刻這套架構在本地跑、以及為什麼騰訊在 4 月底開源的 Cube Sandbox 會把 Docker 比下去。

環境與前置知識:本文涉及的版本是 Claude Managed Agents Beta(API header managed-agents-2026-04-01)、Claude Agent SDK 對應的 Python/TypeScript 套件、以及 Cube Sandbox 開源版本。讀者最好對 Docker、訊息佇列、有限狀態機任一個有基本概念,後面會用到嵌入式韌體類比,但不需要硬體背景。

那篇被低估的部落格,到底在恐嚇什麼

Anthropic 那篇文章 開場就放了一個工程師血淚史:團隊曾經為了 Claude Sonnet 4.5 的「context anxiety」(模型過早壓縮上下文造成的焦慮行為)寫了一整套 harness 補丁,邏輯精妙、考慮周全。結果 Claude Opus 4.5 一發布,這些補丁不只變廢碼,還會干擾新模型的判斷。整篇文章最狠的一句是:

「Harnesses encode assumptions that go stale as models improve.」 (Harness 把假設寫死,但模型一進化,這些假設就餿掉了。)

這句話我反覆讀了三次。對硬體工程師來說,這跟我們做晶片 workaround 是同一個感覺——某顆 MCU 有個 erratum,你寫一段神奇的延遲循環去繞過它;下一個 silicon revision 把 bug 修了,你那段 workaround 變成莫名其妙拖慢系統的死肉。模型也是矽晶片,只是改版週期更快、更殘酷。

Anthropic 的回應是把整個 agent 拆成三個獨立元件:

  1. Brain(Harness):Claude 本體 + control loop,無狀態、可隨時替換。
  2. Hands(Sandbox):執行容器與工具,跟 brain 互不認識。
  3. Session:append-only 的事件日誌,存在 harness 與 container 之外。

關鍵的一句翻譯成 API 語意:「harness 不再住在容器裡,它呼叫容器的方式跟呼叫任何工具一樣,就是 execute(name, input) → string。」這跟硬體界的 HAL(硬體抽象層)是一模一樣的思維——驅動程式不該假設它跑在哪個 SoC 上,只要透過固定 API 跟硬體說話就好。

而這個解耦的收益,Anthropic 自己給了硬數字:p50 TTFT(time-to-first-token)下降約 60%,p95 TTFT 下降超過 90% 。要注意這是他們重構自家基礎設施前後的對比——本質是「砍掉容器冷啟動 + 建立預先暖好的 brain pool」帶來的收益,不是外部 benchmark 可以直接複現的數字。但 p95 砍掉九成這種改進,已經不是優化,是換引擎。

寵物與牛馬:為什麼你的本地 Agent 注定會死

managed-agents-pets-vs-cattle

伺服器運維圈有個老梗叫 pets vs cattle:寵物你會給牠取名、生病了帶去看醫生、死了會難過;牛馬你只看編號,倒了就補一隻新的。十幾年前的虛擬機時代我們把伺服器當寵物養,後來容器化、Kubernetes、不可變基礎設施(immutable infrastructure),整個產業慢慢被「牛馬化」拯救。

把 Anthropic 那段話翻成大白話就是:「以前 Agent 是寵物,現在 Agent 要當牛馬。」 部落格原文有一句更狠:

「The container became cattle. If the container died, the harness caught the failure as a tool-call error.」 (容器變成牛馬。容器死了,harness 只是把它當成一次工具呼叫失敗去處理。)

對應到我自己之前養龍蝦的失敗經驗,根本原因就是當時把 brain、hands、context 全綁在同一個 Docker 容器:模型呼叫工具會修改容器的檔案、conda 環境、<sub>/.cache 被各種 LLM SDK 灌滿、又或者某個 MCP server 半夜默默死掉。一旦這個容器壞了,整個 Agent 的「人格」也跟著毀了。修不修得回來,全看那一刻運氣。

從韌體工程師的角度,這個錯誤幾乎是必然——狀態跟硬體(執行環境)綁在一起的設計,永遠擴展不出去。RTOS 的訊息佇列、雙緩衝、watchdog 自動重啟,本質上都是把「狀態」跟「處理單元」解耦。AI Agent 工程比硬體晚了二十年才學到這個教訓,這篇 Anthropic 部落格其實就是 AI 圈遲到的工業革命宣言。

拆解 Managed Agents 的四個齒輪

managed-agents-four-gears

光看「解耦」這兩個字還不夠,我得拆開 官方 docs 才能看清楚整個齒輪箱怎麼咬合。Anthropic 把整個系統建立在四個核心概念上:

齒輪 角色 類比(嵌入式視角)
Agent 靜態身份模板:模型、system prompt、工具、MCP servers、skills RTOS 任務的 task descriptor
Environment 容器模板:預裝套件、網路規則、掛載檔案 編譯時決定的 board support package
Session 動態實例:跑著 agent + environment 的一次任務,含 append-only event log RTOS 啟動後的具體 task instance
Events App 與 agent 之間的訊息:使用者輸入、工具結果、狀態 訊息佇列裡的 message
[mermaid 圖表 — 原始 HackMD 版本可正常渲染]

flowchart TB subgraph Static[靜態定義 / Bake Time] A[Agent
model + prompt + tools + skills] E[Environment
container template] end subgraph Runtime[執行時 / Runtime] S[Session
append-only event log] T1[Thread #1
coordinator] T2[Thread #2
reviewer] T3[Thread #3
test-writer] end subgraph Persistence[跨會話持久層] M[(Memory Store
/mnt/memory)] V[(Vault
credentials)] end A -.referenced by.-> S E -.referenced by.-> S S --> T1 --> T2 T1 --> T3 M -.mounted into.-> S V -.attached at.-> S

對影片裡提到的「coordinator」,我特地翻了 multiagent 文件 確認所有數字。實際的限制是:

  • Coordinator 的 roster 最多 20 個 unique agents,但每個 agent 可以被開出多份 copy。
  • 單一 session 最多 25 個並發 thread
  • Delegation 只能往下一層depth > 1 會被直接忽略,避免無限遞迴的呼叫塔。
  • 加入 {"type": "self"} 可以讓 coordinator 派同種類的自己出去處理子任務。

實際的 Python 程式碼長這樣(直接照 官方範例 改寫):

from anthropic import Anthropic

client = Anthropic()

# 先建兩個 worker agent
reviewer = client.beta.agents.create(
    name="Reviewer",
    model="claude-opus-4-7",
    system="You are a strict code reviewer. Reply with concise findings.",
    tools=[{"type": "agent_toolset_20260401"}],
)

test_writer = client.beta.agents.create(
    name="TestWriter",
    # 寫測試這種模式化工作配 Sonnet 4.6(比 Opus 便宜很多)就夠用,
    # 重要的 reviewer 與 coordinator 才需要 Opus 4.7。
    model="claude-sonnet-4-6",
    system="Write pytest-style tests for the provided code.",
    tools=[{"type": "agent_toolset_20260401"}],
)

# coordinator 拿到的是 reviewer 和 test_writer 的 ID
coordinator = client.beta.agents.create(
    name="Engineering Lead",
    model="claude-opus-4-7",
    system=(
        "Delegate code review to the reviewer agent "
        "and test writing to the test agent."
    ),
    tools=[{"type": "agent_toolset_20260401"}],
    multiagent={
        "type": "coordinator",
        "agents": [
            {"type": "agent", "id": reviewer.id},
            {"type": "agent", "id": test_writer.id},
        ],
    },
)

這段程式有幾個值得停下來看的細節。第一,coordinator 跟 worker 都是 agents.create() 出來的同一種東西,差別只在前者多了 multiagent 配置;換言之,「coordinator」不是一個特殊角色,只是一個被授予 roster 的普通 agent。第二,每個 agent 可以指定不同的模型——影片裡提到「coordinator 用大模型、worker 用小模型」最佳化 token efficiency,這是真實可行的設計,因為這四個齒輪的解耦讓「模型選擇」變成 per-agent decision,而不是 per-system decision。

常見陷阱:開頭那支介紹 managed agents 的影片把 SDK beta 講成有「6 個模組」(agents/environments/sessions/skills/memory stores/vaults),但對照 官方 overview 文件核心概念其實是 agent/environment/session/events 這四個;memory stores、skills、vaults 是延伸的資源型 API。影片的「6 個模組」是把資源型 API 一起算進來——理解上沒錯,但講課時要分清楚層次,免得被讀者抓出來鞭。

Memory Store 才是真正的「腦」

managed-agents-memory-store

整套架構裡最讓我「後背發涼」的設計,是 Memory Store 。它表面上只是個雲端儲存,但放在四齒輪架構裡看就完全不一樣:Anthropic 把長期記憶從 agent 身上拔走,掛到 session 上

[mermaid 圖表 — 原始 HackMD 版本可正常渲染]

flowchart LR A[Agent
「我是誰」] --> S[Session
「我現在在幹什麼」] S --> MS[Memory Store
「我以前學過什麼」] MS -.mounted at.-> FS[/mnt/memory/] FS --> Tool[Claude 用普通 file IO 讀寫]

關鍵的設計哲學是**「不發明新 API,就用檔案系統」**。memory store 掛載到容器內的 /mnt/memory/ 目錄,模型用它寫程式碼時用的同一套 file tool 讀寫。Anthropic 在文件裡明說:「a note describing each mount is automatically added to the system prompt so the agent knows where to look.」對應到嵌入式工程,這完全就是「把 EEPROM 區段 mmap 到位址空間」的概念。

實際的限制可以記住三組數字:

維度 上限 為什麼這樣設計
單一 session 可掛載 store 8 個 對應不同 owner / access rule:例如 user 偏好、團隊規範、專案 context 分開放
單一 memory 檔案大小 100 KB(約 25k tokens) 強迫你切細,避免被一個爛掉的大檔毀掉 context 預算
Memory version 保留 30 天(不過 head version 永久保留) 給審計與點對點還原用

最被低估的細節是 content_sha256 樂觀並發控制——更新時可以傳一個 precondition,如果儲存端的 hash 不再吻合,更新會被拒絕。這是 etcd / DynamoDB 級別的 concurrency 設計被搬進 agent 記憶層:

client.beta.memory_stores.memories.update(
    memory_id=mem.id,
    memory_store_id=store.id,
    content="CORRECTED: Always use 2-space indentation.",
    precondition={
        "type": "content_sha256",
        "content_sha256": mem.content_sha256,
    },
)

當你有多個 agent 同時修改同一份規範時,這條 precondition 就是你的最後一道防線。

安全踩雷區:memory store 預設是 read_write。Anthropic 文件給了一段明確警告——如果 agent 處理不可信輸入(使用者 prompt、抓回來的網頁內容、第三方 tool output),一次成功的 prompt injection 就能把惡意內容寫進 store,後續 session 把它當成可信記憶讀回來。實務上,所有共用的參考資料一律掛 read_only,只有專屬於該使用者、會話、專案的 store 才開 read_write 這條規矩跟硬體裡「程式碼區絕對不能可寫」的紀律是同一個血統。

我的本地復刻:把蜂群塞進 Docker

managed-agents-local-replica

讀完所有 docs 後我花了一週把這套架構復刻在本地。我沒辦法完全做到 Anthropic 的雲端等級解耦——我的 worker 是 Docker 容器,每個容器裡塞著一個 Claude Code / Codex / 自製 harness(Pi),所以 brain 跟 hands 還是耦合在 worker 行程裡。但我至少做到了三件事:

  1. 無狀態 worker:每個 Docker 啟動時注入 model / harness / skill / 從哪個 session 哪個位置恢復 / SSH key / 工作目錄,跑完就銷毀。
  2. 集中編排:一個主控伺服器拿著任務圖(task graph),fan-out 給 worker,再 fan-in 收結果。
  3. 異質模型組合:不同節點用不同模型——例如初步搜尋用 Haiku、整合寫作用 Opus、最終驗證再回到 Opus,整體 token efficiency 比單一 Opus 跑全程便宜得多。

對應 RTOS 的視角,這就是一個典型的 master/worker + 訊息佇列 結構:

[mermaid 圖表 — 原始 HackMD 版本可正常渲染]

sequenceDiagram participant U as User participant M as Master (Orchestrator) participant Q as Task Queue participant W1 as Worker #1
(Opus, coder) participant W2 as Worker #2
(Sonnet, reviewer) participant W3 as Worker #3
(Haiku, test-runner) participant Mem as Memory Store U->>M: 「幫我加一個 OAuth 登入」 M->>Q: enqueue(code_task) Q->>W1: dispatch code_task W1->>Mem: read coding conventions W1->>Q: enqueue(review_task, patch) Q->>W2: dispatch review_task W2->>W1: 「這裡有 race condition」 W1->>Q: enqueue(test_task, fixed_patch) Q->>W3: dispatch test_task W3->>M: 結果 M->>U: 「OAuth 已完成、測試通過」

唯一痛點:Docker 啟動慢。本機跑一個帶 Python + Node + 必要工具的容器,冷啟動大概 1.53 秒。對單個任務沒感覺,但當 master 同時要 fan-out 12 個 worker 時,那 3 秒乘以 12 變成感官上的「卡了一下」,這在互動式 agent 對話裡是會被使用者投訴的延遲。

Docker 不夠快,Cube Sandbox 接棒

managed-agents-cube-sandbox

正好在我為 Docker 延遲頭痛的時候,2026 年 4 月 21 日 騰訊雲把 Cube Sandbox 全量開源了 ,Apache 2.0,整套 production stack 包含 SDK、控制平面、runtime。它的 GitHub repo 給了一組讓人坐直的 benchmark:

指標 Cube Sandbox 一般 Docker
冷啟動(單併發) 約 60 ms 1–3 秒
50 併發冷啟動 P95 約 90 ms 數秒到十幾秒
50 併發冷啟動 P99 約 137 ms
單實例記憶體額外開銷 < 5 MB 數十 MB
隔離等級 硬體級(RustVMM + KVM) namespace(共享 kernel)

技術上它是基於 RustVMM 與 KVM 重寫的輕量級 microVM,搭配 CoW(copy-on-write)記憶體共用、Rust 重寫過的 runtime,把每個 sandbox 砍到 5 MB 以下。對單機跑「數千個 agent」這個野心目標來說,這幾乎是必備硬體基礎——Docker namespace 那種共享 kernel 的方案,光是 memory overhead 就會在 1000 instance 處撞牆。

更貼心的是它 相容 E2B SDK 與 OpenAI Python SDK:你不需要重寫 agent code,把 endpoint 從 E2B 換成 Cube 就能跑。這對 agent infra 工程師來說等於白送一個遷移路徑,已經把產品決策難度從「要不要換」降到「什麼時候換」。

我目前的做法是 保留 Docker 作為長期 reside 的 worker pool(例如 master 伺服器本身、log aggregator),把 Cube Sandbox 用在 ephemeral 任務(fan-out 子任務、deep research 搜尋節點、單純跑一段 sandbox 化的 Python)。兩個層級的容器各司其職,跟 Linux 裡 systemd unittransient scope 的關係很像。

戰場不只是 SDK:企業基礎設施的大遷徙

如果你以為只有 Anthropic 在玩這套,那就低估了這波的規模。攤開時間軸看一下 2026 年前半年:

時間 廠商 動作 早期客戶
2026-02-05 OpenAI Frontier 平台發布 ,跨本地、企業雲、OpenAI runtime 的 agent 平台 Uber、Intuit、State Farm、HP、Oracle
2026-04-08 Anthropic Managed Agents 公開 beta Notion、Rakuten、Sentry、Asana
2026-04-21 騰訊雲 Cube Sandbox 全量開源(Apache 2.0) 自家 CodeBuddy 即用
持續中 Palantir AI FDE ,AIP 之上的對話式 Foundry 操作員 政府、金融、製造業

連帶推升的一個新興職位是 FDE(Forward Deployed Engineer)。最早是 Palantir 的特色工種,The Pragmatic Engineer 把它定義成 「介於 customer success、solution engineer 與 product engineer 之間的混合體」。換句話說,agent 不再只是程式設計師的玩具,而是一種新的企業基礎設施——你得有人帶著它走進客戶現場、跟既有系統融合、處理權限與資料治理。

把這個格局拉回華語圈來看,當很多人還在比 Openclaw 跟 Hermes 哪個 wrapper 比較好用、誰跑分高的時候,海外四大廠已經把戰場搬到 agent OS:誰能定義「agent 的容器、會話、記憶、編排」的標準,誰就拿到下一個十年的 infra 入場券。這不是 token 多少錢的競爭,是作業系統等級的競爭。

從韌體視角,這套架構為什麼讓我冷汗直流

我自己是硬體 / 韌體工程師背景,看完整套 Managed Agents 設計最強烈的感受是——這幾乎就是一個跑在雲端的 RTOS。 把對應關係攤開:

Managed Agents 概念 嵌入式 / RTOS 對應 共通的設計教訓
Agent(靜態模板) task descriptor / TCB 描述「我是誰」與「我能做什麼」要分離
Environment(容器模板) Board Support Package 環境依賴必須 declarative,不能塞進 task 邏輯裡
Session(執行實例) task instance 同一個 task 可以被 spawn 多份,狀態要本地化
Event stream(append-only log) 訊息佇列 + RTC trace 所有狀態變遷必須可追溯、可重放
Memory Store(持久記憶) 外部 EEPROM / FRAM 跨 power cycle 的狀態必須跟易失狀態解耦
Coordinator + Threads dispatcher + worker tasks 編排者不該幹活,只能調度
容器壞掉直接重建 watchdog reset 失敗的修復策略:reset,而不是 patch

換句話說,AI 圈花了五年才意識到「狀態跟硬體要解耦、編排者不能幹活、失敗了不修只重啟」這幾條教訓——而這些是嵌入式工程師在 2000 年代就已經被市場毒打到肌肉記憶的紀律。當你看 Anthropic 的部落格說「the container became cattle」時,韌體圈會心一笑:我們十五年前就在說「watchdog reset 不丟臉,丟臉的是不會 reset」。

可立即動手的三個改動

  1. 如果你還在維護 harness 補丁:對照官方 docs 確認哪些功能 Anthropic 已經內建,把你的補丁砍掉。模型版本一進化,這些補丁就是技術債。
  2. 如果你在跑本地多 agent:先做的不是換框架,而是把「狀態」(記憶 / 對話 / 中間檔)從 worker 容器拆出來。容器要可以隨時殺。
  3. 如果你在評估 sandbox 方案:把 Docker 跟 Cube Sandbox 並存——常駐服務用 Docker,ephemeral 任務換 Cube。冷啟動延遲從秒級降到 100 ms 內,使用者體感差異是肉眼可見的。

參考資料


本文最初發布於 HackMD @BASHCAT

留言

這個網誌中的熱門文章

Arduino 課本可能沒教的事(1)

SI4432 搭配Arduino

燒錄 Arduino mini Pro 燒錄