Loading...
  • Costruisci
  • Amministrazione
  • Modelli e prezzi
  • Client SDK
  • Riferimento API
Search...
⌘K
Log in
Gestione dei motivi di stop
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
Costruisci/Costruire con Claude

Gestione dei motivi di arresto

Comprendi i valori di stop_reason nell'API Messages e come gestire diversi tipi di risposta di Claude.

Was this page helpful?

  • Il campo stop_reason
  • Valori di stop_reason
  • end_turn
  • max_tokens
  • stop_sequence
  • tool_use
  • pause_turn
  • refusal
  • model_context_window_exceeded
  • Best practices per la gestione dei motivi di arresto
  • 1. Controlla sempre stop_reason
  • 2. Gestisci le risposte troncate con eleganza
  • 3. Implementa la logica di ripetizione per pause_turn
  • Motivi di arresto vs. errori
  • Motivi di arresto (risposte riuscite)
  • Errori (richieste non riuscite)
  • Considerazioni sullo streaming
  • Modelli comuni
  • Gestione dei flussi di lavoro di utilizzo degli strumenti
  • Garantire risposte complete
  • Ottenere il massimo di token senza conoscere la dimensione dell'input

Quando effettui una richiesta all'API Messages, la risposta di Claude include un campo stop_reason che indica il motivo per cui il modello ha smesso di generare la sua risposta. Comprendere questi valori è cruciale per costruire applicazioni robuste che gestiscono diversi tipi di risposta in modo appropriato.

Per dettagli su stop_reason nella risposta dell'API, consulta il riferimento dell'API Messages.

Il campo stop_reason

Il campo stop_reason fa parte di ogni risposta riuscita dell'API Messages. A differenza degli errori, che indicano fallimenti nell'elaborazione della tua richiesta, stop_reason ti dice il motivo per cui Claude ha completato con successo la generazione della sua risposta.

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
  }
}

Valori di stop_reason

end_turn

Il motivo di arresto più comune. Indica che Claude ha completato la sua risposta naturalmente.

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":
    # Process the complete response
    print(response.content[0].text)

Risposte vuote con end_turn

A volte Claude restituisce una risposta vuota (esattamente 2-3 token senza contenuto) con stop_reason: "end_turn". Questo accade tipicamente quando Claude interpreta che il turno dell'assistente è completo, in particolare dopo i risultati degli strumenti.

Cause comuni:

  • Aggiungere blocchi di testo immediatamente dopo i risultati degli strumenti (Claude impara ad aspettarsi che l'utente inserisca sempre testo dopo i risultati degli strumenti, quindi termina il suo turno per seguire il modello)
  • Inviare la risposta completata di Claude indietro senza aggiungere nulla (Claude ha già deciso che è fatto, quindi rimarrà fatto)

Come prevenire risposte vuote:

# INCORRECT: Adding text immediately after 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: Send tool results directly without additional text
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
]


# If you still get empty responses after fixing the above:
def handle_empty_response(client, messages):
    response = client.messages.create(
        model="claude-opus-4-7", max_tokens=1024, messages=messages
    )

    # Check if response is empty
    if response.stop_reason == "end_turn" and not response.content:
        # INCORRECT: Don't just retry with the empty response
        # This won't work because Claude already decided it's done

        # CORRECT: Add a continuation prompt in a NEW user message
        messages.append({"role": "user", "content": "Please continue"})

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

    return response

Best practices:

  1. Non aggiungere mai blocchi di testo immediatamente dopo i risultati degli strumenti - Questo insegna a Claude ad aspettarsi input dell'utente dopo ogni utilizzo di strumenti
  2. Non riprovare risposte vuote senza modifiche - Semplicemente inviare la risposta vuota indietro non aiuterà
  3. Usa prompt di continuazione come ultima risorsa - Solo se le correzioni precedenti non risolvono il problema

max_tokens

Claude si è fermato perché ha raggiunto il limite max_tokens specificato nella tua richiesta.

Python
# Request with limited tokens
response = client.messages.create(
    model="claude-opus-4-7",
    max_tokens=10,
    messages=[{"role": "user", "content": "Explain quantum physics"}],
)

if response.stop_reason == "max_tokens":
    # Response was truncated
    print("Response was cut off at token limit")
    # Consider making another request to continue

Blocchi di utilizzo degli strumenti incompleti

Se la risposta di Claude viene interrotta a causa del raggiungimento del limite max_tokens e la risposta troncata contiene un blocco di utilizzo dello strumento incompleto, dovrai riprovare la richiesta con un valore max_tokens più alto per ottenere l'utilizzo dello strumento completo.

stop_sequence

Claude ha incontrato una delle tue sequenze di arresto personalizzate.

Python
response = client.messages.create(
    model="claude-opus-4-7",
    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 sta chiamando uno strumento e si aspetta che tu lo esegua.

Per la maggior parte delle implementazioni di utilizzo degli strumenti, consigliamo di utilizzare il tool runner che gestisce automaticamente l'esecuzione degli strumenti, la formattazione dei risultati e la gestione della conversazione.

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":
    # Extract and execute the tool
    for content in response.content:
        if content.type == "tool_use":
            result = execute_tool(content.name, content.input)
            # Return result to Claude for final response

pause_turn

Restituito quando il ciclo di campionamento lato server raggiunge il suo limite di iterazione durante l'esecuzione di strumenti server come la ricerca web o il recupero web. Il limite predefinito è 10 iterazioni per richiesta.

Quando ciò accade, la risposta può contenere un blocco server_tool_use senza un corrispondente server_tool_result. Per permettere a Claude di completare l'elaborazione, continua la conversazione inviando la risposta così com'è.

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": "Search for latest AI news"}],
)

if response.stop_reason == "pause_turn":
    # Continue the conversation by sending the response back
    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"}],
    )

La tua applicazione dovrebbe gestire pause_turn in qualsiasi ciclo di agente che utilizza strumenti server. Semplicemente aggiungi la risposta dell'assistente al tuo array di messaggi e effettua un'altra richiesta API per permettere a Claude di continuare.

refusal

Claude ha rifiutato di generare una risposta a causa di problemi di sicurezza.

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

if response.stop_reason == "refusal":
    # Claude declined to respond
    print("Claude was unable to process this request")
    # Consider rephrasing or modifying the request

Se incontri frequentemente motivi di arresto refusal mentre utilizzi Claude Sonnet 4.5 o Opus 4.1, puoi provare ad aggiornare le tue chiamate API per utilizzare Haiku 4.5 (claude-haiku-4-5-20251001), che ha restrizioni di utilizzo diverse. Scopri di più su come comprendere i filtri di sicurezza dell'API di Sonnet 4.5.

Per ulteriori informazioni sui rifiuti attivati dai filtri di sicurezza dell'API per Claude Sonnet 4.5, consulta Comprensione dei filtri di sicurezza dell'API di Sonnet 4.5.

model_context_window_exceeded

Claude si è fermato perché ha raggiunto il limite della finestra di contesto del modello. Questo ti permette di richiedere il massimo numero di token possibile senza conoscere la dimensione esatta dell'input.

Python
# Request with maximum tokens to get as much as possible
response = client.messages.create(
    model="claude-opus-4-7",
    max_tokens=64000,  # Practical non-streaming ceiling (Opus 4.7 supports 128K with streaming)
    messages=[
        {"role": "user", "content": "Large input that uses most of context window..."}
    ],
)

if response.stop_reason == "model_context_window_exceeded":
    # Response hit context window limit before max_tokens
    print("Response reached model's context window limit")
    # The response is still valid but was limited by context window

Questo motivo di arresto è disponibile per impostazione predefinita in Sonnet 4.5 e nei modelli più recenti. Per i modelli precedenti, utilizza l'intestazione beta model-context-window-exceeded-2025-08-26 per abilitare questo comportamento.

Best practices per la gestione dei motivi di arresto

1. Controlla sempre stop_reason

Abituati a controllare stop_reason nella tua logica di gestione della risposta:

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:
        # Handle end_turn and other cases
        return response.content[0].text

2. Gestisci le risposte troncate con eleganza

Quando una risposta viene troncata a causa di limiti di token o finestra di contesto:

def handle_truncated_response(response):
    if response.stop_reason in ["max_tokens", "model_context_window_exceeded"]:
        # Option 1: Warn the user about the specific limit
        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: Continue generation
        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": "Please continue"}],
        )
        return response.content[0].text + continuation.content[0].text

3. Implementa la logica di ripetizione per pause_turn

Quando si utilizzano strumenti server, l'API può restituire pause_turn se il ciclo di campionamento lato server raggiunge il suo limite di iterazione (predefinito 10). Gestisci questo continuando la conversazione:

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-7", messages=messages, tools=tools
        )

        if response.stop_reason != "pause_turn":
            # Claude finished processing - return the final response
            return response

        # pause_turn: replace the full message list to maintain alternating roles
        messages = [
            {"role": "user", "content": user_query},
            {"role": "assistant", "content": response.content},
        ]

    # Reached max continuations - return the last response
    return response

Motivi di arresto vs. errori

È importante distinguere tra i valori di stop_reason e gli errori effettivi:

Motivi di arresto (risposte riuscite)

  • Parte del corpo della risposta
  • Indicano il motivo per cui la generazione si è fermata normalmente
  • La risposta contiene contenuto valido

Errori (richieste non riuscite)

  • Codici di stato HTTP 4xx o 5xx
  • Indicano fallimenti nell'elaborazione della richiesta
  • La risposta contiene dettagli dell'errore
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!"}],
    )

    # Handle successful response with stop_reason
    if response.stop_reason == "max_tokens":
        print("Response was truncated")

except anthropic.APIError as e:
    # Handle actual errors
    if e.status_code == 429:
        print("Rate limit exceeded")
    elif e.status_code == 500:
        print("Server error")

Considerazioni sullo streaming

Quando si utilizza lo streaming, stop_reason è:

  • null nell'evento iniziale message_start
  • Fornito nell'evento message_delta
  • Non fornito in nessun altro evento
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}")

Modelli comuni

Gestione dei flussi di lavoro di utilizzo degli strumenti

Più semplice con tool runner: L'esempio seguente mostra la gestione manuale degli strumenti. Per la maggior parte dei casi d'uso, il tool runner gestisce automaticamente l'esecuzione degli strumenti con molto meno codice.

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":
            # Execute tools and continue
            tool_results = execute_tools(response.content)
            messages.append({"role": "assistant", "content": response.content})
            messages.append({"role": "user", "content": tool_results})
        else:
            # Final response
            return response

Garantire risposte complete

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

        # Continue from where it left off
        messages = [
            {"role": "user", "content": prompt},
            {"role": "assistant", "content": full_response},
            {"role": "user", "content": "Please continue from where you left off."},
        ]

    return full_response

Ottenere il massimo di token senza conoscere la dimensione dell'input

Con il motivo di arresto model_context_window_exceeded, puoi richiedere il massimo numero di token possibile senza calcolare il numero di token di input:

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-7",
        messages=[{"role": "user", "content": prompt}],
        max_tokens=64000,  # Practical non-streaming ceiling (Opus 4.7 supports 128K with streaming)
    )

    if response.stop_reason == "model_context_window_exceeded":
        # Got the maximum possible tokens given input size
        print(
            f"Generated {response.usage.output_tokens} tokens (context limit reached)"
        )
    elif response.stop_reason == "max_tokens":
        # Got exactly the requested tokens
        print(f"Generated {response.usage.output_tokens} tokens (max_tokens reached)")
    else:
        # Natural completion
        print(f"Generated {response.usage.output_tokens} tokens (natural completion)")

    return response.content[0].text

Gestendo correttamente i valori di stop_reason, puoi costruire applicazioni più robuste che gestiscono con eleganza diversi scenari di risposta e forniscono migliori esperienze utente.

# Check if response was truncated during tool use
if response.stop_reason == "max_tokens":
    # Check if the last content block is an incomplete tool_use
    last_block = response.content[-1]
    if last_block.type == "tool_use":
        # Send the request with higher max_tokens
        response = client.messages.create(
            model="claude-opus-4-7",
            max_tokens=4096,  # Increased limit
            messages=messages,
            tools=tools,
        )