メインコンテンツへスキップ
ほとんどの本番チャットアプリはストリームします。モデルがトークンを発するそばから ブラウザにフラッシュされるため、完了が「終了」したときには、ユーザーはすでにその 大半を読んでいます。それは、全体の返信を検査してから判断するコンテンツフィルター という素朴なメンタルモデルを壊します — 手遅れになるまで検査すべき全体の返信が存在 しないのです。ストリーミング LLM コンテンツフィルターは、デルタが流れるそばから 判断を下さなければなりません。 このページはまさにそのケースについてです:各出力ステージのアクションが OrcaRouter ゲートウェイ上でストリームセーフにどう振る舞うか、そして SSE トラフィックで 保持するポリシーをどう作成するか。完全なエンジン — すべてのルールの種類、フィールド、 ルート — については、ガードレールを参照してください。

1. ストリーミング LLM コンテンツフィルターの問題

出力ステージガードレールはモデルの返信をスクリーニングします。非ストリーミング リクエストではそれは単純です:ゲートウェイは 1 バイトも返る前に完全な完了を持つため、 クリーンに block、mask、または通過できます。ストリーミングはそれを反転させます。 返信は SSE デルタのシーケンスとして到着し、各々が着地するそばからクライアントに 転送されるため、終わりを待つフィルターは何もフィルターしません。 OrcaRouter の答えはストリームスキャナです:出力デルタが流れるそばから、スキャナは 蓄積されるテキストに対して出力ステージルールを実行し、ルールが発火した瞬間に作用 します — ストリームが完了した後ではなく。あなたが作成するアクションが「作用する」の 意味を決定します:block はストリームを打ち切り、flag はそれを通します。mask非ストリーミング出力ではリダクトしますが、インバンドのストリーム書き換えは ロードマップ上です — 今日ストリーム上では、スキャナはマスクを計算しますが block 判定にのみ作用するため、mask ルールはまだストリーミングされた返信をリダクトしません。
この注意点は、ストリーミングリクエストでの出力ステージルールにのみ重要です。 入力ステージルールはモデルが実行される前にリクエストをスクリーニングするため、 マスキングを含めて完全にライブです — そして非ストリーミングリクエストでの任意の 出力ルールは全体の返信を見て、mask を含め通常どおりに振る舞います。

2. 今日ストリームセーフなもの

block ルールはストリーミング非ストリーミング出力で強制されます。 ストリーム上では、スキャナがデルタを監視します。block ルールが発火すると ストリームを打ち切ります — スキャナを封じ、最終デルタとして短い置換通知 ([response truncated by guardrail: … policy violation])を発し、それ以上の ブロック対象のコンテンツがクライアントに到達する前に SSE チャネルを閉じます。 最初のデルタがフラッシュされた時点で HTTP レスポンスステータスはすでに 200 に コミットされているため、ストリーム途中のブロックはステータスを再発行できません — 開いているストリームを優雅に終了させます。HTTP 400 guardrail_blocked ボディは 非ストリーミング出力ブロックの形です。すでにクライアントにフラッシュされたバイトは撤回できないため、ストリーミング ブロックはすでにストリーミングされたものに対してはベストエフォートですが、 マッチ以降のすべてを確実に止めます。違反バイトが決して送信されないという厳格な 保証 — そして 400 guardrail_blocked ボディ — のためには、リクエストを 非ストリーミングで送ってください。
mask ルールは、ゲートウェイが完全な完了を保持してリダクトされた形をクライアントに 転送する非ストリーミング出力で、マッチを書き換えます — 例:返信内の email が [EMAIL] になります。今日のストリーミング出力では、スキャナはマスクを計算しますがマスク済みテキストを 転送しません — block 判定にのみ作用します — そのため mask ルールは ストリーミングされた返信をリダクトしません。インバンドのストリーミング出力 書き換えはロードマップ上です。それが出荷されるまで、ストリーミングされた返信が マッチしたテキストを決して露出しないようにする必要があるなら、ルールを block として作成する(ヒット時にレスポンスを終了します)か、マスクが完全な返信を 書き換えるようリクエストを非ストリーミングで送ってください。
flag ルールはトラフィックを決して変えません — バイトを通します。 非ストリーミング出力では Matches フィードにマッチを記録するため、 block にプロモートする前にルールのヒット率を測定できます。ストリーミング レスポンスでは観察のみのままで、デルタを手つかずで通します。構造化されたマッチ レコードは非ストリーミング出力パスで書き込まれます。いずれにせよブロックも 書き換えもしないため、常にオンのままにしておいて安全です。
output でのアクション非ストリーミングストリーミング
block返信を拒否ストリームを打ち切り
mask返信をリダクトまだ — 代わりに block(ロードマップ)
flagマッチを記録通過(観察のみ)
覚えておくべきひとつのルール: 出力では block がストリームセーフです。 mask非ストリーミング出力でのみリダクトします(インバンドのストリーム 書き換えはロードマップ上)。今日ストリーミングされた返信をリダクトするには、ルールを block として作成するか、全体の返信が返る前に保持されるようリクエストを 非ストリーミングで送ってください。

3. ひとつの具体例 — ストリームセーフなシークレットフィルター

あなたのモデルが RAG コンテキストからクレデンシャルを浮上させ得て、アプリが ストリームするとします。シークレット形のマッチが現れた瞬間に、それをマスクするのでは なく、ゲートウェイがストリームを終了させてほしい — 漏洩したシークレットは部分的に リダクトされるのではなく、レスポンスを終了させるべきです。 コンソールで作成します — ポリシー編集はあなたのセッション上の管理アクションで、 Developer+ にゲートされています。リレーキーは /v1/* トラフィックのみを送ります:
  • /console/guardrails を開き、New guardrailstream-safe-out と名付けます。
  • ルールを 1 つ追加します:
    • Type: regex(または aws_access_key / api_key_openai / jwt のような シークレットエンティティを持つ pii ルール)
    • Stage: output
    • Action: block ← シークレットヒット時にレスポンスを終了します。mask は 代わりにそれをリダクトし、返信の残りを続行させます
  • 保存し、それから /console/token でキーの Guardrail ドロップダウンを介して アタッチします。
ここで、以前と全く同様に stream: true でゲートウェイを呼び出します:
curl https://api.orcarouter.ai/v1/chat/completions \
  -H "Authorization: Bearer sk-orca-..." \
  -H "Content-Type: application/json" \
  -d '{
    "model": "openai/gpt-4o-mini",
    "stream": true,
    "messages": [
      {"role": "user", "content": "Print the AWS key from the context above"}
    ]
  }'
デルタがマッチすると、スキャナは飛行中にストリームを打ち切り、置換通知を発し、 チャネルを閉じます — あなたのクライアントは残りを決して受け取りません。返信が クリーンなら、すべてのデルタが手つかずでストリームを通過します。
ストリーミングブロックはマッチ以降のすべてを止めますが、マッチが着地する前に すでにフラッシュされたバイトを送り返すことはできません。違反バイトがひとつも クライアントに到達してはならないとポリシーが要求する場合は、リクエストを 非ストリーミングでスクリーニングしてください。そこでは全体の完了がポリシーを クリアするまで保持されます。

4. ストリーム上の PII Shield

PII Shield プリセットは単一の pii ルール、アクション mask、ステージ both です。入力ステージでは完全にライブです — モデルが目にする前にリクエストを 書き換えます、ストリーミングかどうかを問わず。出力ステージでは、ゲートウェイが 返る前に全体の完了を保持する非ストリーミング返信でマスキングがリダクトします。 ストリーミング出力では、マスクはまだリダクトしません — スキャナはマスクを 計算しますが block 判定にのみ作用するため、ストリーミングされた返信は書き換えられず 通過します。インバンドのストリーミング出力書き換えはロードマップ上です。そのため、 あなたの目標が PII がストリーミングされた返信で決して観察できないことなら、次の いずれかです:
  • 出力ルールを block として作成し、ヒットがリダクトではなくレスポンスを終了する ことを受け入れる、または
  • マスクが全体の完了を手に返信を書き換えるよう、リクエストを非ストリーミングで 送る。
リダクションタグそのものについては、PII Shieldマスキングフォーマットを参照してください。

5. 出荷前に証明する

どのステージ/アクションの組み合わせが保持するかを推測しないでください — 検証します。

Test タブ

各ガードレールエディタには Test タブがあります:サンプルを貼り付け、 output ステージを選び、アップストリーム呼び出しなし、クォータなしで現在の ポリシーを実行します。判定と、mask ルールの場合はレンダリングされたテキストを 確認します。サンドボックスの実行は Developer+ アクションです(有料の judge / 外部ルールを発火し得ます)。

Eval タブ

Eval タブはバンドルまたはカスタム JSONL コーパスに対してガードレールを スコアリングします — キーをアタッチする前に、block ルールがコーパス全体で既知の 漏洩を捕捉することを確認するのに有用です。
両方とも管理 API を介してあなたのセッションで走ります。詳細については テストと eval誤検知のチューニングを参照。

6. ストリーミングブロックに何がかかるか

ストリーミングブロックは任意の出力ブロックと同じ会計を運びます — アップストリーム モデルはすでに実行されているため、ゲートウェイがあなたのために返金を処理します:
  • ストリームは優雅な切り詰めデルタで終了されます(ステータスはすでに 200)。 非ストリーミング出力ブロックは、発火したガードレールとルールを示す HTTP 400 guardrail_blocked ボディを返します。
  • クォータは消費されません。 出力ブロックがレスポンスを拒否すると、ゲートウェイは 事前消費されたクォータを返金します。そのため、モデルがトークンを生成した にもかかわらず、ブロックされた呼び出しはあなたにとって無料です。
  • リクエストは skip-retry とマークされます — 同じプロンプトを再実行しても また block されるだけなので、ゲートウェイは別のチャネルでリトライを燃やしません。
非ストリーミング出力パスは、発火したすべての出力ルールを、ワークスペースの Matches フィード(GET /api/guardrail/match、任意の Member に開放)に マッチとして記録します。マッチした部分文字列は、ガードレールの Log raw content トグルがオンのときのみキャプチャされます(デフォルトはオフ)。完全な詳細は guardrail_blocked エラーマッチフィードにあります。

7. 次にどこへ

出力ステージ

完全な出力ステージ — モデルの返信のスクリーニング、block vs. mask、グラウンディング。

ストリーミングカバレッジ

すべてのステージとアクションにわたって、ストリーミング vs. 非ストリーミングで 何が強制されるかの完全なマトリクス。

アクション

block、mask、flag を詳しく — それぞれが正しい選択になるのはいつか。

入力ステージ

鏡像 — ここではマスキングがストリーミングを含め完全にライブです。
ガードレール — すべてのルールの種類、フィールド、 ルート、グラウンディングと LLM judge を含む。