400 ではなく、コードが分岐できる
型付きエラーを返します。3 つのセキュリティコードが、目にするケースをカバーします:
スクリーニングされたプロンプトまたはレスポンス、拒否されたツール呼び出し、そして
人間による承認のために保留されたツール呼び出しです。
このページは、それらのコードのリファレンスです — それぞれのユースケース、正確な
HTTP ステータス、何があなたのコストになるか、そして最も重要なひとつのルール:
リトライロジックはこれらを特別扱いしなければなりません。 3 つすべてが
skip-retry とマークされています;同じ呼び出しを盲目的に再実行しても、同じ
コントロールがまた発火するだけです。
これらは強制コードです — ゲートウェイがあなたの呼び出しを転送しないと
決定したものです。これらは、アップストリームのプロバイダエラー(モデルの 429、
コンテキストオーバーフロー)や認証エラーとは区別されます。特定のリクエストが
なぜ停止されたかについては、
なぜブロックされたのか?を参照してください。
1. LLM セキュリティエラーコード一覧
すべてのセキュリティブロックは、OpenAI 形式のエラーボディとともに HTTP 400 を返します(error.code は下記の型付き文字列です)。ネイティブ Claude
(/v1/messages)ルートでは、同じコードが Claude のエラー形状で伝わるため、
SDK ルーティングはプロトコルをまたいで決定論的です。
| コード | 停止するもの | クォータコスト |
|---|---|---|
guardrail_blocked | block ルールにヒットしたプロンプトまたはレスポンス | なし |
firewall_blocked | 拒否されたツール呼び出し / アドバタイズ | モデルトークンなし |
firewall_approval_pending | 人間のレビュアーのために保留されたツール呼び出し | モデルトークンなし |
2. guardrail_blocked — スクリーニングされたプロンプトまたはレスポンス
block アクションを持つガードレールルールが発火したときに
返されます — 拒否リストのキーワード、正規表現ヒット、マスクではなくブロックする
ことを選んだ PII やシークレットエンティティ、llm_judge 判定、あるいは失敗した
グラウンディングチェックです。
HTTP 400。 メッセージは、発火したガードレールとルールを名指しします。
クォータへの影響:なし
クォータへの影響:なし
ブロックされたリクエストはクォータを消費しません。入力ステージのブロックは
メータリングの前に発火するため、何も課金されません。出力ステージのブロックは
モデルが応答した後に走るため、ゲートウェイはエラーを返す前に事前消費された
クォータを返金します。いずれにせよ、ブロックされた呼び出しには何も払いません。
なぜ skip-retry なのか
なぜ skip-retry なのか
判定はコンテンツのプロパティであり、チャネルのプロパティではありません。同じ
プロンプトを — 別のモデルに対してでも — 再実行すると、同じブロックが生じます。
リトライする代わりに、入力(またはポリシー)を修正してください。
代わりにマスクがどう見えるか
代わりにマスクがどう見えるか
mask ルールはこのコードを返しません。マスクされたマッチ(例:
jane@acme.com → [EMAIL])はその場でリダクトされ、呼び出しは通常通り進みます
— 200 が返り、機密スパンだけが取り除かれます。block アクションだけが
guardrail_blocked を表面化させます。(flag はトラフィックについて何も変えません。)3. firewall_blocked — 拒否されたツール呼び出し
ファイアウォールがツール呼び出しに対して deny 判定を
解決したときに返されます — 破壊的シェルコマンド、SSRF 形状のフェッチ、拒否リスト
上の egress 宛先、あるいは block モードのスキルです。
deny がどう表面化するかは、強制サーフェス
に依存します:
inbound / response / egress
error.code = firewall_blocked の HTTP 400。ボディは構造化された
error.metadata(reason_code、リスク factors、risk_score)を運ぶため、
ブロックを見るだけでなく説明できます。mcp サーフェス
トランスポート障害ではなく、ツールエラー(
firewall deny: <reason>)として
返されます — モデルは拒否を見て、別のツールを選ぶ、ユーザーに尋ねる、あるいは
停止することができ、実行をクラッシュさせる代わりになります。4. firewall_approval_pending — 人間のために保留
ツール呼び出しが pending_approval 判定にヒットした瞬間に返されます。
ヒューマンインザループのゲートはブロッキングなインラインの待機にはできないため、
ゲートウェイはロングポーリングではなく、即座に保留レスポンスを返します。
HTTP 400。 エラーは承認 id を運ぶため、エージェントはどの保留を解決すべきかを
知ることができます。
これは、終端的な失敗として扱うのではなく、解決して再送信することで反応する
唯一のコードです:
決定を待つ
レビュアーがコンソール(Developer+)からそれを解決するか、あなたの承認システムが
HMAC 署名付き webhook コールバックを受け取ります。エージェントは状態を
GET /api/v1/firewall/approvals/:id でポーリングします。承認ルート(
/api/v1/firewall/approvals/*)は、コンソールセッションではなく
ファイアウォールゲートウェイスコープのキー上で動作します。フルループについては
人間による承認(HITL)を、
コールバック署名についてはWebhook ペイロードを
参照してください。5. なぜ 3 つすべてがリトライをスキップするのか
標準的な SDK リトライロジックは、400 が 2 回目の試行で成功するかもしれないと
仮定します。これらのコードはその仮定を壊します — ブロックは決定論的なので、盲目的な
リトライはラウンドトリップを無駄にし、(保留された呼び出しについては)サイレントに
承認を再キューイングします。
「skip-retry」が実際に意味するもの
「skip-retry」が実際に意味するもの
OrcaRouter 自身の内部リトライ/フォールバック機構は、これらのコードを返す呼び出しを
別のチャネルに対して再試行することは決してありません。クライアントでもそれを
ミラーしてください:セキュリティコードでは、停止して判定に基づいて行動するのであり、
ループしないでください。
コードごとの正しい反応
コードごとの正しい反応
guardrail_blocked→ 入力を修正するかポリシーを緩和する;拒否をユーザーに 表面化する。リトライしない。firewall_blocked→ そのアクションは許可されていません;エージェントに別の ツールを選ばせるか、助けを求めさせます。リトライしない。firewall_approval_pending→ 保留を解決してから、承認ヘッダーとともに一度だけ 再送信する(§4)。ヘッダーなしのリトライは再保留します。
6. クォータと課金のサマリー
セキュリティブロックは、ブロックされた作業単位についてあなたに課金することは 決してありません。| コード | いつ発火するか | 課金結果 |
|---|---|---|
guardrail_blocked(input) | モデル呼び出しの前 | 決してメータリングされない |
guardrail_blocked(output) | モデルが応答した後 | 事前消費されたクォータを返金 |
firewall_blocked(inbound) | モデル呼び出しの前 | モデルトークンなし |
firewall_approval_pending | ディスパッチの前 | モデルトークンなし |
7. 関連リファレンス
なぜブロックされたのか?
1 つのブロックを、それを生み出した正確なルール、サーフェス、理由までトレースします。
判定用語集
すべてのファイアウォール判定 — allow、audit、deny、sanitize、pending_approval、
cap_cost — とそれぞれが何を発するか。
Webhook とエラーペイロード
完全なエラーエンベロープ、
error.metadata フィールド、そして承認コールバック署名。強制モード
シャドウ、観察、強制 — 判定が実際にトラフィックを変えるのはいつか。
