Claude Fable 5 und Claude Opus 5 enthalten Sicherheitsklassifizierer, die eine Anfrage ablehnen können. Wenn das passiert, erhältst du eine normale Antwort, keinen Fehler, mit stop_reason: "refusal". Du kannst in der Regel trotzdem eine Antwort bekommen, indem du dieselbe Anfrage an ein anderes Claude-Modell sendest. Diese Seite zeigt dir, wie du eine „refusal" (Ablehnung) erkennst und wie du diesen Wiederholungsversuch einrichtest.
Lies diese Seite, wenn du auf Claude Fable 5 oder Claude Opus 5 aufbaust und möchtest, dass abgelehnte Anfragen automatisch an ein anderes Modell weitergereicht werden. Sie gilt auch, wenn du gerade "refusal" in einer Antwort gesehen hast und wissen möchtest, was als Nächstes zu tun ist.
Verwandte Seiten:
stop_reason-Werte.Die einfachste Einrichtung, in der Beta auf der Claude API: Setze fallbacks auf "default", und die API wiederholt eine abgelehnte Anfrage auf dem Fallback-Modell, das Anthropic für ihre Ablehnungskategorie empfiehlt. Für Kategorien ohne empfohlenes Fallback bleibt die Ablehnung bestehen.
client = Anthropic()
response = client.beta.messages.create(
model="claude-fable-5",
max_tokens=1024,
messages=[{"role": "user", "content": "Hello, Claude"}],
fallbacks="default",
betas=["server-side-fallback-2026-07-01"],
)
print(response.model)Die folgenden Abschnitte behandeln, was eine Ablehnungsantwort enthält, wann du serverseitiges oder clientseitiges Fallback verwenden solltest und wie jedes abgerechnet wird.
Eine Ablehnung ist eine erfolgreiche HTTP-200-Antwort mit stop_reason: "refusal":
{
"id": "msg_01XFUDYJgAACzvnptvVoYEL",
"type": "message",
"role": "assistant",
"model": "claude-fable-5",
"content": [],
"stop_reason": "refusal",
"stop_details": {
"type": "refusal",
"category": "cyber",
"explanation": "This request was declined because it could enable cyber harm."
},
"usage": {
"input_tokens": 412,
"output_tokens": 0
}
}Das stop_details-Objekt erklärt die Ablehnung:
category: benennt den Richtlinienbereich, der den Klassifizierer ausgelöst hat.explanation: eine menschenlesbare Beschreibung. Der Text ist nicht stabil, zeige ihn also an, anstatt ihn zu parsen.null, wenn die Ablehnung keiner benannten Kategorie zugeordnet werden kann. Dieses null ist ein normaler, dauerhafter Wert, kein Platzhalter.stop_details selbst ist null für jeden Stop-Grund außer refusal.category | Was es bedeutet |
|---|---|
"cyber" | Die Anfrage könnte Cyber-Schäden ermöglichen, etwa die Entwicklung von Malware oder Exploits. Auch harmlose Cybersecurity-Arbeit kann diese Kategorie auslösen. |
"bio" | Die Anfrage könnte biologische Schäden ermöglichen, etwa gefährliche Labormethoden. Auch nützliche Arbeit in den Lebenswissenschaften kann diese Kategorie auslösen. |
"frontier_llm" | Die Anfrage könnte die Entwicklung konkurrierender KI-Modelle unterstützen, was gemäß Anthropics kommerziellen Bedingungen eingeschränkt ist. Auch harmlose Machine-Learning-Arbeit kann diese Kategorie auslösen. |
"reasoning_extraction" | Die Anfrage fordert das Modell auf, sein internes Reasoning im Antworttext wiederzugeben. Um Reasoning stattdessen in strukturierter Form zu erhalten, verwende adaptives Denken. |
"general_harms" | Die Anfrage könnte mit einem Bereich zusammenhängen, der als schädlich eingestuft wurde. Harmlose Arbeit kann diese Kategorie manchmal auslösen. |
Eine Ablehnung kann vor jeglicher Ausgabe eintreffen oder mitten im Stream nach teilweiser Ausgabe. Behandle in beiden Fällen jede teilweise Ausgabe als unvollständig und verwirf sie.
Wie Ablehnungen abgerechnet werden: Eine Ablehnung, die vor jeglicher Ausgabe eintrifft, wird dir nicht in Rechnung gestellt. content ist leer, und Token-Zahlen erscheinen in usage, werden aber nicht berechnet. Die Anfrage zählt dennoch gegen deine Ratenlimits. Eine Ablehnung mitten im Stream berechnet die Input-Token und die bereits gestreamte Ausgabe zu normalen Sätzen.
Es gibt drei Möglichkeiten, eine abgelehnte Anfrage auf einem anderen Modell zu wiederholen. Die richtige hängt davon ab, wo du läufst und wie viel Kontrolle du brauchst.
| Deine Situation | Verwende | Warum |
|---|---|---|
| Claude API, einfachste Einrichtung | Serverseitiges Fallback | Eine Anfrage, eine Antwort. Die API übernimmt den Wiederholungsversuch. |
| Beliebige Plattform, mit einem Anthropic SDK | Die SDK-Middleware | Einmal auf dem Client konfigurieren. Wiederholungsversuche erfolgen automatisch. |
| Rohes HTTP oder eigene Retry-Logik | Manueller Wiederholungsversuch mit Fallback-Guthaben | Volle Kontrolle. Fallback-Guthaben hält die Kosten niedrig. |
Serverseitiges Fallback und die SDK-Middleware wenden Fallback-Guthaben für dich an. Du brauchst die Seite Fallback-Guthaben nur, wenn du den Wiederholungsversuch selbst baust.
Serverseitiges Fallback wiederholt eine abgelehnte Anfrage innerhalb eines einzigen API-Aufrufs. Im Standardmodus führt die API, wenn das primäre Modell ablehnt und die Ablehnungskategorie ein empfohlenes Fallback hat, dieselbe Anfrage auf dem Modell aus, das Anthropic für diese Kategorie empfiehlt. Du kannst stattdessen bis zu drei eigene Fallback-Modelle benennen (siehe unten). In beiden Fällen erhältst du eine Antwort zurück, die das Modell benennt, das geantwortet hat, sodass dein Nutzer in einem einzigen Roundtrip eine Antwort bekommt.
Serverseitiges Fallback ist in der Beta auf der Claude API. Der fallbacks-Parameter wird auf der Message Batches API nicht unterstützt (ein Batch-Element, das ihn enthält, kommt als fehlerhaftes Ergebnis zurück) und ist auf Amazon Bedrock, Google Cloud oder Microsoft Foundry nicht verfügbar. Verwende auf diesen Plattformen stattdessen clientseitiges Fallback mit der SDK-Middleware.
Setze den fallbacks-Parameter auf den String "default" und sende den Beta-Header server-side-fallback-2026-07-01. Die API wendet dann das serverdefinierte Standard-Routing des angeforderten Modells an, das ein empfohlenes Fallback-Modell basierend auf der vom Klassifizierer gemeldeten Ablehnungskategorie auswählt, sodass abgelehnte Anfragen bedient werden, ohne dass du eine Modellliste pflegen musst, wenn sich Empfehlungen ändern.
client = Anthropic()
response = client.beta.messages.create(
model="claude-fable-5",
max_tokens=1024,
messages=[{"role": "user", "content": "Hello, Claude"}],
fallbacks="default",
betas=["server-side-fallback-2026-07-01"],
)
# Ein fallback_message-Eintrag in usage.iterations bedeutet, dass ein Fallback-Modell lief;
# kombiniere ihn mit stop_reason, um zu bestätigen, dass der Fallback die Antwort geliefert hat.
fallback_ran = any(
iteration.type == "fallback_message"
for iteration in response.usage.iterations or []
)
served_by_fallback = fallback_ran and response.stop_reason != "refusal"
print(
json.dumps(
{
"stop_reason": response.stop_reason,
"model": response.model,
"served_by_fallback": served_by_fallback,
}
)
)Anthropic legt Schutzmaßnahmen für jedes Modell einzeln und für jede Richtlinienkategorie fest, entsprechend der Fähigkeit des Modells: Je nach Kategorie kann eine markierte Anfrage auf ein weniger leistungsfähiges Modell zurückfallen oder abgelehnt werden. Der "default"-Modus kodiert diese Empfehlungen pro Modell und pro Kategorie für dich, sodass eine abgelehnte Anfrage auf dem Modell wiederholt wird, das Anthropic für diese Kategorie empfiehlt. Fallbacks sind in jedem Fall sichtbar: Die Antwort benennt das Modell, das sie bedient hat, und der fallback-Content-Block markiert die Übergabe.
Das Routing wird serverseitig angewendet und wird nicht pro Modell auf der Models API veröffentlicht. Um zu sehen, welches Modell eine abgelehnte Anfrage bedient hat, prüfe das model-Feld auf oberster Ebene der Antwort und suche nach einem fallback_message-Eintrag in usage.iterations, wie es die Beispiele auf dieser Seite tun.
Nur eine Ablehnung durch den Sicherheitsklassifizierer löst das Fallback aus. Ein Ratenlimit, eine Überlastung oder ein Serverfehler auf dem angeforderten Modell wird dir unverändert zurückgegeben.
Der Beta-Header muss exakt das Datum 2026-07-01 tragen, das sowohl "default" als auch die explizite Listenform unten unterstützt, oder 2026-06-01, das nur die explizite Listenform akzeptiert. Unter jedem anderen server-side-fallback-*-Wert wird der fallbacks-Parameter mit einem 400-Fehler abgelehnt. Wenn du gegen eine frühere Vorschau dieses Features gebaut hast, aktualisiere den Beta-Header sowie die Anfrage- und Antwortformen gemeinsam auf die auf dieser Seite gezeigten.
Anstelle des Standard-Routings kannst du fallbacks auf eine Liste von bis zu drei Modellen setzen. Wenn das angeforderte Modell ablehnt, führt die API das nächste Modell in der Kette auf derselben Anfrage aus. Verwende diese Form, wenn du genau kontrollieren möchtest, welche Modelle abgelehnte Anfragen bedienen, etwa um ein Modell festzulegen, das deine Anwendung qualifiziert hat.
client = Anthropic()
response = client.beta.messages.create(
model="claude-fable-5",
max_tokens=1024,
messages=[{"role": "user", "content": "Hello, Claude"}],
fallbacks=[{"model": "claude-opus-4-8"}],
betas=["server-side-fallback-2026-07-01"],
)
print(response.model)Für die fallbacks-Liste gelten einige Regeln:
allowed_fallback_models im Eintrag des Modells in der Models API veröffentlicht.model und kann max_tokens, thinking, output_config und speed nur für diesen Versuch überschreiben.Die explizite Listenform funktioniert auch unter dem Beta-Header server-side-fallback-2026-06-01; der "default"-Modus nicht.
Die Antwort hat in beiden Modi dieselbe Form: Das Modell, das den Turn bedient hat, erscheint im model-Feld auf oberster Ebene, ein fallback-Content-Block markiert die Übergabe, und usage.iterations zeichnet jeden Versuch auf.
Die Antwort sieht aus wie jede andere Nachricht, mit zwei Ergänzungen:
model-Feld auf oberster Ebene meldet das Modell, das die zurückgegebene Nachricht erzeugt hat, egal ob das das angeforderte Modell oder ein Fallback ist.fallback-Content-Block markiert jeden Punkt in content, an dem die Ausgabe eines Modells an das nächste übergeht: {"type": "fallback", "from": {"model": ...}, "to": {"model": ...}}.
from.model gibt den Modell-String wieder, den du gesendet hast, wenn der ablehnende Hop das angeforderte Modell ist.to.model ist immer die aufgelöste ID des Modells, das fortfährt.Bei einer Ablehnung vor jeglicher Ausgabe ist der fallback-Block der erste Content-Block. Zum Beispiel, wenn das Standard-Routing Claude Opus 4.8 für die Kategorie der Ablehnung auswählt:
{
"id": "msg_01XFUDYJgAACzvnptvVoYEL",
"type": "message",
"role": "assistant",
"model": "claude-opus-4-8",
"content": [
{
"type": "fallback",
"from": { "model": "claude-fable-5" },
"to": { "model": "claude-opus-4-8" }
},
{ "type": "text", "text": "Hi! How can I help you today?" }
],
"stop_reason": "end_turn",
"stop_details": null,
"usage": {
"input_tokens": 412,
"output_tokens": 264,
"cache_read_input_tokens": 0,
"cache_creation_input_tokens": 0,
"iterations": [
{
"type": "message",
"model": "claude-fable-5",
"input_tokens": 535,
"output_tokens": 0,
"cache_read_input_tokens": 0,
"cache_creation_input_tokens": 0
},
{
"type": "fallback_message",
"model": "claude-opus-4-8",
"input_tokens": 412,
"output_tokens": 264,
"cache_read_input_tokens": 0,
"cache_creation_input_tokens": 0
}
]
}
}Das usage.iterations-Array zeichnet jeden Versuch auf. Ein Modell, das abgelehnt hat, erscheint als gewöhnlicher message-Eintrag, und das Modell, das den Turn bedient hat, erscheint als fallback_message-Eintrag. Wenn jedes Modell in der Kette ablehnt, ist die Antwort die Ablehnung des letzten Modells, mit einem message-Eintrag für jeden früheren Hop und einem fallback_message-Eintrag für den letzten.
Sende im nächsten Turn den Assistant-Content so zurück, wie du ihn erhalten hast. Nach einem Fallback mitten in der Ausgabe kann content Blocktypen enthalten, die das ablehnende Modell vor der Übergabe erzeugt hat; die folgende Tabelle zeigt, welche du behalten und welche du weglassen solltest, wenn du den Turn zurücksendest.
| Blocktyp | Im nächsten Turn |
|---|---|
fallback | Behalte ihn genau dort, wo er erschienen ist. Die API verwendet seine Position, um die Thinking-Blöcke um ihn herum zu validieren, sodass eine Anfrage, die Thinking-Blöcke von beiden Seiten der Grenze zurücksendet, abgelehnt wird, wenn der Block weggelassen oder verschoben wird. |
text | Behalten. |
Jeder Block nach dem letzten fallback-Block | Behalten. |
thinking, redacted_thinking oder connector_text vor dem letzten fallback-Block | Weglassen. |
Clientseitiges tool_use vor dem letzten fallback-Block | Weglassen. |
server_tool_use vor dem letzten fallback-Block | Behalten, wenn mit seinem Ergebnis gepaart. Weglassen, wenn es kein passendes Ergebnis hat. |
Ein connector_text-Block enthält Erzähltext, den manche Tool-nutzenden Antworten zwischen Tool-Aufrufen einfügen.
Bei einer Streaming-Anfrage erfolgt der Wiederholungsversuch auf demselben Stream, und nichts, was du bereits erhalten hast, wird ungültig. Was du siehst, hängt davon ab, wann die Ablehnung erfolgt.
Wenn die Ablehnung vor jeglicher Ausgabe erfolgt:
message_start benennt das Fallback-Modell, und der fallback-Block ist der erste Content-Block.message_start auf den Start des Fallback-Versuchs wartet, schließt die Zeit bis zum ersten Byte den abgelehnten Versuch ein.Wenn die Ablehnung mitten in der Ausgabe erfolgt:
fallback-Block (ein gewöhnliches content_block_start- und content_block_stop-Paar ohne Deltas) markiert die Grenze.text-Blöcke der teilweisen Ausgabe werden dem Fallback-Modell als Kontext übergeben; andere Blocktypen bleiben in content.message_start hat bereits das angeforderte Modell benannt, lies das bedienende Modell also aus dem to.model des fallback-Blocks und aus dem fallback_message-Eintrag in usage.iterations des letzten message_delta.Bei einer Nicht-Streaming-Anfrage verhält sich eine Ablehnung mitten in der Ausgabe anders: Die Antwort lässt die teilweise Ausgabe des abgelehnten Modells weg, und das Fallback-Modell antwortet von Grund auf neu. Das Ergebnis sieht aus wie eine Ablehnung vor jeglicher Ausgabe, mit dem fallback-Block an erster Stelle. Der abgelehnte Versuch und seine Output-Token erscheinen weiterhin in usage.iterations.
Ablehnungen während der Tool-Nutzung: Abgeschlossene Tool-Arbeit blockiert das Fallback nicht. Wenn eine Ablehnung ausgelöst wird, nachdem Server-Tools (zum Beispiel Websuche oder Code-Ausführung) innerhalb einer Anfrage die Ausführung abgeschlossen haben, wird der Fallback-Versuch fortgesetzt: Die abgeschlossenen Tool-Ergebnisse werden übernommen, und das Fallback-Modell kann weiterhin Server-Tools aufrufen. Der eine Fall, der nicht wiederholt wird, ist eine Streaming-Ablehnung, die ausgelöst wird, während ein Tool-Use-Block beliebigen Typs (ein Client-Tool, ein Server-Tool oder ein MCP-Tool-Aufruf) noch auf dem Stream offen ist: Diese Ablehnung wird direkt zurückgegeben, und wenn der Header fallback-credit-2026-07-01 gesetzt ist, trägt sie dennoch ein Guthaben-Token, das durch Fortsetzen der teilweisen Antwort eingelöst werden kann. Nicht-Streaming-Anfragen sind nicht betroffen; die API verwirft die teilweise Arbeit und wiederholt, bevor sie antwortet.
Jedes Anthropic SDK enthält eine Refusal-Fallback-Middleware. Du konfigurierst sie einmal auf dem Client mit deiner Liste von Fallback-Modellen. Aufrufe über client.beta.messages wiederholen abgelehnte Anfragen dann automatisch, auf jeder Plattform. Die Middleware sendet außerdem den Beta-Header fallback-credit-2026-07-01 bei jeder Anfrage, die sie verarbeitet, sodass Wiederholungsversuche ohne Einrichtung pro Anfrage neu bepreist werden.
Übergib die Middleware an den Client-Konstruktor und teile eine BetaFallbackState-Instanz über die Anfragen eines Gesprächs hinweg.
from anthropic import Anthropic, BetaFallbackState, BetaRefusalFallbackMiddleware
# Bei einer Ablehnung wiederholt die Middleware die Anfrage mit dem angegebenen Fallback-Modell und
# sendet automatisch bei jeder verarbeiteten Anfrage den Fallback-Credit-Beta-Header mit.
client = Anthropic(
middleware=[BetaRefusalFallbackMiddleware([{"model": "claude-opus-4-8"}])],
)
state = BetaFallbackState() # pins follow-ups to the model that accepted
# Streaming: Bei einer Ablehnung wiederholt die Middleware die Anfrage mit dem Fallback-Modell und
# fügt dessen Events in den offenen Stream ein.
with (
state,
client.beta.messages.stream(
max_tokens=1024,
model="claude-fable-5",
messages=[{"role": "user", "content": "Hello, Claude"}],
) as stream,
):
for text in stream.text_stream:
print(text, end="", flush=True)
final_message = stream.get_final_message()
print(f"\nserved by: {final_message.model}")
# Non-Streaming: Die Wiederverwendung des State hält die Konversation fixiert.
with state:
message = client.beta.messages.create(
max_tokens=1024,
model="claude-fable-5",
messages=[{"role": "user", "content": "Hello, Claude"}],
)
print(f"served by: {message.model}")fallback-Grenzblöcke, die sie selbst hinzugefügt hat.fallback-Content-Block an jeder Modellgrenze, genau wie serverseitige Fallback-Antworten. Die Middleware verwaltet diese Blöcke für dich bei späteren Anfragen.BetaFallbackState aufgezeichnet, sodass Folgeanfragen, die den State teilen, daran gebunden bleiben, anstatt ein Modell erneut zu fragen, das abgelehnt hat.Die Middleware und der serverseitige fallbacks-Parameter erledigen dieselbe Aufgabe. Konfiguriere das eine oder das andere, niemals beides in derselben Anfrage. Um eine serverseitige fallbacks-Anfrage aus einer Anwendung zu senden, die die Middleware installiert, verwende eine separate Client-Instanz ohne sie.
Eine abgelehnte Anfrage in einem Message Batch kommt als result.type: "succeeded" mit stop_reason: "refusal" zurück. Batch-Ergebnisse tragen dasselbe stop_details-Objekt wie synchrone Antworten, du kannst Ablehnungen also entweder über stop_reason oder stop_details.type erkennen. Ein Unterschied: Batch-Ablehnungen erzeugen keine Fallback-Guthaben, daher enthält stop_details bei einem Batch-Ergebnis nie ein fallback_credit_token.
Serverseitiges Fallback ist für Batches nicht verfügbar (eine Batch-Anfrage, die fallbacks enthält, erzeugt ein fehlerhaftes Ergebnis pro Element). Um abgelehnte Batch-Elemente zu wiederholen:
fallbacks-Parameter wird nicht in Modellaufrufe propagiert, die innerhalb der Tool-Ausführung gemacht werden.fallback_message-Eintrag in usage.iterations markiert Letztere) und alarmiere dann bei der Lücke zwischen den beiden Zählungen.stop_reason oder stop_details.type, nicht auf content oder die inneren stop_details-Felder. Das stop_details-Objekt ist bei einer Ablehnung immer vorhanden, aber seine Felder category und explanation können null sein. Prüfe direkt, ob stop_reason gleich "refusal" ist.Vermeide es, die Prompt-Cache-Kosten zweimal zu bezahlen, wenn du den Wiederholungsversuch selbst baust.
Jeder stop_reason-Wert und wie du damit umgehst.
Wie SDK-Middleware funktioniert, einschließlich des Refusal-Fallback-Helfers.
Migriere eine bestehende Anwendung zu Claude Fable 5.
Was this page helpful?