Wenn Sie eine Anfrage an die Messages API stellen, enthält Claudes Antwort ein stop_reason-Feld, das angibt, warum das Modell die Generierung seiner Antwort gestoppt hat. Das Verständnis dieser Werte ist entscheidend für die Entwicklung robuster Anwendungen, die verschiedene Antworttypen angemessen handhaben.

Für Details über stop_reason in der API-Antwort siehe die Messages API-Referenz.

Was ist stop_reason?

Das stop_reason-Feld ist Teil jeder erfolgreichen Messages API-Antwort. Im Gegensatz zu Fehlern, die Ausfälle bei der Verarbeitung Ihrer Anfrage anzeigen, teilt Ihnen stop_reason mit, warum Claude seine Antwortgenerierung erfolgreich abgeschlossen hat.

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

Stop-Grund-Werte

end_turn

Der häufigste Stop-Grund. Zeigt an, dass Claude seine Antwort natürlich beendet hat.

if response.stop_reason == "end_turn":
    # Verarbeite die vollständige Antwort
    print(response.content[0].text)

max_tokens

Claude stoppte, weil es das in Ihrer Anfrage angegebene max_tokens-Limit erreicht hat.

# Anfrage mit begrenzten Tokens
response = client.messages.create(
    model="claude-sonnet-4-20250514",
    max_tokens=10,
    messages=[{"role": "user", "content": "Explain quantum physics"}]
)

if response.stop_reason == "max_tokens":
    # Antwort wurde abgeschnitten
    print("Response was cut off at token limit")
    # Erwägen Sie eine weitere Anfrage zum Fortsetzen

stop_sequence

Claude ist auf eine Ihrer benutzerdefinierten Stop-Sequenzen gestoßen.

response = client.messages.create(
    model="claude-sonnet-4-20250514",
    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 ruft ein Tool auf und erwartet, dass Sie es ausführen.

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":
    # Extrahiere und führe das Tool aus
    for content in response.content:
        if content.type == "tool_use":
            result = execute_tool(content.name, content.input)
            # Gib das Ergebnis an Claude für die finale Antwort zurück

pause_turn

Wird mit Server-Tools wie Websuche verwendet, wenn Claude eine langwierige Operation pausieren muss.

response = client.messages.create(
    model="claude-sonnet-4-20250514",
    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":
    # Setze die Unterhaltung fort
    messages = [
        {"role": "user", "content": original_query},
        {"role": "assistant", "content": response.content}
    ]
    continuation = client.messages.create(
        model="claude-sonnet-4-20250514",
        messages=messages,
        tools=[{"type": "web_search_20250305", "name": "web_search"}]
    )

refusal

Claude weigerte sich, eine Antwort aufgrund von Sicherheitsbedenken zu generieren.

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

if response.stop_reason == "refusal":
    # Claude lehnte es ab zu antworten
    print("Claude was unable to process this request")
    # Erwägen Sie eine Umformulierung oder Änderung der Anfrage

Best Practices für den Umgang mit Stop-Gründen

1. Überprüfen Sie immer stop_reason

Machen Sie es sich zur Gewohnheit, den stop_reason in Ihrer Antwortbehandlungslogik zu überprüfen:

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 == "pause_turn":
        return handle_pause(response)
    elif response.stop_reason == "refusal":
        return handle_refusal(response)
    else:
        # Behandle end_turn und andere Fälle
        return response.content[0].text

2. Behandeln Sie max_tokens elegant

Wenn eine Antwort aufgrund von Token-Limits abgeschnitten wird:

def handle_truncated_response(response):
    if response.stop_reason == "max_tokens":
        # Option 1: Warnen Sie den Benutzer
        return f"{response.content[0].text}\n\n[Response truncated due to length]"
        
        # Option 2: Setzen Sie die Generierung fort
        messages = [
            {"role": "user", "content": original_prompt},
            {"role": "assistant", "content": response.content[0].text}
        ]
        continuation = client.messages.create(
            model="claude-sonnet-4-20250514",
            max_tokens=1024,
            messages=messages + [{"role": "user", "content": "Please continue"}]
        )
        return response.content[0].text + continuation.content[0].text

3. Implementieren Sie Wiederholungslogik für pause_turn

Für Server-Tools, die pausieren können:

def handle_paused_conversation(initial_response, max_retries=3):
    response = initial_response
    messages = [{"role": "user", "content": original_query}]
    
    for attempt in range(max_retries):
        if response.stop_reason != "pause_turn":
            break
            
        messages.append({"role": "assistant", "content": response.content})
        response = client.messages.create(
            model="claude-sonnet-4-20250514",
            messages=messages,
            tools=original_tools
        )
    
    return response

Stop-Gründe vs. Fehler

Es ist wichtig, zwischen stop_reason-Werten und tatsächlichen Fehlern zu unterscheiden:

Stop-Gründe (erfolgreiche Antworten)

  • Teil des Antwortkörpers
  • Zeigen an, warum die Generierung normal gestoppt wurde
  • Antwort enthält gültigen Inhalt

Fehler (fehlgeschlagene Anfragen)

  • HTTP-Statuscodes 4xx oder 5xx
  • Zeigen Ausfälle bei der Anfrageverarbeitung an
  • Antwort enthält Fehlerdetails
try:
    response = client.messages.create(...)
    
    # Behandle erfolgreiche Antwort mit stop_reason
    if response.stop_reason == "max_tokens":
        print("Response was truncated")
    
except anthropic.APIError as e:
    # Behandle tatsächliche Fehler
    if e.status_code == 429:
        print("Rate limit exceeded")
    elif e.status_code == 500:
        print("Server error")

Streaming-Überlegungen

Bei der Verwendung von Streaming ist stop_reason:

  • null im anfänglichen message_start-Event
  • Bereitgestellt im message_delta-Event
  • Nicht in anderen Events bereitgestellt
with client.messages.stream(...) 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}")

Häufige Muster

Umgang mit Tool-Use-Workflows

def complete_tool_workflow(client, user_query, tools):
    messages = [{"role": "user", "content": user_query}]
    
    while True:
        response = client.messages.create(
            model="claude-sonnet-4-20250514",
            messages=messages,
            tools=tools
        )
        
        if response.stop_reason == "tool_use":
            # Führe Tools aus und setze fort
            tool_results = execute_tools(response.content)
            messages.append({"role": "assistant", "content": response.content})
            messages.append({"role": "user", "content": tool_results})
        else:
            # Finale Antwort
            return response

Sicherstellen vollständiger Antworten

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-sonnet-4-20250514",
            messages=messages,
            max_tokens=4096
        )
        
        full_response += response.content[0].text
        
        if response.stop_reason != "max_tokens":
            break
            
        # Setze dort fort, wo aufgehört wurde
        messages = [
            {"role": "user", "content": prompt},
            {"role": "assistant", "content": full_response},
            {"role": "user", "content": "Please continue from where you left off."}
        ]
    
    return full_response

Durch die ordnungsgemäße Behandlung von stop_reason-Werten können Sie robustere Anwendungen erstellen, die verschiedene Antwortszenarios elegant handhaben und bessere Benutzererfahrungen bieten.