1. 什么是防护栏引擎
防护栏是一个工作区级别的、命名的内容策略—— 一个有序的规则列表,网关会用它来检查请求输入和模型 输出。你保存一次防护栏,将任意 API 密钥绑定到它(或将某个 设为工作区默认),网关就会在上游模型之前和之后检查每一次调用。 每条规则决定一件事——查找什么(规则类型)、在哪里 查找(一个阶段:请求输入或模型输出),以及如何处理 (一个动作:block、mask 或 flag)。引擎运行每一条适用的规则 并将结果汇聚为单一决策。 编辑防护栏会在下一次调用时对绑定到它的每个密钥生效。 无需重新部署。无需修改代码。无需升级 SDK。策略存在于 网关中,而不是你的应用中——你的应用像以前一样继续调用/v1/chat/completions。
对于内置规则类型,引擎是确定性的、无依赖的:
纯字符串和正则匹配,没有网络调用,可以安全地
运行在热中继路径上。高级规则(外部供应商、LLM judge、
上下文 grounding)会向外调用,并被并发派发,因此一个慢
检查永远不会串行阻塞另一个。
防护栏是工作区级别的——每个成员都能看到该工作区的
防护栏;不会跨租户边界。
2. 快速开始——5 步检查你的第一个请求
创建防护栏
在控制台中前往
/console/guardrails,点击 New
guardrail。将其命名为 pii-shield。添加一条规则:- Type: PII detection
- Stage: Input(请求)
- Action: Mask——脱敏匹配项
- Entities:
email、phone、ssn
在沙箱中测试
打开编辑器内的 Test 标签页,粘贴 “email me at
jane@acme.com”,选择
input 阶段,然后运行。沙箱会显示
判定结果和渲染后的文本——email me at [EMAIL]——而不会
向上游发送任何内容。3. 概念:防护栏、规则、阶段、动作
| 概念 | 定义 |
|---|---|
| 防护栏 | 一个命名的、工作区级别的策略。标识符:name(≤ 64 字符)。具有 enabled、is_default 和一个 rules JSON blob。 |
| 规则 | 策略内的一个检查:一个 type、一个 stage、一个 action,外加类型特定的字段。规则按顺序运行。 |
| 阶段 | input(请求)、output(模型的响应)或 both。 |
| 动作 | block(拒绝调用)、mask(脱敏匹配项)或 flag(仅记录——在不改变流量的情况下观察)。 |
限定范围与工作区默认值
防护栏的限定范围与 API 密钥完全相同:当你有活跃工作区时 为工作区共享,否则为按用户。任何请求的解析顺序:- 密钥绑定——如果密钥有明确的
guardrail_id,则该 防护栏适用(当它存在且已启用时)。明确的绑定 永不静默回退;禁用它就是关闭开关。 - 工作区默认值——如果密钥没有绑定,则工作区已启用的
is_default防护栏适用。 - 两者皆无——不执行。请求与从未启用该功能的 工作区字节相同。
设计上故障开放(Fail-open)。 如果防护栏解析遇到瞬时错误
(例如 DB 抖动),网关会降级为不执行,而不是
让流量中断。安全性降级;可用性得以保留。
block 的表现形式
被拦截的请求返回 HTTP 400,错误码为guardrail_blocked,消息中会指明触发的防护栏和规则。被拦截的
请求不消耗任何配额——input 阶段的拦截发生在计量之前,
而 output 阶段的拦截会退回预先扣除的配额——并且会被标记为
skip-retry(重新运行同一个提示词只会再次被拦截)。
4. 规则类型
规则分为两组:内置(确定性,无网络)和 高级(向外调用模型或供应商)。| 类型 | 组 | 作用 |
|---|---|---|
关键词拒绝列表(keyword) | 内置 | 匹配字面词项列表中的任意一个——不区分大小写,按子串匹配(因此 class 也会匹配 classic)。 |
正则表达式(regex) | 内置 | 匹配一个 RE2 模式(线性时间,无反向引用)。 |
PII 检测(pii) | 内置 | 检测内置实体类型(以及你自己的自定义类型)。参见 §5。 |
最大长度(max_chars) | 内置 | 限制某个阶段文本的字符数。 |
外部供应商(external) | 高级 | 将检查委派给已连接的供应商(Aporia、Averta、BYO-webhook……)。参见 §9。 |
LLM judge(llm_judge) | 高级 | 针对你工作区中的某个模型运行语义检查。参见 §6。 |
上下文 grounding(grounding) | 高级 | 根据请求上检索到的来源(RAG)为答案的忠实度评分。参见 §7。 |
external、llm_judge、grounding)会被并发派发,因此
一个慢检查不会串行阻塞另一个。
5. PII 检测详解
pii 规则检测敏感实体,并对每个匹配项应用该规则的动作。
内置检测器集合是封闭的,由引擎、
校验器和规则构建器共享:
email、phone、credit_card、ssn、ip、iban、mac_address、
api_key_openai、aws_access_key、jwt、bitcoin_address。
在 mask 动作下,每个匹配项会被替换为一个带类型的标签——
email 变成 [EMAIL],SSN 变成 [SSN],依此类推。
自定义实体
在内置集合之上叠加你自己的检测器。一个自定义实体是:name——小写 ASCII / 数字 / 下划线,必须以 字母开头(例如employee_id)。会以未加引号的形式流入审计日志和遥测。pattern——一个 Go RE2 正则(线性时间,无反向引用)。checksum——可选;luhn使用 Luhn 算法校验匹配项 (例如用于类似卡号的数字)。mask_with——可选的逐字替换文本;默认为[<UPPERCASE_NAME>]。
按实体的动作覆盖
单条 PII 规则可以通过entity_actions 对不同实体应用
不同的动作。一条规则默认对 email / phone / IP mask,
但对 credit_card 或 ssn block——而不需要三条
互相重叠的规则:
block /
mask / flag。校验器会拒绝其他任何内容。
6. LLM judge
llm_judge 规则针对你工作区已经可以调用的某个模型运行
语义检查。用它来处理任何正则都无法捕获的模糊策略——
毒性、骚扰、跑题、提示注入意图。
| 字段 | 含义 |
|---|---|
judge_model | 用于评估的模型或路由器别名(例如 gpt-4o-mini、orcarouter/cheap)。针对你工作区的通道解析。 |
judge_rubric | 描述要标记什么内容的系统提示词。 |
judge_format | yes_no、score 或 category 之一(必填;控制台预选 yes_no)。 |
judge_threshold | 对于 score:当分数达到或高于此值时 block/flag。 |
judge_categories | 对于 category:被拒绝的列表。 |
judge_timeout_ms | 限定 judge 调用的时间。0 → 引擎默认值。 |
judge_fail_open | true(默认)→ judge 错误会被观察但请求继续;false → 将错误/超时视为 block。 |
7. 上下文 grounding
grounding 规则衡量助手的答案是否符合请求上检索到的
来源(你的 RAG 上下文),并对不忠实于这些来源的
答案进行 flag 或 block。它复用 judge 接缝——相同的
工作区通道,相同的成本归因。
| 字段 | 默认值 | 含义 |
|---|---|---|
grounding_model | 工作区选择 | 运行器解析忠实度检查所用的模型。 |
grounding_rubric | 内置 | 覆盖默认的忠实度 rubric。 |
grounding_threshold | 0.7 | 忠实度下限,0.0–1.0。低于它时触发动作。 |
grounding_strict | false | 为 true 时,“未提供来源”被视为 block(相对于默认的放行)。 |
grounding_max_bytes | 100000 | 限制交给 judge 的拼接后来源上下文。 |
grounding_timeout_ms | 3000 | 限定 judge 调用的时间。 |
8. 模板、沙箱与 eval 工具
模板库
New guardrail 分裂按钮会直接打开一个模板, 完整的库只需一次点击即可。预设在服务端编写,因此 控制台、沙箱和这些文档描述的是完全相同的 行为。类别包括:- PII(
pii)——PII Shield、PII Blocker(严格)、Contact-Info Redactor、 响应 PII 脱敏器。 - Secrets(
secrets)——AWS / OpenAI / GitHub 凭证拦截器、私钥与云令牌、 加密钱包、输出中的密钥。 - Compliance(
compliance)——GDPR(EU PII)、PCI(完整卡号拦截)、HIPAA(PHI)、 金融数据、合规日志记录器、法律免责声明强制。 - Brand(
brand)——脏话(block / mask / 多语言)、竞争对手 提及、儿童安全关键词。 - Safety(
safety)——提示注入、越狱、系统提示泄露、 自残。 - Cost(
cost)——提示/响应大小上限与令牌上限。 - Agent(
agent)——URL 过滤器、markdown 图片、shell 工具调用, 以及输出中的 SQL 注入过滤器。
测试沙箱
每个编辑器都有一个 Test 标签页。粘贴一个样本,选择一个阶段, 在本地运行当前策略——没有上游调用,没有配额。沙箱 返回判定结果,以及(对于 mask 规则)渲染后的文本,让你可以 在绑定密钥之前证明一条规则会按你的预期工作。Eval / 红队工具
Eval 标签页针对一个输入语料库运行防护栏并报告 其得分——有助于调优 judge rubric,或在你发布之前证明某个策略 能捕获已知攻击。- 内置语料库随网关一起提供——对抗性和红队 集合(有害行为提示、工具注入、多语言 红队)以及用于测量误报的良性集合。
- 自定义语料库——上传你自己的 JSONL,以针对你真实的 流量形态进行测试。
- 运行记录会连同其得分一起列出;打开一次运行,逐样本 检查失败项。
9. 外部供应商
external 规则将检查委派给一个已连接的供应商。在
Integrations(Guardrails 页面上的页头 CTA)下连接一个供应商
一次,然后从规则中引用该连接。
支持的供应商
| 供应商 | 它是什么 |
|---|---|
Aporia Guardrails(aporia) | 面向 prompt 与响应的 SLM 集成策略引擎。 |
Averta(averta) | 通用 SLM 分类器端点(POST 文本 → 安全 / 不安全 + 可选改写)。 |
BYO Webhook(webhook) | 你自己的 URL——接收 prompt 并返回 allow / block / mask / flag 裁决。 |
规则字段
| 字段 | 含义 |
|---|---|
connection_id | 要使用的已连接集成(推荐路径——供应商 + 密钥在运行时从工作区的集成解析)。 |
timeout_ms | 限定单次供应商调用的时间。0 → 默认值。 |
fail_open | true(默认)→ 供应商错误会被观察但请求继续;false → 将传输错误 / 超时 / 未知 provider 视为 block。 |
10. 可观测性
防护栏会留下可供你行动的面包屑。匹配(Matches)信息流
每条触发的规则都会记录一个 match——规则类型、动作、一个详情 字符串、阶段,以及(当启用时)匹配的子串。Guardrails 页面上的 Matches 标签页是工作区范围的信息流:列出、分组、 过滤、下钻到单个匹配、导出为 CSV,以及标记误报。原始内容捕获是选择性开启的。 防护栏的 Log raw content
开关默认关闭——隐私保守的姿态。关闭时,
Matches 信息流记录某条规则触发了以及它的详情元字符串,
但不记录实际匹配的子串(例如 email 地址本身)。
当你需要子串进行分诊时,按防护栏开启它;该
设置不可追溯。
统计
Matches 信息流驱动按防护栏的统计——每个防护栏卡片显示一个 7 天匹配迷你图和计数,Matches 标签页携带一个工作区 总计。要按策略切分活动,请使用 Matches 信息流的分组视图 和过滤器(按防护栏、规则类型、动作)——按防护栏的用量、 动作组合和误报率都在那里。版本历史与审计
每次创建、更新和删除都会在与变更相同的事务中写入 一条版本化的历史记录。打开防护栏行上的 History 以:- 查看每个版本,包括谁在何时做了变更。
- Diff 任意两个版本。
- Revert 到一个更旧的版本(记录为一个新版本——历史 永不被修改)。
11. 与网关其他部分的关系
| 模块 | 如何与防护栏组合? |
|---|---|
| Models | 防护栏与模型无关。同一个策略可以在 GPT-5、Claude、Gemini 上运行——它检查文本,而不是模型选择。 |
| Routing | 相互独立。路由决定由哪个模型/通道来处理请求;防护栏无论如何都检查同一份请求/响应文本,且从不覆盖模型选择。输入检查在上游调用之前运行,输出检查在模型响应之后运行。Judge 与 grounding 规则通过你工作区的通道解析它们自己的模型,与该请求的路由相互独立。 |
| Prompts | 独立且互补。提示词注入一条系统消息;防护栏检查并把关内容。两者可以同时作用于一个请求,且防护栏始终运行。顺序很重要:输入规则在注册表提示词被注入之前检查调用方的请求(注入发生在更晚的路由阶段),因此输入规则看到的是调用方的消息,而不是被注入的系统提示词;无论如何输出规则都检查模型的响应。 |
| API Keys | 密钥通过 guardrail_id 绑定到防护栏。绑定存在于网关的密钥上,因此编辑防护栏会一次性切换每个绑定的密钥;没有绑定时回退到工作区默认值。 |
| Matches 信息流 | 每条触发的规则都会落入工作区的 Matches 信息流(它自己的存储,独立于请求日志)。按防护栏、规则类型和动作对其分组和过滤,即可查看每个防护栏的用量、动作组合和误报率。 |
12. API 参考
所有路由都通过X-Workspace-Id 头进行工作区限定。RBAC
执行一致:读取和测试沙箱对每个成员开放;写入
需要 Developer+(以及 guardrails:write 权限);
生产流量变更(删除、回退、供应商配置)相应地受到限制。
防护栏
| 方法与路径 | 角色 | 用途 |
|---|---|---|
GET /api/guardrail/ | Member | 列出防护栏(带绑定密钥数)。 |
GET /api/guardrail/meta | Member | 引擎词汇表——规则类型、阶段、动作、PII 实体、预设、预设类别。 |
GET /api/guardrail/my-permissions | Member | 调用者的防护栏权限(用于 UI 限制)。 |
GET /api/guardrail/:id | Member | 单个防护栏详情。 |
GET /api/guardrail/:id/tokens | Member | 绑定到此防护栏的 API 密钥(有上限,带真实总数)。 |
POST /api/guardrail/test | Member | 沙箱——在某个阶段对样本文本评估一个策略。不持久化任何内容。 |
POST /api/guardrail/ | Developer+ | 创建防护栏。 |
PUT /api/guardrail/ | Developer+ | 更新防护栏(写入一个新历史版本)。 |
DELETE /api/guardrail/:id | Developer+ | 删除防护栏。 |
历史
| 方法与路径 | 角色 | 用途 |
|---|---|---|
GET /api/guardrail/:id/history | Member | 版本历史(最新优先)。 |
GET /api/guardrail/:id/history/diff | Member | Diff 两个版本。 |
GET /api/guardrail/:id/history/:version | Member | 单个历史版本。 |
POST /api/guardrail/:id/revert | Developer+ | 将一个更旧的版本恢复为新版本。 |
Eval 与语料库
| 方法与路径 | 角色 | 用途 |
|---|---|---|
POST /api/guardrail/:id/eval | Member | 针对一个语料库运行 eval(内置名称或上传的 JSONL)。 |
GET /api/guardrail/:id/eval/runs | Member | 列出某个防护栏的 eval 运行记录(分页)。 |
GET /api/guardrail/eval/runs/:run_id | Member | 单次 eval 运行详情。 |
GET /api/guardrail/eval/corpora | Member | 列出工作区语料库 + 内置语料库。 |
POST /api/guardrail/eval/corpora | Developer+ | 上传一个 JSONL 语料库。 |
GET /api/guardrail/eval/corpora/:id | Member | 语料库详情。 |
DELETE /api/guardrail/eval/corpora/:id | Developer+ | 删除一个语料库。 |
匹配(Matches)
| 方法与路径 | 角色 | 用途 |
|---|---|---|
GET /api/guardrail/match | Member | 列出匹配(工作区限定)。 |
GET /api/guardrail/match/grouped | Member | 分组的匹配(例如按规则或防护栏)。 |
GET /api/guardrail/match/stats | Member | 匹配统计(支持 ?days= 和 ?group_by=)。 |
GET /api/guardrail/match/export | Member | 将匹配导出为 CSV。 |
GET /api/guardrail/match/:id | Member | 单个匹配详情。 |
POST /api/guardrail/match/:id/mark-fp | Admin | 将一个匹配标记为误报(限速)。 |
DELETE /api/guardrail/match/:id/mark-fp | Admin | 取消标记误报(限速)。 |
绑定密钥
在 API 密钥上设置guardrail_id(通过密钥编辑器或 token API)。
0/null 表示没有明确绑定——密钥会回退到
工作区默认防护栏(如果设置了的话)。
13. FAQ
如果请求上没有解析出任何防护栏会怎样?
如果请求上没有解析出任何防护栏会怎样?
行为与从未启用该功能的工作区字节相同。如果密钥
没有绑定,且没有设置工作区默认值,
网关不做任何修改。不会拦截、脱敏或
记录任何内容到 Matches 信息流。
被拦截的请求会消耗配额吗?
被拦截的请求会消耗配额吗?
不会。
input 阶段的拦截发生在用量计量之前;output 阶段的
拦截会在响应被拒绝后退回预先扣除的配额。无论哪种方式,
调用者都不收取配额,会得到 HTTP 400 guardrail_blocked,
并且该请求被标记为 skip-retry(针对另一个通道重新运行
同一个提示词只会再次被拦截)。输出(响应)规则在流式传输上会被执行吗?
输出(响应)规则在流式传输上会被执行吗?
这取决于动作。Block 两种方式都会执行:在非流式响应上,
答案会在返回前被筛查;在流式响应上,一个扫描器会中途切断
流,并在任何被拦截的内容到达客户端之前发出一条替换消息。
输出上的 Mask 目前只适用于非流式响应——在流式响应上,
原始 chunk 会未经脱敏地放行(带内的流改写是一项规划中的
增强)。如今要做输出脱敏,请使用非流式请求,或依赖
input 阶段的脱敏。在依赖它之前,先在沙箱中以及通过一次 eval
运行证明你具体的阶段/流组合。
mask 和 block 有什么区别?
mask 和 block 有什么区别?
Mask 脱敏匹配项(例如
jane@acme.com → [EMAIL])并
带着净化后的文本放行请求——上游模型
永远看不到原始内容。Block 以 HTTP 400 拒绝整个请求。
Flag 不改变流量的任何方面,只记录
一个匹配——用它在强制执行前先衡量一条规则。注入的提示词 token 和 judge token 会计费吗?
注入的提示词 token 和 judge token 会计费吗?
内置规则(keyword / regex / PII / max_chars)不做任何模型
调用,不产生任何计费。
llm_judge 或 grounding 规则会通过
你工作区的通道调用模型,因此这些 token 会作为 judge 子项
计费和归因。我如何查看一条规则实际匹配了什么?
我如何查看一条规则实际匹配了什么?
为该防护栏开启 Log raw content。关闭时(默认),
Matches 信息流记录某条规则触发了以及它的详情
元字符串,但不记录匹配的子串——隐私保守的
姿态。该开关不可追溯:它只影响开启后
记录的匹配。
我可以回滚一次防护栏变更吗?
我可以回滚一次防护栏变更吗?
可以。打开防护栏上的 History,diff 各版本,然后
Revert 到你想要的那个。Revert 会将该版本的内容
向前复制为一个新版本——历史永不被修改——并且变更
在下一个请求时生效。
如果外部供应商或 judge 超时会怎样?
如果外部供应商或 judge 超时会怎样?
默认情况下,高级规则故障开放(fail open):超时或传输
错误会被记录为遥测,请求继续。将
fail_open(external)或 judge_fail_open(judge)设为 false 以
故障关闭(fail closed)——将错误视为 block——用于那些
漏掉一次检查就不可接受的策略。