> ## Content Index
> Fetch the complete content index at: https://www.hubwiz.com/blog/llms.txt
> Use this file to discover other available public pages before exploring further.

# PII、越狱和真正的护栏
- URL: https://www.hubwiz.com/blog/pii-jailbreak-and-real-guardrails/
- Published: 2026-02-27T16:56:24.000Z
- Updated: 2026-02-27T16:56:24.000Z
- Description: 在这篇文章中，我探讨了护栏实际上应该做什么——以及不同的框架如何处理这个问题。
- Author: admin
- Tags: AI, #Import 2026-10-14 14:41

我们正在构建越来越多的 AI 智能体来处理真实的公司数据。这些数据通常包含 PII（个人身份信息）——电子邮件地址、电话号码、出生日期和客户案例描述。即使拥有企业 LLM 许可证，一个令人不安的问题仍然存在：

> 我们在法律上和技术上是否允许将那些数据发送到外部 LLM 提供商？

许多团队假设"企业许可证 = 安全"。但合规性、日志记录、痕迹存储和数据驻留权讲述了一个更复杂的故事。

一周前，我观看了 [Aimable](https://aimable.ai/?ref=hubwiz.com) 的发布会演示——这是一个承诺提供安全 AI 工作空间的产品。这触发了我一直推迟的一个问题：

> 我们应该如何在我们自己构建的应用程序中正确实现护栏？

不仅仅是审核。不仅仅是越狱保护。真正的护栏包括 PII 掩码、幻觉检测、工具安全和内容过滤。

在这篇文章中，我探讨了护栏实际上应该做什么——以及不同的框架如何处理这个问题。

## 1、护栏做什么？

并非每个框架都在同一水平上。我讨论了我认为护栏应该做的事情。最初的职责是与 LLM 安全地工作。这意味着用户不能尝试破解提示词，使系统执行智能体开发者不希望它做的事情。护栏确保我们使用礼貌的语言，避免向 LLM 询问错误的事情，以及 LLM 的回答是礼貌的。

护栏有不同的形式。有些充当应用程序和 LLM 之间的**代理**。不是指向 OpenAI，而是指向代理。在开发过程中，这可以是一个 Docker 镜像；对于生产环境，您可以在 Kubernetes 中创建服务或使用 SAAS 版本。支持开源产品的公司通常提供具有更多功能的付费 SAAS 版本。特别是对于 PII 掩码，我更喜欢本地解决方案；将数据发送到远程服务进行掩码，然后让 LLM 搜索该 PII 感觉很奇怪。使用代理很容易；但是，它给您更少的控制权。这些产品的示例是 [LLM Guard](https://protectai.com/llm-guard?ref=hubwiz.com) 和 [Guardrails AI](https://www.guardrailsai.com/?ref=hubwiz.com)。

另一种方法是使用 API 来验证或掩码内容。在将内容提供给智能体或 LLM 之前，您将其通过审核和掩码服务。在收到智能体的响应后，您执行相同的操作。这给您更多的控制权，而通过这种控制权，您承担更多的责任。您必须为每次与智能体的交互自己安排这种保护行为。

第三种方法是使用可用的框架。大多数框架，如 SpringAI、Langchain4j 和 Embabel，都包含护栏的实现。它们旨在在不必自己完成所有事情的情况下给您相同的控制水平。它们通常使用通用接口包装特定的实现。命名不同的功能并不一致。有些使用护栏，其他使用审核，还有其他的为 PII 掩码等功能提供了回调机制。

## 2、阻止或不阻止

护栏可以阻止进行到下一步，从而防止调用 LLM。典型的用例是越狱护栏。这个护栏的目的是防止用户绕过提示词的规则，使智能体做它不被允许做的事情。另一个例子是审核护栏，它检测可能是骚扰、仇恨、自残或暴力的内容。这种类型的护栏用于用户请求以及助手响应。幻觉护栏就是一个例子。这个护栏检查 LLM 返回的内容，以确保它来自我们提供的上下文，而不是 LLM 刚刚编造的东西。

护栏也可以具有非阻止功能。PII 检测就是这里最好的例子。如果内容包含诸如电子邮件地址或出生日期之类的信息，我们要在将其发送到 LLM 之前掩码它。最好的方法是用占位符替换内容。您可以添加功能以保留占位符值，并在返回响应时用该值替换它。

## 3、工具参数和响应

用户和助手是对话的主要贡献者；然而，工具和组件（如技能和 MCP）也向提示词添加内容。对进入工具的信息以及工具的响应值应用护栏很重要。一个问题是一个恶意的 MCP 服务器试图诱骗您的智能体透露它不应该透露的信息。

## 4、一个还是两个端点？

我个人的偏好是使用两种机制：一种来审核内容并返回 true 或 false 值。不更改内容。另一种是执行诸如 PII 掩码、翻译或修剪大提示词之类的操作。

是时候看一些例子了。

## 5、Guardrails AI

我专注于 [Guardrails AI 的开源版本](https://github.com/guardrails-ai/guardrails?ref=hubwiz.com)。在跳转到代码之前，请访问 [Guardrails AI Hub](https://guardrailsai.com/hub?ref=hubwiz.com) 以查看有哪些护栏可用。在第一部分中，我构建 Docker 镜像；在第二部分中，我使用它来实验护栏。

## 6、与 API 交互

我采取的大多数步骤来自 GuardrailsAI [部署页面](https://guardrailsai.com/guardrails/docs/concepts/deploying?ref=hubwiz.com)。一切都从创建账户并获取密钥开始。

[https://guardrailsai.com/hub/keys](https://guardrailsai.com/hub/keys?ref=hubwiz.com)

接下来，我们使用 uv 创建项目，添加一些依赖项，并激活 Python 虚拟环境以使用 guardrails CLI。

```
uv init guardrails-ai-tryout
cd guardrails-ai-tryout
uv add "guardrails-ai[api]"
source .venv/bin/activate

```

有了可用的 guardrails cli，我们配置项目，添加护栏，并配置 config.py。护栏来自我之前提到的中心。

```
guardrails configure
guardrails hub install hub://guardrails/guardrails_pii
# config.py
from guardrails import Guard
from guardrails.hub import GuardrailsPII

pii_check = Guard(
    name="pii",
    description="Checks if the string contains specific PII data."
).use(
    GuardrailsPII(entities=["EMAIL_ADDRESS","PERSON","DATE_TIME"], on_fail="fix")
)

```

这就是在本地运行服务器并检查它是否工作所需的全部内容。

```
guardrails start --config=./config.py

# Use the swagger-ui to send a message
http://localhost:8000/docs

```

如果 guardrails 应用程序的启动成功，您应该看到与此类似的内容。

```
🚀 Guardrails API is available at http://localhost:8000
📖 Visit http://localhost:8000/docs to see available API endpoints.

🟢 Active guards and OpenAI compatible endpoints:
- Guard: pii http://localhost:8000/guards/pii/openai/v1

========================================================================================= Server Logs ==========================================================================================
INFO:     Started server process [31365]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)

```

注意 OpenAI 的代理 URL。目前，我用 curl 演示验证端点。您必须传递 openai api 密钥。下一个代码块显示了带有特定标头的 curl 请求。

```
curl -X 'POST' \
  'http://localhost:8000/guards/pii/validate' \
  -H 'accept: application/json' \
  -H 'Content-Type: application/json' \
  -H 'x-openai-api-key: $GUARDRAILS_API_KEY' \
  -d '{
  "llmOutput": "Ik ben op 1 November 2014 gestart bij Luminis. Mijn eerste taak was het ontwikkelen een PII systeem om email adressen als jettro@donotuse.eu te identificeren.",
  "numReasks": 0,
  "llmApi": "openai.Completion.create"
}'

```

响应是以下 JSON 消息。注意占位符。如果我们得到一个包含替换值的数组也会很好。

```
{
  "callId":"281469803946992",
  "rawLlmOutput":"Ik ben op 1 November 2014 gestart bij Luminis. Mijn eerste 
     taak was het ontwikkelen een PII systeem om email adressen als 
     jettro@donotuse.eu te identificeren.",
  "validatedOutput":"Ik ben op <DATE_TIME> gestart bij Luminis. Mijn eerste 
    taak was het ontwikkelen een PII systeem om email adressen als 
    <EMAIL_ADDRESS> te identificeren.",
  "validationPassed":true
}

```

您也可以为 OpenAI 使用代理。

```
curl -X 'POST' \
  'http://localhost:8000/guards/pii/openai/v1/chat/completions' \
  -H 'accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{
  "model": "gpt-4o-mini",
  "messages": [
    {
      "role": "user",
      "content": "This is a test message for Jettro Coenradie, how are you doing?"
    }
  ],
  "max_tokens": 1000,
  "temperature": 1
}'

```

响应有一个问题：它不返回 ID。根据规范，此字段是必需的。实际响应未显示它。因此，目前使用 Spring AI 和代理不起作用。

```
{
  "choices": [
    {
      "message": {
        "content": "<PERSON>'m just a computer program, so <PERSON> don't have feelings, but <PERSON>'m here to help you! If you have any questions or need assistance, feel free to ask. How can <PERSON> help you today?"
      }
    }
  ],
  "guardrails": {
    "reask": null,
    "validation_passed": true,
    "error": null
  }
}

```

我创建了一个 [问题](https://github.com/guardrails-ai/guardrails/issues/1415?ref=hubwiz.com)，如果有什么变化，我会在这里更新。

请注意，结果包含一个字段 *validation\_passed*。他们对两种类型的护栏都使用一个端点。

## 7、构建 Docker 镜像

我想拥有一个 Docker 镜像来运行 Guardrails 服务。可以[下载](https://raw.githubusercontent.com/guardrails-ai/guardrails-lite-server/refs/heads/main/Dockerfile?ref=hubwiz.com) Docker 配置文件。

Docker 需要一个 requirements-lock.txt 文件。此文件使用 uv 生成。

```
uv export --format requirements-txt --hashes --output-file requirements-lock.txt

```

在使用此命令运行它之前构建镜像。

```
docker build -f Dockerfile -t "guardrails-server:latest" \
    --build-arg GUARDRAILS_TOKEN=<your-token> .

# Run the Docker container
docker run -p 8000:8000 -d guardrails-server:latest

```

## 8、OpenAI

OpenAI 提供多种形式的护栏。其中一个 API 是 [审核](https://developers.openai.com/api/docs/guides/moderation?lang=curl&ref=hubwiz.com)。这是服务器端审核内容的方法。审核输入和输出以删除不良内容很有用。该服务针对有害类别（如暴力、仇恨和自残）对内容进行分类。该 API 与 SDK 很好地集成。因此，Java SDK 也可以访问该 API。

另一种形式是 [Python 库 OpenAI Guardrails](https://openai.github.io/openai-guardrails-python/?ref=hubwiz.com)。该库使用开源 Microsoft 框架 [Presidio](https://github.com/microsoft/presidio?ref=hubwiz.com)。该库提供了聊天客户端的直接替代品，强制执行配置文件中定义的所有护栏。例如：PII、Jailbreak、NSFW。

一个缺点是它仅适用于 Python。如果您像我大多数时间一样在 JVM 领域，那就太可惜了。

让我们试试这个框架。创建一个新项目，添加所需的依赖项，生成配置并尝试一下。

```
uv init guardrails-openai-tryout
cd guardrails-openai-tryout
uv add openai-guardrails
uv add python_dotenv

```

添加一个包含 OPENAI\_API\_KEY 属性的 .env 文件

接下来，转到 [https://guardrails.openai.com/](https://guardrails.openai.com/?ref=hubwiz.com) 并选择您要应用的护栏。我选择：

- 输入：掩码 PII、审核、越狱
- 输出：NSFW

接下来，您可以下载配置，您将获得一个默认的代码实现块。以下是配置、代码和输出。注意护栏是如何配置的，并检查最终结果中的掩码。

```
{
  "version": 1,
  "pre_flight": {
    "version": 1,
    "guardrails": [
      {
        "name": "Contains PII",
        "config": {
          "entities": [
            "CREDIT_CARD",
            "CVV",
            "CRYPTO",
            "DATE_TIME",
            "EMAIL_ADDRESS",
            "IBAN_CODE",
            "BIC_SWIFT",
            "IP_ADDRESS",
            "LOCATION",
            "MEDICAL_LICENSE",
            "NRP",
            "PERSON",
            "PHONE_NUMBER",
            "URL"
          ]
        }
      },
      {
        "name": "Moderation",
        "config": {
          "categories": [
            "sexual",
            "sexual/minors",
            "hate",
            "hate/threatening",
            "harassment",
            "harassment/threatening",
            "self-harm",
            "self-harm/intent",
            "self-harm/instructions",
            "violence",
            "violence/graphic",
            "illicit",
            "illicit/violent"
          ]
        }
      }
    ]
  },
  "input": {
    "version": 1,
    "guardrails": [
      {
        "name": "Jailbreak",
        "config": {
          "confidence_threshold": 0.7,
          "model": "gpt-4.1-mini",
          "include_reasoning": false
        }
      }
    ]
  },
  "output": {
    "version": 1,
    "guardrails": [
      {
        "name": "NSFW Text",
        "config": {
          "confidence_threshold": 0.7,
          "model": "gpt-4.1-mini",
          "include_reasoning": false
        }
      }
    ]
  }
}
import asyncio
from pathlib import Path

from dotenv import load_dotenv
from guardrails import GuardrailsAsyncOpenAI, GuardrailTripwireTriggered
from openai.types.chat import ChatCompletionUserMessageParam

async def call_llm(user_input):
    try:
        # GuardrailsAsyncOpenAI is a drop in replacement for the AsyncOpenAI client
        response = await guardrails_client.chat.completions.create(
            messages=[ChatCompletionUserMessageParam(content=user_input, role="user")],
            model="gpt-4.1-mini",
        )

        print(f"Assistant: {response.choices[0].message.content}")

    # If a guardrail is triggered, an exception will be raised
    except GuardrailTripwireTriggered as exc:
        raise

if __name__ == "__main__":
    load_dotenv()

    # Initialize GuardrailsAsyncOpenAI with the config file
    guardrails_client = GuardrailsAsyncOpenAI(config=Path("guardrails_config.json"))

    asyncio.run(call_llm("I need a bit formal message to Jettro Coenradie, I want to congratulate him for his anniversary since 1 november 2014."))
Assistant: Certainly! Here's a formal congratulatory message you can use:

---

Dear <PERSON>,

I hope this message finds you well. I would like to extend my sincere 
congratulations on your anniversary since <DATE_TIME>. Your dedication and 
commitment are truly commendable, and I wish you continued success in your 
endeavors.

Warm regards,  
[Your Name]

---

Let me know if you'd like it tailored further!

```

我喜欢响应包含大量关于应用的护栏的信息。只需几个简单的打印语句，就可以读取 *GuardrailsResponse* 以获取有关发现的 PII 和越狱护栏结果的信息。

```
def print_guardrail_results(results):
    for guardrail_result in results:
        print(f"Guardrail: {guardrail_result.info["guardrail_name"]}")
        if guardrail_result.info["guardrail_name"] == 'Contains PII':
            for key, value in guardrail_result.info["detected_entities"].items():
                print(f"  {key}: {value}")
        if guardrail_result.info["guardrail_name"] == 'Jailbreak':
            print(f"  Flagged: {guardrail_result.info['flagged']}")
            print(f"  Reason: {guardrail_result.info['reason']}")

print("--- Preflight Guardrails ---")
print_guardrail_results(response.guardrail_results.preflight)

print("--- Input flight Guardrails ---")
print_guardrail_results(response.guardrail_results.input)
--- Preflight Guardrails ---
Guardrail: Contains PII
  PERSON: ['Jettro Coenradie']
  DATE_TIME: ['1 november 2014']
Guardrail: Moderation
--- Input flight Guardrails ---
Guardrail: Jailbreak
  Flagged: False
  Reason: The user is requesting assistance in crafting a formal congratulatory message for an anniversary, which is a legitimate and benign request. There are no signs of deception or manipulation in the input.

```

## 9、Presidio

Microsoft 的数据保护和去识别化 SDK 有一个名为 [Presidio](https://microsoft.github.io/presidio/?ref=hubwiz.com) 的东西。大多数其他项目都引用了该项目。我在本文中讨论的两个——OpenAI 和 Guardrails AI——也不例外。Presidio 是一个用于检测和掩码 PII 数据的框架。

Presidio 有两个部分。在第一部分中，您使用分析器检测 PII 数据。其目标是检测 PII 并标记实体的位置。在第二部分中，您对发现的实体进行匿名化。您可以用 \*\*\* 替换它们，或使用命名掩码。命名掩码对于 LLM 非常完美；它仍然理解掩码文本的上下文。

Presidio 是一个 Python 库，它使用 Spacy 进行一些实体检测。如果您对 Python 方法感兴趣，请查看 [Presidio 的教程](https://microsoft.github.io/presidio/tutorial/?ref=hubwiz.com)。

我尝试 Docker 方法。首先，我下载容器。接下来，我启动容器并通过本地端口暴露服务。

```
docker pull mcr.microsoft.com/presidio-analyzer
docker pull mcr.microsoft.com/presidio-anonymizer

docker run -d -p 5002:3000 mcr.microsoft.com/presidio-analyzer:latest
docker run -d -p 5001:3000 mcr.microsoft.com/presidio-anonymizer:latest

```

有了运行的容器，我可以发送上一节的数据。

```
curl -X POST http://localhost:5002/analyze \
-H "Content-Type: application/json" \
-d '{
  "text": "I need a bit formal message to Jettro Coenradie, I want to 
     congratulate him for his anniversary since 1 november 2014.",
  "language": "en"
}' | jq .

```

Presidio 分析器的响应是：

```
[
  {
    "analysis_explanation": null,
    "end": 47,
    "entity_type": "PERSON",
    "score": 0.85,
    "start": 31
  },
  {
    "analysis_explanation": null,
    "end": 117,
    "entity_type": "DATE_TIME",
    "score": 0.85,
    "start": 102
  }
]

```

我使用带有原始文本的响应与 Presidio 匿名化器掩码 PII 数据。

```
curl -X POST http://localhost:5001/anonymize \
-H "Content-Type: application/json"  \
-d '{
        "text": "I need a bit formal message to Jettro Coenradie, I want to congratulate him for his anniversary since 1 november 2014.",
        "analyzer_results": [
  {
    "analysis_explanation": null,
    "end": 47,
    "entity_type": "PERSON",
    "score": 0.85,
    "start": 31
  },
  {
    "analysis_explanation": null,
    "end": 117,
    "entity_type": "DATE_TIME",
    "score": 0.85,
    "start": 102
  }]}'

```

响应现在包含掩码值。

```
{
  "text": "I need a bit formal message to <PERSON>, I want to congratulate him for his anniversary since <DATE_TIME>.",
  "items": [
    {
      "start": 94,
      "end": 105,
      "entity_type": "DATE_TIME",
      "text": "<DATE_TIME>",
      "operator": "replace"
    },
    {
      "start": 31,
      "end": 39,
      "entity_type": "PERSON",
      "text": "<PERSON>",
      "operator": "replace"
    }
  ]
}

```

第二个响应并不太难自己创建。Presidio 确实提供其他掩码选项。对我来说，特别是第一个检测 PII 数据的服务很有趣。

## 10、结束语

我喜欢 OpenAI Guardrails 方法，它使用包含三个元素的管道：预检、输入和输出。当您停留在 OpenAI 空间中时，LLM 类和智能体的直接替代品当然非常方便。用于创建护栏配置的向导很棒，新功能即将推出。有一个在 beta 中使用的工具护栏，对我来说，绝对是一个值得关注的框架。你听到了但是吗？但它不适用于 JVM。

Presidio 仅用于 PII 检测。这不一定是个问题。Guardrails AI 通过 Presidio 提供 PII，并用许多其他护栏扩展它。他们下载现有护栏的中心是一个很好的补充。对我来说，连接到 OpenAI API 的代理不起作用，因为缺少 id 字段。而且响应不包括提取的实体的值。有了输入和输出，当然可以提取该信息。

Presidio 和 Guardrails AI 都是通过 Docker 容器暴露服务变体的 Python 环境。目前作为与 JVM 语言的集成，这很好。在后续博客中，我将在 Spring AI 和 Embabel 中查看这些护栏的集成。两个框架都在积极开发中；我预计在接下来的几周内可以轻松集成。

---

原文链接: [Building AI agents safely: PII, jailbreaks, and real guardrails](https://freedium-mirror.cfd/https://medium.com/@jettro.coenradie/building-ai-agents-safely-pii-jailbreaks-and-real-guardrails-a52245a5c624?source=home%5Ffor%5Fyou---------65-98--------------------05d0c9ca%5F9a21%5F459a%5Faf8a%5F1a904d9c154b-------15-------)

汇智网翻译整理，转载请标明出处