---
title: Streaming-Ablehnungen behandeln
url: https://platform.claude.com/docs/de/test-and-evaluate/strengthen-guardrails/handle-streaming-refusals
description: Erkenne und behandle Ablehnungs-Stop-Reasons in Streaming-Antworten und wiederhole abgelehnte Anfragen auf einem Fallback-Modell.
---

Ab den Claude-4-Modellen geben Streaming-Antworten von Claudes API **`stop_reason`: `"refusal"`** zurück, wenn Streaming-Klassifikatoren eingreifen, um potenzielle Richtlinienverstöße zu behandeln. Diese Sicherheitsfunktion hilft dabei, die Inhaltskonformität während des Echtzeit-Streamings aufrechtzuerhalten.

<Tip>
  Diese Seite behandelt, wie „refusals“ (Ablehnungen) in Streaming-Antworten erscheinen. Für jeden `stop_reason`-Wert und dessen Behandlung siehe [Stop-Reasons und Fallback](https://platform.claude.com/docs/de/build-with-claude/handling-stop-reasons). Um abgelehnte Anfragen auf einem anderen Claude-Modell zu wiederholen, siehe [Ablehnungen und Fallback](https://platform.claude.com/docs/de/build-with-claude/refusals-and-fallback).
</Tip>

## API-Antwortformat

Wenn Streaming-Klassifikatoren Inhalte erkennen, die gegen die Richtlinien von Anthropic verstoßen, gibt die API diese Antwort zurück:

```json
{
  "role": "assistant",
  "content": [
    {
      "type": "text",
      "text": "Hello.."
    }
  ],
  "stop_reason": "refusal",
  "stop_details": {
    "type": "refusal",
    "category": "cyber",
    "explanation": "This request was declined because it could enable cyber harm."
  }
}
```

Im Event-Stream kommt `stop_details` im `message_delta`-Event zusammen mit `stop_reason` an.

<Note>
  Eine `refusal`-Antwort von Streaming-Klassifikatoren enthält ein `stop_details`-Objekt mit einer `category` und einer menschenlesbaren `explanation`, die du dem Benutzer anzeigen kannst. Siehe [Ablehnungen und Fallback](https://platform.claude.com/docs/de/build-with-claude/refusals-and-fallback#refusal-response) für die vollständige Antwortstruktur und die verfügbaren Kategorien.

  Bei einer Ablehnung ist das `stop_details`-Objekt immer vorhanden, aber seine Felder `category` und `explanation` können `null` sein, zum Beispiel wenn die Ablehnung keiner benannten Kategorie zugeordnet ist. Verzweige anhand von `stop_reason` oder `stop_details.type`, anstatt davon auszugehen, dass `category` und `explanation` befüllt sind, und stelle deine eigenen benutzerseitigen Meldungen bereit, wenn sie `null` sind.
</Note>

## Kontext nach einer Ablehnung zurücksetzen

Wenn du **`stop_reason`: `refusal`** erhältst, musst du den Gesprächskontext zurücksetzen, bevor du fortfährst. Du kannst den Turn, der die Ablehnung ausgelöst hat, entfernen oder umformulieren oder den Gesprächsverlauf vollständig löschen. Der Versuch, ohne Zurücksetzen fortzufahren, führt zu weiteren Ablehnungen.

<Note>
  Nutzungsmetriken werden in der Antwort weiterhin bereitgestellt, auch wenn die Antwort abgelehnt wird. Ob eine abgelehnte Anfrage abgerechnet wird, hängt davon ab, wann die Ablehnung eintrifft und welcher Kategorie sie angehört; siehe [Wie Ablehnungen berechnet werden](https://platform.claude.com/docs/de/build-with-claude/refusals-and-fallback#how-refusals-are-billed).
</Note>

<Tip>
  Das Zurücksetzen des Kontexts ist nicht der einzige Weg zur Wiederherstellung. Du kannst die abgelehnte Anfrage auch auf einem anderen Claude-Modell wiederholen, und die Seite [Ablehnungen und Fallback](https://platform.claude.com/docs/de/build-with-claude/refusals-and-fallback) zeigt, wie du das mit serverseitigem Fallback, der SDK-Middleware oder einer manuellen Wiederholung einrichtest.
</Tip>

## Implementierungsleitfaden

So erkennst und behandelst du Streaming-Ablehnungen in deiner Anwendung:

<CodeGroup>
  ```bash cURL
  response=$(curl -N https://api.anthropic.com/v1/messages \
    -H "anthropic-version: 2023-06-01" \
    -H "content-type: application/json" \
    -H "x-api-key: $ANTHROPIC_API_KEY" \
    -d '{
      "model": "claude-opus-5-5",
      "messages": [{"role": "user", "content": "Hello"}],
      "max_tokens": 1024,
      "stream": true
    }')

  if echo "$response" | jq -R -e 'select(startswith("data: "))
      | sub("^data: "; "") | fromjson
      | select(.delta.stop_reason == "refusal")' >/dev/null; then
    echo "Response refused - resetting conversation context"
    # Setze hier deinen Konversationszustand zurück
  fi
  ```

  ```bash CLI
  response=$(ant messages create --stream --format jsonl \
    --model claude-opus-5-5 \
    --max-tokens 1024 \
    --message '{role: user, content: Hello}')

  if echo "$response" | jq -e 'select(.delta.stop_reason == "refusal")' >/dev/null; then
    echo "Response refused - resetting conversation context"
    # Setze hier deinen Konversationszustand zurück
  fi
  ```

  ```python Python
  client = anthropic.Anthropic()
  messages = []


  def reset_conversation():
      """Reset conversation context after refusal"""
      global messages
      messages = []
      print("Conversation reset due to refusal")


  try:
      with client.messages.stream(
          max_tokens=1024,
          messages=messages + [{"role": "user", "content": "Hello"}],
          model="claude-opus-5-5",
      ) as stream:
          for event in stream:
              # Prüfe das Message-Delta auf eine Ablehnung
              if event.type == "message_delta":
                  if event.delta.stop_reason == "refusal":
                      reset_conversation()
                      break
  except Exception as e:
      print(f"Error: {e}")
  ```

  ```typescript TypeScript
  const client = new Anthropic();
  let messages: Anthropic.MessageParam[] = [];

  function resetConversation() {
    // Gesprächskontext nach einer Ablehnung zurücksetzen
    messages = [];
    console.log("Conversation reset due to refusal");
  }

  try {
    const stream = await client.messages.stream({
      messages: [...messages, { role: "user", content: "Hello" }],
      model: "claude-opus-5-5",
      max_tokens: 1024
    });

    for await (const event of stream) {
      // Im Message-Delta auf eine Ablehnung prüfen
      if (event.type === "message_delta" && event.delta.stop_reason === "refusal") {
        resetConversation();
        break;
      }
    }
  } catch (error) {
    console.error("Error:", error);
  }
  ```

  ```csharp C#
  List<Message> messages = new();
  AnthropicClient client = new();

  var parameters = new MessageCreateParams
  {
      Model = Model.ClaudeOpus5_5,
      MaxTokens = 1024,
      Messages = [new() { Role = Role.User, Content = "Hello" }]
  };

  try
  {
      await foreach (var streamEvent in client.Messages.CreateStreaming(parameters))
      {
          if (
              streamEvent.TryPickDelta(out var deltaEvent)
              && deltaEvent.Delta.StopReason == StopReason.Refusal
          )
          {
              ResetConversation();
              break;
          }
      }
  }
  catch (Exception e)
  {
      Console.WriteLine($"Error: {e.Message}");
  }

  void ResetConversation()
  {
      messages.Clear();
      Console.WriteLine("Conversation reset due to refusal");
  }
  ```

  ```go Go
  var messages []anthropic.MessageParam

  func resetConversation() {
  	messages = []anthropic.MessageParam{}
  	fmt.Println("Conversation reset due to refusal")
  }
  // ...
  	client := anthropic.NewClient()

  	stream := client.Messages.NewStreaming(context.TODO(), anthropic.MessageNewParams{
  		Model:     anthropic.ModelClaudeOpus5_5,
  		MaxTokens: 1024,
  		Messages: []anthropic.MessageParam{
  			anthropic.NewUserMessage(anthropic.NewTextBlock("Hello")),
  		},
  	})

  streamLoop:
  	for stream.Next() {
  		event := stream.Current()
  		switch eventVariant := event.AsAny().(type) {
  		case anthropic.MessageDeltaEvent:
  			if eventVariant.Delta.StopReason == anthropic.StopReasonRefusal {
  				resetConversation()
  				break streamLoop
  			}
  		}
  	}

  	if err := stream.Err(); err != nil {
  		log.Fatal(err)
  	}
  ```

  ```java Java
  import com.anthropic.core.http.StreamResponse;
  import com.anthropic.models.messages.RawMessageStreamEvent;
  import com.anthropic.models.messages.StopReason;
  // ...

  List<MessageParam> messages = new ArrayList<>();

  void main() {
      AnthropicClient client = AnthropicOkHttpClient.fromEnv();

      MessageCreateParams params = MessageCreateParams.builder()
          .model(Model.CLAUDE_OPUS_5_5)
          .maxTokens(1024L)
          .addUserMessage("Hello")
          .build();

      try (StreamResponse<RawMessageStreamEvent> stream = client.messages().createStreaming(params)) {
          stream.stream().forEach(event -> {
              event.messageDelta().ifPresent(deltaEvent -> {
                  deltaEvent.delta().stopReason().ifPresent(stopReason -> {
                      if (stopReason.equals(StopReason.REFUSAL)) {
                          resetConversation();
                      }
                  });
              });
          });
      } catch (Exception e) {
          System.err.println("Error: " + e.getMessage());
      }
  }

  void resetConversation() {
      messages.clear();
      IO.println("Conversation reset due to refusal");
  }
  ```

  ```php PHP
  $client = new Client();
  $messages = [];

  function resetConversation(&$messages) {
      $messages = [];
      echo "Conversation reset due to refusal\n";
  }

  try {
      $stream = $client->messages->createStream(
          maxTokens: 1024,
          messages: [
              ['role' => 'user', 'content' => 'Hello']
          ],
          model: 'claude-opus-5-5',
      );

      foreach ($stream as $event) {
          if ($event->type === 'message_delta' && $event->delta->stopReason === 'refusal') {
              resetConversation($messages);
              break;
          }
      }
  } catch (\Exception $e) {
      echo "Error: " . $e->getMessage() . "\n";
  }
  ```

  ```ruby Ruby
  client = Anthropic::Client.new
  messages = []

  def reset_conversation(messages)
    messages.clear
    puts "Conversation reset due to refusal"
  end

  begin
    stream = client.messages.stream(
      model: :"claude-opus-5-5",
      max_tokens: 1024,
      messages: [{ role: "user", content: "Hello" }]
    )

    stream.each do |event|
      if event.type == :message_delta && event.delta.stop_reason == :refusal
        reset_conversation(messages)
        break
      end
    end
  rescue => e
    puts "Error: #{e.message}"
  end
  ```
</CodeGroup>

## Aktuelle Ablehnungstypen

Die API behandelt Ablehnungen derzeit auf drei verschiedene Arten:

| Ablehnungstyp                               | Antwortformat                | Wann er auftritt                                                 |
| ------------------------------------------- | ---------------------------- | ---------------------------------------------------------------- |
| Ablehnungen durch Streaming-Klassifikatoren | **`stop_reason`: `refusal`** | Während des Streamings, wenn Inhalte gegen Richtlinien verstoßen |
| API-Eingabe- und Urheberrechtsvalidierung   | 400-Fehlercodes              | Wenn die Eingabe Validierungsprüfungen nicht besteht             |
| Vom Modell generierte Ablehnungen           | Standard-Textantworten       | Wenn das Modell selbst ablehnt                                   |

## Best Practices

* **Auf Ablehnungen überwachen:** Nimm Prüfungen auf **`stop_reason`: `refusal`** in deine Fehlerbehandlung auf
* **Automatisch zurücksetzen:** Implementiere ein automatisches Zurücksetzen des Kontexts, wenn Ablehnungen erkannt werden
* **Auf ein anderes Modell ausweichen:** Konfiguriere [serverseitigen Fallback oder die SDK-Middleware](https://platform.claude.com/docs/de/build-with-claude/refusals-and-fallback), damit abgelehnte Anfragen auf einem anderen Claude-Modell wiederholt werden, anstatt dem Benutzer eine Ablehnung anzuzeigen. Claude Haiku 5.5 hat keinen serverseitigen Fallback, richte die Wiederholung dafür also in deinem Client ein
* **Fallback-Guthaben bei manuellen Wiederholungen einlösen:** Wenn du die Wiederholung selbst baust, übergib das [Fallback-Guthaben](https://platform.claude.com/docs/de/build-with-claude/fallback-credit)-Token der Ablehnung, damit die Wiederholung die Prompt-Cache-Kosten nicht doppelt bezahlt. Ablehnungen von Claude Haiku 5.5 enthalten kein Fallback-Guthaben
* **Eigene Meldungen bereitstellen:** Erstelle benutzerfreundliche Meldungen für eine bessere UX, wenn Ablehnungen auftreten
* **Ablehnungsmuster verfolgen:** Überwache die Häufigkeit von Ablehnungen, um potenzielle Probleme mit deinen Prompts zu identifizieren

## Migrationshinweise

Wenn du eine Ablehnungsbehandlung gebaut hast, als diese Funktion erstmals ausgeliefert wurde, oder sie zu einer bestehenden Integration hinzufügst, prüfe Folgendes:

* **Ablehnungen sind Antworten, keine Fehler.** Eine Ablehnung kommt als erfolgreiche HTTP-200-Antwort mit `stop_reason`: `"refusal"` an, sodass ein Monitoring, das nur auf Fehlerraten basiert, sie nicht sichtbar macht. Verfolge Ablehnungen als eigenes Signal.
* **Ablehnungen enthalten strukturierte Details.** Bei jedem Modell enthält eine Ablehnung auch ein `stop_details`-Objekt, das die Richtlinienkategorie hinter der Ablehnung identifiziert. Siehe [Ablehnungen und Fallback](https://platform.claude.com/docs/de/build-with-claude/refusals-and-fallback#refusal-response) für die vollständige Antwortstruktur.
* **Auf einem anderen Modell wiederholen.** Das erneute Senden einer abgelehnten Anfrage an dasselbe Modell führt in der Regel zu einer weiteren Ablehnung. Anstatt nur den Kontext zurückzusetzen, wiederhole die Anfrage auf einem Fallback-Modell mit [serverseitigem Fallback, der SDK-Middleware oder einer manuellen Wiederholung](https://platform.claude.com/docs/de/build-with-claude/refusals-and-fallback), und löse [Fallback-Guthaben](https://platform.claude.com/docs/de/build-with-claude/fallback-credit) ein, wenn du die Wiederholung selbst baust. Claude Haiku 5.5 hat keinen serverseitigen Fallback, und seine Ablehnungen enthalten kein Fallback-Guthaben, richte die Wiederholung dafür also in deinem Client ein.
* **Batch-Ergebnisse auf Ablehnungen prüfen.** Eine abgelehnte Anfrage in einem [Message Batch](https://platform.claude.com/docs/de/build-with-claude/batch-processing) wird als erfolgreiches Ergebnis mit `stop_reason`: `"refusal"` zurückgegeben, nicht als fehlerhaftes Ergebnis.
* **Behandlung auf `stop_reason` zentralisieren.** Die API konsolidiert die Ablehnungsbehandlung weiterhin rund um `stop_reason`: `"refusal"`, verzweige also anhand des Stop-Reasons statt anhand modellspezifischen Verhaltens.

## Nächste Schritte

<CardGroup cols={2}>
  <Card title="Ablehnungen und Fallback" icon="arrows-clockwise" href="https://platform.claude.com/docs/de/build-with-claude/refusals-and-fallback">
    Wiederhole abgelehnte Anfragen auf einem anderen Claude-Modell, serverseitig oder in deinem Client.
  </Card>

  <Card title="Stop-Reasons und Fallback" icon="code" href="https://platform.claude.com/docs/de/build-with-claude/handling-stop-reasons">
    Jeder `stop_reason`-Wert und wie du ihn behandelst.
  </Card>

  <Card title="Streaming von Nachrichten" icon="lightning" href="https://platform.claude.com/docs/de/build-with-claude/streaming">
    Streame Antworten und lies `stop_reason` aus `message_delta`-Events, sobald sie eintreffen.
  </Card>

  <Card title="Mehrsprachige Unterstützung" icon="text-aa" href="https://platform.claude.com/docs/de/build-with-claude/multilingual-support">
    Bediene Benutzer in verschiedenen Sprachen mit Claudes sprachübergreifenden Fähigkeiten.
  </Card>
</CardGroup>
