response a
remove ou reescreve antes que seu agente aja sobre ela. A decisão de
enforcement é idêntica em cada provedor — mesmas regras, mesmos vereditos, mesmos
events. O que difere é a forma na transmissão que seu cliente vê uma vez que o
firewall agiu sobre uma chamada de ferramenta em streaming, porque OpenAI chat, a
OpenAI Responses API e o Claude /v1/messages nativo cada um enquadra as chamadas
de ferramenta de forma diferente.
Esta página é a nota focada nessas diferenças observáveis pelo cliente. Ela não
re-documenta a linguagem de regras — veja
Regras do Firewall — ou o modelo de stage, coberto
em Stages. Para o mecanismo interno de
reter-e-remontar compartilhado pelos três, leia
Internals de streaming.
1. Por que o streaming de provedor do firewall difere por transmissão
Numa resposta não transmitida o firewall vê a resposta inteira de uma vez e decide. Num stream, a chamada de ferramenta do modelo chega como uma sequência de fragmentos — um nome num frame, o JSON de argumento pingando através de muitos mais. Um veredito precisa da chamada completa (nome e argumentos completos), e um fragmento de chamada de ferramenta, uma vez encaminhado, não pode ser retraído. Então em cada provedor o gateway faz a mesma coisa: ele deixa o conteúdo comum fazer streaming ao vivo, e retém os frames de chamada de ferramenta até a chamada estar totalmente montada. Ao fim do stream ele avalia cada chamada montada e emite apenas os sobreviventes — na própria forma de evento daquele provedor.Seu texto nunca trava. Apenas os frames de chamada de ferramenta são retidos.
Frames de conteúdo, raciocínio e role do assistente fazem streaming ao vivo e
inalterados. A retenção se aplica do primeiro fragmento de chamada de ferramenta
até o fim daquele turno — então uma resposta só-de-chat faz streaming exatamente
como se nenhum firewall estivesse vinculado.
2. OpenAI chat completions
Em/v1/chat/completions, chamadas de ferramenta fazem streaming como fragmentos
delta.tool_calls chaveados por índice. O portão retém esses (e a forma legada
delta.function_call) e, no frame de fechamento, emite as chamadas sobreviventes
re-indexadas a partir de zero, seguidas por um frame de finalização:
| Resultado | O que seu cliente recebe |
|---|---|
| allow | Os frames retidos originais, byte-a-byte — passagem verdadeira. |
| sanitize | Um delta tool_calls com argumentos reescritos, depois finish_reason: "tool_calls". |
| deny (algumas chamadas) | Apenas as chamadas sobreviventes, depois finish_reason: "tool_calls". |
| deny (todas as chamadas) | Nenhuma chamada de ferramenta, depois finish_reason: "stop" — o turno parece como se o modelo tivesse escolhido responder em texto. |
3. OpenAI Responses API
O stream nativo/v1/responses tem seu próprio modelo de evento — uma chamada de
ferramenta é um item function_call que abre com response.output_item.added,
transmite fragmentos response.function_call_arguments.delta, e completa em
response.output_item.done. O firewall avalia em done, o primeiro ponto em que
a chamada está inteira:
allow → eventos bufferizados liberados verbatim
allow → eventos bufferizados liberados verbatim
Os eventos
added / argument-delta / done do item são emitidos inalterados
uma vez que a chamada passa.sanitize → shell do item + done reescrito
sanitize → shell do item + done reescrito
O shell
added faz streaming, depois um done cujos argumentos são a versão
redigida — os fragmentos de argument-delta originais são descartados para que
o valor não redigido nunca chegue a você.deny → item removido em todo lugar
deny → item removido em todo lugar
Os eventos bufferizados são descartados, e o item negado também é filtrado do
objeto terminal
response.completed a partir do qual seu cliente constrói seu
estado final — nenhuma referência pendente a uma chamada que nunca rodou.4. Claude /v1/messages nativo
Um stream Anthropic nativo é um bicho diferente: o conteúdo chega como blocos
indexados — content_block_start → content_block_delta
(input_json_delta fragmentos) → content_block_stop — fechado por um
message_delta carregando stop_reason. O firewall retém a partir do primeiro
bloco tool_use, avalia cada um, e reconstrói os blocos sobreviventes com
índices contíguos para que um bloco removido não deixe gap de índice.
O sinal específico do Claude é stop_reason. Se cada bloco tool_use é negado,
um stop_reason de tool_use prometeria ao seu cliente uma chamada de ferramenta
que nunca chega — então o gateway o reescreve para end_turn:
tool_use sobreviventes, re-indexados
contiguamente, e deixa stop_reason: "tool_use" intacto.
5. Um exemplo concreto
A mesma regra produz a mesma decisão em cada provedor — apenas a forma na transmissão que seu cliente lê difere. Crie-a uma vez, no stageresponse:
rm -rf
toda vez. O que seu cliente observa:
| Transmissão | Sinal terminal após uma remoção completa |
|---|---|
| OpenAI chat | finish_reason: "stop" |
| OpenAI Responses | item ausente de response.completed |
| Claude nativo | stop_reason: "end_turn" |
6. O que permanece constante através dos provedores
A transmissão difere; o contrato não:- Vereditos e regras são agnósticos à transmissão.
allow/audit/deny/sanitizesignificam a mesma coisa em cada provedor. Veja Vereditos. - O sanitize toca apenas nos argumentos da chamada de ferramenta, nunca no conteúdo que uma ferramenta retorna — em cada transmissão. Veja Sanitizar respostas.
- Allow é passagem verdadeira. Quando o firewall não toma nenhuma ação, os frames retidos são reproduzidos como os bytes upstream exatos — sem re-batching, sem campos específicos de provedor perdidos.
- O shadow mode se aplica em todo lugar. Ligue-o e as chamadas de ferramenta
retidas sempre sobrevivem (rebaixadas para
audit) para que você possa medir o impacto de uma política através dos provedores antes que ela mude o tráfego. Veja Shadow mode.
7. Onde isso se encaixa
Internals de streaming
O mecanismo de reter-montar-remontar que cada provedor compartilha.
Stages
Por que o enforcement de chamada de ferramenta em streaming vive na superfície
response.Vereditos
As decisões agnósticas a provedor para as quais uma chamada em streaming
resolve.
Filtragem de response
Controlando as chamadas de ferramenta que um modelo emite, em stream ou não.
