Claude Platform Docs

遷移

將以 Messages API 或 Claude Agent SDK 建構的現有代理遷移至 Claude Managed Agents。

Claude Managed Agents 以受管理的基礎設施取代您手寫的代理迴圈(agent loop)。本頁說明當您從以 Messages API 建構的自訂迴圈,或從 Claude Agent SDK 遷移時會有哪些變化。

從 Messages API 代理迴圈遷移

如果您是透過在 while 迴圈中呼叫 messages.create、自行執行工具呼叫,並將結果附加到對話歷史中來建構代理,那麼這些程式碼大部分都可以移除。

您不再需要管理的項目

之前之後
您維護對話歷史陣列,並在每一輪將其傳回。工作階段(session)在伺服器端儲存歷史。傳送事件、接收事件。
您逐一處理 tool_use 內容區塊、執行每個工具,並以 tool_result 訊息回到迴圈。預先建置的工具會自動在沙箱內執行。您只需透過 agent.custom_tool_use 事件處理自訂工具。
您自行佈建沙箱以執行代理產生的程式碼。工作階段沙箱負責處理程式碼執行、檔案操作與 bash。
您決定迴圈何時結束。當代理沒有更多事情要做時,工作階段會發出 session.status_idle

程式碼比較

之前(Messages API 迴圈,簡化版):

messages = [{"role": "user", "content": task}]
while True:
    response = client.messages.create(
        model="claude-opus-5",
        max_tokens=1024,
        messages=messages,
        tools=tools,
    )
    messages.append({"role": "assistant", "content": response.content})
    if response.stop_reason == "end_turn":
        break
    for block in response.content:
        if block.type == "tool_use":
            result = execute_tool(block.name, block.input)
            messages.append(
                {
                    "role": "user",
                    "content": [
                        {
                            "type": "tool_result",
                            "tool_use_id": block.id,
                            "content": result,
                        }
                    ],
                }
            )

之後(Claude Managed Agents):

agent = client.beta.agents.create(
    name="Task Runner",
    model="claude-opus-5",
    tools=[{"type": "agent_toolset_20260401"}],
)

session = client.beta.sessions.create(
    agent={"type": "agent", "id": agent.id, "version": agent.version},
    environment_id=environment.id,
)

with client.beta.sessions.events.stream(session.id) as stream:
    client.beta.sessions.events.send(
        session.id,
        events=[{"type": "user.message", "content": [{"type": "text", "text": task}]}],
    )
    for event in stream:
        if event.type == "session.status_idle":
            break

您仍可控制的項目

  • 系統提示與模型: 相同的欄位,現在位於代理定義上。
  • 自訂工具: 仍以 JSON Schema 宣告。執行方式從行內處理改為回應 agent.custom_tool_use 事件。請參閱工作階段事件串流
  • 網頁搜尋與網頁擷取設定: 相同的 allowed_domainsblocked_domainsmax_content_tokensuser_location 欄位,現在只需在代理工具集 configs 陣列中的 web_searchweb_fetch 項目上設定一次,而非在每個請求上設定。max_usescitationscache_control 欄位不可用。請參閱限制網頁搜尋與網頁擷取的網域
  • 上下文: 您仍可透過系統提示、檔案資源技能注入上下文。

從 Claude Agent SDK 遷移

如果您是以 Claude Agent SDK 建構,您已經在使用代理、工具與工作階段這些概念。差別在於它們在哪裡執行:SDK 在您所操作的程序中執行,而 Managed Agents 則在 Anthropic 的基礎設施中執行。遷移的大部分工作是將 SDK 設定物件對應到 API 端的等效項目。

有哪些變化

Agent SDKManaged Agents
每次執行時建構 ClaudeAgentOptions(...)呼叫一次 client.beta.agents.create(...);Agent 會在伺服器端持久保存並進行版本管理。請參閱代理設定
async with ClaudeSDKClient(...)query(...)client.beta.sessions.create(...),然後傳送與接收事件
@tool 裝飾的函式由 SDK 自動分派在 Agent 上宣告為 {"type": "custom", ...};您的用戶端處理 agent.custom_tool_use 事件並以 user.custom_tool_result 回覆。請參閱工具
內建工具在您的程序中針對您的檔案系統執行{"type": "agent_toolset_20260401"} 在工作階段沙箱內針對 /workspace 執行相同的工具。
cwdadd_dirs 指向本機路徑上傳或掛載檔案作為工作階段資源。
system_promptCLAUDE.md 階層Agent 上的單一 system 字串。每次變更代理的更新都會產生新的伺服器端版本;將工作階段釘選到特定版本,即可在不需部署的情況下升級或回滾。請參閱代理設定
mcp_servers 在同一處設定與驗證在 Agent 上宣告伺服器;透過 Session 上的 Vault 提供憑證。
permission_modecan_use_tool每個工具的 permission_policy;針對 always_ask 工具傳送 user.tool_confirmation 事件。

程式碼比較

之前(Agent SDK):

from claude_agent_sdk import (
    ClaudeAgentOptions,
    ClaudeSDKClient,
    create_sdk_mcp_server,
    tool,
)


@tool("get_weather", "Get the current weather for a city.", {"city": str})
async def get_weather(args: dict) -> dict:
    return {"content": [{"type": "text", "text": f"{args['city']}: 18°C, clear"}]}


options = ClaudeAgentOptions(
    model="claude-opus-5",
    system_prompt="You are a concise weather assistant.",
    mcp_servers={
        "weather": create_sdk_mcp_server("weather", "1.0", tools=[get_weather])
    },
)

async with ClaudeSDKClient(options=options) as agent:
    await agent.query("What's the weather in Tokyo?")
    async for msg in agent.receive_response():
        print(msg)

之後(Managed Agents):

from anthropic import Anthropic

client = Anthropic()

agent = client.beta.agents.create(
    name="weather-agent",
    model="claude-opus-5",
    system="You are a concise weather assistant.",
    tools=[
        {
            "type": "custom",
            "name": "get_weather",
            "description": "Get the current weather for a city.",
            "input_schema": {
                "type": "object",
                "properties": {"city": {"type": "string"}},
                "required": ["city"],
            },
        }
    ],
)
environment = client.beta.environments.create(
    name="weather-env",
    config={"type": "cloud", "networking": {"type": "unrestricted"}},
)

session = client.beta.sessions.create(
    agent={"type": "agent", "id": agent.id, "version": agent.version},
    environment_id=environment.id,
)


def get_weather(city: str) -> str:
    return f"{city}: 18°C, clear"


with client.beta.sessions.events.stream(session.id) as stream:
    client.beta.sessions.events.send(
        session.id,
        events=[
            {
                "type": "user.message",
                "content": [{"type": "text", "text": "What's the weather in Tokyo?"}],
            }
        ],
    )
    for event in stream:
        if event.type == "agent.message":
            print(
                "".join(block.text for block in event.content if block.type == "text")
            )
        elif event.type == "agent.custom_tool_use":
            result = get_weather(**event.input)
            client.beta.sessions.events.send(
                session.id,
                events=[
                    {
                        "type": "user.custom_tool_result",
                        "custom_tool_use_id": event.id,
                        "content": [{"type": "text", "text": result}],
                    }
                ],
            )
        elif (
            event.type == "session.status_idle"
            and event.stop_reason
            and event.stop_reason.type == "end_turn"
        ):
            break

Agent 與 Environment 只需建立一次,即可在各工作階段間重複使用。工具函式仍在您的程序中執行;差別在於您需讀取 agent.custom_tool_use 事件並明確傳送結果,而非由 SDK 替您分派。

移至您用戶端的功能

由 Anthropic 執行代理迴圈的取捨在於,SDK 原本自動處理的一些事項將成為您用戶端的責任。

SDK 功能Managed Agents 做法
規劃模式(Plan mode)先執行一個僅做規劃的工作階段,再以第二個工作階段執行該計畫。
輸出樣式、斜線指令在傳送 user.message 之前或接收 agent.message 之後,於您的用戶端套用。
PreToolUse / PostToolUse 掛鉤您的用戶端在回應前已能看到每個 agent.custom_tool_use 事件;將邏輯放在那裡。對於內建工具,請使用 permission_policy: always_ask
max_turns在用戶端計算輪數。

遷移檢查清單

  1. 建立環境,具備您的代理所需的網路與執行環境。
  2. 將您的系統提示與工具選擇移植到代理定義
  3. sessions.createsessions.events.stream 取代您的迴圈。
  4. 對於代理讀取的任何本機檔案,透過 Files API 上傳並將其掛載為 resources
  5. 對於任何自訂工具處理程式,將執行移入您的事件迴圈中,作為對 agent.custom_tool_use 事件的回應。
  6. 在將正式環境流量導向新流程之前,先以測試工作階段進行驗證。

在模型版本之間遷移

當新的 Claude 模型發布時,遷移 Claude Managed Agents 整合通常只需變更一個欄位:更新代理定義上的 model,變更會在您建立的下一個工作階段生效。

ant beta:agents update --agent-id "$AGENT_ID" < agent.yaml
agent.yaml
name: Task Runner
model: claude-opus-5
system: You are a task automation agent. Complete the task you are given end to end.
tools:
  - type: agent_toolset_20260401

Messages API 遷移指南中記載的大多數模型層級行為變更,都不需要您採取任何行動:

  • 請求參數變更max_tokens 預設值、thinking 設定)由 Claude Managed Agents 執行環境處理。這些欄位不會在代理定義上公開。
  • 助理訊息預填(prefilling) 在以事件為基礎的工作階段模型中並不存在,因此在較新模型上移除此功能不會有任何影響。
  • 工具引數 JSON 跳脫 會在您收到 agent.custom_tool_use 事件之前由執行環境解析。您看到的是結構化資料,而非原始字串。

Messages API 指南中的行為描述(模型有哪些不同的行為)仍然適用。遷移步驟(如何變更您的請求程式碼)則不適用。

Was this page helpful?