跳转到主要内容
当防护栏拒绝一个调用时,网关会以 HTTP 400 和错误码 guardrail_blocked 回应你的应用。本页是针对这一个错误的落地 参考:响应体是什么样子、它为什么这样行为,以及如何在客户端 代码中处理它。它背后的策略引擎请见 防护栏概览完整参考

1. 你何时会看到 guardrail_blocked

防护栏是网关用来检查请求输入和 模型输出的一个有序规则列表。当一条动作为 block 的规则触发时, 调用被拒绝——上游模型从不被调用(输入阶段)或它的答案被扣留 (输出阶段)。客户端收到一个携带 guardrail_blocked 的 400。 没有其他动作会产生这个错误。mask 脱敏匹配项并放行净化后的 文本,flag 在不改变流量的情况下记录一条匹配,而塑形提示词的 动作(annotatespotlight)在添加注释或包裹不可信文本的 同时让调用继续。在五种动作中,只有 block 会拒绝。参见 动作
guardrail_blocked 是一种内容拒绝(文本进,文本出)。其伴生的 工具策略拒绝是来自智能体防火墙firewall_blocked——一个形态不同的不同错误。参见 防护栏 vs. 防火墙

2. 响应体

拦截以网关标准的 OpenAI 形态错误信封返回。在 OpenAI 风格的 端点(/v1/chat/completions/v1/responses)上:
{
  "error": {
    "message": "request blocked by guardrail \"pii-shield\": pii(ssn)",
    "type": "orcarouter_api_error",
    "param": "",
    "code": "guardrail_blocked"
  }
}
你依据来判断的字段:
稳定的机器标识符。基于它分支,而不是基于消息字符串。它在 每个端点上都是相同的值,且永不本地化。
人类可读。形式为 request blocked by guardrail "<name>": <detail>,其中 <detail><type>(<rule-detail>) 的形式 概括触发的规则类型——例如 pii(pii: ssn)keyword(matched 1 keyword(s))。一个输出阶段的拦截读作 response blocked by guardrail "<name>": <detail>,因此动词 告诉你是哪个阶段拒绝了调用。消息在离开网关前会经过敏感信息 脱敏,所以不要指望在这里看到原始的匹配子串。
OpenAI 风格端点上的通用网关错误类型。区分性信号是 code, 而不是 type
在原生 Anthropic 面(/v1/messages)上,信封是 Claude 形态—— {"error": {"type": ..., "message": ...}}——并且 guardrail_blocked 出现在 type 字段中,因此原生 Claude SDK 可以区分一次策略 拒绝与一次通用网关失败。
想在上线一条规则之前得到确切的判定?控制台 Test 标签页在无 上游调用、无配额的情况下对样本文本评估当前策略——参见 测试与 eval

3. 为什么 guardrail_blocked 不消耗配额

被拦截的请求是免费的——它永不从你的额度余额中扣款。
阶段拦截何时触发配额影响
input在上游调用之前、计量之前什么都不计量
output在模型回答之后、答案返回之前退回预先扣除的配额
所以输入拦截不收费,因为计量还没发生;输出拦截会撤销网关在 转发前所做的占用。无论哪种方式,调用方为拦截付出的是一个 400, 而不是额度。参见 输入阶段输出阶段

4. 为什么 guardrail_blocked 跳过重试

该错误被标记为 skip-retry。网关自己的路由不会把这个请求 故障转移到另一个通道,因为拦截是你的内容和你的策略的一个 属性——重新运行相同的提示词只会在下一个通道上再次拦截并 浪费这次尝试。
也不要把 guardrail_blocked 放进你客户端的重试循环。它是 确定性的:相同的提示词针对相同的策略每次都会拦截。重试 会为一个无法改变的结果烧掉延迟。把它当作一个终结性拒绝—— 修正输入,或修正策略。

5. 在客户端代码中处理它

基于 code 字段分支,并向终端用户呈现一条有用的消息,而不是 重试。
import httpx

resp = httpx.post(
    "https://api.orcarouter.ai/v1/chat/completions",
    headers={"Authorization": "Bearer sk-orca-..."},
    json={
        "model": "openai/gpt-4o-mini",
        "messages": [{"role": "user", "content": "My SSN is 123-45-6789"}],
    },
)

if resp.status_code == 400:
    err = resp.json().get("error", {})
    if err.get("code") == "guardrail_blocked":
        # Terminal — do not retry. Tell the user what to change.
        raise ValueError(f"Blocked by policy: {err['message']}")

resp.raise_for_status()
这里的 sk-orca-... 密钥是一个中继密钥——它只承载 /v1/* 流量。你永远不会用它编辑防护栏;编写和绑定策略是你会话上的 控制台 / 管理 API 操作,而创建或编辑防护栏需要 Developer+ 角色。

6. 确认并调优一次拦截

每条触发的规则——包括拦截——都会带着它的类型、动作、阶段和 一个详情字符串落入工作区 Matches 信息流。那里是你确认 哪条规则拒绝了某个调用并分诊误报的地方。

Matches 信息流

查看每一次 block、mask 和 flag 及其类型、动作和阶段。匹配的 子串只有在开启 Log raw content 时才出现。

日志与隐私

原始内容默认关闭——隐私保守的姿态。当你需要子串进行分诊时 按防护栏开启它。

调优误报

误报是一个调优信号,而不是禁用规则的理由。标记它并收窄 模式。

版本管理

改了策略想撤销它?Diff 任意两个版本并以新版本形式回退—— 历史永不被修改。
流式响应上,输出 block 仍然适用:扫描器会在任何被 拦截的内容到达客户端之前中途切断流。输出 mask 在流上也 带内适用——扫描器在安全前缀被发出之前在滚动缓冲区中改写 匹配。参见 流式覆盖流安全规则

7. 相关