移行
Messages API または Claude Agent SDK で構築された既存のエージェントを Claude Managed Agents に移行します。
Claude Managed Agents は、手書きのエージェントループをマネージドインフラストラクチャに置き換えます。このページでは、Messages API 上に構築したカスタムループ、または Claude Agent SDK から移行する際に何が変わるかを説明します。
Messages API のエージェントループからの移行
client.messages.create()をループ内で呼び出し、ツール呼び出しを自分で実行し、結果を会話履歴に追加する形でエージェントを構築していた場合、そのコードの大部分は不要になります。
管理しなくてよくなるもの
| 移行前 | 移行後 |
|---|---|
| 会話履歴の配列を保持し、毎ターンそれを渡し直します。 | セッションが履歴をサーバー側に保存します。イベントを送信し、イベントを受信します。 |
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-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-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イベントへの応答に移ります。セッションイベントストリームを参照してください。 - Web検索とWebフェッチの設定: 同じ
allowed_domains、blocked_domains、max_content_tokens、user_locationフィールドを、リクエストごとではなく、エージェントツールセットのconfigs配列内のweb_searchおよびweb_fetchエントリに一度だけ設定します。max_uses、citations、cache_controlフィールドは利用できません。Messages APIのツールとの違いを参照してください。 - コンテキスト: システムプロンプト、ファイルリソース、またはスキルを通じて、引き続きコンテキストを注入できます。
Claude Agent SDK からの移行
Claude Agent SDK で構築していた場合、すでにエージェント、ツール、セッションという概念を扱っています。違いはそれらがどこで実行されるかです。SDK はあなたが運用するプロセス内で実行されますが、Managed Agents は Anthropic のインフラストラクチャ内で実行されます。移行作業の大部分は、SDK の設定オブジェクトを API 側の同等物にマッピングすることです。
変わるもの
| Agent SDK | Managed 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に対して実行します。 |
cwd、add_dirsはローカルパスを指す | ファイルをセッションリソースとしてアップロードまたはマウントします。 |
system_promptとCLAUDE.mdの階層 | Agent上の単一のsystem文字列です。エージェントを変更する更新のたびに、サーバー側で新しいバージョンが作成されます。セッションを特定のバージョンに固定することで、デプロイなしで昇格やロールバックができます。エージェントのセットアップを参照してください。 |
1か所で設定および認証されるmcp_servers | Agent上でサーバーを宣言し、Session上のVaultを通じて認証情報を提供します。 |
permission_mode、can_use_tool | ツールごとのpermission_policy(always_allow、always_ask、またはauto)を使用します。承認待ちで一時停止した呼び出しに対しては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-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-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": "limited", "allow_package_managers": True},
},
)
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:
match event.type:
case "agent.message":
print(
"".join(
block.text for block in event.content if block.type == "text"
)
)
case "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}],
}
],
)
case "session.status_idle":
if event.stop_reason and event.stop_reason.type == "end_turn":
breakAgent と Environment は一度作成され、セッション間で再利用されます。ツール関数は引き続きあなたのプロセス内で実行されます。違いは、SDK が代わりにディスパッチするのではなく、あなたが agent.custom_tool_use イベントを読み取り、結果を明示的に送信する点です。
クライアント側に移る機能
Anthropic がエージェントループを実行することのトレードオフとして、SDK が自動的に処理していたいくつかのことがクライアントの責任になります。
| SDKの機能 | Managed Agentsでのアプローチ |
|---|---|
| プランモード | まず計画のみを行うセッションを実行し、次に2つ目のセッションで計画を実行します。 |
| 出力スタイル、スラッシュコマンド | user.messageを送信する前、またはagent.messageを受信した後に、クライアント側で適用します。 |
PreToolUse / PostToolUseの「hooks」(フック) | クライアントは応答する前にすべてのagent.custom_tool_useイベントをすでに確認しているため、そこにロジックを配置します。組み込みツールについては、permission_policy: always_askを使用してすべての呼び出しを確認します。autoを使用すると、代わりにサーバーが各呼び出しを評価しますが、サーバーが呼び出しを安全と評価した場合、その呼び出しはクライアントに届くことなく実行されます。 |
max_turns | クライアント側でターン数をカウントします。 |
移行チェックリスト
- エージェントが必要とするネットワークとランタイムを備えた環境を作成します。
- システムプロンプトとツールの選択をエージェント定義に移植します。
- ループを置き換えます:
client.beta.sessions.create()でセッションを作成し、client.beta.sessions.events.stream()でそのイベントをストリーミングします。 - エージェントが読み取るローカルファイルは、Files APIを通じてアップロードし、
resourcesとしてマウントします。 - カスタムツールハンドラーがあれば、実行を
agent.custom_tool_useイベントへの応答としてイベントループ内に移します。 - 本番トラフィックを新しいフローに向ける前に、テストセッションで検証します。
モデルバージョン間の移行
新しいClaudeモデルがリリースされた場合、Claude Managed Agentsの統合の移行は通常1つのフィールドの変更で済みます。エージェント定義のmodelを更新すると、次に作成するセッションから変更が反映されます。
ant apply agent.md---
name: Task Runner
model: claude-opus-5-5
tools:
- type: agent_toolset_20260401
---
You are a task automation agent. Complete the task you are given end to end.Messages API 移行ガイドに記載されているモデルレベルの動作変更のほとんどは、あなたの側での対応を必要としません。
- リクエストパラメータの変更(
max_tokensのデフォルト値、thinkingの設定)は、Claude Managed Agentsのランタイムによって処理されます。これらのフィールドはエージェント定義上では公開されていません。 - アシスタントメッセージのプリフィルはイベントベースのセッションモデルには存在しないため、新しいモデルでの廃止は影響がありません。
- ツール引数の JSON エスケープは、
agent.custom_tool_useイベントを受信する前にランタイムによって解析されます。生の文字列ではなく、構造化されたデータを受け取ります。
Messages API ガイドの動作の説明(モデルの動作がどう変わるか)は引き続き適用されます。移行手順(リクエストコードをどう変更するか)は適用されません。
Was this page helpful?