メインコンテンツへスキップ
ファイアウォールポリシーをキーにアタッチすると、モデルが ツール呼び出しをストリームで返し、response ステージがエージェントがそれに作用する 前にそれを剥がすか書き換えます。強制決定はすべてのプロバイダで同一です — 同じ ルール、同じ判定、同じイベント。異なるのは、ファイアウォールがストリーミングされた ツール呼び出しに作用した後にクライアントが見るワイヤーの形です。OpenAI chat、 OpenAI Responses API、ネイティブ Claude /v1/messages がそれぞれツール呼び出しを 異なってフレーム化するからです。 このページはそれらの顧客が観測可能な違いへの焦点を絞った注記です。ルール言語を 再文書化はしません — ファイアウォールルールを参照 — ステージモデルも同様で、ステージでカバーされています。 3 つすべてが共有する内部の保持・再組み立てメカニズムについては、 ストリーミング内部を読んでください。

1. なぜファイアウォールのプロバイダストリーミングがワイヤーで異なるか

非ストリームレスポンスでは、ファイアウォールは返信全体を一度に見て決定します。 ストリームでは、モデルのツール呼び出しは断片のシーケンスとして到着します — 1 つの フレームに名前、引数 JSON はさらに多くにまたがって少しずつ。判定は完全な呼び出し (名前完全な引数)を必要とし、ツール呼び出しの断片は一度転送されると撤回 できません。 そのためすべてのプロバイダでゲートウェイは同じことをします:通常のコンテンツを ライブでストリームさせ、呼び出しが完全に組み立てられるまでツール呼び出しフレームを 保持します。ストリーム終了時に各組み立てられた呼び出しを評価し、生き残ったもの のみを — そのプロバイダ独自のイベント形で — 発行します。
テキストは決して停滞しません。 ツール呼び出しフレームのみが保持されます。アシス タントコンテンツ、推論、role フレームはライブで変更なくストリームされます。保持は 最初のツール呼び出し断片からそのターンの終わりまで適用されます — そのためチャットのみの レスポンスはファイアウォールがアタッチされていないのと全く同様にストリームされます。

2. OpenAI chat completions

/v1/chat/completions では、ツール呼び出しはインデックスでキー付けられた delta.tool_calls 断片としてストリームされます。ゲートはそれら(とレガシーの delta.function_call 形)を保持し、終了フレームで、生き残った呼び出しをゼロから 再インデックスして発行し、続いて finish フレームを発行します:
結果クライアントが受け取るもの
allow元の保持されたフレーム、バイト単位 — 真の通過。
sanitize引数が書き換えられた 1 つの tool_calls デルタ、それから finish_reason: "tool_calls"
deny(一部の呼び出し)生き残った呼び出しのみ、それから finish_reason: "tool_calls"
deny(すべての呼び出し)ツール呼び出しなし、それから finish_reason: "stop" — ターンはモデルがテキストで答えることを選んだように見えます。
その最後の行がテスト対象となる手がかりです:ファイアウォールが OpenAI chat ターンから すべてのツール呼び出しを剥がすと、エージェントはエラーフレームではなくクリーンな finish_reason: "stop" を見ます。ループを「このターンはツール呼び出しなし」を有効な 結果として扱うように構築してください。

3. OpenAI Responses API

ネイティブの /v1/responses ストリームは独自のイベントモデルを持ちます — ツール 呼び出しは response.output_item.added で開き、response.function_call_arguments.delta 断片をストリームし、response.output_item.done で完了する function_call アイテム です。ファイアウォールは done、呼び出しが完全になる最初のポイントで評価します:
呼び出しがクリアされると、アイテムの added / argument-delta / done イベントが 変更なく発行されます。
added シェルがストリームされ、それから引数がリダクト版である done が — 元の argument-delta 断片はドロップされるため、リダクトされていない値が決してあなたに 到達しません。
バッファされたイベントはドロップされ、deny されたアイテムは、クライアントが最終 状態を構築する終端の response.completed オブジェクトからもフィルタアウトされ ます — 決して実行されなかった呼び出しへのぶら下がった参照はありません。
テキストと推論のデルタは、chat completions と全く同様に、全体を通じてライブで ストリームされます。

4. ネイティブ Claude /v1/messages

ネイティブの Anthropic ストリームは異なる獣です:コンテンツはインデックス付きの ブロックとして到着します — content_block_startcontent_block_deltainput_json_delta 断片)→ content_block_stopstop_reason を運ぶ message_delta で閉じられます。ファイアウォールは最初の tool_use ブロックから保持し、 それぞれを評価し、生き残ったブロックを連続したインデックスで再構築するため、剥がされた ブロックがインデックスのギャップを残しません。 Claude 固有の手がかりは stop_reason です。すべての tool_use ブロックが deny される 場合、tool_usestop_reason はクライアントに決して到着しないツール呼び出しを 約束してしまう — そのためゲートウェイはそれを end_turn に書き換えます:
upstream:  content_block_start (tool_use) … message_delta {stop_reason: "tool_use"}
            ↓ firewall denies the only tool_use
client:    (no tool_use block)            … message_delta {stop_reason: "end_turn"}
部分的な剥がしは、生き残った tool_use ブロックを連続して再インデックスして保ち、 stop_reason: "tool_use" をそのまま残します。
これはネイティブの Claude ストリームに適用されます。OpenAI 形式のエンドポイント 経由で呼び出された Claude モデルは代わりに OpenAI chat ワイヤー(§2)で強制されるため、 stop_reason: "end_turn" ではなく finish_reason: "stop" を表示します。ターン終了の 処理を、基礎となるモデルではなく呼び出したワイヤーフォーマットに合わせてください。

5. 具体例 1 つ

同じルールはすべてのプロバイダで同じ決定を生成します — クライアントが読むワイヤーの 形のみが異なります。response ステージで一度作成します:
{
  "stage": "response",
  "tool_name_glob": "shell.exec",
  "verdict": "deny",
  "args_match_json": "{\"clauses\":[{\"path\":\"$.command\",\"op\":\"regex\",\"value\":\"rm -rf|mkfs\"}]}"
}
同じプロンプトを 3 通りでストリームすると、ファイアウォールは毎回 rm -rf 呼び出しを deny します。クライアントが観測するもの:
ワイヤー完全な剥がし後の終端シグナル
OpenAI chatfinish_reason: "stop"
OpenAI Responsesresponse.completed からアイテムが不在
ネイティブ Claudestop_reason: "end_turn"
マッチして deny された呼び出しは、ワイヤーに関わらず ファイアウォールイベントに同一に表示されるため、 ストリームはそうでなくても可観測性はプロバイダに依存しません。

6. プロバイダをまたいで一定であるもの

ワイヤーは異なります;コントラクトは異なりません:
  • 判定とルールはワイヤーに依存しません。 allow / audit / deny / sanitize は すべてのプロバイダで同じことを意味します。判定を参照。
  • サニタイズはツール呼び出しの引数のみを触ります。ツールが返すコンテンツは 決して触りません — すべてのワイヤーで。 レスポンスのサニタイズを参照。
  • allow は真の通過です。 ファイアウォールが何も作用しないとき、保持されたフレームは 正確なアップストリームバイトとして再生されます — 再バッチなし、プロバイダ固有の フィールドの損失なし。
  • シャドウモードはどこでも適用されます。 それをオンにすると、保持されたツール 呼び出しは常に生き残り(audit に格下げ)、ポリシーがトラフィックを変える前に プロバイダをまたいだその影響を測定できます。 シャドウモードを参照。

7. これがどこに収まるか

ストリーミング内部

すべてのプロバイダが共有する保持・組み立て・再組み立てメカニズム。

ステージ

なぜストリーミングされたツール呼び出しの強制が response サーフェスに存在するか。

判定

ストリーミングされた呼び出しが解決するプロバイダに依存しない決定。

レスポンスフィルタリング

モデルが発行するツール呼び出しを、ストリームかどうかに関わらずゲート。
これらのストリーミングされたチェックが対処する脅威については、 危険なツール呼び出しデータ持ち出しを;ストリーム強制がリクエスト パスのどこに位置するかについては、 強制パスのレイテンシを参照してください。