• Messages
  • Agents gérés
  • Administration
Search...
⌘K
Premiers pas
Introduction à ClaudeDémarrage rapide
Développer avec Claude
Aperçu des fonctionnalitésUtilisation de l'API MessagesRaisons d'arrêt et repliRefus et repliCrédit de repli
Capacités du modèle
Réflexion étendueRéflexion adaptativeEffortBudgets de tâches (bêta)Mode rapide (aperçu de recherche)Sorties structuréesCitationsMessages en streamingTraitement par lotsRésultats de rechercheRefus en streamingPrise en charge multilingueEmbeddings
Outils
AperçuFonctionnement de l'utilisation d'outilsTutoriel : Créer un agent utilisant des outilsDéfinir des outilsGérer les appels d'outilsUtilisation d'outils en parallèleTool Runner (SDK)Utilisation d'outils stricteUtilisation d'outils avec mise en cache des promptsOutils serveurDépannageOutil de recherche webOutil de récupération webOutil d'exécution de codeOutil conseillerOutil de mémoireOutil BashOutil d'utilisation de l'ordinateurOutil d'éditeur de texte
Infrastructure des outils
Référence des outilsGérer le contexte des outilsCombinaisons d'outilsRecherche d'outilsAppel d'outils programmatiqueStreaming d'outils granulaire
Gestion du contexte
Fenêtres de contexteCompactageÉdition du contexteMise en cache des promptsMessages système en cours de conversationCréer un mode d'orchestrationDiagnostics de cache (bêta)Comptage de tokens
Travailler avec des fichiers
API FilesPrise en charge des PDFImages et vision
Compétences
AperçuDémarrage rapideBonnes pratiquesCompétences pour l'entrepriseCompétences dans l'API
MCP
Serveurs MCP distantsConnecteur MCP
Claude sur les plateformes cloud
Amazon BedrockAmazon Bedrock (ancienne version)Claude Platform sur AWSMicrosoft FoundryVertex AI
Log in
Raisons d'arrêt et repli
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...

Solutions

  • AI agents
  • Code modernization
  • Coding
  • Customer support
  • Education
  • Financial services
  • Government
  • Life sciences

Partners

  • Amazon Bedrock
  • Google Cloud's Vertex AI

Learn

  • Blog
  • Courses
  • Use cases
  • Connectors
  • Customer stories
  • Engineering at Anthropic
  • Events
  • Powered by Claude
  • Service partners
  • Startups program

Company

  • Anthropic
  • Careers
  • Economic Futures
  • Research
  • News
  • Responsible Scaling Policy
  • Security and compliance
  • Transparency

Learn

  • Blog
  • Courses
  • Use cases
  • Connectors
  • Customer stories
  • Engineering at Anthropic
  • Events
  • Powered by Claude
  • Service partners
  • Startups program

Help and security

  • Availability
  • Status
  • Support
  • Discord

Terms and policies

  • Privacy policy
  • Responsible disclosure policy
  • Terms of service: Commercial
  • Terms of service: Consumer
  • Usage policy
Messages/Développer avec Claude

Raisons d'arrêt et repli

Le champ stop_reason, la signification de chaque valeur, et où gérer les refus et le repli.

Lorsque vous effectuez une requête à l'API Messages, la réponse de Claude inclut un champ stop_reason qui indique pourquoi le modèle a arrêté de générer sa réponse. Comprendre ces valeurs est essentiel pour créer des applications robustes qui gèrent correctement les différents types de réponses.

Pour plus de détails sur stop_reason dans la réponse de l'API, consultez la référence de l'API Messages.

Le champ stop_reason

Le champ stop_reason fait partie de chaque réponse réussie de l'API Messages. Contrairement aux erreurs, qui indiquent des échecs dans le traitement de votre requête, stop_reason vous indique pourquoi Claude a terminé la génération de sa réponse.

Example response
{
  "id": "msg_01234",
  "type": "message",
  "role": "assistant",
  "content": [
    {
      "type": "text",
      "text": "Here's the answer to your question..."
    }
  ],
  "stop_reason": "end_turn",
  "stop_sequence": null,
  "usage": {
    "input_tokens": 100,
    "output_tokens": 50
  }
}

Valeurs de stop_reason

end_turn

La raison d'arrêt la plus courante. Indique que Claude a terminé sa réponse naturellement.

Python
from anthropic import Anthropic

client = Anthropic()
response = client.messages.create(
    model="claude-sonnet-4-20250514",
    max_tokens=1024,
    messages=[{"role": "user", "content": "Hello!"}],
)
if response.stop_reason == "end_turn":
    # Traiter la réponse complète
    print(response.content[0].text)

Réponses vides avec end_turn

Parfois, Claude renvoie une réponse vide (exactement 2 à 3 tokens sans contenu) avec stop_reason: "end_turn". Cela se produit généralement lorsque Claude interprète que le tour de l'assistant est terminé, en particulier après des résultats d'outils.

Causes courantes :

  • Ajout de blocs de texte immédiatement après les résultats d'outils (Claude apprend à s'attendre à ce que l'utilisateur insère toujours du texte après les résultats d'outils, il termine donc son tour pour suivre ce schéma)
  • Renvoi de la réponse terminée de Claude sans rien ajouter (Claude a déjà décidé qu'il avait terminé, il restera donc dans cet état)

Comment éviter les réponses vides :

# INCORRECT : Ajout de texte immédiatement après tool_result
messages = [
    {"role": "user", "content": "Calculate the sum of 1234 and 5678"},
    {
        "role": "assistant",
        "content": [
            {
                "type": "tool_use",
                "id": "toolu_123",
                "name": "calculator",
                "input": {"operation": "add", "a": 1234, "b": 5678},
            }
        ],
    },
    {
        "role": "user",
        "content": [
            {"type": "tool_result", "tool_use_id": "toolu_123", "content": "6912"},
            {
                "type": "text",
                "text": "Here's the result",  # Don't add text after tool_result
            },
        ],
    },
]

# CORRECT : Envoyez les résultats d'outils directement sans texte supplémentaire
messages = [
    {"role": "user", "content": "Calculate the sum of 1234 and 5678"},
    {
        "role": "assistant",
        "content": [
            {
                "type": "tool_use",
                "id": "toolu_123",
                "name": "calculator",
                "input": {"operation": "add", "a": 1234, "b": 5678},
            }
        ],
    },
    {
        "role": "user",
        "content": [
            {"type": "tool_result", "tool_use_id": "toolu_123", "content": "6912"}
        ],
    },  # Just the tool_result, no additional text
]


# Si vous obtenez toujours des réponses vides après avoir corrigé la structure des messages :
def handle_empty_response(client, messages):
    response = client.messages.create(
        model="claude-opus-4-8", max_tokens=1024, messages=messages
    )

    # Vérifiez si la réponse est vide
    if response.stop_reason == "end_turn" and not response.content:
        # INCORRECT : Ne réessayez pas simplement avec la réponse vide
        # Cela ne fonctionnera pas car Claude a déjà décidé qu'il avait terminé

        # CORRECT : Ajoutez un prompt de continuation dans un NOUVEAU message utilisateur
        messages.append({"role": "user", "content": "Please continue"})

        response = client.messages.create(
            model="claude-opus-4-8", max_tokens=1024, messages=messages
        )

    return response

Bonnes pratiques :

  1. N'ajoutez jamais de blocs de texte immédiatement après les résultats d'outils - Cela apprend à Claude à attendre une entrée utilisateur après chaque utilisation d'outils
  2. Ne réessayez pas les réponses vides sans modification - Renvoyer simplement la réponse vide n'aidera pas
  3. Utilisez les prompts de continuation en dernier recours - Uniquement si ces correctifs ne résolvent pas le problème

max_tokens

Claude s'est arrêté parce qu'il a atteint la limite max_tokens spécifiée dans votre requête.

Python
# Requête avec un nombre limité de tokens
response = client.messages.create(
    model="claude-opus-4-8",
    max_tokens=10,
    messages=[{"role": "user", "content": "Explain quantum physics"}],
)

if response.stop_reason == "max_tokens":
    # La réponse a été tronquée
    print("Response was cut off at token limit")
    # Envisagez d'effectuer une autre requête pour continuer

Blocs d'utilisation d'outils incomplets

Si la réponse de Claude est tronquée parce qu'elle a atteint la limite max_tokens, et que la réponse tronquée contient un bloc d'utilisation d'outils incomplet, vous devrez réessayer la requête avec une valeur max_tokens plus élevée pour obtenir l'utilisation d'outils complète.

# Vérifier si la réponse a été tronquée pendant l'utilisation d'outils
if response.stop_reason == "max_tokens":
    # Vérifier si le dernier bloc de contenu est un tool_use incomplet
    last_block = response.content[-1]
    if last_block.type == "tool_use":
        # Envoyer la requête avec un max_tokens plus élevé
        response = client.messages.create(
            model="claude-opus-4-8",
            max_tokens=4096,  # Increased limit
            messages=messages,
            tools=tools,
        )

stop_sequence

Claude a rencontré l'une de vos séquences d'arrêt personnalisées.

Python
response = client.messages.create(
    model="claude-opus-4-8",
    max_tokens=1024,
    stop_sequences=["END", "STOP"],
    messages=[{"role": "user", "content": "Generate text until you say END"}],
)

if response.stop_reason == "stop_sequence":
    print(f"Stopped at sequence: {response.stop_sequence}")

tool_use

Claude appelle un outil et s'attend à ce que vous l'exécutiez.

Pour la plupart des implémentations d'utilisation d'outils, utilisez le tool runner, qui gère automatiquement l'exécution des outils, le formatage des résultats et la gestion de la conversation.

Python
from anthropic import Anthropic

client = Anthropic()
weather_tool = {
    "name": "get_weather",
    "description": "Get the current weather in a given location",
    "input_schema": {
        "type": "object",
        "properties": {
            "location": {"type": "string", "description": "City and state"},
        },
        "required": ["location"],
    },
}


def execute_tool(name, tool_input):
    """Execute a tool and return the result."""
    return f"Weather in {tool_input.get('location', 'unknown')}: 72°F"


response = client.messages.create(
    model="claude-sonnet-4-20250514",
    max_tokens=1024,
    tools=[weather_tool],
    messages=[{"role": "user", "content": "What's the weather?"}],
)

if response.stop_reason == "tool_use":
    # Extraire et exécuter l'outil
    for content in response.content:
        if content.type == "tool_use":
            result = execute_tool(content.name, content.input)
            # Renvoyer le résultat à Claude pour la réponse finale

pause_turn

Renvoyé lorsque la boucle d'échantillonnage côté serveur atteint sa limite d'itérations lors de l'exécution d'outils serveur comme la recherche web ou la récupération web. La limite par défaut est de 10 itérations par requête.

Lorsque cela se produit, la réponse peut contenir un bloc server_tool_use sans server_tool_result correspondant. Pour permettre à Claude de terminer le traitement, poursuivez la conversation en renvoyant la réponse telle quelle.

Python
response = client.messages.create(
    model="claude-opus-4-8",
    max_tokens=1024,
    tools=[{"type": "web_search_20250305", "name": "web_search"}],
    messages=[{"role": "user", "content": "Search for latest AI news"}],
)

if response.stop_reason == "pause_turn":
    # Poursuivez la conversation en renvoyant la réponse
    messages = [
        {"role": "user", "content": original_query},
        {"role": "assistant", "content": response.content},
    ]
    continuation = client.messages.create(
        model="claude-opus-4-8",
        max_tokens=1024,
        messages=messages,
        tools=[{"type": "web_search_20250305", "name": "web_search"}],
    )

Votre application doit gérer pause_turn dans toute boucle d'agent qui utilise des outils serveur. Ajoutez simplement la réponse de l'assistant à votre tableau de messages et effectuez une autre requête API pour permettre à Claude de continuer.

refusal

Claude a refusé de générer une réponse. Sur Claude Fable 5, les classificateurs de sécurité renvoient cette raison d'arrêt sous forme de réponse HTTP 200 normale, et non d'erreur.

Python
response = client.messages.create(
    model="claude-opus-4-8",
    max_tokens=1024,
    messages=[{"role": "user", "content": "[Unsafe request]"}],
)

if response.stop_reason == "refusal":
    # Claude a refusé de répondre
    print("Claude was unable to process this request")
    # Envisagez de reformuler ou de modifier la requête

Si vous rencontrez fréquemment des raisons d'arrêt refusal lors de l'utilisation de Claude Sonnet 4.5 ou Opus 4.1 (déprécié), vous pouvez essayer de mettre à jour vos appels API pour utiliser Haiku 4.5 (claude-haiku-4-5-20251001), qui a des restrictions d'utilisation différentes. En savoir plus sur la compréhension des filtres de sécurité de l'API de Sonnet 4.5.

Lors d'un refus, l'objet stop_details identifie la catégorie de politique qui l'a déclenché. Les catégories et la structure complète de la réponse de refus sont décrites dans Refus et repli. stop_details est null pour toutes les raisons d'arrêt autres que refusal.

Une requête refusée sur Claude Fable 5 peut généralement être traitée en réessayant sur un autre modèle Claude, et Refus et repli montre comment configurer cette nouvelle tentative, côté serveur ou dans votre client. Crédit de repli explique comment éviter de payer deux fois le coût du cache de prompt lorsque vous implémentez vous-même la nouvelle tentative.

model_context_window_exceeded

Claude s'est arrêté parce qu'il a atteint la limite de la fenêtre de contexte du modèle. Cela vous permet de demander le maximum de tokens possible sans connaître la taille exacte de l'entrée.

Python
# Requête avec le maximum de tokens pour obtenir autant que possible
response = client.messages.create(
    model="claude-opus-4-8",
    max_tokens=20000,  # Python SDK requires streaming for max_tokens above ~21k (Opus 4.8 supports 128k with streaming)
    messages=[
        {"role": "user", "content": "Large input that uses most of context window..."}
    ],
)

if response.stop_reason == "model_context_window_exceeded":
    # La réponse a atteint la limite de la fenêtre de contexte avant max_tokens
    print("Response reached model's context window limit")
    # La réponse reste valide mais a été limitée par la fenêtre de contexte

Cette raison d'arrêt est disponible par défaut dans Sonnet 4.5 et les modèles plus récents. Pour les modèles antérieurs, utilisez l'en-tête bêta model-context-window-exceeded-2025-08-26 pour activer ce comportement.

Bonnes pratiques pour gérer les raisons d'arrêt

1. Vérifiez toujours stop_reason

Prenez l'habitude de vérifier le stop_reason dans votre logique de traitement des réponses :

def handle_response(response):
    if response.stop_reason == "tool_use":
        return handle_tool_use(response)
    elif response.stop_reason == "max_tokens":
        return handle_truncation(response)
    elif response.stop_reason == "model_context_window_exceeded":
        return handle_context_limit(response)
    elif response.stop_reason == "pause_turn":
        return handle_pause(response)
    elif response.stop_reason == "refusal":
        return handle_refusal(response)
    else:
        # Gérer end_turn et les autres cas
        return response.content[0].text

2. Gérez les réponses tronquées avec élégance

Lorsqu'une réponse est tronquée en raison des limites de tokens ou de la fenêtre de contexte :

def handle_truncated_response(response):
    if response.stop_reason in ["max_tokens", "model_context_window_exceeded"]:
        # Option 1 : Avertir l'utilisateur de la limite spécifique
        if response.stop_reason == "max_tokens":
            message = "[Response truncated due to max_tokens limit]"
        else:
            message = "[Response truncated due to context window limit]"
        return f"{response.content[0].text}\n\n{message}"

        # Option 2 : Poursuivre la génération
        messages = [
            {"role": "user", "content": original_prompt},
            {"role": "assistant", "content": response.content[0].text},
        ]
        continuation = client.messages.create(
            model="claude-opus-4-8",
            max_tokens=1024,
            messages=messages + [{"role": "user", "content": "Please continue"}],
        )
        return response.content[0].text + continuation.content[0].text

3. Implémentez une logique de nouvelle tentative pour pause_turn

Lors de l'utilisation d'outils serveur, l'API peut renvoyer pause_turn si la boucle d'échantillonnage côté serveur atteint sa limite d'itérations (10 par défaut). Gérez cela en poursuivant la conversation :

def handle_server_tool_conversation(client, user_query, tools, max_continuations=5):
    """
    Handle server tool conversations that may require multiple continuations.

    The server runs a sampling loop when executing server tools. If the loop
    reaches its iteration limit, the API returns pause_turn. Continue the
    conversation by sending the response back to let Claude finish.
    """
    messages = [{"role": "user", "content": user_query}]

    for _ in range(max_continuations):
        response = client.messages.create(
            model="claude-opus-4-8", max_tokens=1024, messages=messages, tools=tools
        )

        if response.stop_reason != "pause_turn":
            # Claude a terminé le traitement - renvoyer la réponse finale
            return response

        # pause_turn : remplacer la liste complète des messages pour maintenir l'alternance des rôles
        messages = [
            {"role": "user", "content": user_query},
            {"role": "assistant", "content": response.content},
        ]

    # Nombre maximal de continuations atteint - renvoyer la dernière réponse
    return response

Raisons d'arrêt vs erreurs

Il est important de distinguer les valeurs de stop_reason des erreurs réelles :

Raisons d'arrêt (réponses réussies)

  • Font partie du corps de la réponse
  • Indiquent pourquoi la génération s'est arrêtée normalement
  • La réponse contient du contenu valide

Erreurs (requêtes échouées)

  • Codes de statut HTTP 4xx ou 5xx
  • Indiquent des échecs de traitement de la requête
  • La réponse contient les détails de l'erreur
Python
import anthropic
from anthropic import Anthropic

client = Anthropic()

try:
    response = client.messages.create(
        model="claude-sonnet-4-20250514",
        max_tokens=1024,
        messages=[{"role": "user", "content": "Hello!"}],
    )

    # Gérer la réponse réussie avec stop_reason
    if response.stop_reason == "max_tokens":
        print("Response was truncated")

except anthropic.APIStatusError as e:
    # Gérer les erreurs réelles
    if e.status_code == 429:
        print("Rate limit exceeded")
    elif e.status_code == 500:
        print("Server error")

Considérations relatives au streaming

Lors de l'utilisation du streaming, stop_reason est :

  • null dans l'événement initial message_start
  • Fourni dans l'événement message_delta
  • Non fourni dans les autres événements
Python
from anthropic import Anthropic

client = Anthropic()

with client.messages.stream(
    model="claude-sonnet-4-20250514",
    max_tokens=1024,
    messages=[{"role": "user", "content": "Hello!"}],
) as stream:
    for event in stream:
        if event.type == "message_delta":
            stop_reason = event.delta.stop_reason
            if stop_reason:
                print(f"Stream ended with: {stop_reason}")

Schémas courants

Gestion des flux d'utilisation d'outils

Plus simple avec le tool runner : L'exemple suivant montre la gestion manuelle des outils. Pour la plupart des cas d'usage, le tool runner gère automatiquement l'exécution des outils avec beaucoup moins de code.

def complete_tool_workflow(client, user_query, tools):
    messages = [{"role": "user", "content": user_query}]

    while True:
        response = client.messages.create(
            model="claude-opus-4-8", max_tokens=1024, messages=messages, tools=tools
        )

        if response.stop_reason == "tool_use":
            # Exécuter les outils et continuer
            tool_results = execute_tools(response.content)
            messages.append({"role": "assistant", "content": response.content})
            messages.append({"role": "user", "content": tool_results})
        else:
            # Réponse finale
            return response

Garantir des réponses complètes

def get_complete_response(client, prompt, max_attempts=3):
    messages = [{"role": "user", "content": prompt}]
    full_response = ""

    for _ in range(max_attempts):
        response = client.messages.create(
            model="claude-opus-4-8", messages=messages, max_tokens=4096
        )

        full_response += response.content[0].text

        if response.stop_reason != "max_tokens":
            break

        # Continuer là où il s'est arrêté
        messages = [
            {"role": "user", "content": prompt},
            {"role": "assistant", "content": full_response},
            {"role": "user", "content": "Please continue from where you left off."},
        ]

    return full_response

Obtenir le maximum de tokens sans connaître la taille de l'entrée

Avec la raison d'arrêt model_context_window_exceeded, vous pouvez demander le maximum de tokens possible sans calculer la taille de l'entrée :

def get_max_possible_tokens(client, prompt):
    """
    Get as many tokens as possible within the model's context window
    without needing to calculate input token count
    """
    response = client.messages.create(
        model="claude-opus-4-8",
        messages=[{"role": "user", "content": prompt}],
        max_tokens=20000,  # Python SDK requires streaming for max_tokens above ~21k
    )

    if response.stop_reason == "model_context_window_exceeded":
        # Nombre maximal de tokens possible obtenu compte tenu de la taille de l'entrée
        print(
            f"Generated {response.usage.output_tokens} tokens (context limit reached)"
        )
    elif response.stop_reason == "max_tokens":
        # Nombre exact de tokens demandés obtenu
        print(f"Generated {response.usage.output_tokens} tokens (max_tokens reached)")
    else:
        # Complétion naturelle
        print(f"Generated {response.usage.output_tokens} tokens (natural completion)")

    return response.content[0].text

En gérant correctement les valeurs de stop_reason, vous pouvez créer des applications plus robustes qui gèrent avec élégance différents scénarios de réponse et offrent de meilleures expériences utilisateur.

Was this page helpful?

  • Le champ stop_reason
  • Valeurs de stop_reason
  • end_turn
  • max_tokens
  • stop_sequence
  • tool_use
  • pause_turn
  • refusal
  • model_context_window_exceeded
  • Bonnes pratiques pour gérer les raisons d'arrêt
  • 1. Vérifiez toujours stop_reason
  • 2. Gérez les réponses tronquées avec élégance
  • 3. Implémentez une logique de nouvelle tentative pour pause_turn
  • Raisons d'arrêt vs erreurs
  • Raisons d'arrêt (réponses réussies)
  • Erreurs (requêtes échouées)
  • Considérations relatives au streaming
  • Schémas courants
  • Gestion des flux d'utilisation d'outils
  • Garantir des réponses complètes
  • Obtenir le maximum de tokens sans connaître la taille de l'entrée