跳到正文
Anthropic:Engineering·· 1 小時前精選AI 評分76

Anthropic 解説 Managed Agents 如何透過解耦架構擴展

Scaling Managed Agents: Decoupling the brain from the hands

AI 導讀

Anthropic 説明 Claude Managed Agents 以獨立介面拆分 Claude 及其 harness、session log、sandbox 和工具,讓各部分可獨立替換,以支援長時程智能體工作。

推薦理由

Managed Agents 將 harness、session 與 sandbox 解耦,並以 p50 TTFT 約降 60%、p95 降逾 90% 呈現架構對延遲的影響。

正文 · 繁體中文

按照我們的文件,開始使用 Claude Managed Agents。

Engineering Blog 持續探討的主題之一,是如何建立有效的 Agent,以及如何設計執行框架,以支援長時間運行的工作。這些工作有一個共同點:執行框架會把 Claude 無法獨力完成哪些事情的假設編入其中。然而,這些假設需要經常重新審視,因為隨着模型改進,它們可能會過時。

舉一個例子,在較早前的工作中,我們發現 Claude Sonnet 4.5 在察覺上下文限制將至時,會提早結束任務。這種行為有時稱為「上下文焦慮」。我們透過在執行框架中加入上下文重設來處理這個問題。但在 Claude Opus 4.5 上使用同一個執行框架時,我們發現這種行為已不復存在。重設因此成了無用負擔。

我們預期執行框架會持續演進。因此,我們打造了 Managed Agents:Claude Platform 上的一項託管服務,透過一小組旨在比任何特定實作更長久的介面,代你運行長時間執行的 Agent;這些實作包括我們目前採用的實作。

打造 Managed Agents,意味着要解決計算領域一個由來已久的問題:如何為「尚未構思出的程式」設計系統。幾十年前,作業系統透過將硬件虛擬化為抽象概念——程序、檔案——解決了這個問題;這些抽象概念足夠通用,能供當時尚不存在的程式使用。這些抽象概念比硬件存續得更久。read() 命令無須理會存取的是 1970 年代的磁碟組,還是現代 SSD。上層抽象保持穩定,底層實作則可自由更改。

Managed Agents 採用相同模式。我們將 Agent 的元件虛擬化:工作階段(記錄所有已發生事情、只可追加內容的日誌)、執行框架(呼叫 Claude,並將 Claude 的工具呼叫轉送至相關基礎設施的迴圈),以及沙盒(Claude 可在其中執行程式碼和編輯檔案的執行環境)。這樣一來,各元件的實作都可以互換,而不影響其他元件。我們對這些介面的形式有明確主張,但不限定介面背後運行的內容。

不要養寵物

我們最初把所有 Agent 元件放進同一個容器,令工作階段、執行框架和沙盒共用同一個環境。這種做法有其優點,包括編輯檔案會直接透過系統呼叫完成,而且無需設計服務邊界。

但把所有東西耦合到同一個容器,令我們遇上一個由來已久的基礎設施問題:我們養了一隻寵物。在「寵物與牲畜」的比喻中,寵物是有名字、需要人手悉心照料而且不能失去的個體;牲畜則可以互相替代。在我們的情況下,伺服器就成了那隻寵物;如果容器故障,工作階段就會遺失。如果容器沒有回應,我們便得設法讓它恢復正常。

要照料容器,就得為沒有回應、卡住的工作階段除錯。我們唯一的觀察途徑是 WebSocket 事件串流,但它無法告訴我們故障發生在何處,結果無論是執行框架中的錯誤、事件串流中的封包遺失,還是容器離線,呈現出的情況都一樣。要查明問題所在,工程師必須在容器內開啟 shell;但由於容器通常也存有用戶資料,這種做法實際上令我們無法進行除錯。

另一個問題是,執行框架假設 Claude 所處理的一切都位於它所在的容器中。當客戶要求我們將 Claude 連接至他們的虛擬私有雲時,他們只能選擇將自己的網絡與我們的網絡建立對等連線,或在自己的環境中執行我們的執行框架。當我們想把它連接至不同的基礎架構時,執行框架內建的一項假設便成了問題。

我們最後採取的解決方案,是將我們所説的「大腦」(Claude 及其執行框架)與「雙手」(執行操作的沙盒和工具),以及「工作階段」(工作階段事件記錄)分開。每一部分都成為一個介面,對其他部分的假設很少;而且各自可以獨立失效或替換。

執行框架離開容器。 將大腦與雙手分開,代表執行框架不再位於容器內。它呼叫容器的方式,與呼叫其他任何工具無異:execute(name, input) → string。容器成了可替換的資源。如果容器失效,執行框架便會將故障視為工具呼叫錯誤,並回傳給 Claude。如果 Claude 決定重試,就可以按照標準配方重新初始化一個新容器:provision({resources})。我們不再需要設法修復失效的容器。

從執行框架故障中恢復。 執行框架本身也成了可替換的資源。由於工作階段記錄位於執行框架之外,框架內沒有任何內容需要在當機後保留。當執行框架失效時,可以透過wake(sessionId)重新啟動一個新的框架,使用getSession(id)取回事件記錄,並從最後一個事件繼續。在 Agent 迴圈期間,執行框架會透過emitEvent(id, event)將資料寫入工作階段,以持續保留事件記錄。

安全邊界。在耦合式設計中,Claude 生成的任何不可信程式碼都會在存有憑證的同一個容器中執行,因此提示詞注入只需誘使 Claude 讀取自身環境即可。一旦攻擊者取得這些權杖,便可建立全新、不受限制的工作階段,並委派工作給它們。收窄權限範圍是顯而易見的緩解方法,但這種做法暗含一項假設:Claude 無法憑受限權杖做到某些事;然而 Claude 正變得愈來愈聰明。從結構上解決問題的方法,是確保 Claude 生成的程式碼執行所在的沙盒永遠無法存取這些權杖。

我們採用兩種模式來確保這一點。驗證資料可以與資源一併封裝,也可以存放在沙盒外的保管庫中。對於 Git,我們會在沙盒初始化期間使用各個儲存庫的存取權杖複製儲存庫,並將權杖接入本機的 git remote。Git push 和 pull 可在沙盒內執行,無須 Agent 本身處理權杖。對於自訂工具,我們支援 MCP,並將 OAuth 權杖存放在安全保管庫中。Claude 透過專用代理呼叫 MCP 工具;代理會接收與工作階段相關聯的權杖,然後從保管庫取得相應憑證,並呼叫外部服務。執行框架完全不會得知任何憑證。

工作階段並非 Claude 的上下文視窗

長時間任務往往超出 Claude 上下文視窗的長度,而常見的處理方式都涉及不可逆地決定保留哪些內容。我們曾在先前的工作中探討上下文工程相關技術。例如,壓縮機制讓 Claude 儲存上下文視窗的摘要,而記憶工具則讓 Claude 將上下文寫入檔案,從而能在不同工作階段之間累積學習成果。這可以配合上下文裁剪使用,選擇性移除舊的工具結果或思考區塊等 token。

但若不可逆地決定選擇性保留或捨棄上下文,可能會導致失敗。要判斷後續回合會用到哪些 token 並不容易。如果訊息經過壓縮步驟轉換,執行框架便會從 Claude 的上下文視窗中移除已壓縮的訊息;只有將這些訊息儲存起來,才能還原。過往研究曾探討如何解決這個問題,其中一種做法是把上下文儲存為一個位於上下文視窗之外的物件。例如,上下文可以是 REPL 中的物件,讓 LLM 透過編寫程式碼來篩選或擷取其中一部分,以程式方式存取。

在 Managed Agents 中,工作階段也具備同樣的優點:它充當位於 Claude 上下文視窗之外的上下文物件。不過,上下文並非儲存在沙盒或 REPL 中,而是持久儲存在工作階段記錄中。介面 getEvents(), 可讓大腦按事件串流中的位置選取片段,藉此查閲上下文。這個介面用法靈活,大腦可以從上次停止閲讀的位置繼續、倒回特定時刻前的幾個事件以查看前因,或重新閲讀特定操作前的上下文。

擷取的事件也可以在傳送至 Claude 的上下文視窗前,由執行框架轉換。執行框架可以按照自身編碼的方式進行各種轉換,包括整理上下文以提高提示詞快取命中率,以及上下文工程。我們把工作階段中可還原的上下文儲存,與執行框架中任意的上下文管理分開處理,因為我們無法預測未來模型需要哪種特定的上下文工程。這些介面把上下文管理交由執行框架處理,只保證工作階段具持久性,並可供查閲。


多個大腦,多雙手

多個大腦。 將大腦與雙手分離,解決了我們最早收到的客戶意見之一。當團隊希望 Claude 使用其自家 VPC 內的資源時,唯一方法是將他們的網絡與我們的網絡建立對等連線,因為當時容納執行框架的容器預設所有資源都位於其旁邊。執行框架不再放在容器內後,這個假設便不復存在。同一改動亦帶來效能提升。最初把大腦放進容器時,需要多少個大腦,就要配置多少個容器。每個大腦都要等容器配置完成後才能進行推理;每個工作階段一開始都要承擔完整的容器設定成本。每個工作階段,即使永遠不會使用沙盒,也要複製程式碼儲存庫、啟動程序,並從我們的伺服器擷取待處理事件。

這段等待時間反映在首 token 時間(TTFT)上,即工作階段從接收工作到產生首個回應 token 需要等待多久。TTFT 是用戶感受最明顯的延遲。

將大腦與雙手分離後,只有在需要時,大腦才會透過工具呼叫 (execute(name, input) → string) 配置容器。因此,未有即時需要容器的工作階段便毋須等待容器。編排層從工作階段記錄擷取待處理事件後,便可立即開始推理。採用這種架構後,我們的 p50 TTFT 約降低 60%,p95 則降低超過 90%。擴展至多個大腦,只需啟動多個無狀態執行框架,並只在有需要時才將它們連接至雙手。

多隻手。我們亦希望能讓每個大腦連接多隻手。實際上,這表示 Claude 必須推理多個執行環境,並決定把工作交到哪裏執行——這比在單一 shell 中操作更需要認知能力。由於早期模型尚未具備這種能力,我們最初讓大腦運行於單一容器中。隨着智能提升,單一容器反而成為限制:容器一旦失效,我們便會失去大腦所連接的每隻手的狀態。

將大腦與雙手分開後,每隻手便成為一種工具,execute(name, input) → string:傳入名稱和輸入,然後返回一個字串。這個介面支援任何自訂工具、任何 MCP 伺服器,以及我們自己的工具。執行框架無須知道沙盒是容器、手機,還是 Pokémon 模擬器。由於雙手不會與任何大腦綁定,各個大腦便可以互相轉交雙手。

結語

我們面對的挑戰由來已久:如何設計一個能支援「尚未構思出來的程式」的系統。作業系統透過將硬件虛擬化為足夠通用的抽象層,得以沿用數十年,支援當時尚不存在的程式。設計 Managed Agents 時,我們希望打造一個能容納未來各種執行框架、沙盒或 Claude 周邊其他元件的系統。

Managed Agents 是一種秉持相同理念的元執行框架,不會預設 Claude 未來需要使用哪一種特定執行框架。相反,它是一個設有通用介面的系統,讓多種不同的執行框架都能使用。例如,Claude Code 是一個出色的執行框架,我們廣泛用於各種任務。我們亦展示過,針對特定任務的智能體執行框架在狹窄領域中表現出色。Managed Agents 能夠容納任何一種框架,並隨時間配合 Claude 的智能水平。

元執行框架的設計,意味著我們對 Claude 周邊介面的設計有明確主張:我們預期 Claude 需要能夠操作狀態(工作階段)和執行運算(沙盒)。我們亦預期 Claude 需要具備擴展至多個大腦和多隻手的能力。我們設計這些介面,讓它們能夠在長時間跨度內可靠、安全地運作。但我們不會假設 Claude 需要多少個大腦或多少隻手,也不會假設它們位於何處。

鳴謝

本文由 Lance Martin、Gabe Cemaj 和 Michael Cohen 撰寫。感謝 Nodir Turakulov 和 Jeremy Fox 就這些議題提供寶貴意見。特別感謝 Agents API 團隊和 Jake Eaton 作出貢獻。

來源:Anthropic:Engineering · anthropic.com