Loading...
  • Construire
  • Admin
  • Modèles & tarification
  • SDKs clients
  • Référence API
Search...
⌘K
Log in
Gérer les raisons d'arrêt
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
Construire/Construire avec Claude

Gérer les raisons d'arrêt

Comprendre et gérer les valeurs stop_reason dans les réponses de l'API Messages pour construire des applications robustes.

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 crucial pour construire des applications robustes qui gèrent différents types de réponses de manière appropriée.

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 défaillances dans le traitement de votre requête, stop_reason vous indique pourquoi Claude a réussi à terminer la génération de sa réponse.

Exemple de réponse
{
  "id": "msg_01234",
  "type": "message",
  "role": "assistant",
  "content": [
    {
      "type": "text",
      "text": "Voici la réponse à votre 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 retourne 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é, particulièrement après les résultats d'outils.

Causes courantes :

  • Ajouter des 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, donc il termine son tour pour suivre le modèle)
  • Renvoyer la réponse complétée de Claude sans rien ajouter (Claude a déjà décidé que c'était fini, donc il restera fini)

Comment prévenir les réponses vides :

# INCORRECT: Ajouter du texte immédiatement après tool_result
messages = [
    {"role": "user", "content": "Calculez la somme de 1234 et 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": "Voici le résultat",  # N'ajoutez pas de texte après tool_result
            },
        ],
    },
]

# CORRECT: Envoyer les résultats d'outils directement sans texte supplémentaire
messages = [
    {"role": "user", "content": "Calculez la somme de 1234 et 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"}
        ],
    },  # Juste le tool_result, pas de texte supplémentaire
]


# Si vous obtenez toujours des réponses vides après avoir corrigé ce qui précède :
def handle_empty_response(client, messages):
    response = client.messages.create(
        model="claude-opus-4-7", max_tokens=1024, messages=messages
    )

    # Vérifier 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é que c'était fini

        # CORRECT: Ajouter une invite de continuation dans un NOUVEAU message utilisateur
        messages.append({"role": "user", "content": "Veuillez continuer"})

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

    return response

Meilleures pratiques :

  1. Ne jamais ajouter de blocs de texte immédiatement après les résultats d'outils - Cela apprend à Claude à s'attendre à une entrée utilisateur après chaque utilisation d'outil
  2. Ne pas réessayer les réponses vides sans modification - Renvoyer simplement la réponse vide ne servira à rien
  3. Utiliser les invites de continuation en dernier recours - Seulement si les corrections ci-dessus ne résolvent pas le problème

max_tokens

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

Python
# Requête avec tokens limités
response = client.messages.create(
    model="claude-opus-4-7",
    max_tokens=10,
    messages=[{"role": "user", "content": "Expliquez la physique quantique"}],
)

if response.stop_reason == "max_tokens":
    # La réponse a été tronquée
    print("La réponse a été coupée à la limite de tokens")
    # Envisagez de faire une autre requête pour continuer

Blocs d'utilisation d'outils incomplets

Si la réponse de Claude est coupée en raison du dépassement de la limite max_tokens, et que la réponse tronquée contient un bloc d'utilisation d'outil incomplet, vous devrez réessayer la requête avec une valeur max_tokens plus élevée pour obtenir l'utilisation d'outil complète.

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-7",
    max_tokens=1024,
    stop_sequences=["END", "STOP"],
    messages=[{"role": "user", "content": "Générez du texte jusqu'à ce que vous disiez END"}],
)

if response.stop_reason == "stop_sequence":
    print(f"Arrêté à la séquence : {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, nous recommandons d'utiliser 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": "Obtenir la météo actuelle dans un lieu donné",
    "input_schema": {
        "type": "object",
        "properties": {
            "location": {"type": "string", "description": "Ville et état"},
        },
        "required": ["location"],
    },
}


def execute_tool(name, tool_input):
    """Exécuter un outil et retourner le résultat."""
    return f"Météo à {tool_input.get('location', 'inconnu')} : 72°F"


response = client.messages.create(
    model="claude-sonnet-4-20250514",
    max_tokens=1024,
    tools=[weather_tool],
    messages=[{"role": "user", "content": "Quelle est la météo ?"}],
)

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)
            # Retourner le résultat à Claude pour la réponse finale

pause_turn

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

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

Python
response = client.messages.create(
    model="claude-opus-4-7",
    max_tokens=1024,
    tools=[{"type": "web_search_20250305", "name": "web_search"}],
    messages=[{"role": "user", "content": "Recherchez les dernières actualités sur l'IA"}],
)

if response.stop_reason == "pause_turn":
    # Continuer 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-7",
        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 laisser Claude continuer.

refusal

Claude a refusé de générer une réponse en raison de préoccupations de sécurité.

Python
response = client.messages.create(
    model="claude-opus-4-7",
    max_tokens=1024,
    messages=[{"role": "user", "content": "[Requête non sécurisée]"}],
)

if response.stop_reason == "refusal":
    # Claude a refusé de répondre
    print("Claude n'a pas pu traiter cette requête")
    # 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, 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é API de Sonnet 4.5.

Pour en savoir plus sur les refus déclenchés par les filtres de sécurité API pour Claude Sonnet 4.5, consultez Comprendre les filtres de sécurité API de Sonnet 4.5.

model_context_window_exceeded

Claude s'est arrêté car 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 tokens maximum pour obtenir autant que possible
response = client.messages.create(
    model="claude-opus-4-7",
    max_tokens=64000,  # Plafond pratique sans streaming (Opus 4.7 supporte 128K avec streaming)
    messages=[
        {"role": "user", "content": "Grande entrée qui utilise la plupart de la fenêtre de contexte..."}
    ],
)

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("La réponse a atteint la limite de la fenêtre de contexte du modèle")
    # La réponse est toujours 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.

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

1. Toujours vérifier stop_reason

Prenez l'habitude de vérifier le stop_reason dans votre logique de gestion 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 autres cas
        return response.content[0].text

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

Lorsqu'une réponse est tronquée en raison de limites de tokens ou de 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 = "[Réponse tronquée en raison de la limite max_tokens]"
        else:
            message = "[Réponse tronquée en raison de la limite de la fenêtre de contexte]"
        return f"{response.content[0].text}\n\n{message}"

        # Option 2 : Continuer 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-7",
            max_tokens=1024,
            messages=messages + [{"role": "user", "content": "Veuillez continuer"}],
        )
        return response.content[0].text + continuation.content[0].text

3. Implémenter la logique de réessai pour pause_turn

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

def handle_server_tool_conversation(client, user_query, tools, max_continuations=5):
    """
    Gérer les conversations avec outils serveur qui peuvent nécessiter plusieurs continuations.

    Le serveur exécute une boucle d'échantillonnage lors de l'exécution des outils serveur.
    Si la boucle atteint sa limite d'itération, l'API retourne pause_turn. Continuez la
    conversation en renvoyant la réponse pour laisser Claude terminer.
    """
    messages = [{"role": "user", "content": user_query}]

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

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

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

    # Atteint le nombre maximum de continuations - retourner la dernière réponse
    return response

Raisons d'arrêt vs. erreurs

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

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

  • 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 défaillances dans le traitement des requêtes
  • 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("La réponse a été tronquée")

except anthropic.APIError as e:
    # Gérer les erreurs réelles
    if e.status_code == 429:
        print("Limite de débit dépassée")
    elif e.status_code == 500:
        print("Erreur serveur")

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 aucun autre événement
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"Le flux s'est terminé avec : {stop_reason}")

Modèles courants

Gestion des flux de travail d'utilisation d'outils

Plus simple avec tool runner : L'exemple ci-dessous montre la gestion manuelle des outils. Pour la plupart des cas d'utilisation, 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-7", 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

Assurer les 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-7", messages=messages, max_tokens=4096
        )

        full_response += response.content[0].text

        if response.stop_reason != "max_tokens":
            break

        # Continuer à partir de là où c'était arrêté
        messages = [
            {"role": "user", "content": prompt},
            {"role": "assistant", "content": full_response},
            {"role": "user", "content": "Veuillez continuer à partir de là où vous vous étiez arrêté."},
        ]

    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 le nombre de tokens d'entrée :

def get_max_possible_tokens(client, prompt):
    """
    Obtenir autant de tokens que possible dans la fenêtre de contexte du modèle
    sans avoir besoin de calculer le nombre de tokens d'entrée
    """
    response = client.messages.create(
        model="claude-opus-4-7",
        messages=[{"role": "user", "content": prompt}],
        max_tokens=64000,  # Plafond pratique sans streaming (Opus 4.7 supporte 128K avec streaming)
    )

    if response.stop_reason == "model_context_window_exceeded":
        # Obtenu le maximum de tokens possible compte tenu de la taille de l'entrée
        print(
            f"Généré {response.usage.output_tokens} tokens (limite de contexte atteinte)"
        )
    elif response.stop_reason == "max_tokens":
        # Obtenu exactement les tokens demandés
        print(f"Généré {response.usage.output_tokens} tokens (max_tokens atteint)")
    else:
        # Achèvement naturel
        print(f"Généré {response.usage.output_tokens} tokens (achèvement naturel)")

    return response.content[0].text

En gérant correctement les valeurs stop_reason, vous pouvez construire des applications plus robustes qui gèrent élégamment 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
  • Meilleures pratiques pour gérer les raisons d'arrêt
  • 1. Toujours vérifier stop_reason
  • 2. Gérer les réponses tronquées avec élégance
  • 3. Implémenter la logique de réessai 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
  • Modèles courants
  • Gestion des flux de travail d'utilisation d'outils
  • Assurer les réponses complètes
  • Obtenir le maximum de tokens sans connaître la taille de l'entrée
# Vérifier si la réponse a été tronquée lors de l'utilisation d'outil
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-7",
            max_tokens=4096,  # Limite augmentée
            messages=messages,
            tools=tools,
        )