Как вы обрабатываете PII в данных для RAG (GDPR, 152-ФЗ)?

Краткий тезис

Обработка PII (Personally Identifiable Information) в RAG — обязательная мера для соблюдения GDPR, 152-ФЗ и других законов о приватности. Основной подход — на этапе предобработки данных запустить NER-модель (spaCy, DeBERTa-NER, Presidio) для обнаружения PII, затем применить маскирование или удаление до индексации. Для возможности обратимости (например, для дата-сайентистов) можно хранить маппинг PII -> обезличенные идентификаторы в отдельной защищённой БД с строгим контролем доступа.


1. Что такое PII и почему это важно для RAG?

PII — любая информация, которая может прямо или косвенно идентифицировать физическое лицо: ФИО, адрес, телефон, email, ИНН, паспортные данные, IP-адрес и т.д.

В контексте RAG:

  • Данные для индексации часто содержат конфиденциальную информацию пользователей, клиентов или сотрудников.
  • Если эти данные попадут в ответ LLM, это нарушит приватность и может привести к штрафам.
  • Даже если LLM не выдаёт PII напрямую, векторная БД может быть скомпрометирована, и эмбеддинги могут быть декодированы (атаки инверсии).

Термин «Анонимизация» — необратимое удаление PII. «Псевдонимизация» — замена PII на псевдоним с возможностью восстановления при наличии ключа.


2. Основные регуляции: GDPR и 152-ФЗ

РегуляцияОсновные требованияШтрафы
GDPR (ЕС)Обработка персональных данных только с согласия; право на забывание; минимизация данных; сообщение об утечке в 72 часадо 20 млн евро или 4% годового оборота
152-ФЗ (РФ)Обработка ПДн с согласия; локализация данных на территории РФ; уведомление Роскомнадзора; обезличивание по методикедо 18 млн рублей (административные)

Обе регуляции требуют прозрачности — пользователь должен знать, какие данные собираются. В RAG это означает, что мы должны удалить или псевдонимизировать PII до того, как данные попадут в индекс.


3. Шаги обработки PII в RAG-пайплайне

3.1 Обнаружение (Detection)

Первый этап — найти PII в документах. Используются NER (Named Entity Recognition) модели: spaCy (en_core_web_trf, ru_core_news_lg), Hugging Face модели (DeBERTa-NER, dslim/bert-base-NER), Microsoft Presidio (анализирует контекстные и паттерные правила). Для русского языка хорошо работает NLP‑Lab/rubert-base-cased-conversational с дообучением на PII.

Пример обнаружения с Presidio и spaCy:

from presidio_analyzer import AnalyzerEngine
from presidio_analyzer.nlp_engine import NlpEngineProvider

provider = NlpEngineProvider(nlp_configuration={
    "nlp_engine_name": "spacy",
    "models": [{"lang_code": "ru", "model_name": "ru_core_news_sm"}]
})
nlp_engine = provider.create_engine()
analyzer = AnalyzerEngine(nlp_engine=nlp_engine)

results = analyzer.analyze(text="Меня зовут Иван Петров, номер паспорта 1234 567890", language="ru")
for r in results:
    print(f"Тип: {r.entity_type}, текст: {text[r.start:r.end]}, уверенность: {r.score}")

3.2 Маскирование (Masking) и удаление

После обнаружения нужно заменить PII на плейсхолдеры (маскирование) или полностью удалить.

  • Маскирование «Иван Петров» → «[PERSON]» или «[NAME]». Сохраняет структуру текста.
  • Удаление вырезать кусок текста. Может исказить смысл.
  • Псевдонимизация замена на уникальный идентификатор, например «ID_12345». Необходимо сохранить маппинг.

Выбор зависит от бизнес-требований: для юридической аналитики часто достаточно маскировки, для дата-сетов машинного обучения — псевдонимизация с возможностью восстановления.

3.3 Анонимизация через нейросеть (Advanced)

Современные подходы используют генеративные модели (например, Anonymization by prompting LLM): попросить LLM переписать текст без PII. Недостаток — высокая стоимость и риск изменения смысла. Чаще применяется на этапе пост-процессинга ответа LLM, а не на стадии индексации.


4. Инструменты и библиотеки

ИнструментОписаниеПреимущества
spaCyNER-модели для многих языков, быстраяЛёгкая интеграция, настраиваемые правила
Microsoft PresidioАнализатор + анонимайзер; использует NLP + регулярные выраженияИз коробки маскировка, шаблоны для разных стран
DeBERTa-NERSOTA по F1 на английском; ruBERT-аналоги для русскогоВысокая точность на редких сущностях
Amazon ComprehendCloud API, обнаружение PIIНе нужно держать модель, масштабируется
Google DLPData Loss Prevention APIИнтеграция с GCP, автоматическая классификация

Для российского рынка важно использовать модели, обученные на русских ПДн (паспорта, СНИЛС, ИНН).


5. Стратегии хранения маппинга для обратимости

Если выбрана псевдонимизация, маппинг «оригинальная PII → псевдоним» должен храниться отдельно:

  • Отдельная БД (PostgreSQL с шифрованием на уровне столбцов через pgcrypto).
  • HashiCorp Vault — для централизованного управления секретами.
  • AWS Secrets Manager / Azure Key Vault — облачные решения.

Требования безопасности:

  • Маппинг не должен храниться в той же векторной БД или в той же файловой системе, что и обезличенные данные.
  • Доступ только по API с аутентификацией (OAuth, mTLS).
  • Журналирование всех запросов на декодирование.

6. Контроль доступа и шифрование для индексированных данных

Даже обезличенные данные (чреваты косвенной идентификацией) требуют защиты:

  • Шифрование эмбеддингов в хранилище (AES-256) и при передаче (TLS).
  • Ролевая модель (RBAC): пользователь, имеющий право на retrieval, получает доступ только к документам, которые он имеет право видеть (фильтрация по метаданным).
  • Дифференциальная приватность (advanced): добавление шума в эмбеддинги, чтобы затруднить извлечение PII.

7. Аудит и комплаенс

Необходимо логировать:

  • Какие документы были обезличены,
  • Какая модель NER использовалась,
  • Какие сущности были найдены и как обработаны,
  • Запросы на расшифровку маппинга (с указанием причины).

Это помогает пройти проверки регуляторов (например, Роскомнадзора).


8. Пример полного пайплайна на Python

from presidio_analyzer import AnalyzerEngine
from presidio_anonymizer import AnonymizerEngine

# Шаг 1: анализ
analyzer = AnalyzerEngine()
anonymizer = AnonymizerEngine()

text = "Клиент: Иванов Иван, email: ivan@example.com, телефон: +7 123 456-78-90"
results = analyzer.analyze(text=text, language="ru")

# Шаг 2: анонимизация (маскирование)
anonymized_result = anonymizer.anonymize(
    text=text,
    analyzer_results=results,
    operators={"DEFAULT": {"type": "replace", "new_value": "[PII]"}}
)
print(anonymized_result.text)
# Вывод: "Клиент: [PII], email: [PII], телефон: [PII]"

Для хранения маппинга можно добавить словарь:

from presidio_anonymizer.entities import OperatorConfig

mapping = {"replace": {"new_value": lambda x: f"ID_{hash(x)}"}}
# сохранить map {hash: original} в отдельную БД

9. Компромисс между приватностью и полезностью данных

Удаление PMI может снизить качество retrieval (например, если имя является ключевым для поиска). Варианты:

  • Использовать контекстную маскировку: заменять только высокочувствительные сущности (паспорт, СНИЛС), оставляя имена.
  • Применять синтетические данные для генерации PII, которые выглядят реалистично, но не относятся к реальным людям.
  • При retrieval маппить PII обратно для контекста LLM, но только если пользователь авторизован (риск утечки).

10. Дополнительные техники безопасности

  • Проверка ответа LLM на утечку PII (фильтр на генерации): запускать детектор PII на выходе перед отправкой пользователю.
  • Регулярное переобучение NER-модели: паттерны утечек меняются (например, номера карт).
  • Валидация набора данных: проверка случайной выборки документов после обезличивания.

Пет-проект для закрепления

Задача Разработать конвейер для обработки конфиденциальных документов (резюме) перед загрузкой в RAG-систему на основе LangChain.

Инструменты Python, spaCy (с русской моделью), Presidio, PostgreSQL (с шифрованием), ChromaDB (векторная БД), LangChain.

Шаги:

  1. Соберите 50-100 примеров текстов резюме (сгенерируйте синтетические PII).
  2. Реализуйте модуль обнаружения PII (имена, телефоны, email, адреса) через Presidio.
  3. Создайте анонимайзер, который заменяет все PII на плейсхолдеры, но записывает маппинг в таблицу PostgreSQL.
  4. Загрузите обезличенные тексты в ChromaDB.
  5. Напишите простой retrieval: при запросе через LangChain верните обезличенные чанки.
  6. Добавьте эндпоинт для авторизованного пользователя, который расшифровывает псевдонимы (поднимать маппинг из БД).
  7. Протестируйте, что PII не видно в выводе LLM.

Ожидаемый результат Пайплайн, который надёжно скрывает PII, но при необходимости позволяет восстановить оригиналы через защищённый API.


Связь с другими вопросами

ВопросТема
18Как вы обрабатываете конфиденциальные данные в RAG?
23Как вы гарантируете, что LLM не выдаст чувствительную информацию?
41Как вы управляете версиями данных и аудитом в RAG?
56Какие стратегии фильтрации контекста вы используете?
71Как вы обрабатываете пользовательские подсказки, которые могут содержать PII?
89Как вы обеспечиваете соответствие GDPR при использовании облачных API LLM?

Навигация