stop_reason: refusal

Claude Fable 5 の stop_reason: refusal

安全性分類器がリクエストを拒否しました。成功した HTTP 200 レスポンスであり、だからこそ多くの連携がこれに気づけません。

30 秒でわかる要点

Fable 5 にはリクエストを拒否できる安全性分類器があります。拒否は HTTP 200 で、stop_reason は refusal、content 配列は空、カテゴリを示す stop_details オブジェクトが付き、例外は発生しません。呼び出しのたびに stop_reason で分岐し、カテゴリを読み、別の Claude モデルで再試行してください。特に reasoning_extraction は意表を突かれやすく、モデルに考えた過程を示すよう求めるプロンプトが該当します。

5 つの拒否カテゴリ

stop_details.category が反応したポリシー領域を示します。名前付きカテゴリに対応しない拒否では category も explanation も null になり、この null はプレースホルダーではなく恒久的な値です。

  • bio

    危険な実験手法など、生物学的な危害につながり得るリクエストです。有益なライフサイエンス業務でも該当することがあります。Claude Code では Fable 5 で bio 判定が出るとセッションが Opus 5 に移りますが、Opus 5 も独自の生物学分類器を持ちその先のフォールバックがないため、以降の bio 判定はそのまま拒否になります。

  • cyber

    マルウェアやエクスプロイト開発など、サイバー面の危害につながり得るリクエストです。良性のセキュリティ業務でも該当します。ペネトレーションテスト、CTF 演習、セキュリティツールのリポジトリでは頻繁に、しばしば最初のリクエストから発生しますが、これは想定内のルーティングであり、アカウントに問題があるわけではありません。

  • frontier_llm

    競合する AI モデルの開発支援につながり得るリクエストで、Anthropic の商用規約で制限されています。良性の機械学習業務でも該当することがあり、評価ハーネスやモデル比較ツールが思わぬ形でここに入ることがあります。

  • general_harms

    有害と判断された領域に触れるものの、より具体的なカテゴリに当てはまらないリクエストです。良性の業務でもまれに該当します。表現を変えたり、意図の背景を補足したりすることで解消できる可能性が最も高いカテゴリでもあります。

  • reasoning_extraction

    モデルに内部の推論を応答テキストとして再現するよう求めるリクエストです。プロンプト、スキル、ハーネスの指示に「考えた過程を示して」「順を追って考えて」「推論を説明して」といった表現があると該当し、Opus 4.8 へのフォールバックが急増します。Fable 5 で最も多い自作自演型の拒否です。

この順序で対処する

緩和より先に検知です。拒否の件数を数えられなければ、フォールバックが機能しているかどうかも判断できません。

  1. 1

    2. プロンプトから推論再現を求める表現を洗い出す

    システムプロンプト、スキル、ハーネスの指示から、内部の推論を応答テキストとして復唱・転記・説明させる記述を探して削除してください。推論を可視化したい場合は、アダプティブ思考が返す構造化された thinking ブロックを読む方式に変更します。

  2. 2

    1. content ではなく stop_reason で分岐する

    呼び出しのたびに stop_reason が refusal かどうか、または stop_details.type を直接確認してください。content 配列が空であることから推測してはいけませんし、stop_details.explanation もパースしないでください。文言は安定せず、ロジック用ではなく表示用です。

  3. 3

    3. すべてのリクエスト経路にフォールバックを設定する

    サーバーサイドフォールバックには fallbacks パラメータと server-side-fallback-2026-07-01 ベータヘッダーが必要で、Claude API ではベータ提供です。SDK ミドルウェアはどのプラットフォームでも使えます。いずれの場合も、リトライハンドラやバックグラウンドワーカーにも適用し、サブエージェントの呼び出しには個別に設定してください。このパラメータはツール実行内で行われるモデル呼び出しには伝播しません。

  4. 4

    5. 拒否を独立した指標として計測する

    拒否は 200 なので、エラー率や 5xx を前提とした監視では決して検知できません。拒否 1 件につき 1 イベント、フォールバックが応答した場合にも 1 イベント(usage.iterations の fallback_message エントリで識別)を発行し、両者の差分にアラートを設定してください。

  5. 5

    4. フォールバック先にレート制限の余裕を確保する

    フォールバック先のモデル自体がレート制限や過負荷になっていると、フォールバックの試行はスキップされ、元の拒否がそのまま返されます。想定する拒否量に見合う上限を確保しないと、負荷が最も高いときに限ってフォールバックが静かに拒否へ退化します。

拒否ではない場合

レスポンスが 200 ではなく実際の HTTP エラーなら、ステータスコードから調べ始めてください。対処方法はまったく異なります。

よくある質問