面向 LLM 安全性的 AI Guardrails

TrustyAI Guardrails Orchestrator 会在 LLM 的输入和输出上运行 detector,以过滤或标记内容。它基于开源 FMS-Guardrails 项目。TrustyAI Operator 提供 GuardrailsOrchestrator CRD,用于部署和管理它。

本文仅介绍 AutoConfig 部署和 内置 regex detector

前提条件

  • 已安装 TrustyAI Operator(请参阅 Install TrustyAI)。
  • 在目标 namespace 中已将一个 LLM 作为 InferenceService 部署。

使用 AutoConfig 部署

使用 AutoConfig 时,operator 会根据 namespace 中的资源生成 orchestrator 和 gateway 配置;对于基础设置,无需手动创建 ConfigMap。

创建一个启用了 autoConfig、内置 detector 和 gateway 的 GuardrailsOrchestrator 自定义资源:

apiVersion: trustyai.opendatahub.io/v1alpha1
kind: GuardrailsOrchestrator
metadata:
  name: guardrails-orchestrator
  namespace: <your-namespace>
  # Optional: enable auth for routes (Bearer token required)
  annotations:
    security.opendatahub.io/enable-auth: "false"
spec:
  autoConfig:
    inferenceServiceToGuardrail: <inference-service-name>
  enableBuiltInDetectors: true
  enableGuardrailsGateway: true
  replicas: 1
  • inferenceServiceToGuardrail:要进行 guardrail 的 InferenceService(LLM)名称;必须与同一 namespace 中已部署的 model 匹配。
  • enableBuiltInDetectors:当为 true 时,会添加一个内置 regex detector sidecar。
  • enableGuardrailsGateway:当为 true 时,gateway 会暴露预设路由(例如 /all/v1/chat/completions)。

资源状态

该资源具有 status 子资源。status.phase 可以为 ProgressingReadyError。使用 AutoConfig 时,status.autoConfigState 保存生成的 ConfigMap 名称(generatedConfigMapgeneratedGatewayConfigMap)、检测到的 services,以及一个 message。只有在 status.phase == Ready 且对应的 Deployment 就绪后,才应发送流量。

operator 会创建一个 orchestrator ConfigMap 和一个名为 <orchestrator-name>-gateway-auto-config 的 gateway ConfigMap。内置 detector 会注册为 built-in-detector

内置 regex detector

内置 detector 提供基于 regex 的算法。支持的算法包括:

类别算法
regexemailus-social-security-numbercredit-cardipv4ipv6us-phone-numberuk-post-code,或自定义 regex

默认的 gateway 配置使用占位 regex($^)。要启用某个特定算法(例如 email),请 patch 该 ConfigMap,并将 detector_params.regex 设置为算法名称(例如 - email)。

Gateway ConfigMap 结构

ConfigMap 名称:<orchestrator-name>-gateway-auto-config。示例:

apiVersion: v1
kind: ConfigMap
metadata:
  name: guardrails-orchestrator-gateway-auto-config
  namespace: <your-namespace>
data:
  config.yaml: |
    orchestrator:
      host: "localhost"
      port: 8032
    detectors:
      - name: built-in-detector
        input: true
        output: true
        detector_params:
          regex:
            - $^                          # change this placeholder, e.g. email
    routes:
      - name: all
        detectors:
          - built-in-detector
      - name: passthrough
        detectors:

built-in-detector 下的 regex 改为所需算法(例如 - email)。更新后,请等待 Deployment 就绪。

Service 端口和 API 参考

Guardrails Orchestrator 通过名为 <orchestrator-name>-service 的 Service 暴露。端口号取决于是否启用认证(在 GuardrailsOrchestrator 上设置注解 security.opendatahub.io/enable-auth: "true")。

端口和角色

端口名称禁用 auth启用 auth角色
gateway80908490Guardrails Gateway:预设 detector pipeline 和 OpenAI 风格的 chat completion 端点。使用它可以发送 chat 请求,在调用 LLM 之前/之后由内置(或已配置)的 detector 进行检查。
built-in-detector80808480内置 regex detector API。独立内容检测(不调用 LLM)。请求体:contents(字符串列表)和 detector_params(例如 regex: ["email"])。
https (orchestrator)80328432Orchestrator API:直接访问 orchestrator 端点(例如自定义检测流程、健康检查)。
health80348034健康检查端点。

启用 auth 后,gateway 和 built-in-detector 端口需要 Bearer token。

认证(已启用 auth)

对 gateway 或 built-in-detector 端口的请求必须包含:

Authorization: Bearer <token>

该 token 必须是一个有效的 Kubernetes ServiceAccount token(或集群 auth proxy 接受的其他 token),且其 subject 需要具备访问该 service 的权限(例如 services/proxy)。未授权请求会返回 401/403。

如何获取 token

在与 Guardrails Orchestrator 相同的 namespace 中创建 ServiceAccount、Role(对 services/proxy 具有 getcreate 权限)和 RoleBinding,然后为该 ServiceAccount 创建 token:

# Replace <your-namespace> and optionally the ServiceAccount name (e.g. guardrails-client)
kubectl create serviceaccount -n <your-namespace> guardrails-client
kubectl create role -n <your-namespace> guardrails-client --verb=get,create --resource=services/proxy
kubectl create rolebinding -n <your-namespace> guardrails-client --role=guardrails-client --serviceaccount=<your-namespace>:guardrails-client
kubectl create token -n <your-namespace> guardrails-client

也可以设置 token 有效期,例如使用 --duration=8760h 表示一年。最后一条命令会输出 token;将其设置为 Authorization: Bearer <token> 头的值。

集群内的客户端可以使用挂载的 ServiceAccount token volume 作为 Bearer token。

请求路径参考

路径端口用途
POST /all/v1/chat/completionsgateway(8090 或 8490)通过 guardrails 的 chat completions:请求在输入检查后发送给 LLM,响应再由 detector 检查。请求体:modelmessages(OpenAI 风格)。Detector pipeline 由 gateway 配置固定。
POST /api/v2/chat/completions-detectionorchestrator(8032 或 8432)通过 每个请求 选择 detector 的 chat completions。请求体:modelmessages,以及可选的 detectors(例如 {"input": {"built-in-detector": {"regex": ["email"]}}, "output": {...}})。当指定 detector 时,会返回 model reply 以及 detectionswarnings。当调用方需要为每个请求选择运行哪些 detector,而不是使用预设 gateway 路由时,请使用此接口。
POST /api/v1/text/contentsbuilt-in-detector(8080 或 8480)独立内容检测。对给定文本运行内置 regex(或已配置)的 detector;不调用 LLM。请求体:contentsdetector_params
GET /healthorchestrator(8032 或 8432)orchestrator 的健康检查。

其他 gateway 路由(例如 /<preset-name>/v1/chat/completions)定义在 gateway ConfigMap 的 routes 中。

API 用法和示例

独立检测(/api/v1/text/contents

在不调用 LLM 的情况下,对文本运行内置 regex detector。使用 built-in-detector 端口(8080 或 8480)。请求体:contents(字符串列表)、detector_params(例如 regex: ["email"])。

使用 service 地址(集群内部:<orchestrator-name>-service.<your-namespace>.svc.cluster.local;集群外部:如果已暴露,则使用 Ingress host)以及 built-in-detector 端口(参见 Ports and roles)。

# If auth is enabled, set TOKEN. Use port 8480 (auth) or 8080 (no auth).
curl -k -s -X POST "https://<service-address>:8480/api/v1/text/contents" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -H "Authorization: Bearer $TOKEN" \
  -d '{"contents":["hello, my email is test@example.com"],"detector_params":{"regex":["email"]}}'

响应: 一个数组(每个 contents 项对应一个条目),其中每个条目都是检测对象数组。每个对象包含 startendtextdetection(例如 EmailAddress)、detection_type(例如 pii)和 score

响应示例(独立检测,检测到 email)
[
  [
    {
      "detection": "EmailAddress",
      "detection_type": "pii",
      "end": 35,
      "score": 1.0,
      "start": 19,
      "text": "test@example.com"
    }
  ]
]

Orchestrator API:每个请求选择 detector(/api/v2/chat/completions-detection

当调用方必须为每个请求选择运行哪些 detector 时,请使用 orchestrator 端口(8032 或 8432)。请求体:modelmessages,以及可选的 detectors(例如带 detector 参数的 input / output)。

示例:在输入和输出上运行带有 regex email 的内置 detector:

# Use orchestrator port 8432 (auth) or 8032 (no auth).
curl -k -s -X POST "https://<service-address>:8432/api/v2/chat/completions-detection" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -H "Authorization: Bearer $TOKEN" \
  -d '{
    "model": "<inference-service-name>",
    "messages": [{"content": "my email is test@example.com", "role": "user"}],
    "detectors": {
      "input":  { "built-in-detector": { "regex": ["email"] } },
      "output": { "built-in-detector": { "regex": ["email"] } }
    }
  }'

当 detector 在输入中发现匹配项(例如 email)时,响应会包含 detectionswarnings,并且 choices 为空:

响应示例(输入触发检测)
{
  "id": "0c339dbab9ab45f59e6bf052d4fd78c6",
  "object": "",
  "created": 1773118440,
  "model": "......",
  "choices": [],
  "usage": {
    "prompt_tokens": 0,
    "total_tokens": 0,
    "completion_tokens": 0
  },
  "detections": {
    "input": [
      {
        "message_index": 0,
        "results": [
          {
            "start": 12,
            "end": 28,
            "text": "test@example.com",
            "detection": "EmailAddress",
            "detection_type": "pii",
            "detector_id": "built-in-detector",
            "score": 1.0
          }
        ]
      }
    ]
  },
  "warnings": [
    {
      "type": "UNSUITABLE_INPUT",
      "message": "Unsuitable input detected. Please check the detected entities on your input and try again with the unsuitable input removed."
    }
  ]
}

响应结构与 gateway chat 一致:choicesdetectionswarnings。如果只是进行普通 chat completion 且不需要 detection,请省略 detectors

Gateway API:预设 pipeline(/all/v1/chat/completions

使用 gateway 端口(8090 或 8490)进行带固定 detector pipeline 的 chat(该 pipeline 在 gateway ConfigMap 中定义)。请求体:modelmessages(OpenAI 风格)。如果需要按请求选择 detector,请改用 orchestrator API

使用 service 地址和 gateway 端口(参见 Ports and roles)。

# Use port 8490 (auth) or 8090 (no auth).
curl -k -s -X POST "https://<service-address>:8490/all/v1/chat/completions" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $TOKEN" \
  -d '{"model":"<inference-service-name>","messages":[{"content":"my email is test@example.com","role":"user"}]}'

当输入/输出通过检查时: detectionswarnings 为 null,choices 包含 model 回复:

响应示例(输入/输出通过)
{
  "choices": [
    {
      "finish_reason": "stop",
      "index": 0,
      "logprobs": null,
      "message": {
        "content": "......",
        "role": "assistant"
      }
    }
  ],
  "created": 1773109415,
  "detections": null,
  "id": "chatcmpl-6d190200e68646bba140fa584ce5c301",
  "model": "......",
  "object": "chat.completion",
  "usage": {
    "completion_tokens": 28,
    "prompt_tokens": 30,
    "total_tokens": 58
  },
  "warnings": null
}

当输入触发 detection(例如 PII)时: detectionswarnings 会被设置,choices 为空:

响应示例(输入触发检测)
{
  "choices": [],
  "created": 1773109609,
  "detections": {
    "input": [
      {
        "message_index": 0,
        "results": [
          {
            "detection": "EmailAddress",
            "detection_type": "pii",
            "detector_id": "built-in-detector",
            "end": 28,
            "score": 1.0,
            "start": 12,
            "text": "test@example.com"
          }
        ]
      }
    ],
    "output": null
  },
  "id": "24dcf55e14344b4bbc760944eb6c1630",
  "model": "......",
  "object": "",
  "usage": {
    "completion_tokens": 0,
    "prompt_tokens": 0,
    "total_tokens": 0
  },
  "warnings": [
    {
      "type": "UNSUITABLE_INPUT",
      "message": "Unsuitable input detected. Please check the detected entities on your input and try again with the unsuitable input removed."
    }
  ]
}