Корпоративный контроль и доверие27 октября 2026 г.Flatkey Team

Руководство по API удаления PII (2026): сравнение AWS, Google Cloud, Azure и Presidio для LLM-приложений

API удаления PII находит и маскирует персональные данные в тексте. Сравниваем Amazon Comprehend, Google Sensitive Data Protection, Azure Language PII и Presidio: примеры кода, единицы тарификации, реальные результаты обнаружения и конвейер обезличивания для LLM.

Руководство по API удаления PII (2026): сравнение AWS, Google Cloud, Azure и Presidio для LLM-приложений

Руководство по API удаления PII (2026): сравнение AWS, Google Cloud, Azure и Presidio для LLM-приложений

API удаления PII принимает текст, находит персональные данные — имена, адреса электронной почты, номера телефонов, банковских карт и государственных идентификационных документов — и возвращает либо позиции этих данных, либо копию текста, в которой они замаскированы, заменены или токенизированы. Для команд, создающих ИИ-продукты, основная задача — удалить или псевдонимизировать персональные данные до того, как промпты, документы и логи попадут в стороннюю LLM. Чаще всего команды рассматривают четыре варианта: Amazon Comprehend DetectPiiEntities, Google Cloud Sensitive Data Protection (ранее Cloud DLP), обнаружение PII в Azure Language и Microsoft Presidio с открытым исходным кодом.

В этом руководстве мы сравниваем их эндпоинты, аутентификацию, поддержку языков, единицы тарификации и формат вывода, приводя готовые к запуску примеры с синтетическими данными. Также показываем реальные результаты локального теста Presidio, включая пропуски и ложные срабатывания, которые стоит учитывать. Все сведения о провайдерах сверены с официальной документацией 27 октября 2026 года.

У Flatkey нет встроенного API удаления PII. Описанные ниже подходы реализуются в вашем сервисе до отправки запроса через любой шлюз моделей, включая Flatkey. О том, как выстроить политику обработки таких данных, читайте в нашем руководстве по политике удаления персональных данных для API ИИ.

Удаление, маскирование, обнаружение сущностей и токенизация: в чем разница?

Метод Что возвращает Обратимость Типичное применение
Обнаружение сущностей Тип сущности, оценку уверенности и символьные смещения Неприменимо (текст не меняется) Выбор действия для каждой сущности; аудит передаваемых данных
Удаление Текст с удаленными PII или с метками вроде [PERSON_1] вместо них Нет Промпты для внешних LLM, логи, аналитика
Маскирование Текст со скрытыми символами, например ***********1111 Нет Интерфейсы службы поддержки, где нужна часть значения
Токенизация / псевдонимизация Текст, в котором PII заменены стабильным токеном или зашифрованным значением Да, при наличии ключа или таблицы соответствий Сценарии работы с LLM, где в ответ нужно вернуть реальные значения
Удаление на уровне полей Известные поля (например, email в JSON), удаленные или замененные по схеме Зависит от реализации Структурированные данные с известными полями, содержащими PII

Для структурированных данных правила на уровне полей быстрее и надежнее любой модели. Используйте API обнаружения PII для произвольного текста: сообщений в чате, обращений в поддержку, расшифровок и документов.

Сравнение API удаления PII (октябрь 2026)

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 символов, минимум 3 единицы Оплата за GiB; минимум 1 KB на запрос Оплата за текстовую запись Ваши вычислительные ресурсы
Бесплатный объем 50K единиц (5M символов) на каждый API в месяц в течение 12 месяцев Первый 1 GiB в месяц для проверки 5,000 текстовых записей в месяц (бесплатный тариф) Бесплатное ПО
Данные покидают вашу сеть Да (AWS) Да (Google Cloud) Да, если вы не используете контейнер Нет

Источники: документация Amazon Comprehend по PII, цены Comprehend, документация Google по обезличиванию, цены Sensitive Data Protection, обзор Azure PII, цены Azure Language, документация Presidio. Все источники проверены 27 октября 2026 года.

Сколько это стоит?

  • Amazon Comprehend: в примере AWS для Detect PII 10,000 комментариев клиентов по 550 символов тарифицируются как 6 единиц на запрос: итого 60,000 единиц по $0.0001 за единицу обходятся в $6 (цены Comprehend, пример 7). Для коротких запросов действует минимум 3 единицы (300 символов), поэтому объединение небольших сообщений в пакеты экономит деньги.
  • Google Sensitive Data Protection: проверка содержимого бесплатна в пределах первого 1 GiB в месяц, затем стоит $3.00 за GiB, а при больших объемах — $2.00 за GiB; цена преобразования указана как $2.00 за GiB, затем $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). Обезличенный текст 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

API Google проверяет и преобразует текст за один вызов. Вы выбираете 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 API).

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"}
    ]}
  }'

В примере ответа из документации Microsoft возвращается "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 (идентификатор заказа) Не обнаружен Неприменимо Пропуск: для бизнес-идентификаторов нужны собственные правила

Три вывода из этого небольшого теста:

  1. Пороги задают баланс между пропусками и лишними срабатываниями. При повторном запуске с score_threshold=0.5 номер телефона (оценка 0.4) выпал из результатов и остался в тексте без изменений. Настраивайте пороги для каждого типа сущности, а не глобально.
  2. Для ваших идентификаторов нужны собственные распознаватели. Добавление PatternRecognizer для \bA-\d{5}\b с оценкой 0.6 позволило обнаружить идентификатор заказа. Реалистичное значение в формате SSN (536-90-4399) было определено как US_SSN с оценкой 0.85.
  3. Обратимая токенизация работает. Оператор encrypt со 128-битным ключом и DeanonymizeEngine с decrypt позволили в точности восстановить исходный текст.

Конвейер удаления PII для LLM-приложений

Типичная схема для ИИ-продуктов: обезличить текст, вызвать модель, затем восстановить данные, которые нужно показать пользователю:

  1. Сначала правила для полей. Удалите или замените известные поля с PII в структурированных данных по схеме.
  2. Обнаружение в произвольном тексте. Обработайте сообщения, обращения и документы с помощью API обнаружения PII или 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. Идентификатор заказа по-прежнему проходит без изменений, поэтому в рабочей среде необходим собственный распознаватель из предыдущего раздела. Встроенный модуль анонимизации Presidio разрешает пересечения за вас.

Обработка сбоев и тестирование

Риск Мера защиты
Тайм-аут API обнаружения PII или ошибка 5xx При сбое блокируйте передачу: не отправляйте в LLM необезличенный текст; поставьте запрос в очередь и повторите попытку
Обнаружение с низкой уверенностью Пороги для отдельных типов сущностей; еженедельная проверка выборки
Неподдерживаемый язык Сначала определяйте язык; AWS Comprehend PII поддерживает только английский и испанский
Бизнес-идентификаторы (идентификаторы заказов, номера счетов) Собственные распознаватели на регулярных выражениях или правила для полей
Ложные срабатывания, искажающие смысл Списки исключений для названий продуктов и общедоступных адресов
PII в ответе модели Проверяйте ответы перед записью в логи или показом другим пользователям
Исходные данные в логах Записывайте только обезличенный текст и количество сущностей

Подготовьте размеченный тестовый набор синтетических сообщений, похожих на ваш реальный трафик: включите имена из разных культур, международные форматы телефонных номеров и собственные форматы идентификаторов. Измеряйте полноту обнаружения по каждому типу сущности перед запуском и после каждого изменения правил.

Как выбрать API удаления PII

  • Уже используете AWS, а тексты на английском или испанском: Amazon Comprehend прост в использовании и недорог при небольших объемах.
  • Нужна обратимая токенизация в виде управляемого сервиса или множество идентификаторов, специфичных для отдельных стран: Google Sensitive Data Protection.
  • Нужен сразу обезличенный текст, обнаружение PII в диалогах или документах либо контейнеры для локального развертывания: Azure Language PII.
  • Данные не должны покидать вашу сеть или нужен полный контроль над правилами: Presidio с собственными распознавателями и оценкой качества на ваших данных.

Многие команды совмещают эти подходы: Presidio или правила для полей — в основном потоке запросов, а управляемый API — для пакетной проверки документов.

Как это сочетается с Flatkey

Flatkey — это шлюз моделей: один ключ и эндпоинт, совместимый с OpenAI, для множества LLM. Он не обнаруживает и не удаляет PII за вас, поэтому обезличивайте данные в приложении до того, как запросы покинут ваш сервис, как в конвейере выше. В документации Flatkey для корпоративных клиентов описано отсутствие хранения содержимого запросов: это снижает риск раскрытия данных, но не заменяет их обезличивание. Материалы по теме: политика удаления персональных данных для API ИИ, безопасное управление API-ключами, учет затрат на LLM и каталог моделей Flatkey.

Частые вопросы

Что такое API удаления PII?

Это API, который обнаруживает персональные данные в тексте — например, имена, адреса электронной почты, номера телефонов и идентификационные номера — и возвращает их позиции либо версию текста, в которой они удалены, замаскированы или заменены.

Какой API удаления PII лучше?

Зависит от вашего стека и данных. Amazon Comprehend подходит для текстов на английском и испанском в AWS, Google Sensitive Data Protection наиболее силен в обратимой токенизации и поддержке множества infoTypes, Azure сразу возвращает обезличенный текст и работает в контейнерах, а Presidio лучше всего подходит, когда данные должны оставаться внутри вашей сети.

Есть ли бесплатный API удаления PII?

Presidio — бесплатное ПО с открытым исходным кодом. У управляемых сервисов есть бесплатные лимиты: AWS Comprehend предоставляет 50K единиц (5M символов) на каждый API в месяц в течение 12 месяцев, Google — первый 1 GiB проверок в месяц бесплатно, а бесплатный тариф Azure включает 5,000 текстовых записей в месяц.

Нужно ли удалять PII перед отправкой промптов в ChatGPT, Claude или API других LLM?

Да, если модели не нужны реальные значения. Псевдонимизируйте имена, контактные данные и идентификаторы, отправляйте модели плейсхолдеры и восстанавливайте значения в своем сервисе, если они нужны пользователю.

Можно ли отменить удаление PII?

Обычное удаление и маскирование необратимы. Токенизацию или псевдонимизацию на основе шифрования можно обратить с помощью ключа или таблицы соответствий, которые следует надежно хранить отдельно от обезличенных данных.

Насколько точны API обнаружения PII?

Ни один не идеален. В нашем тесте Presidio номер телефона получил оценку всего 0.4, а идентификатор заказа не обнаруживался, пока мы не добавили собственное правило. Измеряйте полноту обнаружения на собственных синтетических данных и блокируйте передачу при ошибках детектора.

Удаляет ли Flatkey PII?

Нет. Flatkey направляет запросы к моделям; обезличивание должно выполняться в вашем приложении до отправки запроса.