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 beendet hat. Das Verständnis dieser Werte ist entscheidend für die Entwicklung robuster Anwendungen, die verschiedene Antworttypen angemessen behandeln.

Einzelheiten zu stop_reason in der API-Antwort finden Sie in der Messages API-Referenz.

Was ist stop_reason?

Das Feld stop_reason ist Teil jeder erfolgreichen Messages API-Antwort. Im Gegensatz zu Fehlern, die auf Probleme bei der Verarbeitung Ihrer Anfrage hinweisen, teilt Ihnen stop_reason mit, warum Claude die Generierung seiner Antwort erfolgreich abgeschlossen hat.

Beispielantwort
{
  "id": "msg_01234",
  "type": "message",
  "role": "assistant",
  "content": [
    {
      "type": "text",
      "text": "Hier ist die Antwort auf Ihre Frage..."
    }
  ],
  "stop_reason": "end_turn",
  "stop_sequence": null,
  "usage": {
    "input_tokens": 100,
    "output_tokens": 50
  }
}

Stop-Reason-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 hat gestoppt, weil es das in Ihrer Anfrage angegebene max_tokens-Limit erreicht hat.

# Anfrage mit begrenzten Tokens
response = client.messages.create(
    model="claude-3-7-sonnet-20250219",
    max_tokens=10,
    messages=[{"role": "user", "content": "Erkläre Quantenphysik"}]
)

if response.stop_reason == "max_tokens":
    # Antwort wurde abgeschnitten
    print("Antwort wurde am Token-Limit abgeschnitten")
    # Erwägen Sie eine weitere Anfrage zur Fortsetzung

stop_sequence

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

response = client.messages.create(
    model="claude-3-7-sonnet-20250219",
    max_tokens=1024,
    stop_sequences=["ENDE", "STOP"],
    messages=[{"role": "user", "content": "Generiere Text, bis du ENDE sagst"}]
)

if response.stop_reason == "stop_sequence":
    print(f"Gestoppt bei Sequenz: {response.stop_sequence}")

tool_use

Claude ruft ein Tool auf und erwartet, dass Sie es ausführen.

response = client.messages.create(
    model="claude-3-7-sonnet-20250219",
    max_tokens=1024,
    tools=[weather_tool],
    messages=[{"role": "user", "content": "Wie ist das Wetter?"}]
)

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)
            # Ergebnis an Claude für endgültige Antwort zurückgeben

pause_turn

Wird bei Server-Tools wie der Websuche verwendet, wenn Claude eine lang laufende Operation pausieren muss.

response = client.messages.create(
    model="claude-3-7-sonnet-20250219",
    max_tokens=1024,
    tools=[{"type": "web_search_20250305", "name": "web_search"}],
    messages=[{"role": "user", "content": "Suche nach den neuesten KI-Nachrichten"}]
)

if response.stop_reason == "pause_turn":
    # Setze die Konversation fort
    messages = [
        {"role": "user", "content": original_query},
        {"role": "assistant", "content": response.content}
    ]
    continuation = client.messages.create(
        model="claude-3-7-sonnet-20250219",
        messages=messages,
        tools=[{"type": "web_search_20250305", "name": "web_search"}]
    )

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 Antwortverarbeitungslogik 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)
    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: Warne den Benutzer
        return f"{response.content[0].text}\n\n[Antwort aufgrund der Länge abgeschnitten]"
        
        # Option 2: Setze die Generierung fort
        messages = [
            {"role": "user", "content": original_prompt},
            {"role": "assistant", "content": response.content[0].text}
        ]
        continuation = client.messages.create(
            model="claude-3-7-sonnet-20250219",
            max_tokens=1024,
            messages=messages + [{"role": "user", "content": "Bitte fahre fort"}]
        )
        return response.content[0].text + continuation.content[0].text

3. Implementieren Sie eine Wiederholungslogik für pause_turn

Für Server-Tools, die möglicherweise pausieren:

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-3-7-sonnet-20250219",
            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ültige Inhalte

Fehler (fehlgeschlagene Anfragen)

  • HTTP-Statuscodes 4xx oder 5xx
  • Zeigen Fehler bei der Anfrageverarbeitung an
  • Antwort enthält Fehlerdetails
try:
    response = client.messages.create(...)
    
    # Erfolgreiche Antwort mit stop_reason behandeln
    if response.stop_reason == "max_tokens":
        print("Antwort wurde abgeschnitten")
    
except anthropic.APIError as e:
    # Tatsächliche Fehler behandeln
    if e.status_code == 429:
        print("Rate-Limit überschritten")
    elif e.status_code == 500:
        print("Serverfehler")

Streaming-Überlegungen

Bei Verwendung von Streaming ist stop_reason:

  • null im ersten message_start-Event
  • Bereitgestellt im message_delta-Event
  • Nicht-null in allen anderen Events
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 endete mit: {stop_reason}")

Häufige Muster

Behandlung von 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-3-7-sonnet-20250219",
            messages=messages,
            tools=tools
        )
        
        if response.stop_reason == "tool_use":
            # Tools ausführen und fortfahren
            tool_results = execute_tools(response.content)
            messages.append({"role": "assistant", "content": response.content})
            messages.append({"role": "user", "content": tool_results})
        else:
            # Endgültige 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-3-7-sonnet-20250219",
            messages=messages,
            max_tokens=4096
        )
        
        full_response += response.content[0].text
        
        if response.stop_reason != "max_tokens":
            break
            
        # Fahre fort, wo es aufgehört hat
        messages = [
            {"role": "user", "content": prompt},
            {"role": "assistant", "content": full_response},
            {"role": "user", "content": "Bitte fahre dort fort, wo du aufgehört hast."}
        ]
    
    return full_response

Durch die richtige Behandlung von stop_reason-Werten können Sie robustere Anwendungen erstellen, die verschiedene Antwortszenarien elegant behandeln und bessere Benutzererfahrungen bieten.