> ## Documentation Index
> Fetch the complete documentation index at: https://docs.hitheo.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# 网关护栏

> 可选启用的输入/输出策略，Theo 网关会在绑定到某个 API 密钥的每次补全请求上强制执行这些策略。

网关护栏（Gateway Guardrails）让你可以为任意 API 密钥附加由策略驱动的安全、隐私和可靠性检查。绑定的策略会在每次补全请求上触发——包括 `/v1/completions`（流式与非流式）、`/v1/images`、`/v1/code`、`/v1/documents`、playground，以及嵌入式组件。

## 严格的选择性启用（opt-in）契约

**在你将策略绑定到某个 API 密钥之前，护栏不会生效。** 新建的密钥、所有现有密钥，以及每一个通过 Clerk 会话发起调用的调用方，都会完全绕过护栏。系统不存在自动的组织级或用户级默认策略——护栏是一个强制执行边界，而不是路由偏好设置，因此网关永远不会强制执行你没有明确选择启用的东西。

这意味着：

* **现有 API 密钥不受影响**，除非你明确绑定了策略。上线部署零风险。
* **没有回退链。** 清除某个绑定（`policy_id: null`）会让密钥回到无强制执行的状态。
* **每个密钥一对一。** 一个密钥最多只能绑定一个策略；而一个策略可以绑定到任意数量的密钥。

## 五种内置保护

每种保护都是一个纯评估器：相同的输入始终产生相同的输出。它们都是厂商中立的，绝不会在面向客户的字符串中提及上游提供商。

<AccordionGroup>
  <Accordion title="pii_redactor — 隐藏个人信息">
    在任何模型调用**之前**，从提示词中清除电子邮件、电话号码、美国社会安全号码、符合 Luhn 校验的信用卡号，以及形似驾照号码的 ID。

    允许的判定结果：`redact`（默认）、`flag`（仅记录日志，提示词保持不变）。

    阶段：仅 `input`。

    ```json theme={null}
    { "guardrail_id": "pii_redactor", "phase": "input", "verdict": "redact" }
    ```
  </Accordion>

  <Accordion title="prompt_injection — 拦截越狱尝试">
    捕获典型的 OWASP-LLM01 模式：诸如"忽略之前的指令"、角色劫持、伪造的系统消息、提示词窃取探测等。

    允许的判定结果：`deny`（默认——向调用方返回一个厂商中立的 422 错误）、`flag`。

    阶段：仅 `input`。

    ```json theme={null}
    { "guardrail_id": "prompt_injection", "phase": "input", "verdict": "deny" }
    ```
  </Accordion>

  <Accordion title="json_repair — 始终返回有效的 JSON">
    检测模型输出中格式错误的 JSON。当判定结果为 `repair` 时，运行器会进行一次修复尝试；如果无法生成有效的 JSON，则回退到原始缓冲区内容。

    允许的判定结果：`repair`（默认）、`flag`。

    阶段：仅 `output`。

    配置：`{ "fenced": true }`（默认 `true`）——启用后，评估器会先剥离一个围栏式的 `json` 代码块再进行解析，以匹配最常见的大模型输出形态。

    ```json theme={null}
    { "guardrail_id": "json_repair", "phase": "output", "verdict": "repair", "config": { "fenced": true } }
    ```
  </Accordion>

  <Accordion title="max_length — 限制输入或输出长度">
    将缓冲区截断到配置的上限，并附加一个简短的 `…[truncated]` 标记。

    允许的判定结果：`truncate`（默认）、`flag`。

    阶段：`input` 和/或 `output`。

    配置（二选一）：

    * `{ "maxChars": 16000 }` —— 硬性字符数上限。
    * `{ "maxTokens": 4000, "charsPerToken": 4 }` —— 令牌数上限（默认每令牌 4 个字符）。

    ```json theme={null}
    { "guardrail_id": "max_length", "phase": "output", "verdict": "truncate", "config": { "maxTokens": 4000 } }
    ```
  </Accordion>

  <Accordion title="profanity — 保持内容干净">
    在输入或输出方向上检测常见的粗俗用语。默认判定为 `flag`（仅可见，不拦截），方便你先审查活动记录再决定是否要拦截。

    允许的判定结果：`flag`（默认）、`deny`。

    阶段：`input` 和/或 `output`。

    ```json theme={null}
    { "guardrail_id": "profanity", "phase": "output", "verdict": "flag" }
    ```
  </Accordion>
</AccordionGroup>

## 五种判定结果

规则的判定结果（verdict）告诉运行器在该保护触发时应该做什么。运行器会针对某个阶段汇总所有匹配规则中最严重的判定结果，并只应用一次：

* **flag（标记）** —— 直接放行。匹配记录会写入执行日志；其余内容不做任何改动。
* **redact（脱敏）** —— 在转发之前，将匹配到的文本替换为 `[REDACTED:<kind>]`。
* **truncate（截断）** —— 裁剪到配置的限制并追加 `…[truncated]`。
* **repair（修复）** —— 对缓冲区执行一次修复处理。仅 `json_repair` 使用。
* **deny（拒绝）** —— 拦截该请求。在 `input` 阶段，网关会在任何模型调用之前返回 `422 invalid_request_error`，并附带 `code: "guardrail_violation"`。在 `output` 阶段，响应内容会被替换为拒绝原因，并且当次生成产生的所有产物都会被丢弃。

面向客户的消息永远不会提及上游提供商——SDK 会暴露一个稳定的 `guardrail_violation` 代码，让你的应用可以基于策略强制执行结果来做分支处理，而无需知道具体是哪个检测器触发的。

## 快速开始 —— 仪表盘

1. 打开 **Dashboard → Guardrails**，选择一个预设（或点击 **New policy** 新建一个空白策略）。
2. 从选择器中添加保护项；每张卡片都可以让你选择阶段和判定结果。
3. 使用右侧栏中的 **Test bench（测试台）**，通过该策略回放一个示例提示词以及可选的模型输出。你将看到每条规则的判定轨迹。
4. 在编辑器下方的 **Bindings（绑定）** 面板中，为你想要强制执行该策略的每个 API 密钥打开开关。

就是这样。策略会立即在所有已绑定的密钥上生效。

## 快速开始 —— SDK

```typescript theme={null}
import { Theo } from "@hitheo/sdk";

const theo = new Theo({ apiKey: process.env.THEO_API_KEY! });

// 1. （可选）从预设开始
const presets = await theo.guardrails.presets.list();
const enterprise = presets.find((p) => p.id === "enterprise-default")!;

// 2. 创建策略
const policy = await theo.guardrails.policies.create({
  name: "Production defaults",
  description: "PII redaction + jailbreak deny + JSON repair on output.",
  rules: enterprise.rules,
});

// 3. 将其绑定到某个 API 密钥
await theo.keys.setGuardrailPolicy("<key-uuid>", policy.id);

// 4. 验证绑定情况
const bindings = await theo.guardrails.policies.bindings(policy.id);
console.log(`Policy is enforcing on ${bindings.count} key(s).`);

// 5. 追踪审计日志
const recent = await theo.guardrails.executions.list({ policyId: policy.id, limit: 20 });
```

<Note>
  管理端点（`/api/v1/guardrail-policies/*`、`/api/v1/keys/{id}/guardrails`）需要 `billing` API 密钥作用域——与路由偏好设置的约定保持一致。如果你打算以编程方式管理策略，请显式铸造一个具有该作用域的密钥；对于正常流量而言，默认的 `completions` 作用域已经足够。
</Note>

## 错误信封

当输入阶段的 `deny` 触发时，API 会返回：

```json theme={null}
{
  "error": {
    "type": "invalid_request_error",
    "code": "guardrail_violation",
    "message": "Request blocked by your active guardrail policy.",
    "request_id": "req_..."
  }
}
```

HTTP 状态码为 `422`。对于流式补全，同一个信封会以 `error` SSE 事件的形式发出：

```
event: error
data: { "error": { "type": "invalid_request_error", "code": "guardrail_violation", ... } }
```

拒绝原因是该保护项暴露给客户的文案；匹配到的模式 ID（例如 `ignore_previous`）刻意**不会**被包含在内，以防攻击者借此探测出到底是哪个检测器触发的。

## 流式行为

输出护栏会在服务器完整收集完整个令牌流之后才运行。这意味着：

* **令牌会在模型生成时实时流式传输。** 客户端实时看到的是未经护栏处理的原始文本。
* **`done` 事件携带的是经过护栏处理的缓冲区内容。** 任何从 `done` 事件重新渲染消息主体的客户端（官方 SDK、playground、嵌入式组件）最终展示的都是符合策略的版本。
* **在 `deny` 判定下，会在 `done` 之前额外发出一个 `error` SSE 事件。** `done.content` 会被替换为拒绝原因，并且该轮对话中产生的所有产物都会被丢弃。

如果你的客户端是实时渲染令牌流、并且不会重新读取 `done.content`，那么当你需要对每一个可见字符都进行字节级精确的策略强制执行时，请考虑切换到非流式模式（`stream: false`）。

## 团队策略

`scope: "team"` 策略对所属组织的每一位成员都可见，创建/更新需要 `manageWebhooks` 权限（该权限被复用作为通用的团队配置门槛；目前还没有专门的 `manageGuardrails` 权限位）。

个人策略只对其创建者可见。团队密钥只能绑定到同一组织内的团队策略——当作用域不匹配时，绑定端点会以 `guardrail_policy_not_bindable` 强制执行这一规则。

## 审计与遥测

每次评估都会向 `guardrail_executions` 写入一条不可变的记录（保留期 90 天，由 BullMQ 保留期工作进程强制执行）。每条记录都会捕获：

* `policy_id`、`key_id`、`user_id` —— 触发本次评估的主体/对象。
* `guardrail_id`、`phase`、`verdict` —— 触发的规则与结果。
* `matched_pattern`、`redacted_count` —— 有边界限制的取证上下文（不包含原始提示词）。
* `latency_ms` —— 每条规则的开销，会展示在仪表盘的活动流中。

可以通过 `theo.guardrails.executions.list({ keyId, policyId, since })` 或 `GET /api/v1/guardrail-executions` 追踪该日志。仪表盘的 **Recent activity（最近活动）** 面板会以通俗易懂的语言渲染同一批记录。

## 护栏不会改变的内容

* **模型允许列表、路由规则、技能、品牌人格、响应风格与个性**都会各自独立地照常工作。护栏是围绕请求/响应路径附加的一层，不会覆盖其他密钥级功能。
* **没有绑定的现有密钥保持不变。** 你需要按密钥逐一选择启用。
* **不影响成本。** 内置保护项都是纯评估器（亚毫秒级）；`json_repair` 的修复处理只有在检测到格式错误的 JSON 时才会额外产生一次很小的调用开销。

## API 参考

* [列出策略](/api-reference/guardrails/list-policies)
* [创建策略](/api-reference/guardrails/create-policy)
* [获取 / 更新 / 删除策略](/api-reference/guardrails/get-policy)
* [测试策略](/api-reference/guardrails/test-policy)
* [列出某策略的绑定](/api-reference/guardrails/policy-bindings)
* [列出预设](/api-reference/guardrails/presets)
* [获取 / 设置密钥绑定](/api-reference/guardrails/key-binding)
* [列出执行记录](/api-reference/guardrails/executions)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.