메인 콘텐츠로 건너뛰기
대부분의 프로덕션 채팅 앱은 스트리밍합니다. 모델이 토큰을 내보내는 대로 브라우저로 플러시되므로, 완성이 “끝났을” 때쯤이면 당신의 사용자는 이미 대부분을 읽었습니다. 그것은 전체 응답을 검사한 뒤 결정하는 콘텐츠 필터의 순진한 멘탈 모델을 깨뜨립니다 — 너무 늦을 때까지 검사할 전체 응답이 없습니다. 스트리밍 llm 콘텐츠 필터는 델타가 흐르는 대로 그것에 대해 판단해야 합니다. 이 페이지는 정확히 그 경우에 관한 것입니다: 각 출력 스테이지 액션이 OrcaRouter 게이트웨이에서 어떻게 스트림 안전하게 동작하는지, 그리고 SSE 트래픽에서 유지되는 정책을 작성하는 방법. 전체 엔진 — 모든 규칙 타입, 필드, 라우트 — 은 Guardrails를 참조하세요.

1. 스트리밍 llm 콘텐츠 필터 문제

출력 스테이지 guardrail은 모델의 응답을 검사합니다. 비스트리밍 요청에서는 간단합니다: 게이트웨이는 단 한 바이트도 반환되기 전에 전체 완성을 가지므로, 깔끔하게 차단, 마스킹, 또는 통과시킬 수 있습니다. 스트리밍은 그것을 뒤집습니다. 응답은 SSE 델타의 시퀀스로 도착하며, 각각이 안착하는 즉시 클라이언트로 전달되므로, 끝을 기다리는 필터는 아무것도 필터링하지 않습니다. OrcaRouter의 답은 스트림 스캐너입니다: 출력 델타가 흐르는 대로, 스캐너는 누적되는 텍스트에 대해 당신의 출력 스테이지 규칙을 실행하고 규칙이 발동하는 순간 작동합니다 — 스트림이 완료된 후가 아니라. 당신이 작성한 액션이 “작동한다”의 의미를 결정합니다: block은 스트림을 끊고 flag는 그것을 통과시킵니다. mask비스트리밍 출력에서 마스킹하지만, 인밴드 스트림 재작성은 로드맵에 있습니다 — 오늘날 스트림에서는 스캐너가 마스크를 계산하지만 block 결정에만 작동하므로, mask 규칙은 아직 스트리밍 응답을 마스킹하지 않습니다.
이 caveat는 스트리밍 요청의 출력 스테이지 규칙에만 중요합니다. 입력 스테이지 규칙은 모델이 실행되기 전에 요청을 검사하므로 마스킹을 포함하여 완전히 라이브입니다 — 그리고 비스트리밍 요청의 모든 출력 규칙은 전체 응답을 보고 mask를 포함하여 정상적으로 동작합니다.

2. 오늘날 무엇이 스트림 안전한가

block 규칙은 스트리밍 그리고 비스트리밍 출력에서 강제됩니다. 스트림에서, 스캐너는 델타를 지켜봅니다; block 규칙이 발동하면 스트림을 끊습니다 — 스캐너를 봉인하고, 짧은 대체 알림([response truncated by guardrail: … policy violation])을 최종 델타로 내보내고, 추가 차단된 콘텐츠가 클라이언트에 도달하기 전에 SSE 채널을 닫습니다. 첫 델타가 플러시된 시점에 HTTP 응답 상태가 이미 200으로 확정되었으므로, 스트림 도중 차단은 상태를 다시 발행할 수 없습니다 — 열린 스트림을 우아하게 종료합니다. HTTP 400 guardrail_blocked 본문은 비스트리밍 출력 차단 형태입니다.클라이언트에 이미 플러시된 바이트는 회수할 수 없으므로, 스트리밍 차단은 이미 스트리밍된 것에 대해서는 최선 노력이지만 매치 이후의 모든 것을 안정적으로 중단합니다. 어떤 위반 바이트도 결코 전송되지 않는다는 하드 보장을 위해 — 그리고 400 guardrail_blocked 본문을 위해 — 요청을 비스트리밍으로 보내세요.
mask 규칙은 매치를 재작성합니다 — 예: 응답의 이메일이 [EMAIL]이 됩니다 — 비스트리밍 출력에서, 게이트웨이가 전체 완성을 쥐고 마스킹된 형태를 클라이언트에 전달하는 곳에서.오늘날 스트리밍 출력에서 스캐너는 마스크를 계산하지만 마스킹된 텍스트를 전달하지 않습니다 — block 결정에만 작동합니다 — 따라서 mask 규칙은 스트리밍 응답을 마스킹하지 않습니다. 인밴드 스트리밍 출력 재작성은 로드맵에 있습니다. 그것이 출시되기 전까지, 스트리밍 응답이 매치된 텍스트를 결코 노출하지 않아야 한다면, 규칙을 block으로 작성하거나(히트 시 응답을 종료) 마스크가 전체 응답을 재작성하도록 요청을 비스트리밍으로 보내세요.
flag 규칙은 결코 트래픽을 변경하지 않습니다 — 바이트를 통과시킵니다. 비스트리밍 출력에서 Matches 피드에 match를 기록하므로, 규칙을 block으로 프로모트하기 전에 그 히트율을 측정할 수 있습니다. 스트리밍 응답에서는 관찰 전용으로 남아 델타를 변경 없이 통과시킵니다; 구조화된 매치 기록은 비스트리밍 출력 경로에서 작성됩니다. 어느 쪽이든 결코 차단하거나 재작성하지 않으므로, 항상 켜둔 채로 두는 것이 안전합니다.
output에서의 액션비스트리밍스트리밍
block응답을 거부스트림을 끊음
mask응답을 마스킹아직 아님 — 대신 block(로드맵)
flag매치를 기록통과(관찰 전용)
기억해야 할 한 규칙: block은 출력에서 스트림 안전합니다; mask비스트리밍 출력에서만 마스킹합니다(인밴드 스트림 재작성은 로드맵에 있습니다). 오늘날 스트리밍 응답을 마스킹하려면, 규칙을 block으로 작성하거나, 전체 응답이 반환되기 전에 쥐어지도록 요청을 비스트리밍으로 보내세요.

3. 하나의 구체적인 예 — 스트림 안전 시크릿 필터

당신의 모델이 RAG 컨텍스트에서 자격 증명을 드러낼 수 있고, 당신의 앱이 스트리밍한다고 합시다. 시크릿 형태 매치가 나타나는 순간 게이트웨이가 그것을 마스킹하기보다 스트림을 죽이기를 원합니다 — 유출된 시크릿은 부분적으로 마스킹되기보다 응답을 종료해야 합니다. 콘솔에서 작성하세요 — 정책 편집은 당신의 세션에 대한 관리 액션이며 **Developer+**로 게이팅됩니다; 릴레이 키는 /v1/* 트래픽만 보냅니다:
  • /console/guardrails를 열고, New guardrail, stream-safe-out으로 이름을 지정합니다.
  • 규칙을 하나 추가합니다:
    • 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 탭

각 guardrail 에디터에는 Test 탭이 있습니다: 샘플을 붙여넣고, output 스테이지를 선택한 뒤, 업스트림 호출 없이, 쿼터 없이 현재 정책을 실행합니다. 판정과(mask 규칙의 경우) 렌더링된 텍스트를 보세요. 샌드박스 실행은 Developer+ 액션입니다(유료 judge / external 규칙을 발동할 수 있음).

Eval 탭

Eval 탭은 번들 또는 커스텀 JSONL 코퍼스에 대해 guardrail을 채점합니다 — 키를 연결하기 전에 block 규칙이 코퍼스 전반에서 알려진 유출을 잡는지 확인하는 데 유용합니다.
둘 다 관리 API를 통해 당신의 세션에서 실행됩니다. 심층은 테스트 및 평가거짓 양성 튜닝을 참조하세요.

6. 스트리밍 차단이 소모하는 것

스트리밍 차단은 다른 출력 차단과 동일한 회계를 운반합니다 — 업스트림 모델이 이미 실행되었으므로, 게이트웨이가 환불을 대신 처리합니다:
  • 스트림은 우아한 절단 델타로 종료됩니다(상태는 이미 200입니다); 비스트리밍 출력 차단은 발동한 guardrail과 규칙을 명시하는 HTTP 400 guardrail_blocked 본문을 반환합니다.
  • 쿼터가 청구되지 않습니다. 출력 차단이 응답을 거부하면, 게이트웨이는 사전 소모된 쿼터를 환불하므로, 모델이 토큰을 생성했더라도 차단된 호출은 당신에게 무료입니다.
  • 요청은 skip-retry로 표시됩니다 — 동일한 프롬프트를 다시 실행해도 그저 다시 차단될 뿐이므로, 게이트웨이는 다른 채널에서 재시도를 태우지 않습니다.
비스트리밍 출력 경로는 발동하는 모든 출력 규칙을 워크스페이스 Matches 피드에 match로 기록합니다(GET /api/guardrail/match, 모든 Member에게 개방); 매치된 부분 문자열은 guardrail의 Log raw content 토글이 켜져 있을 때만 캡처됩니다(기본적으로 꺼짐). 전체 상세는 guardrail_blocked 오류matches 피드에 있습니다.

7. 다음으로 갈 곳

출력 스테이지

전체 출력 스테이지 — 모델의 응답 검사, block vs. mask, 그리고 grounding.

스트리밍 커버리지

모든 스테이지와 액션에 걸쳐 스트리밍 vs. 비스트리밍에서 무엇이 강제되는지의 완전한 매트릭스.

액션

block, mask, flag를 심층적으로 — 각각이 올바른 선택일 때.

입력 스테이지

거울 이미지 — 여기서는 스트리밍을 포함하여 마스킹이 완전히 라이브입니다.
Guardrails — grounding과 LLM judge를 포함한 모든 규칙 타입, 필드, 라우트.