Claude Platform Docs
PesanMembangun dengan Claude

Penolakan dan fallback

Bagaimana model Claude Fable, model Claude Opus, Claude Sonnet 5.5, dan Claude Haiku 5.5 mengembalikan penolakan classifier dan cara mencoba ulang permintaan yang ditolak pada model fallback.

Claude Fable 5.1, Claude Fable 5, Claude Opus 5.5, Claude Opus 5, Claude Sonnet 5.5, dan Claude Haiku 5.5 menyertakan "safety classifier" (pengklasifikasi keamanan) yang dapat menolak sebuah permintaan. Ketika hal itu terjadi, Anda menerima respons normal, bukan error, dengan stop_reason: "refusal". stop_details.category pada respons tersebut menyebutkan area kebijakannya (lihat Seperti apa penolakan itu). Anda biasanya masih bisa mendapatkan jawaban dengan mengirimkan permintaan yang sama ke model Claude lain. Halaman ini menunjukkan cara mengenali "refusal" (penolakan) dan cara menyiapkan percobaan ulang tersebut.

Baca halaman ini ketika Anda membangun di atas salah satu model ini dan ingin permintaan yang ditolak diteruskan ke model lain secara otomatis. Halaman ini juga berlaku ketika Anda telah melihat "refusal" dalam sebuah respons dan ingin tahu apa yang harus dilakukan selanjutnya.

Halaman terkait:

Penyiapan paling sederhana, dalam beta di Claude API: atur fallbacks ke "default", dan API akan mencoba ulang permintaan yang ditolak pada model fallback yang direkomendasikan Anthropic untuk kategori penolakannya. Untuk kategori tanpa fallback yang direkomendasikan, penolakan tetap berlaku. Claude Haiku 5.5 tidak memiliki fallback sisi server, jadi untuk model tersebut gunakan fallback sisi klien dengan middleware SDK atau tulis percobaan ulang sendiri.

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.

Seperti apa penolakan itu

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 saja alih-alih mem-parse-nya.
  • recommended_model: hanya ada pada permintaan yang mengatur fallbacks (fallback sisi server, beta). Field ini menyebutkan model untuk dicoba ulang secara langsung ketika API melewatkan percobaan fallback (misalnya, model fallback terkena batas laju), dan bernilai null jika tidak. Ini adalah petunjuk, bukan jaminan.
  • category dan explanation keduanya null ketika penolakan tidak terpetakan ke kategori bernama. Nilai null itu adalah nilai normal dan permanen, bukan placeholder.
  • stop_details sendiri bernilai null untuk setiap stop reason selain refusal.
categoryArtinyaDitagih sebelum output apa pun
"cyber"Permintaan dapat memungkinkan bahaya siber, seperti pengembangan malware atau exploit. Pekerjaan keamanan siber yang tidak berbahaya juga dapat memicu kategori ini.Tidak
"bio"Permintaan dapat memungkinkan bahaya biologis, seperti metode laboratorium berbahaya. Pekerjaan ilmu hayati yang bermanfaat juga dapat memicu kategori ini.Ya
"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.Ya
"reasoning_extraction"Permintaan meminta model untuk mereproduksi penalaran internalnya dalam teks respons. Untuk mendapatkan penalaran dalam bentuk terstruktur, gunakan adaptive thinking. Lihat Simpan penalaran di blok thinking.Ya
"general_harms"Permintaan termasuk dalam area kebijakan penggunaan di luar empat kategori bernama. Pekerjaan yang tidak berbahaya juga dapat memicu kategori ini.Tidak

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.

Simpan penalaran di blok thinking

Penolakan reasoning_extraction biasanya berasal dari prompt yang meminta model untuk menaruh pemikiran atau penalarannya di output, baik secara verbatim maupun dalam format tetap. Contoh umum:

  • Bagian <thinking>, <reasoning>, atau scratchpad yang diisi model sebelum menjawab
  • Field reasoning, thinking, atau trace dalam output JSON atau dalam input alat
  • Catatan pribadi model, atau log berjalan dari penalarannya
  • Penalaran yang diminta secara verbatim atau secara lengkap

Kata-kata tersebut dapat berada di prompt sistem, skill, atau deskripsi alat, jadi periksa juga bagian-bagian itu.

Anda tetap dapat meminta Claude untuk menjelaskan jawabannya. Mintalah penjelasan singkat, bukti di balik suatu hasil, atau ringkasan tindakan yang diambilnya. Untuk melihat bagaimana model bernalar, atur display: "summarized" dan baca blok thinking. Kategori ini tidak memiliki model fallback yang direkomendasikan, jadi ubah prompt alih-alih mencoba ulang permintaan. Jika permintaan yang sudah diubah kata-katanya masih ditolak, hubungi dukungan dan sertakan ID permintaan.

Cara penolakan ditagih

Aturan penagihan ini berlaku di setiap platform: Claude API, Amazon Bedrock, Claude Platform on AWS, Google Cloud, dan Microsoft Foundry.

Penolakan sebelum output apa pun: Untuk menghambat upaya mengakali pengamanan Anthropic dalam skala besar, penolakan yang tiba sebelum output apa pun ditagih jika stop_details.category-nya adalah "bio", "frontier_llm", atau "reasoning_extraction". Per September 2026, ini adalah kategori dengan volume "false positive" (positif palsu) yang rendah menurut pengukuran Anthropic. Penolakan ini ditagih seperti permintaan lainnya, dengan tarif model yang menjalankannya. Penolakan sebelum output apa pun dalam kategori lain, atau dengan kategori null, tidak ditagih. Dalam kedua kasus, content kosong dan jumlah token muncul di usage. Permintaan tetap dihitung terhadap batas laju Anda.

Penolakan di tengah stream: Penolakan di tengah stream menagih token input dan output yang sudah di-stream dengan tarif normal.

Fallback: Saat Anda menggunakan fallback, penolakan yang memicunya ditagih, selain permintaan fallback itu sendiri, jika penolakan tersebut terjadi di tengah stream atau termasuk dalam salah satu kategori yang ditagih. Kredit fallback mengompensasi cache miss prompt pada permintaan fallback, sehingga Anda tidak membayar untuk meng-cache percakapan dua kali. Penolakan Claude Haiku 5.5 tidak membawa kredit fallback, sehingga fallback setelahnya membayar biaya penuh untuk menulis prompt cache model fallback. Untuk cara fallback sisi server melaporkan setiap percobaan, lihat Penagihan dan batas laju.

Kategori yang ditagih dapat berubah seiring Anthropic terus mengukur dan menyempurnakan tingkat positif palsu pengamanannya. Kolom Ditagih sebelum output apa pun dalam tabel kategori penolakan mencantumkan kategori yang ditagih.

Memilih pendekatan fallback

Ada tiga cara untuk mencoba ulang permintaan yang ditolak pada model lain. Cara yang tepat bergantung pada di mana Anda menjalankannya dan seberapa banyak kontrol yang Anda butuhkan.

Situasi AndaGunakanMengapa
Claude API, penyiapan paling sederhanaFallback sisi serverSatu permintaan, satu respons. API menangani percobaan ulang.
Platform apa pun, menggunakan SDK AnthropicMiddleware SDKKonfigurasi sekali pada klien. Percobaan ulang terjadi secara otomatis.
HTTP mentah atau logika percobaan ulang kustomPercobaan ulang manual dengan kredit fallbackKontrol penuh. Kredit fallback menekan biaya.

Fallback sisi server dan middleware SDK menerapkan kredit fallback untuk Anda. Anda hanya memerlukan halaman Kredit fallback ketika Anda membangun percobaan ulang sendiri. Claude Haiku 5.5 tidak memiliki fallback sisi server maupun kredit fallback, jadi gunakan middleware SDK atau percobaan ulang manual.

Fallback sisi server

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. Sebagai gantinya, Anda dapat menyebutkan hingga tiga model fallback Anda sendiri. Dengan cara mana pun, Anda mendapatkan kembali satu respons yang menyebutkan model yang menjawab, sehingga pengguna Anda mendapatkan jawaban dalam satu round trip.

Membuat permintaan

Atur parameter fallbacks ke string "default" dan kirim header beta server-side-fallback-2026-07-01. API kemudian menerapkan routing 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 harus memelihara daftar model saat rekomendasi berubah.

Routing default tidak pernah memunculkan penolakan gambar berukuran berlebih di awal untuk model yang tidak Anda pilih: model hasil routing yang akan mengubah ukuran gambar bertanda "oversized_image": "error" dikeluarkan dari routing, sehingga gambar yang ditandai tidak pernah disajikan dalam ukuran yang diubah.

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 dalam usage.iterations berarti model fallback dijalankan;
# pasangkan dengan stop_reason untuk memastikan 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 pengaman untuk setiap model secara individual dan untuk setiap kategori kebijakan, sesuai dengan kemampuan model: bergantung pada kategorinya, permintaan yang ditandai dapat di-fallback ke model yang kurang mampu atau ditolak. Mode "default" mengodekan 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 mana pun: respons menyebutkan model yang melayaninya, dan blok konten fallback menandai serah terima.

Routing diterapkan di sisi server dan tidak dipublikasikan per model di 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, overload, atau error server pada model yang diminta dikembalikan kepada Anda apa adanya.

Menyebutkan model fallback Anda sendiri

Alih-alih routing 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 dengan tepat model mana yang melayani permintaan yang ditolak, seperti mengunci model yang telah dikualifikasi oleh aplikasi Anda.

Model fallback yang disebutkan dihitung dalam pemeriksaan gambar berukuran berlebih: permintaan yang blok gambarnya mengatur "oversized_image": "error" diperiksa di awal terhadap model yang diminta dan setiap fallback yang disebutkan, ditolak jika salah satunya akan mengubah ukuran gambar tersebut, dan target rescale yang dilaporkan pada penolakan cocok untuk semuanya.

Baris yang disorot adalah satu-satunya perbedaan dari permintaan routing default.

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:

  • Entri dicoba secara berurutan. Setiap entri harus berbeda dari entri lainnya dan dari model yang diminta.
  • Setiap entri harus merupakan salah satu target yang diizinkan untuk model yang diminta. Dengan beta header diatur, daftar tersebut dipublikasikan sebagai allowed_fallback_models pada entri model di Models API.
  • Setiap entri menyebutkan model dan dapat menimpa max_tokens, thinking, output_config, dan speed hanya untuk percobaan tersebut.
  • Permintaan harus valid sebagai permintaan langsung ke setiap model yang disebutkan. Jika model fallback tidak mendukung fitur yang digunakan permintaan, API menolak permintaan di awal. Dengan header 2026-07-01, thinking: {"type": "between_tools"} adalah pengecualian: ketika permintaan Claude Sonnet 5.5 dialihkan ke Claude Sonnet 5, percobaan fallback berjalan dengan thinking: {"type": "disabled"} dan display: "omitted". Dengan 2026-06-01, atur thinking pada entri Claude Sonnet 5, atau permintaan akan ditolak di awal.
  • Sama seperti mode default, hanya penolakan oleh pengklasifikasi keamanan yang memicu fallback. Batas laju, kelebihan beban, atau error server pada model yang diminta dikembalikan kepada Anda apa adanya.
  • Jika model fallback terkena batas laju atau kelebihan beban, percobaan fallback tidak dilakukan dan penolakan sebelumnya yang dikembalikan. Field stop_details.recommended_model pada penolakan tersebut kemudian menyebutkan model untuk dicoba ulang secara langsung. Sesuaikan batas laju model fallback dengan volume penolakan yang Anda perkirakan, atau fallback akan berubah menjadi penolakan saat beban tinggi.

Respons memiliki bentuk yang sama di kedua mode: model yang melayani giliran muncul di field model tingkat atas, blok konten fallback menandai serah terima, dan usage.iterations mencatat setiap percobaan.

Apa yang terkandung dalam respons

Respons terlihat seperti pesan lainnya, dengan dua tambahan:

  • Field model tingkat atas melaporkan model yang menghasilkan pesan yang dikembalikan, baik itu model yang diminta maupun fallback.
  • Blok konten fallback menandai setiap titik di content tempat 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 di-resolve dari model yang melanjutkan.

Pada penolakan sebelum output apa pun, blok fallback adalah blok konten pertama. Misalnya, ketika routing 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.

Sticky routing dapat mengirim giliran berikutnya langsung ke model fallback. Giliran seperti itu tidak membawa blok konten fallback, karena tidak ada model yang menolak giliran tersebut. Identifikasi melalui entri fallback_message di usage.iterations, tidak adanya entri message untuk model yang diminta, dan field model pada respons.

Melanjutkan percakapan

Pada giliran berikutnya, kirim kembali konten asisten sebagaimana Anda menerimanya. Setelah fallback di tengah output, content dapat menyertakan tipe blok yang dihasilkan model yang menolak sebelum serah terima. Tabel berikut membahas mana yang dipertahankan dan mana yang dibuang ketika Anda menggemakan giliran tersebut.

Tipe blokPada giliran berikutnya
fallbackPertahankan tepat di tempat ia muncul. API menggunakan posisinya untuk memvalidasi blok thinking di sekitarnya, sehingga permintaan yang menggemakan blok thinking dari kedua sisi batas ditolak jika blok ini dihilangkan atau dipindahkan.
textPertahankan.
Blok apa pun setelah blok fallback terakhirPertahankan.
thinking, redacted_thinking, atau connector_text sebelum blok fallback terakhirBuang.
tool_use sisi klien sebelum blok fallback terakhirBuang.
server_tool_use sebelum blok fallback terakhirPertahankan jika berpasangan dengan hasilnya. Buang jika tidak memiliki hasil yang cocok.

Streaming

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.
  • Karena message_start menunggu percobaan fallback dimulai, time to first byte mencakup percobaan yang ditolak.

Ketika penolakan terjadi di tengah output:

  • Blok konten yang terbuka ditutup, dan blok fallback (pasangan content_block_start dan content_block_stop biasa tanpa delta) menandai batasnya.
  • Model fallback melanjutkan dari output parsial. Hanya blok text dari output parsial yang diteruskan ke model fallback sebagai konteks. Tipe blok lain 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.

Respons non-streaming

Pada permintaan non-streaming, penolakan di tengah output berperilaku berbeda: respons menghilangkan output parsial model yang ditolak, dan model fallback menjawab dari awal. Hasilnya terlihat seperti penolakan sebelum output apa pun, dengan blok fallback di posisi pertama. Percobaan yang ditolak dan token outputnya tetap muncul di usage.iterations.

Penagihan dan batas laju

Setiap percobaan mengikuti aturan di Cara penolakan ditagih, dengan tarif model yang menjalankannya. Percobaan yang menolak sebelum menghasilkan output apa pun hanya ditagih jika kategori penolakannya termasuk yang ditagih, dan tokennya tetap dilaporkan pada entri usage.iterations-nya. Setiap percobaan yang menghasilkan output, termasuk yang menolak di tengah responsnya, ditagih secara terpisah. Array usage.iterations adalah catatan per-percobaan dari apa yang ditagihkan kepada Anda. Jumlah usage tingkat atas hanya menggambarkan percobaan yang menghasilkan pesan yang dikembalikan. Token dari model yang berbeda tidak pernah dijumlahkan ke dalam satu field.

Setiap percobaan yang berjalan, termasuk yang menolak, dihitung terhadap batas laju modelnya sendiri.

Sticky routing

Setelah percakapan mengalami fallback, API mencatat model mana yang melayaninya. Permintaan berikutnya untuk percakapan tersebut yang menyertakan fallbacks langsung menuju model fallback itu, tanpa menjalankan model yang diminta. Ini menghindari pembayaran untuk percobaan yang dapat diprediksi akan ditolak lagi pada setiap giliran.

Beberapa sifat keputusan routing:

  • Disimpan selama kurang lebih 1 jam dan dicakup ke organisasi Anda.
  • Disimpan sebagai hash konten dari prefiks percakapan ditambah model yang melayaninya. Konten pesan itu sendiri tidak disimpan.
  • Bersifat best-effort, sehingga kode Anda harus menangani kemungkinan model yang diminta dicoba lagi kapan saja.

Sticky routing berlaku untuk permintaan streaming maupun non-streaming. Pada permintaan streaming, keputusan routing dibuat sebelum stream dibuka, sehingga field model pada event message_start sudah membawa ID model fallback.

Fallback sisi klien dengan middleware SDK

SDK menyertakan middleware refusal-fallback. Anda mengonfigurasinya sekali pada 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 mengirim header beta fallback-credit-2026-07-01 pada setiap permintaan yang ditanganinya, sehingga percobaan ulang dihitung ulang harganya tanpa penyiapan per permintaan. Penolakan Claude Haiku 5.5 tidak membawa kredit fallback, sehingga percobaan ulang setelahnya membayar biaya penuh untuk menulis prompt cache model fallback.

Menyiapkannya

Teruskan BetaRefusalFallbackMiddleware ke konstruktor klien, dan bagikan satu instance 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 terpatok.
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}")

Bagaimana perilakunya

  • Percobaan ulang menelusuri daftar fallback Anda secara berurutan. Model fallback yang juga menolak akan meneruskan permintaan ke entri berikutnya.
  • Ketika setiap model dalam daftar telah menolak, middleware mengembalikan penolakan terakhir (respons penolakan dari model terakhir) alih-alih memunculkan error.
  • Blok thinking dari Claude Fable 5.1, Claude Opus 5.5, Claude Sonnet 5.5, Claude Haiku 5.5, atau Claude Fable 5 diteruskan tanpa perubahan. Setiap percobaan ulang mengirim ulang body permintaan asli Anda, dan satu-satunya blok yang dihapus middleware dari riwayat percakapan pada permintaan berikutnya adalah blok batas fallback yang ditambahkannya sendiri. Model fallback tidak dapat membaca blok Claude Fable 5.1, yang hanya dibaca oleh Claude Fable 5.1 dan Claude Mythos 5.1, sehingga API membuangnya. API juga membuang blok Claude Opus 5.5 untuk setiap model fallback kecuali Claude Fable 5.1 dan Claude Mythos 5.1 (lihat Beralih model di tengah percakapan). API juga membuang blok Claude Sonnet 5.5 untuk setiap model fallback kecuali Claude Opus 5.5 di Claude API dan Google Cloud. Claude Opus 5.5 dan Claude Sonnet 5.5 membaca blok Claude Haiku 5.5 di Claude API dan Google Cloud, dan API membuangnya untuk model fallback yang tidak dapat membacanya.
  • Respons yang dilayani melalui middleware menyertakan blok konten fallback di setiap batas model, sama seperti respons fallback sisi server. Middleware mengelola blok-blok tersebut untuk Anda pada permintaan berikutnya.
  • Model yang menerima permintaan dicatat di BetaFallbackState, sehingga permintaan lanjutan yang berbagi state tersebut tetap terkunci pada model itu alih-alih bertanya lagi ke model yang menolak.

Menulis percobaan ulang sendiri

Melalui HTTP mentah atau dengan logika percobaan ulang kustom, implementasikan pola yang dibungkus middleware:

  1. Deteksi penolakan

    Periksa respons untuk stop_reason: "refusal".

  2. Kirim ulang pada model fallback

    Kirim permintaan yang sama dengan model diatur ke model fallback, seperti Claude Opus 4.8. Jika permintaan yang ditolak mengirim thinking: {"type": "between_tools"}, ubah thinking terlebih dahulu: hanya Claude Sonnet 5.5 yang menerima nilai tersebut, jadi hilangkan thinking atau atur nilai yang diterima model fallback. Fallback sisi server dengan header 2026-07-01 melakukan perubahan ini untuk Anda ketika beralih ke Claude Sonnet 5. Model lain biasanya dapat melayani permintaan yang ditolak oleh Claude Fable 5.1 atau Claude Fable 5. Cara Anda menangani riwayat percakapan bergantung pada apakah Anda menukarkan kredit fallback:

    • Tidak menukarkan kredit: Anda dapat membiarkan blok thinking dan redacted_thinking sebelumnya tetap di tempatnya atau menghapusnya untuk menghemat token input. Model fallback biasanya tidak dapat menggunakannya dalam kedua kasus: hanya Claude Fable 5.1 dan Claude Mythos 5.1 yang membaca blok Claude Fable 5.1, dan hanya kedua model tersebut, Claude Fable 5, dan Claude Mythos 5 yang membaca blok Claude Fable 5, sehingga untuk model fallback lainnya API membuangnya. API juga membuang blok Claude Opus 5.5 untuk setiap model fallback kecuali Claude Fable 5.1 dan Claude Mythos 5.1 (lihat Beralih model di tengah percakapan). API juga membuang blok Claude Sonnet 5.5 untuk setiap model fallback kecuali Claude Opus 5.5 di Claude API dan Google Cloud. Percobaan ulang setelah penolakan Claude Haiku 5.5 selalu termasuk dalam kasus ini. Claude Opus 5.5 dan Claude Sonnet 5.5 membaca blok Claude Haiku 5.5 di Claude API dan Google Cloud, jadi biarkan blok tersebut tetap di tempatnya ketika Anda beralih ke salah satu model tersebut di sana. Untuk model fallback yang tidak dapat membacanya, API membuangnya tanpa menagihnya.
    • Menukarkan kredit: kirim body tanpa perubahan, karena penukaran memerlukan kecocokan persis. Server menangani blok thinking dari model sebelumnya saat penukaran, jadi jangan menghapusnya (lihat Field yang harus cocok dengan permintaan yang ditolak).
  3. Tetap gunakan model fallback

    Untuk percakapan multi-giliran, terus gunakan model fallback untuk giliran-giliran berikutnya alih-alih beralih kembali.

Percobaan ulang manual menulis prompt cache model fallback dari awal, yang biayanya lebih tinggi daripada membaca cache yang sudah ada. Kredit fallback mengembalikan biaya tersebut; tukarkan kredit itu pada setiap percobaan ulang yang Anda bangun sendiri. Penolakan Claude Haiku 5.5 tidak membawa kredit fallback, sehingga percobaan ulang setelahnya membayar biaya penuh untuk menulis prompt cache model fallback.

Penolakan dalam Message Batches

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 menerbitkan 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:

  1. Kumpulkan item yang ditolak dari hasil.
  2. Biarkan blok thinking dalam riwayat multi-giliran tetap di tempatnya, atau hapus untuk menghemat token input. Untuk model fallback yang tidak dapat membacanya, API membuangnya tanpa menagihnya, seperti pada percobaan ulang manual.
  3. Jika item yang ditolak mengirim thinking: {"type": "between_tools"}, hilangkan thinking atau atur nilai yang diterima model fallback. Hanya Claude Sonnet 5.5 yang menerima between_tools.
  4. Kirim ulang item tersebut pada model fallback sebagai batch baru atau sebagai permintaan langsung.

Kesalahan umum

  • Coba ulang pada model yang berbeda. Mengirim ulang permintaan yang ditolak ke model yang sama biasanya menghasilkan penolakan lagi. Arahkan percobaan ulang ke model fallback.
  • Anggarkan percobaan ulang per permintaan, bukan per giliran atau per sesi. Satu giliran dapat menghasilkan beberapa penolakan, misalnya sebuah agen beserta sub-agennya.
  • Konfigurasikan fallback pada setiap jalur permintaan. Handler percobaan ulang, cabang pemulihan error, dan worker latar belakang semuanya membutuhkannya. Handler yang menerbitkan ulang permintaan tanpa fallback kehilangan perlindungan tepat pada permintaan yang paling mungkin membutuhkannya.
  • Berikan panggilan sub-agen fallback-nya sendiri. Parameter fallbacks tidak merambat ke panggilan model yang dibuat dari dalam eksekusi alat.
  • Jadikan fallback sebagai properti permintaan, bukan state ambien. Flag bersama, nilai konfigurasi yang di-cache, atau toggle global dapat menjadi tidak sinkron dan diam-diam membiarkan permintaan tidak terlindungi. Ketika Anda tidak dapat memastikan fallback aktif, konfigurasikan alih-alih berasumsi bahwa ia aktif.
  • Instrumentasikan penolakan sebagai sinyal tersendiri. Penolakan adalah HTTP 200, sehingga pemantauan yang dibangun berdasarkan tingkat error atau respons 5xx tidak pernah melihatnya. Pancarkan satu event per penolakan dan satu per respons yang dilayani fallback (entri fallback_message di usage.iterations menandai yang terakhir), lalu buat peringatan berdasarkan selisih antara kedua hitungan tersebut.
  • Bercabanglah berdasarkan stop_reason atau stop_details.type, bukan content atau field stop_details bagian dalam. Objek stop_details selalu ada pada penolakan, tetapi field category dan explanation-nya bisa null. Periksa stop_reason sama dengan "refusal" secara langsung.

Langkah selanjutnya

Hindari membayar biaya prompt-cache 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 sudah ada ke Claude Fable 5.1.

Was this page helpful?