Claude Fable 5 dan Claude Opus 5 menyertakan safety classifier (pengklasifikasi keamanan) yang dapat menolak sebuah permintaan. Ketika itu terjadi, Anda menerima respons normal, bukan error, dengan stop_reason: "refusal". Anda biasanya masih bisa mendapatkan jawaban dengan mengirimkan permintaan yang sama ke model Claude lain. Halaman ini menunjukkan cara mengenali penolakan dan cara menyiapkan percobaan ulang tersebut.
Baca halaman ini ketika Anda membangun di atas Claude Fable 5 atau Claude Opus 5 dan ingin permintaan yang ditolak dialihkan ke model lain secara otomatis. Halaman ini juga berlaku ketika Anda baru saja melihat "refusal" dalam sebuah respons dan ingin tahu apa yang harus dilakukan selanjutnya.
Halaman terkait:
stop_reason.Penyiapan paling sederhana, dalam beta di Claude API: atur fallbacks ke "default", dan API mencoba ulang permintaan yang ditolak pada model fallback yang direkomendasikan Anthropic untuk kategori penolakannya. Untuk kategori tanpa fallback yang direkomendasikan, penolakan tetap berlaku.
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)Bagian-bagian berikut membahas apa yang terkandung dalam respons penolakan, kapan menggunakan fallback sisi server atau sisi klien, dan bagaimana masing-masing ditagih.
Penolakan adalah respons HTTP 200 yang berhasil dengan 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
}
}Objek stop_details menjelaskan penolakan tersebut:
category: menyebutkan area kebijakan yang memicu classifier.explanation: deskripsi yang dapat dibaca manusia. Teksnya tidak stabil, jadi tampilkan alih-alih mem-parsing-nya.null ketika penolakan tidak terpetakan ke kategori bernama. Nilai null tersebut adalah nilai normal dan permanen, bukan placeholder.stop_details sendiri bernilai null untuk setiap stop reason selain refusal.category | Artinya |
|---|---|
"cyber" | Permintaan dapat memungkinkan bahaya siber, seperti pengembangan malware atau exploit. Pekerjaan keamanan siber yang tidak berbahaya juga dapat memicu kategori ini. |
"bio" | Permintaan dapat memungkinkan bahaya biologis, seperti metode laboratorium yang berbahaya. Pekerjaan ilmu hayati yang bermanfaat juga dapat memicu kategori ini. |
"frontier_llm" | Permintaan dapat membantu pengembangan model AI pesaing, yang dibatasi berdasarkan ketentuan komersial Anthropic. Pekerjaan machine learning yang tidak berbahaya juga dapat memicu kategori ini. |
"reasoning_extraction" | Permintaan meminta model untuk mereproduksi penalaran internalnya dalam teks respons. Untuk mendapatkan penalaran dalam bentuk terstruktur, gunakan adaptive thinking. |
"general_harms" | Permintaan dapat terkait dengan area yang ditentukan sebagai berbahaya. Pekerjaan yang tidak berbahaya terkadang dapat memicu kategori ini. |
Penolakan dapat tiba sebelum output apa pun, atau di tengah stream setelah output parsial. Dalam kedua kasus, perlakukan output parsial apa pun sebagai tidak lengkap dan buang.
Bagaimana penolakan ditagih: Anda tidak ditagih untuk penolakan yang tiba sebelum output apa pun. content kosong, dan jumlah token muncul di usage tetapi tidak dikenakan biaya. Permintaan tersebut tetap dihitung terhadap batas laju Anda. Penolakan di tengah stream menagih token input dan output yang sudah di-stream dengan tarif normal.
Ada tiga cara untuk mencoba ulang permintaan yang ditolak pada model lain. Pilihan yang tepat bergantung pada di mana Anda berjalan dan seberapa banyak kontrol yang Anda butuhkan.
| Situasi Anda | Gunakan | Alasan |
|---|---|---|
| Claude API, penyiapan paling sederhana | Fallback sisi server | Satu permintaan, satu respons. API menangani percobaan ulang. |
| Platform apa pun, menggunakan SDK Anthropic | Middleware SDK | Konfigurasikan sekali di klien. Percobaan ulang terjadi secara otomatis. |
| HTTP mentah atau logika percobaan ulang kustom | Percobaan ulang manual dengan kredit fallback | Kontrol penuh. Kredit fallback menjaga biaya tetap rendah. |
Fallback sisi server dan middleware SDK menerapkan kredit fallback untuk Anda. Anda hanya memerlukan halaman Kredit fallback ketika Anda membangun percobaan ulang sendiri.
Fallback sisi server mencoba ulang permintaan yang ditolak di dalam satu panggilan API. Dalam mode default, ketika model utama menolak dan kategori penolakan memiliki fallback yang direkomendasikan, API menjalankan permintaan yang sama pada model yang direkomendasikan Anthropic untuk kategori tersebut. Anda juga dapat menyebutkan hingga tiga model fallback Anda sendiri (di bawah). Dengan cara apa pun, Anda mendapatkan kembali satu respons yang menyebutkan model yang menjawab, sehingga pengguna Anda mendapatkan jawaban dalam satu perjalanan bolak-balik.
Fallback sisi server dalam beta di Claude API. Parameter fallbacks tidak didukung pada Message Batches API (item batch yang menyertakannya kembali sebagai hasil error) dan tidak tersedia di Amazon Bedrock, Google Cloud, atau Microsoft Foundry. Pada platform tersebut, gunakan fallback sisi klien dengan middleware SDK sebagai gantinya.
Atur parameter fallbacks ke string "default" dan kirim header beta server-side-fallback-2026-07-01. API kemudian menerapkan perutean default yang ditentukan server untuk model yang diminta, yang memilih model fallback yang direkomendasikan berdasarkan kategori penolakan yang dilaporkan classifier, sehingga permintaan yang ditolak dilayani tanpa Anda perlu memelihara daftar model saat rekomendasi berubah.
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"],
)
# Entri fallback_message di usage.iterations berarti model fallback telah berjalan;
# padukan dengan stop_reason untuk memastikan bahwa fallback yang melayani respons.
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 menetapkan pengamanan untuk setiap model secara individual dan untuk setiap kategori kebijakan, sesuai dengan kemampuan model: bergantung pada kategorinya, permintaan yang ditandai dapat dialihkan ke model yang kurang mampu atau ditolak. Mode "default" mengkodekan rekomendasi per-model, per-kategori ini untuk Anda, sehingga permintaan yang ditolak dicoba ulang pada model yang direkomendasikan Anthropic untuk kategori tersebut. Fallback terlihat dengan cara apa pun: respons menyebutkan model yang melayaninya, dan blok konten fallback menandai peralihan.
Perutean diterapkan di sisi server dan tidak dipublikasikan per model pada Models API. Untuk melihat model mana yang melayani permintaan yang ditolak, periksa field model tingkat atas pada respons dan cari entri fallback_message di usage.iterations, seperti yang dilakukan contoh-contoh di halaman ini.
Hanya penolakan safety classifier yang memicu fallback. Batas laju, kelebihan beban, atau error server pada model yang diminta dikembalikan kepada Anda apa adanya.
Header beta harus membawa tepat tanggal 2026-07-01, yang mendukung baik "default" maupun bentuk daftar eksplisit di bawah, atau 2026-06-01, yang hanya menerima bentuk daftar eksplisit. Di bawah nilai server-side-fallback-* lainnya, parameter fallbacks ditolak dengan error 400. Jika Anda membangun berdasarkan pratinjau awal fitur ini, perbarui header beta serta bentuk permintaan dan respons secara bersamaan ke yang ada di halaman ini.
Alih-alih perutean default, Anda dapat mengatur fallbacks ke daftar hingga tiga model. Ketika model yang diminta menolak, API menjalankan model berikutnya dalam rantai pada permintaan yang sama. Gunakan bentuk ini ketika Anda ingin mengontrol secara tepat model mana yang melayani permintaan yang ditolak, seperti menetapkan model yang telah dikualifikasi oleh aplikasi Anda.
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)Beberapa aturan berlaku untuk daftar fallbacks:
allowed_fallback_models pada entri model di Models API.model dan dapat menimpa max_tokens, thinking, output_config, dan speed hanya untuk percobaan tersebut.Bentuk daftar eksplisit juga berfungsi di bawah header beta server-side-fallback-2026-06-01; mode "default" tidak.
Respons memiliki bentuk yang sama dalam kedua mode: model yang melayani giliran muncul di field model tingkat atas, blok konten fallback menandai peralihan, dan usage.iterations mencatat setiap percobaan.
Respons terlihat seperti pesan lainnya, dengan dua tambahan:
model tingkat atas melaporkan model yang menghasilkan pesan yang dikembalikan, baik itu model yang diminta maupun fallback.fallback menandai setiap titik dalam content di mana output satu model beralih ke model berikutnya: {"type": "fallback", "from": {"model": ...}, "to": {"model": ...}}.
from.model menggemakan string model yang Anda kirim ketika hop yang menolak adalah model yang diminta.to.model selalu merupakan ID yang telah diselesaikan dari model yang melanjutkan.Pada penolakan sebelum output apa pun, blok fallback adalah blok konten pertama. Misalnya, ketika perutean default memilih Claude Opus 4.8 untuk kategori penolakan tersebut:
{
"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
}
]
}
}Array usage.iterations mencatat setiap percobaan. Model yang menolak muncul sebagai entri message biasa, dan model yang melayani giliran muncul sebagai entri fallback_message. Jika setiap model dalam rantai menolak, responsnya adalah penolakan model terakhir, dengan entri message untuk setiap hop sebelumnya dan entri fallback_message untuk yang terakhir.
Pada giliran berikutnya, kirim kembali konten assistant seperti yang Anda terima. Setelah fallback di tengah output, content dapat menyertakan tipe blok yang dihasilkan model yang menolak sebelum peralihan; tabel berikut membahas mana yang harus dipertahankan dan mana yang harus dibuang ketika Anda menggemakan giliran tersebut.
| Tipe blok | Pada giliran berikutnya |
|---|---|
fallback | Pertahankan tepat di tempat ia muncul. API menggunakan posisinya untuk memvalidasi blok thinking di sekitarnya, sehingga permintaan yang menggemakan blok thinking dari kedua sisi batas akan ditolak jika blok tersebut dihilangkan atau dipindahkan. |
text | Pertahankan. |
Blok apa pun setelah blok fallback terakhir | Pertahankan. |
thinking, redacted_thinking, atau connector_text sebelum blok fallback terakhir | Buang. |
tool_use sisi klien sebelum blok fallback terakhir | Buang. |
server_tool_use sebelum blok fallback terakhir | Pertahankan ketika dipasangkan dengan hasilnya. Buang ketika tidak memiliki hasil yang cocok. |
Blok connector_text membawa teks narasi yang disertakan beberapa respons penggunaan alat di antara panggilan alat.
Pada permintaan streaming, percobaan ulang terjadi pada stream yang sama, dan tidak ada yang sudah Anda terima yang menjadi tidak valid. Apa yang Anda lihat bergantung pada kapan penolakan terjadi.
Ketika penolakan terjadi sebelum output apa pun:
message_start menyebutkan model fallback, dan blok fallback adalah blok konten pertama.message_start menunggu percobaan fallback dimulai, waktu ke byte pertama mencakup percobaan yang ditolak.Ketika penolakan terjadi di tengah output:
fallback (pasangan content_block_start dan content_block_stop biasa tanpa delta) menandai batasnya.text dari output parsial yang diteruskan ke model fallback sebagai konteks; tipe blok lainnya tetap berada di content.message_start sudah menyebutkan model yang diminta, jadi baca model yang melayani dari to.model pada blok fallback dan dari entri fallback_message di usage.iterations pada message_delta terakhir.Pada permintaan non-streaming, penolakan di tengah output berperilaku berbeda: respons menghilangkan output parsial dari model yang menolak, dan model fallback menjawab dari awal. Hasilnya terlihat seperti penolakan sebelum output apa pun, dengan blok fallback di urutan pertama. Percobaan yang ditolak dan token output-nya tetap muncul di usage.iterations.
Penolakan selama penggunaan alat: pekerjaan alat yang telah selesai tidak menghalangi fallback. Ketika penolakan terjadi setelah alat server (misalnya, pencarian web atau eksekusi kode) selesai dieksekusi dalam sebuah permintaan, percobaan fallback tetap berjalan: hasil alat yang telah selesai terbawa, dan model fallback dapat terus memanggil alat server. Satu-satunya kasus yang tidak dicoba ulang adalah penolakan streaming yang terjadi saat blok tool-use dari tipe apa pun (alat klien, alat server, atau panggilan alat MCP) masih terbuka pada stream: penolakan tersebut dikembalikan secara langsung, dan jika header fallback-credit-2026-07-01 diatur, penolakan tersebut tetap membawa token kredit yang dapat ditukarkan dengan melanjutkan respons parsial. Permintaan non-streaming tidak terpengaruh; API membersihkan pekerjaan parsial dan mencoba ulang sebelum merespons.
Setiap SDK Anthropic menyertakan middleware refusal-fallback. Anda mengonfigurasinya sekali di klien dengan daftar model fallback Anda. Panggilan melalui client.beta.messages kemudian mencoba ulang permintaan yang ditolak secara otomatis, di platform apa pun. Middleware juga mengirimkan header beta fallback-credit-2026-07-01 pada setiap permintaan yang ditanganinya, sehingga percobaan ulang dihargai ulang tanpa penyiapan per-permintaan.
Berikan middleware ke konstruktor klien, dan bagikan satu instans BetaFallbackState di seluruh permintaan dalam sebuah percakapan.
from anthropic import Anthropic, BetaFallbackState, BetaRefusalFallbackMiddleware
# Saat terjadi penolakan, middleware mencoba ulang pada model fallback yang terdaftar dan
# secara otomatis mengirim header beta fallback-credit pada setiap permintaan yang ditanganinya.
client = Anthropic(
middleware=[BetaRefusalFallbackMiddleware([{"model": "claude-opus-4-8"}])],
)
state = BetaFallbackState() # pins follow-ups to the model that accepted
# Streaming: saat terjadi penolakan, middleware mencoba ulang pada model fallback dan
# menyambungkan event-nya ke stream yang sedang terbuka.
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: menggunakan kembali state menjaga percakapan tetap terpaku (pinned).
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 yang ditambahkannya sendiri.fallback pada setiap batas model, sama seperti respons fallback sisi server. Middleware mengelola blok-blok tersebut untuk Anda pada permintaan berikutnya.BetaFallbackState, sehingga permintaan lanjutan yang berbagi state tersebut tetap terikat padanya alih-alih menanyakan kembali model yang menolak.Middleware dan parameter fallbacks sisi server melakukan pekerjaan yang sama. Konfigurasikan salah satunya, jangan pernah keduanya pada permintaan yang sama. Untuk mengirim permintaan fallbacks sisi server dari aplikasi yang memasang middleware, gunakan instans klien terpisah tanpa middleware tersebut.
Permintaan yang ditolak dalam Message Batch kembali sebagai result.type: "succeeded" dengan stop_reason: "refusal". Hasil batch membawa objek stop_details yang sama dengan respons sinkron, sehingga Anda dapat mendeteksi penolakan melalui stop_reason atau stop_details.type. Satu perbedaan: penolakan batch tidak menghasilkan kredit fallback, sehingga stop_details pada hasil batch tidak pernah menyertakan fallback_credit_token.
Fallback sisi server tidak tersedia untuk batch (permintaan batch yang menyertakan fallbacks menghasilkan hasil error per-item). Untuk mencoba ulang item batch yang ditolak:
fallbacks tidak menyebar ke panggilan model yang dibuat dari dalam eksekusi alat.fallback_message di usage.iterations menandai yang terakhir), lalu buat peringatan pada selisih antara kedua hitungan tersebut.stop_reason atau stop_details.type, bukan berdasarkan content atau field dalam stop_details. Objek stop_details selalu ada pada penolakan, tetapi field category dan explanation-nya dapat bernilai null. Periksa stop_reason yang sama dengan "refusal" secara langsung.Hindari membayar biaya cache prompt dua kali ketika Anda membangun percobaan ulang sendiri.
Setiap nilai stop_reason dan cara menanganinya.
Cara kerja middleware SDK, termasuk helper refusal-fallback.
Pindahkan aplikasi yang ada ke Claude Fable 5.
Was this page helpful?