Почему ваш LLM-ассистент уже нарушает 152-ФЗ (и вы об этом не знаете)
Вы настроили умного помощника на Gemini 2.0 Pro. Он читает документы, отвечает на вопросы сотрудников, ищет информацию в базе знаний. И в этот самый момент он спокойно отправляет полные ФИО, паспортные данные и телефоны ваших клиентов на серверы Google в Айову. Поздравляю, вы только что схлопотали нарушение 152-ФЗ с штрафами до 6 миллионов рублей. И нет, фраза "мы же используем облако" Роскомнадзора не убедит.
Важно: Трансграничная передача персональных данных — даже в обезличенном виде — требует уведомления Роскомнадзора. Если данные можно обратно идентифицировать (а LLM это умеют, см. исследование про деанонимизацию), это все еще персональные данные. Юридическая казуистика на грани фола.
Обезличивание — это не про "найти-заменить", а про инженерный пайплайн
Многие думают: "Прогоним текст через регулярки и заменим имена на [ФИО_1]. Готово". Это подход самоубийцы. Во-первых, регулярки не ловят контекст ("договор с Ивановым И.И. по паспорту 4510 123456"). Во-вторых, после такой обработки LLM не поймет, о ком речь. В-третьих, вы теряете возможность вернуть данные обратно, если это нужно для ответа пользователю. Нужна система.
1 Аудит: что за данные у вас летят в LLM?
Откройте логи вашего AI-ассистента. Что вы видите? Резюме кандидатов (смотрите HR-автоматизацию 2026), договоры с клиентами, внутренние переписки с упоминанием сотрудников. Все это — персональные данные по 152-ФЗ. Составьте список сущностей, которые нужно детектировать:
- Прямые идентификаторы: ФИО, паспортные данные, СНИЛС, ИНН, телефоны, email, почтовые адреса.
- Косвенные идентификаторы: Должность + компания, ники в корпоративном чате, уникальные номера договоров, которые можно связать с человеком.
- Особые категории: Биометрические данные, здоровье, политические взгляды — тут вообще адская юрисдикция.
2 Выбор инструмента для детекции PII: облако vs локальная модель
Тут два пути. Первый — использовать облачный API (например, тот же Google Cloud DLP). Удобно, точно, но вы снова отправляете данные в облако, потенциально нарушая закон. Второй — запустить модель локально. В 2026 году есть отличные open-source варианты, например, модель Presidio 3.0 от Microsoft или специализированные SLM, как в кейсе с Artifex.
| Инструмент | Точность | Скорость | Где работает | Поддержка русского |
|---|---|---|---|---|
| Presidio 3.0 (open-source) | ~92% на PII-датасетах | Средняя, зависит от NER-модели | Локально, в Docker | Есть, но требует дообучения на русских данных |
| Google Cloud DLP API | ~98% | Высокая | Облако Google | Отличная |
| Самописная модель на основе Hugging Face Transformers (партнерская ссылка на GPU-инстансы) | Зависит от данных | Низкая без GPU | Локально, можно на A100 | Идеальная, если обучали на своих данных |
Мой совет: если данные сверхчувствительные (медицина, финансы), крутите все локально. Для внутренних HR-задач, где риск ниже, можно взять облачный DLP, но только если у вас есть согласие субъектов на трансграничную передачу (спойлер: у вас его нет).
3 Проектируем пайплайн: от сырого текста до обезличенного промпта
Цель: текст на входе, обезличенный текст и mapping-таблица (словарь замен) на выходе. Все это должно работать в реальном времени, потому что пользователь ждет ответа от ассистента.
# Упрощенная схема пайплайна на Python с Presidio
import json
from presidio_analyzer import AnalyzerEngine
from presidio_anonymizer import AnonymizerEngine, DeanonymizeEngine
from presidio_anonymizer.entities import OperatorConfig
# Инициализация (модели грузятся один раз)
analyzer = AnalyzerEngine()
anonymizer = AnonymizerEngine()
deanonymizer = DeanonymizeEngine()
def anonymize_text(text: str) -> (str, dict):
"""Обнаруживает PII и заменяет на токены."""
# Анализ: находит сущности в тексте
analyzer_results = analyzer.analyze(text=text, language='ru')
# Замена: настраиваем операторы (например, для ФИО - замена на [PERSON_1])
operators = {
"PERSON": OperatorConfig("replace", {"new_value": "[PERSON_{}]"}),
"PHONE_NUMBER": OperatorConfig("replace", {"new_value": "[PHONE_{}]"}),
"RUS_PASSPORT": OperatorConfig("replace", {"new_value": "[PASSPORT_{}]"}),
}
# Анонимизация
anonymized_result = anonymizer.anonymize(
text=text,
analyzer_results=analyzer_results,
operators=operators
)
# Возвращаем обезличенный текст и mapping для возможной деанонимизации
mapping = {entity.entity_type: entity.text for entity in analyzer_results}
return anonymized_result.text, mapping
# Пример
raw_text = "Договор с Ивановым Иваном Ивановичем (паспорт 4510 123456) по тел. +7 999 123-45-67."
anonymized_text, mapping = anonymize_text(raw_text)
print(f"Обезличенно: {anonymized_text}") # Договор с [PERSON_1] (паспорт [PASSPORT_1]) по тел. [PHONE_1].
print(f"Mapping: {mapping}") # {'PERSON': 'Ивановым Иваном Ивановичем', 'RUS_PASSPORT': '4510 123456', ...}
4 Интеграция с Gemini API: отправляем только безопасный промпт
Допустим, вы используете Gemini 2.0 Flash — быструю и дешевую модель для ассистентов. Ваш пайплайн теперь выглядит так:
- Пользователь задает вопрос: "Какие условия договора с Ивановым И.И.?"
- Система ищет договор в базе, находит текст документа.
- Текст договора обезличивается (ФИО → [PERSON_1], паспорт → [DOC_1]).
- Собирается промпт: "На основе следующего договора: [обезличенный текст]. Вопрос: какие условия договора с [PERSON_1]?"
- Промпт отправляется в Gemini API.
- Ответ Gemini получаем, и если нужно, заменяем обратно токены [PERSON_1] на "Иванов И.И." используя mapping.
- Пользователь видит ответ с реальными именами, но они никогда не уходили в облако.
Звучит просто? Вот где начинается боль.
Подводные камни, которые разобьют вашу систему вдребезги
Ошибка 1: Неполное обезличивание. Вы вычистили ФИО, но остался номер договора "ДГ-2026-ИВАНОВ". По нему можно идентифицировать человека. Решение: добавляйте в детекцию кастомные паттерны — номера договоров, внутренние табельные номера, логины. Используйте паспорт требований, чтобы заранее описать все форматы данных.
Ошибка 2: Потеря контекста. Если вы заменили "Иванов", "Петров" и "Сидоров" на [PERSON_1], [PERSON_2], [PERSON_3], LLM не поймет, кто есть кто в диалоге. Решение: используйте семантические токены, например, [PERSON_АВТОР_ДОГОВОРА], [PERSON_ИСПОЛНИТЕЛЬ]. Это требует дополнительного анализа ролей, но сохраняет смысл. Об этом есть в статье про контекстуализацию корпоративных данных.
Ошибка 3: Деанонимизация по ответу LLM. Даже если вы отправили обезличенный текст, умная модель может восстановить данные из контекста. Например, спросите: "Кто [PERSON_1] по профессии?", а в тексте было: "[PERSON_1], врач-кардиолог высшей категории из клиники в Москве". В небольшом коллективе этого достаточно для идентификации. Защита: никогда не задавайте LLM прямых вопросов об обезличенных сущностях. Контролируйте промпты.
Ошибка 4: Игнорирование метаданных. Вы очистили текст документа, но отправили в API вместе с именем файла "Договор_Иванов_И.И._2026.pdf". Файл-то летит в заголовках! Решение: чистите все метаданные, имена файлов, ID запросов — всё, что может нести информацию.
А если вообще не отправлять данные в облако? Локальные LLM
Самый радикальный способ соблюсти 152-ФЗ — не выносить данные за периметр. В 2026 году можно запустить мощную модель типа Raft 3B или Qwen2.5 7B на своем сервере с GPU. Плюсы: полный контроль, нет трансграничной передачи. Минусы: дороже (железо), слабее качество, нужно самим обслуживать. Подробности в статьях про эксперимент с Raft и Ollama vs другие. Для многих бизнес-задач (например, анализ договорных рисков) локальных моделей хватает.
Вопросы, которые мне задают чаще всего (и ответы на них)
Вопрос: Нужно ли получать согласие человека на обезличивание его данных для LLM?
Ответ: Если обезличивание происходит для внутренних бизнес-процессов (например, анализ резюме для HR), то достаточно указать это в политике обработки персональных данных. Если данные потом уходят к третьим лицам (в облако AI-провайдера), нужно отдельное информированное согласие на трансграничную передачу. Суды в 2025-2026 годах уже штрафовали за отсутствие такого согласия.
Вопрос: Что делать, если LLM в ответе генерирует новые персональные данные (например, придумывает номер паспорта)?
Ответ: Это реальная проблема. Gemini и другие модели иногда галлюцинируют и "восстанавливают" данные. Защита: пост-обработка ответов. Прогоняйте ответ LLM через тот же детектор PII. Если нашли что-то похожее на паспорт или телефон — либо маскируйте, либо удаляйте фрагмент. И обязательно логируйте такие случаи для аудита.
Вопрос: Как оценить, насколько хорошо работает наш пайплайн обезличивания?
Ответ: Нужен тестовый датасет с размеченными PII. Запускаете на нем ваш детектор и смотрите метрики: precision (сколько найденного — реальные PII) и recall (сколько реальных PII вы нашли). Цель — recall близкий к 100%, иначе рискуете пропустить данные. Поможет статья про Lexometrica Ground Truth.
Итоговая архитектура, которая не подведет
Собираем все вместе:
- Входной шлюз: Принимает запрос пользователя, извлекает данные из базы.
- Детектор PII (локальный): Presidio 3.0 с дообученной моделью для русских юридических и HR-текстов.
- Анонимайзер: Замена на семантические токены ([PERSON_АВТОР], [PHONE_РАБОЧИЙ]). Mapping пишется в зашифрованный Redis с TTL=5 минут.
- Построитель промптов: Объединяет обезличенный текст, инструкцию и вопрос. Отправляет в Gemini 2.0 API через VPN-канал с российского сервера.
- Пост-обработчик: Проверяет ответ LLM на утечки, при необходимости делает обратную замену токенов на исходные данные из mapping (только если пользователю нужно показывать реальные имена).
- Логирование: Все операции (кроме mapping) пишутся в SIEM-систему для будущих проверок Роскомнадзора. Используйте Grafana Cloud (партнерская ссылка) для мониторинга аномалий.
Да, это сложнее, чем просто вызвать API. Но именно так выглядит инженерная ответственность в 2026 году. Иначе вы не строите AI-ассистента, а просто легализуете утечку данных под соусом инноваций. Выбирайте.