Was this page helpful?
Claude Managed Agentsは、手書きのエージェントループをマネージドインフラストラクチャに置き換えます。このページでは、Messages API上に構築されたカスタムループ、またはClaude Agent SDKから移行する際の変更点について説明します。
すべてのManaged Agents APIリクエストには、managed-agents-2026-04-01ベータヘッダーが必要です。SDKはベータヘッダーを自動的に設定します。
whileループ内でmessages.createを呼び出し、ツール呼び出しを自分で実行し、結果を会話履歴に追加することでエージェントを構築した場合、そのコードのほとんどは不要になります。
| 移行前 | 移行後 |
|---|---|
| 会話履歴配列を管理し、毎ターン渡し返す。 | セッションがサーバー側で履歴を保存します。イベントを送受信するだけです。 |
stop_reason: "tool_use"をパースし、ツールを実行し、tool_resultメッセージでループバックする。 | 事前構築済みのツールがコンテナ内で自動的に実行されます。カスタムツールのみagent.custom_tool_useイベントを通じて処理します。 |
| エージェントが生成したコードを実行するための独自のサンドボックスをプロビジョニングする。 | セッションコンテナがコード実行、ファイル操作、bashを処理します。 |
| ループの終了タイミングを自分で決定する。 | エージェントがこれ以上行うことがなくなると、セッションがsession.status_idleを発行します。 |
移行前(Messages APIループ、簡略版):
移行後(Claude Managed Agents):
agent.custom_tool_useイベントへの応答に移行します。セッションイベントストリームを参照してください。Claude Agent SDKで構築した場合、すでにエージェント、ツール、セッションをコンセプトとして扱っています。違いは実行場所です:SDKはあなたが運用するプロセスで実行されますが、Managed AgentsはAnthropicのインフラストラクチャで実行されます。移行の大部分は、SDK設定オブジェクトをAPIサイドの同等物にマッピングすることです。
| Agent SDK | Managed Agents |
|---|---|
実行ごとに構築されるClaudeAgentOptions(...) | client.beta.agents.create(...)を一度実行するだけで、エージェントはサーバー側で永続化・バージョン管理されます。エージェントのセットアップを参照してください。 |
async with ClaudeSDKClient(...)またはquery(...) | client.beta.sessions.create(...)を実行し、イベントを送受信します。 |
SDKによって自動的にディスパッチされる@toolデコレータ付き関数 | エージェントに{"type": "custom", ...}として宣言し、クライアントがagent.custom_tool_useイベントを処理してuser.custom_tool_resultで返信します。ツールを参照してください。 |
| あなたのファイルシステムに対してあなたのプロセスで実行される組み込みツール | {"type": "agent_toolset_20260401"}は同じツールをセッションコンテナ内のに対して実行します。 |
移行前(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-sonnet-4-6",
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-sonnet-4-6",
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 ev in stream:
if ev.type == "agent.message":
print("".join(b.text for b in ev.content))
elif ev.type == "agent.custom_tool_use":
result = get_weather(**ev.input)
client.beta.sessions.events.send(
session.id,
events=[
{
"type": "user.custom_tool_result",
"custom_tool_use_id": ev.id,
"content": [{"type": "text", "text": result}],
}
],
)
elif ev.type == "session.status_idle" and ev.stop_reason.type == "end_turn":
breakエージェントと環境は一度作成され、セッション間で再利用されます。ツール関数は引き続きあなたのプロセスで実行されます。違いは、SDKがディスパッチする代わりに、agent.custom_tool_useイベントを読み取り、結果を明示的に送信することです。
Anthropicがエージェントループを実行するトレードオフとして、SDKが自動的に処理していたいくつかのことがクライアントの責任になります。
| SDK機能 | Managed Agentsのアプローチ |
|---|---|
| プランモード | まず計画専用セッションを実行し、次に実行のための2番目のセッションを実行します。 |
| 出力スタイル、スラッシュコマンド | user.messageを送信する前、またはagent.messageを受信した後にクライアントで適用します。 |
PreToolUse / PostToolUseフック | クライアントはすでに応答前にすべてのagent.custom_tool_useイベントを確認しています。そこにロジックを配置してください。組み込みツールにはpermission_policy: always_askを使用します。 |
max_turns | クライアント側でターンをカウントします。 |
sessions.createとsessions.streamに置き換えます。resourcesとしてマウントします。agent.custom_tool_useイベントへの応答としてイベントループに移動します。新しいClaudeモデルがリリースされた場合、Claude Managed Agentsインテグレーションの移行は通常、1フィールドの変更です:エージェント定義のmodelを更新すると、次に作成するセッションから変更が有効になります。
Messages APIマイグレーションガイドに記載されているほとんどのモデルレベルの動作変更は、あなた側での対応を必要としません:
max_tokensのデフォルト、thinkingの設定)はClaude Managed Agentsランタイムによって処理されます。これらのフィールドはエージェント定義には公開されていません。agent.custom_tool_useイベントを受信する前にランタイムによってパースされます。生の文字列ではなく、構造化されたデータが表示されます。Messages APIガイドの動作説明(モデルが異なる動作をする内容)は引き続き適用されます。移行手順(リクエストコードの変更方法)は適用されません。
messages = [{"role": "user", "content": task}]
while True:
response = client.messages.create(
model="claude-sonnet-4-6",
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,
}
],
}
)agent=$(
curl --fail-with-body -sS "https://api.anthropic.com/v1/agents?beta=true" \
-H "x-api-key: ${ANTHROPIC_API_KEY}" \
-H "anthropic-version: 2023-06-01" \
-H "anthropic-beta: managed-agents-2026-04-01" \
--json '{
"name": "Task Runner",
"model": "claude-sonnet-4-6",
"tools": [{"type": "agent_toolset_20260401"}]
}'
)
agent_id=$(jq -r '.id' <<< "${agent}")
session_id=$(
curl --fail-with-body -sS "https://api.anthropic.com/v1/sessions?beta=true" \
-H "x-api-key: ${ANTHROPIC_API_KEY}" \
-H "anthropic-version: 2023-06-01" \
-H "anthropic-beta: managed-agents-2026-04-01" \
--json "$(jq -n --argjson a "${agent}" --arg env "${environment_id}" \
'{agent: {type: "agent", id: $a.id, version: $a.version}, environment_id: $env}')" \
| jq -r '.id'
)
# バックグラウンドでSSEストリームを開き、ユーザーメッセージを送信します。
stream_log=$(mktemp)
curl --fail-with-body -sS -N \
"https://api.anthropic.com/v1/sessions/${session_id}/stream?beta=true" \
-H "x-api-key: ${ANTHROPIC_API_KEY}" \
-H "anthropic-version: 2023-06-01" \
-H "anthropic-beta: managed-agents-2026-04-01" \
> "${stream_log}" &
stream_pid=$!
curl --fail-with-body -sS \
"https://api.anthropic.com/v1/sessions/${session_id}/events?beta=true" \
-H "x-api-key: ${ANTHROPIC_API_KEY}" \
-H "anthropic-version: 2023-06-01" \
-H "anthropic-beta: managed-agents-2026-04-01" \
--json "$(jq -n --arg text "${task}" \
'{events: [{type: "user.message", content: [{type: "text", text: $text}]}]}')" \
> /dev/null
# セッションがアイドル状態になるまでイベントを読み取ります。
while IFS= read -r line; do
[[ ${line} == data:* ]] || continue
event_type=$(jq -r '.type // empty' 2>/dev/null <<< "${line#data: }" || true)
[[ ${event_type} == "session.status_idle" ]] && break
done < <(tail -f -n +1 "${stream_log}")
kill "${stream_pid}" 2>/dev/null || true/workspaceローカルパスを指すcwd、add_dirs | ファイルをセッションリソースとしてアップロードまたはマウントします。 |
system_promptとCLAUDE.md階層 | エージェントの単一のsystem文字列。各更新で新しいサーバー側バージョンが生成されます。デプロイなしでプロモートまたはロールバックするために、セッションを特定のバージョンに固定できます。エージェントのセットアップを参照してください。 |
一箇所で設定・認証されるmcp_servers | エージェントにサーバーを宣言し、セッションのVaultを通じて認証情報を提供します。 |
permission_mode、can_use_tool | ツールごとのpermission_policy;always_askツールのuser.tool_confirmationイベントに応答します。 |
curl -sS --fail-with-body "https://api.anthropic.com/v1/agents/$AGENT_ID?beta=true" \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "anthropic-beta: managed-agents-2026-04-01" \
--json "$(jq -n --argjson version "$AGENT_VERSION" '{version: $version, model: "claude-sonnet-4-6"}')"