企业管控与信任2026年10月27日Flatkey Team

PII 脱敏 API 指南(2026):面向 LLM 应用的 AWS、Google Cloud、Azure 与 Presidio 对比

PII 脱敏 API 可识别并遮盖文本中的个人数据。本文对比 Amazon Comprehend、Google Sensitive Data Protection、Azure Language PII 和 Presidio,提供代码、计费单位、实际检测结果及 LLM 脱敏处理流程。

PII 脱敏 API 指南(2026):面向 LLM 应用的 AWS、Google Cloud、Azure 与 Presidio 对比

PII 脱敏 API 指南(2026):面向 LLM 应用的 AWS、Google Cloud、Azure 与 Presidio 对比

PII 脱敏 API 接收文本,识别其中的姓名、电子邮箱、电话号码、银行卡号和政府签发的证件号码等个人数据,然后返回这些数据的位置,或返回一份已对这些数据进行遮盖、替换或令牌化的文本。 对 AI 产品团队来说,核心任务是在提示词、文档和日志传入第三方 LLM 之前,移除个人数据或进行假名化处理。大多数团队会评估四种方案:Amazon Comprehend DetectPiiEntities、Google Cloud Sensitive Data Protection(原 Cloud DLP)、Azure Language PII 检测,以及微软开源的 Presidio。

本指南从端点、身份验证、语言覆盖、计费单位和输出格式几个方面对比这些方案,并提供使用合成数据的可运行示例。文中还展示了本地 Presidio 测试的实际检测结果,包括你需要提前考虑的漏检和误报。所有服务商信息均已于 2026年10月27日对照官方文档核实。

Flatkey 不提供内置的 PII 脱敏 API。下文的处理方案在你自己的服务中运行,发生在请求发送至任何模型网关(包括 Flatkey)之前。关于这一问题的策略制定,请参阅我们的 AI API 脱敏策略指南。

脱敏、遮盖、实体检测和令牌化有什么区别?

技术 返回内容 是否可逆? 典型用途
实体检测 实体类型、置信度分数及字符偏移量 不适用(不修改文本) 针对每个实体决定处理方式;审计流转中的数据
脱敏 移除了 PII 或用 [PERSON_1] 等标签替换后的文本 否 发往外部 LLM 的提示词、日志、分析数据
遮盖 隐藏了部分字符的文本,例如 ***********1111 否 需要显示部分信息的客服界面
令牌化 / 假名化 用一致的令牌或加密值替换 PII 后的文本 是,需持有密钥或映射表 需要在回答中还原真实值的 LLM 工作流
字段级脱敏 按照数据模式删除或替换已知字段(例如 JSON 中的 email) 视情况而定 已知哪些字段包含 PII 的结构化请求数据

对于结构化数据,字段级规则比任何模型都更快、更可靠。PII 检测 API 适合处理自由文本:聊天消息、客服工单、转录文本和文档。

PII 脱敏 API 对比(2026年10月)

Amazon Comprehend Google Sensitive Data Protection Azure Language PII Microsoft Presidio
类型 托管 API 托管 API 托管 API(也提供容器) 开源,自行托管
主要调用 DetectPiiEntities projects.content.deidentify analyze-text,使用 PiiEntityRecognition AnalyzerEngine + AnonymizerEngine
是否直接返回脱敏文本 否,返回偏移量(需据此进行脱敏) 是 是(redactedText) 是
可逆令牌化 不支持 支持(基于密码学的转换) 不支持 支持(encrypt / decrypt 操作符)
PII 语言覆盖 英语和西班牙语 多种 infoTypes,部分针对特定国家或地区 文档列出了多种语言 取决于加载的 NLP 模型
输入限制 / 计费单位 每次请求 100 KB;每 100 个字符计费 1 个单位,最低 3 个单位 按 GiB 计费;每次请求最低按 1 KB 计费 按文本记录计费 自行承担计算资源费用
免费额度 每个 API 每月 50K 个单位(5M 个字符),持续 12 个月 每月前 1 GiB 的检测量免费 每月 5,000 条文本记录(免费套餐) 软件免费
数据是否离开你的网络 是(AWS) 是(Google Cloud) 是,除非自行运行容器 否

来源:Amazon Comprehend PII 文档、Comprehend 定价、Google 去标识化文档、Sensitive Data Protection 定价、Azure PII 概述、Azure Language 定价和 Presidio 文档,均已于 2026年10月27日核实。

费用是多少?

  • Amazon Comprehend: AWS 官方的 Detect PII 示例中,10,000 条客户评论,每条 550 个字符,每次请求计为 6 个单位,因此共 60,000 个单位,按每单位 $0.0001 计算,总费用为 $6(Comprehend 定价,示例 7)。短请求最低按 3 个单位(300 个字符)计费,因此合并多条短消息可以节省费用。
  • Google Sensitive Data Protection: 内容检测每月前 1 GiB 免费,之后每 GiB 收费 $3.00,用量更高时降至每 GiB $2.00;转换操作的标价为每 GiB $2.00,随后降至 $1.00。每次请求最低按 1 KB 计费。
  • Azure Language: PII 检测按文本记录计费,免费套餐每月提供 5,000 条免费文本记录。付费套餐价格可在你所在区域的 Azure 定价页面查看。
  • Presidio: 无许可费;你需要承担运行分析器和 NLP 模型的计算资源费用。

Amazon Comprehend:DetectPiiEntities

Comprehend 可以检测英语或西班牙语文本中的 PII。DetectPiiEntities 返回每个实体的 Type、Score、BeginOffset 和 EndOffset;输入上限为 100 KB 的 UTF-8 文本(API 参考)。它不返回脱敏后的文本,因此需要你自行替换对应的文本片段。

import boto3

comprehend = boto3.client("comprehend", region_name="us-east-1")
text = "Hi, I'm Dana Whitfield. Email dana.whitfield@example.com or call 212-555-0187."

resp = comprehend.detect_pii_entities(Text=text, LanguageCode="en")

# Replace from the end so earlier offsets stay valid
redacted = text
for e in sorted(resp["Entities"], key=lambda e: e["BeginOffset"], reverse=True):
    if e["Score"] >= 0.5:
        redacted = redacted[:e["BeginOffset"]] + f"[{e['Type']}]" + redacted[e["EndOffset"]:]
print(redacted)

身份验证使用标准 AWS 凭证(IAM 角色、SSO 或访问密钥),并需具备 comprehend:DetectPiiEntities 权限。

Google Cloud Sensitive Data Protection:content.deidentify

Google 的 API 可在一次调用中完成检测和转换。你可以选择 infoTypes(例如 EMAIL_ADDRESS 和 PHONE_NUMBER),以及一种转换方式:replaceWithInfoTypeConfig、redactConfig、characterMaskConfig 或基于密码学的假名化处理(去标识化文档)。

curl -X POST \
  "https://dlp.googleapis.com/v2/projects/$PROJECT_ID/content:deidentify" \
  -H "Authorization: Bearer $(gcloud auth print-access-token)" \
  -H "Content-Type: application/json" \
  -d '{
    "item": {"value": "Email dana.whitfield@example.com or call 212-555-0187."},
    "inspectConfig": {
      "infoTypes": [{"name": "EMAIL_ADDRESS"}, {"name": "PHONE_NUMBER"}, {"name": "PERSON_NAME"}]
    },
    "deidentifyConfig": {
      "infoTypeTransformations": {
        "transformations": [{"primitiveTransformation": {"replaceWithInfoTypeConfig": {}}}]
      }
    }
  }'

响应中的 item.value 包含类似 Email [EMAIL_ADDRESS] or call [PHONE_NUMBER]. 的文本。Google 建议只列出所需的 infoTypes,因为扫描默认类型集合会增加延迟。

Azure Language:PII 实体识别

Azure 的 analyze-text 端点同时返回实体和 redactedText 字段。redactionPolicies 参数控制输出方式,例如使用 entityMask 输出标签,或使用 characterMask 输出星号(REST 参考)。

curl -X POST "$AZURE_LANGUAGE_ENDPOINT/language/:analyze-text?api-version=2026-05-01" \
  -H "Ocp-Apim-Subscription-Key: $AZURE_LANGUAGE_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "kind": "PiiEntityRecognition",
    "parameters": {"redactionPolicies": [{"policyKind": "entityMask"}]},
    "analysisInput": {"documents": [
      {"id": "1", "language": "en", "text": "My name is John Doe My phone number is 424 878 9192"}
    ]}
  }'

微软文档中的示例响应返回 "redactedText": "My name is [PERSON_1] My phone number is [PHONENUMBER_1]",以及每个实体的类别、偏移量、长度和置信度分数。Azure 还支持对话和文档中的 PII 检测,并提供容器,便于在你自己的环境中运行模型。

Node.js 版本

const res = await fetch(
  `${process.env.AZURE_LANGUAGE_ENDPOINT}/language/:analyze-text?api-version=2026-05-01`,
  {
    method: "POST",
    headers: {
      "Ocp-Apim-Subscription-Key": process.env.AZURE_LANGUAGE_KEY,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      kind: "PiiEntityRecognition",
      parameters: { redactionPolicies: [{ policyKind: "entityMask" }] },
      analysisInput: {
        documents: [{ id: "1", language: "en", text: "Call Dana at 212-555-0187." }],
      },
    }),
  }
);
const data = await res.json();
console.log(data.results.documents[0].redactedText);

Microsoft Presidio:开源 PII 脱敏

Presidio 完全运行在你自己的基础设施中。分析器结合了 NLP 命名实体识别、正则表达式、校验和及上下文词;匿名化器则应用 replace、mask、redact、hash 和 encrypt 等操作符。其文档明确指出,自动检测无法保证找出所有敏感数据,因此需要规划额外的防护措施。

我们安装了 Presidio(分析器版本 2.2.365,搭配 spaCy 的 en_core_web_lg 模型),并用以下合成句子进行了测试:

你好,我叫 Dana Whitfield。请发送邮件至 dana.whitfield@example.com,或拨打 212-555-0187。银行卡号为 4111 1111 1111 1111,SSN 为 078-05-1120。订单 #A-77231 将寄往 42 Elm Street。

from presidio_analyzer import AnalyzerEngine
from presidio_anonymizer import AnonymizerEngine
from presidio_anonymizer.entities import OperatorConfig

text = ("Hi, I'm Dana Whitfield. Email dana.whitfield@example.com or call 212-555-0187. "
        "Card 4111 1111 1111 1111, SSN 078-05-1120. Order #A-77231 ships to 42 Elm Street.")

results = AnalyzerEngine().analyze(text=text, language="en")
for r in sorted(results, key=lambda r: r.start):
    print(r.entity_type, repr(text[r.start:r.end]), round(r.score, 2))

out = AnonymizerEngine().anonymize(
    text=text,
    analyzer_results=results,
    operators={
        "DEFAULT": OperatorConfig("replace", {"new_value": "<REDACTED>"}),
        "PERSON": OperatorConfig("replace", {"new_value": "<PERSON>"}),
        "EMAIL_ADDRESS": OperatorConfig("replace", {"new_value": "<EMAIL>"}),
        "CREDIT_CARD": OperatorConfig("mask", {"masking_char": "*", "chars_to_mask": 15, "from_end": False}),
    },
)
print(out.text)

检出了什么,又漏掉了什么

文本 检测类型 分数 结论
Dana Whitfield PERSON 0.85 正确
dana.whitfield@example.com EMAIL_ADDRESS 1.0 正确
example.com(邮箱地址内部) URL 0.5 误报,与邮箱地址重叠
212-555-0187 PHONE_NUMBER 0.4 正确,但置信度较低
4111 1111 1111 1111 CREDIT_CARD 1.0 正确(通过校验和验证)
078-05-1120 PHONE_NUMBER 0.4 类型错误:这是一个广为人知的无效 SSN 示例,因此 SSN 识别器未接受它
Elm Street LOCATION 0.85 部分正确;门牌号“42”仍留在文本中
A-77231(订单 ID) 未检出 不适用 漏检:业务标识符需要自定义规则

这次小规模测试带来了三点启示:

  1. 阈值需要在漏检和误报之间取舍。 我们用 score_threshold=0.5 重新运行后,电话号码(分数 0.4)被过滤掉,未能脱敏。应按实体类型分别调整阈值,而不是统一设置全局阈值。
  2. 自有标识符需要自定义识别器。 添加一个匹配 \bA-\d{5}\b、分数设为 0.6 的 PatternRecognizer 后,成功检出了订单 ID。一个符合实际 SSN 格式的值(536-90-4399)被识别为 US_SSN,分数为 0.85。
  3. 可逆令牌化确实有效。 使用带有 128 位密钥的 encrypt 操作符,再通过 DeanonymizeEngine 配合 decrypt,即可完整还原原始文本。

面向 LLM 应用的 PII 脱敏处理流程

AI 产品的常见处理方式是先脱敏,再调用模型,最后还原用户需要看到的信息:

  1. 优先应用字段规则。 按照数据模式,删除或替换结构化请求数据中的已知 PII 字段。
  2. 检测自由文本。 使用 PII API 或 Presidio 检测消息、工单和文档。
  3. 保持假名化结果一致。 将每个实体替换为稳定的占位符(<PERSON_1>),并将映射保存在你自己的服务中,绝不能放入提示词。
  4. 调用 LLM,传入脱敏后的文本。
  5. 还原模型输出中的占位符,仅在用户有权查看真实值时进行还原。
  6. 记录脱敏版本及实体数量,不记录原文。
import os, re
from openai import OpenAI
from presidio_analyzer import AnalyzerEngine

analyzer = AnalyzerEngine()
client = OpenAI(api_key=os.environ["FLATKEY_API_KEY"], base_url="https://router.flatkey.ai/v1")

def non_overlapping(results, min_score=0.35):
    kept = []
    # prefer higher scores, then longer spans; drop anything overlapping a kept span
    for r in sorted(results, key=lambda r: (-r.score, -(r.end - r.start))):
        if r.score >= min_score and all(r.end <= k.start or r.start >= k.end for k in kept):
            kept.append(r)
    return sorted(kept, key=lambda r: r.start, reverse=True)

def pseudonymize(text):
    mapping, counters = {}, {}
    for r in non_overlapping(analyzer.analyze(text=text, language="en")):
        counters[r.entity_type] = counters.get(r.entity_type, 0) + 1
        token = f"<{r.entity_type}_{counters[r.entity_type]}>"
        mapping[token] = text[r.start:r.end]
        text = text[:r.start] + token + text[r.end:]
    return text, mapping

ticket = "Customer Dana Whitfield (dana.whitfield@example.com) says order A-77231 never arrived."
safe, mapping = pseudonymize(ticket)
reply = client.chat.completions.create(
    model="claude-haiku-5-5",
    messages=[{"role": "user", "content": f"Draft a short apology email for this ticket:\n{safe}"}],
).choices[0].message.content
for token, value in mapping.items():  # restore only on your side
    reply = reply.replace(token, value)
print(reply)

non_overlapping 这一步很关键:缺少它时,在邮箱地址内部检测到的 URL 会破坏替换结果。加上它之后,我们的测试工单变成了 Customer <PERSON_1> (<EMAIL_ADDRESS_1>) says order A-77231 never arrived.。订单 ID 仍被原样传出,因此生产环境需要加入上一节中的自定义识别器。Presidio 自带的匿名化器会自动处理重叠问题。

故障处理与测试

风险 应对措施
PII API 超时或返回 5xx 错误 出错时阻断请求:不向 LLM 发送未脱敏文本;放入队列并重试
低置信度检测结果 按实体类型设置阈值;每周审查样本
不支持的语言 先检测语言;AWS Comprehend PII 仅支持英语和西班牙语
业务标识符(订单 ID、账号) 自定义正则识别器或字段规则
误报破坏语义 为产品名称和公开地址设置允许列表
模型输出中的 PII 在记录日志或向其他用户展示之前,对响应进行检测
日志包含原文 仅记录脱敏文本和实体数量

使用贴近真实流量的合成消息构建带标注的测试集,涵盖不同文化背景的姓名、国际电话号码格式及你自己的 ID 格式。在上线前和每次规则变更后,按实体类型衡量召回率。

如何选择 PII 脱敏 API

  • 已经使用 AWS,且文本为英语或西班牙语: Amazon Comprehend 简单易用,小用量下费用较低。
  • 需要提供可逆令牌化的托管服务,或需要识别许多国家或地区特有的标识符: 选择 Google Sensitive Data Protection。
  • 需要直接获取脱敏文本、检测对话或文档中的 PII,或使用本地部署容器: 选择 Azure Language PII。
  • 数据必须留在自己的网络内,或需要完全掌控规则: 选择 Presidio,搭配自定义识别器和自行评估。

许多团队会组合使用这些方案:在实时处理链路中使用 Presidio 或字段规则,通过托管 API 批量扫描文档。

如何与 Flatkey 配合使用

Flatkey 是一个模型网关:凭一个密钥和一个 OpenAI 兼容端点,即可访问多种 LLM。它不会代你检测或脱敏 PII,因此应按照上文的流程,在请求离开你的服务之前,由应用完成脱敏。Flatkey 企业文档说明其不保留请求内容,这能减少数据暴露,但无法替代脱敏。相关阅读:AI API 脱敏策略、安全管理 API 密钥、LLM 成本跟踪和 Flatkey 模型目录。

常见问题

什么是 PII 脱敏 API?

这类 API 会检测文本中的个人数据,例如姓名、电子邮箱、电话号码和证件号码,然后返回这些数据的位置,或返回一份已移除、遮盖或替换这些数据的文本。

哪个 PII 脱敏 API 最好?

这取决于你的技术栈和数据。Amazon Comprehend 适合 AWS 上的英语和西班牙语文本;Google Sensitive Data Protection 在可逆令牌化和丰富的 infoTypes 支持方面最有优势;Azure 可直接返回脱敏文本,并支持容器运行;当数据必须留在自己的网络内时,Presidio 最合适。

有免费的 PII 脱敏 API 吗?

Presidio 是免费开源软件。托管服务也提供免费额度:AWS Comprehend 每个 API 每月提供 50K 个单位(5M 个字符),持续 12 个月;Google 每月前 1 GiB 的检测量免费;Azure 免费套餐每月包含 5,000 条文本记录。

向 ChatGPT、Claude 或其他 LLM API 发送提示词之前,应该先对 PII 脱敏吗?

应该,前提是模型不需要真实值。对姓名、联系方式和 ID 进行假名化处理,将占位符发送给模型;如果用户需要真实值,再在你自己的服务中还原。

PII 脱敏可以逆向还原吗?

简单的移除和遮盖无法还原。令牌化或基于加密的假名化处理可以借助密钥或映射表还原;你应安全保存这些信息,并与脱敏数据分开存储。

PII 检测 API 的准确性如何?

没有哪种方案是完美的。在我们的 Presidio 测试中,一个电话号码的分数仅为 0.4,而订单 ID 直到添加自定义规则后才被检出。请使用自己的合成数据衡量召回率,并在检测器出错时阻断请求。

Flatkey 会对 PII 脱敏吗?

不会。Flatkey 负责将请求路由到模型;脱敏应由你的应用在发送请求之前完成。