Claude Managed Agents remplace votre boucle d'agent écrite à la main par une infrastructure gérée. Cette page couvre les changements lorsque vous migrez à partir d'une boucle personnalisée construite sur l'API Messages ou à partir du Claude Agent SDK.
Toutes les demandes de l'API Managed Agents nécessitent l'en-tête bêta managed-agents-2026-04-01. Le SDK définit automatiquement l'en-tête bêta.
Si vous avez construit un agent en appelant messages.create dans une boucle while, en exécutant vous-même les appels d'outils et en ajoutant les résultats à l'historique de conversation, la plupart de ce code disparaît.
| Avant | Après |
|---|---|
| Vous maintenez le tableau d'historique de conversation et le transmettez à chaque tour. | La session stocke l'historique côté serveur. Envoyez des événements, recevez des événements. |
Vous analysez stop_reason: "tool_use", exécutez l'outil et bouclez avec un message tool_result. | Les outils prédéfinis s'exécutent automatiquement dans le conteneur. Vous ne gérez que les outils personnalisés via les événements agent.custom_tool_use. |
| Vous provisionnez votre propre bac à sable pour exécuter le code généré par l'agent. | Le conteneur de session gère l'exécution du code, les opérations sur les fichiers et bash. |
| Vous décidez quand la boucle est terminée. | La session émet session.status_idle quand l'agent n'a plus rien à faire. |
Avant (boucle API Messages, simplifiée) :
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,
}
],
}
)Après (Claude Managed Agents) :
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 || trueagent.custom_tool_use. Voir Flux d'événements de session.Si vous avez construit avec le Claude Agent SDK, vous travaillez déjà avec les agents, les outils et les sessions en tant que concepts. La différence est l'endroit où ils s'exécutent : le SDK s'exécute dans un processus que vous exploitez, tandis que Managed Agents s'exécute dans l'infrastructure d'Anthropic. La plupart de la migration consiste à mapper les objets de configuration du SDK à leurs équivalents côté API.
| Agent SDK | Managed Agents |
|---|---|
ClaudeAgentOptions(...) construit par exécution | client.beta.agents.create(...) une fois ; l'Agent est persisté et versionné côté serveur. Voir Configuration de l'agent. |
async with ClaudeSDKClient(...) ou query(...) | client.beta.sessions.create(...) puis envoyer et recevoir des événements. |
Fonctions décorées @tool distribuées automatiquement par le SDK | Déclarez comme {"type": "custom", ...} sur l'Agent ; votre client gère les événements agent.custom_tool_use et répond avec user.custom_tool_result. Voir Outils. |
| Les outils intégrés s'exécutent dans votre processus contre votre système de fichiers | {"type": "agent_toolset_20260401"} exécute les mêmes outils à l'intérieur du conteneur de session contre /workspace. |
cwd, add_dirs pointent vers des chemins locaux | Téléchargez ou montez des fichiers en tant que ressources de session. |
system_prompt et la hiérarchie CLAUDE.md | Une seule chaîne system sur l'Agent. Chaque mise à jour produit une nouvelle version côté serveur ; épinglez les sessions à une version spécifique pour promouvoir ou revenir en arrière sans déploiement. Voir Configuration de l'agent. |
mcp_servers configurés et authentifiés en un seul endroit | Déclarez les serveurs sur l'Agent ; fournissez les identifiants via un Vault sur la Session. |
permission_mode, can_use_tool | permission_policy par outil ; répondez aux événements user.tool_confirmation pour les outils always_ask. |
Avant (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)Après (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":
breakL'Agent et l'Environnement sont créés une fois et réutilisés dans les sessions. La fonction d'outil s'exécute toujours dans votre processus ; la différence est que vous lisez l'événement agent.custom_tool_use et envoyez le résultat explicitement au lieu que le SDK le distribue pour vous.
Le compromis pour qu'Anthropic exécute la boucle d'agent est que quelques choses que le SDK gérait automatiquement deviennent la responsabilité de votre client.
| Fonctionnalité du SDK | Approche Managed Agents |
|---|---|
| Mode de planification | Exécutez d'abord une session de planification uniquement, puis une deuxième session pour exécuter. |
| Styles de sortie, commandes slash | Appliquez dans votre client avant d'envoyer user.message ou après avoir reçu agent.message. |
Crochets PreToolUse / PostToolUse | Votre client voit déjà chaque événement agent.custom_tool_use avant de répondre ; mettez la logique là. Pour les outils intégrés, utilisez permission_policy: always_ask. |
max_turns | Comptez les tours côté client. |
sessions.create et sessions.stream.resources.agent.custom_tool_use.Quand un nouveau modèle Claude est publié, la migration d'une intégration Claude Managed Agents est généralement un changement d'un seul champ : mettez à jour model sur votre définition d'agent et le changement prend effet sur la prochaine session que vous créez.
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"}')"La plupart des changements de comportement au niveau du modèle documentés dans le guide de migration de l'API Messages ne nécessitent pas d'action de votre côté :
max_tokens, configuration thinking) sont gérés par le runtime Claude Managed Agents. Ces champs ne sont pas exposés sur la définition de l'agent.agent.custom_tool_use. Vous voyez des données structurées, pas des chaînes brutes.Les descriptions de comportement du guide de l'API Messages (ce que le modèle fait différemment) s'appliquent toujours. Les étapes de migration (comment modifier votre code de demande) ne s'appliquent pas.
Was this page helpful?