Vai al contenuto principale
Se la tua app fa streaming, ti serve una risposta diretta prima di fidarti di una content policy: cosa viene effettivamente applicato su una risposta SSE. Un guardrail che ispeziona una risposta intera è facile da comprendere; un guardrail che deve agire sui delta man mano che vengono emessi al browser no. Questa pagina è la matrice di copertura dei guardrail in streaming — ogni azione, attraverso gli stage di input e output, su traffico in streaming e non — scritta per essere precisa su come si comporta ogni cella su uno stream attivo. Per il motore completo — ogni tipo di regola, campo e rotta — vedi Guardrails. Per i meccanismi di come uno stream viene interrotto, vedi regole stream-safe.

1. La domanda sulla copertura dei guardrail in streaming

Una regola di guardrail porta uno stage (input, output o both) e un’azione — una tra cinque: block, mask, flag, annotate o spotlight. Lo stage decide quando il gateway la esegue; l’azione decide cosa fa. L’unico posto in cui lo streaming cambia la forma della risposta è lo stage di output — perché è l’unico stage in cui il gateway sta inoltrando byte al tuo client man mano che arrivano, senza possibilità di detenere prima l’intero payload. Quindi la matrice ha due celle dove lo streaming conta, e si comportano diversamente: il block di output è completamente applicato su uno stream (lo scanner lo interrompe), ma il mask di output è applicato solo sulle risposte non in streaming. Su una risposta in streaming lo scanner rileva comunque il match e può agire su una decisione di block, ma non riscrive il testo mascherato nello stream oggi — il masking dell’output in-band in streaming è nella roadmap.
L’input non è mai il problema. Le regole dello stage di input girano prima del modello — il gateway filtra (e, per mask, riscrive) la tua richiesta, poi inoltra la versione sanitizzata upstream. Se la risposta sarà in streaming è irrilevante; la richiesta è un payload completo che il gateway detiene per intero. La scansione di input è completamente attiva, masking incluso, su ogni richiesta.

2. La matrice di copertura

Leggi questa dall’alto in basso. Ogni cella di block è attiva, streaming incluso — ma output + mask + streaming è l’unica cella che non è ancora applicata nello stream: una regola mask redige una risposta non in streaming, e su una risposta in streaming rileva il match senza riscrivere il delta (il masking dell’output in-stream è nella roadmap).
Stage · azioneNon streamingStreaming
input · blockrifiuta la richiestarifiuta la richiesta
input · maskriscrive la richiestariscrive la richiesta
output · blockrifiuta la rispostainterrompe lo stream
output · maskredige la rispostarileva il match; non redige in-stream (roadmap)
qualsiasi · flagregistra soloregistra solo
annotate e spotlight allegano una nota (o avvolgono il testo corrispondente) senza rifiutare il traffico e sono in pratica azioni dello stage di input, quindi non cambiano le celle output/streaming sopra; registrano un match come qualsiasi altra regola.
Le regole dello stage di input filtrano la richiesta prima che il modello upstream giri. Un block corto-circuita la chiamata (HTTP 400 guardrail_blocked, prima della misurazione, quindi non costa quota). Un mask riscrive i campi corrispondenti nel prompt sul posto — il testo sanitizzato è ciò che va upstream, e il modello non vede mai l’originale. Nulla di ciò dipende dal fatto che la risposta sia in streaming.
Su una risposta non in streaming la completion viene filtrata per intero prima che torni — un block emerge come HTTP 400 guardrail_blocked. Su una risposta in streaming uno scanner di stream osserva i delta man mano che fluiscono; quando una regola di block scatta interrompe lo stream — sigilla lo scanner, emette un breve avviso sostitutivo al posto del resto, e chiude il canale SSE prima che ulteriore contenuto bloccato raggiunga il client. Poiché gli header SSE 200 sono già usciti per allora, un block in streaming non può restituire un 400: consegna il block come un delta in-band finale anziché un errore HTTP.
Su una risposta non in streaming una regola mask riscrive la completion — es. un’email diventa [EMAIL] — e il testo sanitizzato è ciò che il tuo client ottiene. Su una risposta in streaming lo scanner di stream rileva comunque il match e calcola la maschera, ma non inoltra il testo mascherato nel delta — l’output mascherato viene scartato e solo una decisione di block viene agita. Quindi una regola mask non redige una risposta in streaming oggi; il masking dell’output in-band in streaming è nella roadmap. Se hai bisogno che la PII sia tenuta fuori da una risposta streamata adesso, scrivi la regola come block (lo scanner interrompe lo stream sul match) o filtra in modalità non streaming.
Una regola flag non altera mai il traffico — registra un match e lascia passare i byte. Stage e stream non cambiano il suo comportamento. Usala per misurare il tasso di hit di una regola prima di promuoverla a block.
L’unica riga da ricordare: il block di output è applicato attivo su entrambi i trasporti — streaming incluso — e il masking di input è sempre attivo. Il mask di output redige solo le risposte non in streaming; su uno stream rileva il match ma non riscrive ancora il delta (il masking dell’output in-stream è nella roadmap). Per tenere la PII fuori da una risposta streamata oggi, scrivi la regola come block o filtra in modalità non streaming.

3. Un esempio concreto — tieni la PII fuori da una risposta streamata

Supponi che il modello possa far emergere un’email di cliente dal contesto RAG, e che la tua app faccia streaming. Il mask di output non redige nello stream oggi (il masking dell’output in-stream è nella roadmap) — quindi per tenere la PII fuori da una risposta streamata, scrivi la regola di output come block: lo scanner uccide lo stream nel momento in cui appare un match. (Il mask di output redige su una risposta non in streaming.) La modifica della policy è un’azione di management sulla tua sessione della console (gestita a Developer+); la chiave di relay sk-orca-... invia solo traffico /v1/* e non modifica mai la policy.
  • Apri /console/guardrails, New guardrail, chiamalo stream-pii-out.
  • Aggiungi una regola:
    • Type: PII detection
    • Stage: output
    • Action: block ← interrompe lo stream sul match; su uno stream mask solo rileva (redige le risposte non in streaming)
  • Salva, poi collegalo su /console/token tramite il menu a tendina Guardrail della chiave.
Ora chiama il gateway con stream: true, esattamente come prima:
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": "Email the customer from the record above"}
    ]
  }'
Se un delta corrisponde, lo scanner interrompe lo stream, emette un avviso sostitutivo e chiude il canale — il client non riceve mai il resto. Se la risposta è pulita, ogni delta passa intatto.
Un block in streaming ferma tutto dopo il match, ma non può non-inviare i byte già emessi prima che il match atterrasse. Se la tua policy esige che nemmeno un byte offensivo raggiunga mai il client, filtra la richiesta non in streaming, dove l’intera completion è detenuta finché la policy non la libera.

4. PII Shield attraverso la matrice

Il preset PII Shield è una singola regola pii, azione mask, stage both. Mappalo sulla matrice e la copertura è esattamente ciò che ti aspetteresti dalla §2:
  • Stage di input — completamente attivo, in streaming o meno. La richiesta è mascherata prima che il modello la veda (il valore principale del masking di input).
  • Stage di output, non streaming — la completion è mascherata prima che torni.
  • Stage di output, streaming — lo scanner di stream rileva il match ma non riscrive il delta oggi, quindi la forma mascherata non raggiunge un client streamato (il masking dell’output in-stream è nella roadmap).
Quindi il preset mask non copre la PII fuori da una risposta streamata da solo. Per tenere la PII fuori da una risposta streamata, scrivi quella regola come block (o chiama in modalità non streaming) così che lo stream venga interrotto sul match. Vedi PII Shield e formati di masking.

5. Cosa costa un block in streaming

Un block in streaming porta la stessa contabilità di qualsiasi block di output — il modello è già girato, quindi il gateway gestisce il rimborso per te:
  • Su una risposta non in streaming la chiamata restituisce HTTP 400 guardrail_blocked che nomina il guardrail e la regola che ha scattato. Su una risposta in streaming gli header SSE 200 sono già sul filo, quindi il block arriva come un delta sostitutivo in-band finale e una chiusura pulita del canale invece di un 400.
  • Nessuna quota viene addebitata. Un block di input scatta prima della misurazione; un block di output (in streaming o meno) rimborsa la quota pre-consumata una volta che la risposta è rifiutata. In entrambi i casi il chiamante non paga nulla.
  • La richiesta è marcata skip-retry — rieseguire lo stesso prompt si limiterebbe a bloccarlo di nuovo, quindi il gateway non brucerà un retry su un altro canale.
Ogni regola di output che scatta registra anche un match nel feed Matches del workspace (GET /api/guardrail/match, aperto a qualsiasi Member); la sottostringa corrispondente viene catturata solo quando il toggle Log raw content del guardrail è attivo (disattivato per default). Il dettaglio completo vive in l’errore guardrail_blocked e nel feed dei match.

6. Dimostra la tua combinazione stage/azione prima di metterla in produzione

Non indovinare quale cella della matrice si applica alla tua policy — verificala. Entrambi gli strumenti girano sulla tua sessione della console tramite la management API:

Tab Test

Ogni editor di guardrail ha una tab Test: incolla un campione, scegli lo stage ed esegui la policy corrente senza chiamata upstream e senza quota. Vedi il verdetto e, per le regole mask, il testo renderizzato. La sandbox di Test è gestita a Developer+ (può scatenare chiamate judge/grounding a pagamento e richieste di integrazione in uscita).

Tab Eval

La tab Eval valuta un guardrail contro corpora JSONL inclusi o personalizzati — utile per confermare che una regola di block cattura una fuga nota prima di collegare una chiave. Eseguire un eval richiede solo accesso in lettura (viewer+).
Vedi testing ed eval e tuning dei falsi positivi per approfondire.

7. Dove andare dopo

Regole stream-safe

Come lo scanner interrompe uno stream SSE a metà, e come scrivere una policy che tiene sul traffico in streaming.

Stage di output

Filtrare la risposta del modello — block vs. mask, il rimborso della quota e grounding.

Stage di input

Filtrare la richiesta prima del modello — masking incluso, in streaming o meno.

Azioni

block, mask, flag, annotate e spotlight in profondità — quando ciascuno è la scelta giusta.
Guardrails — ogni tipo di regola, campo e rotta, incluso il grounding e l’LLM judge.