• Nachrichten
  • Managed Agents
  • Admin
Search...
⌘K
Erste Schritte
Einführung in ClaudeSchnellstart
Entwickeln mit Claude
FunktionsübersichtVerwendung der Messages APIStoppgründe und FallbackAblehnungen und FallbackFallback-Guthaben
Modellfähigkeiten
Erweitertes DenkenAdaptives DenkenAufwandAufgabenbudgets (Beta)Schnellmodus (Forschungsvorschau)Strukturierte AusgabenZitateStreaming von NachrichtenBatch-VerarbeitungSuchergebnisseStreaming von AblehnungenMehrsprachige UnterstützungEmbeddings
Tools
ÜbersichtWie Tool-Nutzung funktioniertTutorial: Einen Tool-nutzenden Agenten erstellenTools definierenTool-Aufrufe verarbeitenParallele Tool-NutzungTool Runner (SDK)Strikte Tool-NutzungTool-Nutzung mit Prompt-CachingServer-ToolsFehlerbehebungWebsuche-ToolWeb-Fetch-ToolCodeausführungs-ToolAdvisor-ToolMemory-ToolBash-ToolComputer-Use-ToolTexteditor-Tool
Tool-Infrastruktur
Tool-ReferenzTool-Kontext verwaltenTool-KombinationenTool-SucheProgrammatischer Tool-AufrufFeingranulares Tool-Streaming
Kontextverwaltung
KontextfensterKompaktierungKontextbearbeitungPrompt-CachingSystemnachrichten während der KonversationEinen Orchestrierungsmodus erstellenCache-Diagnose (Beta)Token-Zählung
Arbeiten mit Dateien
Files APIPDF-UnterstützungBilder und Vision
Skills
ÜbersichtSchnellstartBest PracticesSkills für UnternehmenSkills in der API
MCP
Remote-MCP-ServerMCP-Connector
Claude auf Cloud-Plattformen
Amazon BedrockAmazon Bedrock (Legacy)Claude Platform auf AWSMicrosoft FoundryVertex AI
Log in
Stoppgründe und Fallback
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
Nachrichten/Entwickeln mit Claude

Stop-Gründe und Fallback

Das stop_reason-Feld, was jeder Wert bedeutet und wo du Ablehnungen und Fallback behandelst.

Wenn du eine Anfrage an die Messages API stellst, 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.

Details zu stop_reason in der API-Antwort findest du in der Messages API-Referenz.

Das stop_reason-Feld

Das stop_reason-Feld ist Teil jeder erfolgreichen Messages API-Antwort. Im Gegensatz zu Fehlern, die auf Probleme bei der Verarbeitung deiner Anfrage hinweisen, teilt dir stop_reason mit, warum Claude die Generierung seiner Antwort 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-Reason-Werte

end_turn

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

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":
    # Verarbeite die vollständige Antwort
    print(response.content[0].text)

Leere Antworten mit end_turn

Manchmal gibt Claude eine leere Antwort zurück (genau 2–3 Token ohne Inhalt) mit stop_reason: "end_turn". Dies passiert typischerweise, wenn Claude interpretiert, dass der Assistant-Turn abgeschlossen ist, insbesondere nach Tool-Ergebnissen.

Häufige Ursachen:

  • Hinzufügen von Textblöcken direkt nach Tool-Ergebnissen (Claude lernt zu erwarten, dass der Nutzer immer Text nach Tool-Ergebnissen einfügt, und beendet daher seinen Turn, um dem Muster zu folgen)
  • Zurücksenden von Claudes abgeschlossener Antwort, ohne etwas hinzuzufügen (Claude hat bereits entschieden, dass es fertig ist, also bleibt es dabei)

So verhinderst du leere Antworten:

# FALSCH: Text direkt nach tool_result hinzufügen
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
            },
        ],
    },
]

# RICHTIG: Sende Tool-Ergebnisse direkt ohne zusätzlichen 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
]


# Falls du nach Korrektur der Nachrichtenstruktur weiterhin leere Antworten erhältst:
def handle_empty_response(client, messages):
    response = client.messages.create(
        model="claude-opus-4-8", max_tokens=1024, messages=messages
    )

    # Prüfe, ob die Antwort leer ist
    if response.stop_reason == "end_turn" and not response.content:
        # FALSCH: Nicht einfach mit der leeren Antwort erneut versuchen
        # Das funktioniert nicht, weil Claude bereits entschieden hat, dass es fertig ist

        # RICHTIG: Füge einen Fortsetzungs-Prompt in einer NEUEN User-Nachricht hinzu
        messages.append({"role": "user", "content": "Please continue"})

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

    return response

Best Practices:

  1. Füge niemals Textblöcke direkt nach Tool-Ergebnissen hinzu – Dies bringt Claude bei, nach jeder Tool-Nutzung eine Nutzereingabe zu erwarten
  2. Wiederhole leere Antworten nicht ohne Änderung – Das bloße Zurücksenden der leeren Antwort hilft nicht
  3. Verwende Fortsetzungs-Prompts nur als letzten Ausweg – Nur wenn diese Korrekturen das Problem nicht lösen

max_tokens

Claude hat gestoppt, weil es das in deiner Anfrage angegebene max_tokens-Limit erreicht hat.

Python
# Anfrage mit begrenzten 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":
    # Antwort wurde abgeschnitten
    print("Response was cut off at token limit")
    # Erwäge eine weitere Anfrage, um fortzufahren

Unvollständige Tool-Use-Blöcke

Wenn Claudes Antwort aufgrund des Erreichens des max_tokens-Limits abgeschnitten wird und die abgeschnittene Antwort einen unvollständigen Tool-Use-Block enthält, musst du die Anfrage mit einem höheren max_tokens-Wert wiederholen, um die vollständige Tool-Nutzung zu erhalten.

# Prüfe, ob die Antwort während der Tool-Nutzung abgeschnitten wurde
if response.stop_reason == "max_tokens":
    # Prüfe, ob der letzte Content-Block ein unvollständiges tool_use ist
    last_block = response.content[-1]
    if last_block.type == "tool_use":
        # Sende die Anfrage mit höherem max_tokens
        response = client.messages.create(
            model="claude-opus-4-8",
            max_tokens=4096,  # Increased limit
            messages=messages,
            tools=tools,
        )

stop_sequence

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

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 ruft ein Tool auf und erwartet, dass du es ausführst.

Für die meisten Tool-Use-Implementierungen verwende den Tool Runner, der die Tool-Ausführung, Ergebnisformatierung und Konversationsverwaltung automatisch übernimmt.

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":
    # 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 zurückgegeben, wenn die serverseitige Sampling-Schleife ihr Iterationslimit erreicht, während sie Server-Tools wie Websuche oder Web-Fetch ausführt. Das Standardlimit beträgt 10 Iterationen pro Anfrage.

Wenn dies passiert, kann die Antwort einen server_tool_use-Block ohne ein entsprechendes server_tool_result enthalten. Um Claude die Verarbeitung abschließen zu lassen, setze die Konversation fort, indem du die Antwort unverändert zurücksendest.

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":
    # Setze die Konversation fort, indem du die Antwort zurücksendest
    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"}],
    )

Deine Anwendung sollte pause_turn in jeder Agent-Schleife behandeln, die Server-Tools verwendet. Füge einfach die Antwort des Assistenten zu deinem Messages-Array hinzu und stelle eine weitere API-Anfrage, damit Claude fortfahren kann.

refusal

Claude hat es abgelehnt, eine Antwort zu generieren. Bei Claude Fable 5 geben Sicherheitsklassifikatoren diesen Stop-Grund als normale HTTP-200-Antwort zurück, nicht als Fehler.

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 hat die Antwort abgelehnt
    print("Claude was unable to process this request")
    # Erwäge, die Anfrage umzuformulieren oder anzupassen

Wenn du bei der Verwendung von Claude Sonnet 4.5 oder Opus 4.1 (veraltet) häufig auf refusal-Stop-Gründe stößt, kannst du versuchen, deine API-Aufrufe auf Haiku 4.5 (claude-haiku-4-5-20251001) umzustellen, das andere Nutzungsbeschränkungen hat. Erfahre mehr über das Verständnis der API-Sicherheitsfilter von Sonnet 4.5.

Bei einer Ablehnung identifiziert das stop_details-Objekt die Richtlinienkategorie, die sie ausgelöst hat. Die Kategorien und die vollständige Struktur der Ablehnungsantwort werden unter Ablehnungen und Fallback behandelt. stop_details ist null für alle Stop-Gründe außer refusal.

Eine abgelehnte Anfrage bei Claude Fable 5 kann in der Regel durch einen erneuten Versuch mit einem anderen Claude-Modell bedient werden, und Ablehnungen und Fallback zeigt, wie du diesen Retry einrichtest – serverseitig oder in deinem Client. Fallback-Guthaben erklärt, wie du vermeidest, die Prompt-Cache-Kosten doppelt zu bezahlen, wenn du den Retry selbst implementierst.

model_context_window_exceeded

Claude hat gestoppt, weil es das Kontextfenster-Limit des Modells erreicht hat. Dies ermöglicht es dir, die maximal möglichen Token anzufordern, ohne die genaue Eingabegröße zu kennen.

Python
# Anfrage mit maximalen Tokens, um so viel wie möglich zu erhalten
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":
    # Antwort hat das Kontextfenster-Limit vor max_tokens erreicht
    print("Response reached model's context window limit")
    # Die Antwort ist weiterhin gültig, wurde aber durch das Kontextfenster begrenzt

Dieser Stop-Grund ist standardmäßig in Sonnet 4.5 und neueren Modellen verfügbar. Für frühere Modelle verwende den Beta-Header model-context-window-exceeded-2025-08-26, um dieses Verhalten zu aktivieren.

Best Practices für die Behandlung von Stop-Gründen

1. Überprüfe immer stop_reason

Mache es dir zur Gewohnheit, stop_reason in deiner 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 == "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:
        # Behandle end_turn und andere Fälle
        return response.content[0].text

2. Behandle abgeschnittene Antworten elegant

Wenn eine Antwort aufgrund von Token-Limits oder des Kontextfensters abgeschnitten wird:

def handle_truncated_response(response):
    if response.stop_reason in ["max_tokens", "model_context_window_exceeded"]:
        # Option 1: Warne den Nutzer vor dem spezifischen 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: Setze die Generierung fort
        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. Implementiere Retry-Logik für pause_turn

Bei der Verwendung von Server-Tools kann die API pause_turn zurückgeben, wenn die serverseitige Sampling-Schleife ihr Iterationslimit erreicht (Standard: 10). Behandle dies, indem du die Konversation fortsetzt:

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 hat die Verarbeitung abgeschlossen – gib die finale Antwort zurück
            return response

        # pause_turn: ersetze die gesamte Nachrichtenliste, um abwechselnde Rollen beizubehalten
        messages = [
            {"role": "user", "content": user_query},
            {"role": "assistant", "content": response.content},
        ]

    # Maximale Fortsetzungen erreicht – gib die letzte Antwort zurück
    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 Antwort-Bodys
  • Zeigen an, warum die Generierung normal gestoppt wurde
  • Antwort enthält gültigen Inhalt

Fehler (fehlgeschlagene Anfragen)

  • HTTP-Statuscodes 4xx oder 5xx
  • Zeigen Fehler bei der Anfrageverarbeitung an
  • Antwort enthält Fehlerdetails
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!"}],
    )

    # Behandle erfolgreiche Antwort mit stop_reason
    if response.stop_reason == "max_tokens":
        print("Response was truncated")

except anthropic.APIStatusError as e:
    # Behandle tatsächliche Fehler
    if e.status_code == 429:
        print("Rate limit exceeded")
    elif e.status_code == 500:
        print("Server error")

Überlegungen zum Streaming

Bei der Verwendung von Streaming ist stop_reason:

  • null im initialen message_start-Event
  • Im message_delta-Event bereitgestellt
  • In keinem anderen Event bereitgestellt
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}")

Gängige Muster

Behandlung von Tool-Use-Workflows

Einfacher mit dem Tool Runner: Das folgende Beispiel zeigt die manuelle Tool-Behandlung. Für die meisten Anwendungsfälle übernimmt der Tool Runner die Tool-Ausführung automatisch mit deutlich weniger 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":
            # Führe Tools aus und fahre fort
            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-opus-4-8", messages=messages, max_tokens=4096
        )

        full_response += response.content[0].text

        if response.stop_reason != "max_tokens":
            break

        # Fahre dort fort, wo es aufgehört hat
        messages = [
            {"role": "user", "content": prompt},
            {"role": "assistant", "content": full_response},
            {"role": "user", "content": "Please continue from where you left off."},
        ]

    return full_response

Maximale Token erhalten, ohne die Eingabegröße zu kennen

Mit dem Stop-Grund model_context_window_exceeded kannst du die maximal möglichen Token anfordern, ohne die Eingabegröße zu berechnen:

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":
        # Maximale mögliche Token-Anzahl bei gegebener Eingabegröße erhalten
        print(
            f"Generated {response.usage.output_tokens} tokens (context limit reached)"
        )
    elif response.stop_reason == "max_tokens":
        # Genau die angeforderte Token-Anzahl erhalten
        print(f"Generated {response.usage.output_tokens} tokens (max_tokens reached)")
    else:
        # Natürlicher Abschluss
        print(f"Generated {response.usage.output_tokens} tokens (natural completion)")

    return response.content[0].text

Durch die korrekte Behandlung von stop_reason-Werten kannst du robustere Anwendungen entwickeln, die verschiedene Antwortszenarien elegant handhaben und bessere Nutzererfahrungen bieten.

Was this page helpful?

  • Das stop_reason-Feld
  • Stop-Reason-Werte
  • end_turn
  • max_tokens
  • stop_sequence
  • tool_use
  • pause_turn
  • refusal
  • model_context_window_exceeded
  • Best Practices für die Behandlung von Stop-Gründen
  • 1. Überprüfe immer stop_reason
  • 2. Behandle abgeschnittene Antworten elegant
  • 3. Implementiere Retry-Logik für pause_turn
  • Stop-Gründe vs. Fehler
  • Stop-Gründe (erfolgreiche Antworten)
  • Fehler (fehlgeschlagene Anfragen)
  • Überlegungen zum Streaming
  • Gängige Muster
  • Behandlung von Tool-Use-Workflows
  • Sicherstellen vollständiger Antworten
  • Maximale Token erhalten, ohne die Eingabegröße zu kennen