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(...) 그 다음 이벤트를 보내고 받습니다. |
@tool 데코레이터 함수가 SDK에 의해 자동으로 디스패치됨 | 에이전트에서 {"type": "custom", ...}으로 선언; 클라이언트가 agent.custom_tool_use 이벤트를 처리하고 user.custom_tool_result로 응답합니다. 도구를 참조하세요. |
| 기본 제공 도구가 파일 시스템에 대해 프로세스에서 실행됨 | {"type": "agent_toolset_20260401"}이 세션 컨테이너 내에서 /workspace에 대해 동일한 도구를 실행합니다. |
이전 (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에이전트와 환경은 한 번 생성되고 세션 전체에서 재사용됩니다. 도구 함수는 여전히 프로세스에서 실행됩니다. 차이점은 agent.custom_tool_use 이벤트를 읽고 SDK가 디스패치하는 대신 명시적으로 결과를 보낸다는 것입니다.
Anthropic이 에이전트 루프를 실행하는 대신, SDK가 자동으로 처리하던 몇 가지 사항이 클라이언트의 책임이 됩니다.
| SDK 기능 | Managed Agents 접근 방식 |
|---|---|
| 계획 모드 | 먼저 계획 전용 세션을 실행한 다음 두 번째 세션을 실행하여 실행합니다. |
| 출력 스타일, 슬래시 명령 | 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 통합을 마이그레이션하는 것은 일반적으로 한 필드 변경입니다. 에이전트 정의에서 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'
)
# Open the SSE stream in the background, then send the user message.
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
# Read events until the session goes idle.
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 || truecwd, 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"}')"