1. 流式防护栏覆盖问题
防护栏规则带有一个阶段(input、output 或 both)和一个
动作——五种之一:block、mask、flag、annotate 或
spotlight。阶段决定网关何时运行它;动作决定它做什么。流式
唯一改变答案形态的地方是输出阶段——因为那是网关唯一在字节
到达时就转发给你的客户端、没有机会先持有整个负载的阶段。
所以矩阵有两个流式重要的格子,它们的行为不同:输出 block 在
流上完全执行(扫描器切断它),但输出 mask 只在非流式回复上
执行。在一个流式回复上,扫描器仍然检测匹配并可以对一个 block
决策采取行动,但它今天不把脱敏后的文本改写进流——带内的
流式输出脱敏在规划路线图上。
输入从不是问题。 输入阶段规则在模型之前运行——网关筛查
(并且对于
mask,改写)你的请求,然后把净化后的版本转发上游。
响应是否会流式无关紧要;请求是网关完整持有的一个完整负载。输入
扫描在每个请求上完全上线,包括脱敏。2. 覆盖矩阵
从上往下读这个。每个 block 格子都已上线,包括流式——但输出 + mask + 流式是那个在流中尚未执行的格子:一条 mask 规则脱敏 非流式回复,而在流式回复上它检测匹配但不改写 delta(带内的 流式输出脱敏在规划路线图上)。| 阶段 · 动作 | 非流式 | 流式 |
|---|---|---|
input · block | 拒绝请求 | 拒绝请求 |
input · mask | 改写请求 | 改写请求 |
output · block | 拒绝回复 | 切断流 |
output · mask | 脱敏回复 | 检测匹配;不在流中脱敏(路线图) |
| any · flag | 仅记录 | 仅记录 |
annotate 和 spotlight 在不拒绝流量的情况下附加一条注释(或
包裹匹配的文本),且实际上是输入阶段动作,因此它们不改变上面的
输出/流式格子;它们像任何其他规则一样记录一条匹配。
input——完全上线,两种方式(block + mask)
input——完全上线,两种方式(block + mask)
输入阶段规则在上游模型运行之前筛查请求。一个
block 会短路
调用(HTTP 400 guardrail_blocked,在计量之前,因此它不
消耗配额)。一个 mask 会就地改写提示词中匹配的字段——
净化后的文本就是上游收到的,而模型永远看不到原始内容。这些
都不取决于响应是否流式。output · block——流式和非流式都执行
output · block——流式和非流式都执行
在非流式回复上,补全在返回前被完整筛查——一个拦截呈现为
HTTP 400
guardrail_blocked。在流式回复上,一个流扫描器
监视流过的 delta;当一条拦截规则触发时它切断流——封闭
扫描器,发出一条简短的替换通知取代其余部分,并在进一步被拦截的
内容到达客户端之前关闭 SSE 通道。由于那时 200 SSE 头已经
发出,一次流式拦截无法返回一个 400:它把拦截作为最后一个
带内 delta 而不是一个 HTTP 错误递送。output · mask——仅非流式(流式在规划路线图上)
output · mask——仅非流式(流式在规划路线图上)
在非流式回复上,一条
mask 规则改写补全——例如一个 email
变成 [EMAIL]——而你的客户端得到的就是净化后的文本。在
流式回复上,流扫描器仍然检测匹配并计算脱敏,但它不把
脱敏后的文本转发进 delta——被脱敏的输出被丢弃,只有一个 block
决策被采取行动。所以一条 mask 规则今天不会脱敏一个流式
回复;带内的流式输出脱敏在规划路线图上。如果你现在就需要 PII
不进入一个流式回复,把规则编写为 block(匹配时扫描器切断流)
或以非流式筛查。flag——仅观察,处处相同
flag——仅观察,处处相同
一条
flag 规则从不改变流量——它记录一条匹配并放行字节。阶段
和流式不改变它的行为。用它在把规则晋级到 block 之前衡量它的
命中率。3. 一个具体示例——让 PII 不进入一个流式回复
假设模型可能从 RAG 上下文中带出一个客户 email,而你的应用是 流式的。输出mask 今天不会在流中脱敏(带内的流式输出脱敏
在规划路线图上)——因此要让 PII 不进入一个流式回复,把输出
规则编写为 block:扫描器在一个匹配出现的那一刻杀掉流。
(输出 mask 确实会在非流式回复上脱敏。)
策略编辑是你控制台会话上的一个管理操作(门控为
Developer+);sk-orca-... 中继密钥只发送 /v1/* 流量,从不
编辑策略。
- 打开
/console/guardrails,New guardrail,命名它stream-pii-out。 - 添加一条规则:
- Type: PII detection
- Stage:
output - Action:
block← 匹配时切断流;在流上mask只检测(它脱敏非流式回复)
- 保存,然后在
/console/token通过密钥的 Guardrail 下拉菜单 绑定它。
stream: true 调用网关,与以前完全一样:
4. PII Shield 跨矩阵
PII Shield 预设是单条pii 规则,动作 mask,阶段 both。
把它映射到矩阵上,覆盖范围正是你从 §2 所料想的:
- 输入阶段——完全上线,无论是否流式。请求在模型看到之前被 脱敏(输入脱敏的头号价值)。
- 输出阶段,非流式——补全在返回之前被脱敏。
- 输出阶段,流式——流扫描器检测匹配但今天不改写 delta, 因此脱敏后的形式不会到达一个流式客户端(带内的流式输出脱敏 在规划路线图上)。
block(或以非流式调用),这样
流在匹配时被切断。参见
PII Shield和
脱敏格式。
5. 流式拦截花费什么
流式拦截带有与任何输出拦截相同的记账——模型已经运行,因此网关 为你处理退回:- 在非流式回复上,调用返回指明触发的防护栏和规则的
HTTP 400
guardrail_blocked。在流式回复上,200SSE 头 已经在线上,因此拦截作为一个最后的带内替换 delta 和一次干净的 通道关闭到达,而不是一个400。 - 不消耗任何配额。 输入拦截在计量之前触发;输出拦截(无论是否 流式)会在回复被拒绝后退回预先扣除的配额。无论哪种方式, 调用方都不付费。
- 该请求被标记为 skip-retry——重新运行同一个提示词只会再次 拦截,因此网关不会在另一个通道上烧掉一次重试。
GET /api/guardrail/match,对任何 Member 开放);
匹配的子串只有在防护栏的 Log raw content 开关开启时才捕获
(默认关闭)。完整细节见
guardrail_blocked 错误
和 matches 信息流。
6. 上线前先证明你的阶段/动作组合
不要猜测矩阵的哪个格子适用于你的策略——验证它。两个工具都在你的 控制台会话上通过管理 API 运行:Test 标签页
每个防护栏编辑器都有一个 Test 标签页:粘贴一个样本,选择
阶段,并在无上游调用、无配额的情况下运行当前策略。查看判定
结果,以及(对于 mask 规则)渲染后的文本。Test 沙箱门控为
Developer+(它可以触发付费的 judge/grounding 调用和出站
集成请求)。
Eval 标签页
Eval 标签页针对内置或自定义 JSONL 语料库为一个防护栏打分
——有助于在你绑定密钥之前确认一条拦截规则能捕获一个已知泄露。
运行一次 eval 只需读取访问(viewer+)。
7. 接下来去哪里
流安全规则
扫描器如何中途切断一个 SSE 流,以及如何编写一个在流式流量上
成立的策略。
输出阶段
筛查模型的回复——block vs. mask、配额退回,以及 grounding。
输入阶段
在模型之前筛查请求——包括脱敏,无论是否流式。
动作
深入介绍 block、mask、flag、annotate 和 spotlight——每一个何时是
正确选择。
