- BrainTools - https://www.braintools.ru -

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

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

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

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

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

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

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

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

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

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

Паттерн токен-подмены: принцип работы

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

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

Шаг 1. Пользователь вводит сообщение с реальными данными.

Шаг 2. Система перехватывает сообщение до отправки в Gemini API и заменяет все персональные данные на токены: Дмитрий → [USER_NAME], dmitriy@company.com [1] → [USER_EMAIL], ООО Ромашка → [USER_COMPANY].

Шаг 3. LLM получает очищенный текст. Отвечает: «Отлично, [USER_NAME]! Подготовлю расчёт для [USER_COMPANY] и пришлю на [USER_EMAIL]».

Шаг 4. Система подставляет реальные данные обратно в ответ AI перед показом пользователю.

Шаг 5. Пользователь видит естественный ответ. AI не знал ничего реального. Роскомнадзор доволен.

Что пришлось решать по дороге — без купюр

Концепция простая. Production-реализация на NestJS — нет. Вот где мы споткнулись.

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

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

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

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

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

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

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

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

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

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

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

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

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

Что осталось за кадром — честно

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

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

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

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

Если вы строите AI-решения для российского рынка и столкнулись с похожей задачей — буду рад обсудить в комментариях. Исходная архитектура: NestJS + PostgreSQL + Google Vertex AI (Gemini), но паттерн применим к любому LLM-провайдеру.

Теги: информационная безопасность, персональные данные, 152-ФЗ, LLM, большие языковые модели, NestJS, Gemini API, защита данных, PII, бэкенд, разработка

Автор: Dimus-frontes

Источник [3]


Сайт-источник BrainTools: https://www.braintools.ru

Путь до страницы источника: https://www.braintools.ru/article/27807

URLs in this post:

[1] dmitriy@company.com: mailto:dmitriy@company.com

[2] partner@gmail.com: mailto:partner@gmail.com

[3] Источник: https://habr.com/ru/articles/1015694/?utm_source=habrahabr&utm_medium=rss&utm_campaign=1015694

www.BrainTools.ru

Rambler's Top100