152-ФЗ и LLM несовместимы по умолчанию: как мы это исправили без потери качества AI

152-ФЗ и LLM несовместимы по умолчанию: как мы это исправили без потери качества AI

Строим AI-ассистента для бизнеса — и обнаруживаем, что каждое сообщение пользователя с персональными данными уходит в Google. Рассказываю, как это исправить, не сломав UX.

Проблема: данные уходят за границу

Когда мы запускали AI-ассистента для квалификации лидов в строительном бизнесе, первый же вопрос от клиента поставил меня в тупик: «А куда уходят персональные данные, которые люди вводят в чат?»

Я знал ответ. И он мне не нравился.

Пользователь пишет: «Меня зовут Дмитрий, наша компания ООО Ромашка, телефон +7 903 123-45-67, email dmitriy@company.com». Это сообщение в том же виде уходит в Google Gemini API для генерации ответа. Google получает PII — имя, телефон, email конкретного человека. Каждый раз. С каждым пользователем.

Для бизнеса в России это три проблемы одновременно.

Юридическая. 152-ФЗ требует, чтобы персональные данные российских граждан обрабатывались на территории РФ. Передача данных на серверы Google — даже для обработки, не хранения — это трансграничная передача, требующая уведомления Роскомнадзора и согласия субъекта. Штрафы — от 3 млн рублей.

Бизнес-риск. Контактная база клиентов — главный актив отдела продаж. Отдавать её третьим лицам, даже крупной корпорации, — вопрос корпоративной гигиены.

Этика. Клиент пишет в ваш чат. Он доверяет вам. Не Google.

Решение: паттерн токен-подмены

Задача была чёткой: большая языковая модель должна вести диалог естественно — обращаться по имени, знать компанию, упоминать email — но никогда не получать реальные персональные данные. Звучит как противоречие. Решение — элегантное.

Представьте сотрудника колл-центра, которому перед звонком говорят: «Клиента зовут КЛИЕНТ_ИМЯ, его компания — КОМПАНИЯ, телефон — ТЕЛЕФОН». Сотрудник ведёт разговор, использует эти метки, а в финальной стенограмме подставляются реальные данные. Сам он так и не узнал, с кем говорил.

Именно так работает защита PII при обращении к LLM.

  • Шаг 1. Пользователь вводит сообщение с реальными данными.
  • Шаг 2. Система перехватывает сообщение до отправки в Gemini API и заменяет PII на токены: Дмитрий → [USER_NAME], dmitriy@company.com → [USER_EMAIL], ООО Ромашка → [USER_COMPANY].
  • Шаг 3. LLM получает очищенный текст и отвечает: «Отлично, [USER_NAME]! Подготовлю расчёт для [USER_COMPANY] и пришлю на [USER_EMAIL]».
  • Шаг 4. Система подставляет реальные данные обратно в ответ перед показом пользователю.
  • Шаг 5. Пользователь видит естественный ответ. AI не знал ничего реального. Роскомнадзор доволен.

Сложности в реализации

WebSocket стриминг ломал всё. LLM отвечает кусочками в реальном времени. Сначала мы восстанавливали PII только в финальном тексте — и пользователь видел мелькающий [USER_NAME].

Потом обнаружили: токен может быть разрезан между чанками. Первый приходит [USER_, второй — NAME]. Каждый по отдельности — не токен, замена не срабатывает.

Решение — буферизация: держать хвост чанка, убедиться, что токен закрыт ], и только тогда отправлять. Отдельный класс StreamingPiiRestorer, инстанцируемый per-stream, а не singleton — иначе буфер шарится между сессиями.

Один модуль обходил весь pipeline. Генератор сметы читал сообщения напрямую из PostgreSQL и отправлял в Gemini API без очистки. Все PII утекали в этот момент — когда их было больше всего. Нашли только через аудит кода. Теперь каждый LLM-вызов проходит через единую точку входа — обойти невозможно.

Числа в сметах взрывали regex. Паттерн «10–15 цифр подряд» ловил не только ИНН и ОГРН, но и суммы, артикулы, номера заказов. Пришлось писать отдельные валидаторы с проверкой контрольных цифр по алгоритму ФНС. Разделили: ИНН юрлица — 10 цифр, физлица — 12, ОГРН — начинается с 1 или 5.

Архитектура защиты: пять слоёв

Слой 1 — токен-подмена известных PII. Имя, email, телефон, компания из профиля. Детерминированная замена, надёжность ~99%.

Слой 2 — regex-сканер для данных третьих лиц. Пользователь может упомянуть: «позвоните партнёру на partner@gmail.com». Этих данных нет в профиле. Сканер ловит email, телефоны, ИНН, ОГРН, паспортные данные, IP, номера карт — с валидацией.

Слой 3 — шифрование в PostgreSQL. Все PII-поля шифруются AES-256-GCM до записи в базу. Ключ — в env, отдельно от БД. Снапшот без ключа — набор нечитаемых байт.

Слой 4 — HMAC-верифицируемый audit log. Каждая отправка в LLM фиксируется: что ушло (очищенный текст), какие поля заменены. Для доказательства обезличивания используется HMAC-SHA256 от оригинального текста с секретным ключом. SHA-256 без ключа — это псевдонимизация, которая по позиции РКН всё ещё считается персональными данными. HMAC с ключом — иной правовой статус: без ключа значение необратимо.

Слой 5 — автоматическое удаление по data retention policy. По ст. 21 152-ФЗ данные уничтожаются после достижения цели. Ночной cron анонимизирует PII в завершённых диалогах старше 90 дней батчами по 500 записей — без table lock на PostgreSQL.

Что это даёт бизнесу

Клиенты общаются с AI-ассистентом и оставляют контакты. Эти данные остаются вашими. Они не уходят в Google, не хранятся за рубежом. При проверке Роскомнадзора у вас есть журнал с криптографическими доказательствами, что персональные данные никогда не покидали ваш контур в открытом виде.

При этом LLM работает так же хорошо — обращается по имени, помнит компанию, ведёт естественный диалог. Пользователь не замечает ничего.

Что осталось за кадром

Имена третьих лиц в свободном тексте не перехватываются: «позвоните Ивану Петрову» — имя уйдёт в LLM. Regex не умеет отличать имена от слов. NER-модели для русского языка дают точность 65–75% — слишком много ложных срабатываний. Компромисс: имя без контактных данных — не actionable PII по 152-ФЗ.

Важнее другое: никакая техническая защита не заменяет административный compliance. Форма согласия на обработку данных, уведомление Роскомнадзора, договор с поставщиком AI-сервиса (DPA с Google) — это отдельная работа. Технология решает технический слой. Юридический — решают юристы.

Мы потратили несколько недель, чтобы довести это до уровня, где можно спокойно отвечать на вопрос: «А куда уходят данные?»

Теперь есть что ответить.

Читать оригинал