Зачем. Пока Лиза работает как шлюз на Claude, каждый запрос пользователя физически уходит в Anthropic (США). Сырые персональные данные (ПДн) россиян в таком запросе = трансграничная передача + риск по 152-ФЗ. Обфускация маскирует ПДн до отправки и восстанавливает их в ответе. Когда Лиза переедет на свою ИИ внутри периметра — слой можно ослабить или выключить одним флагом.
01Главный принцип: обфускация — это отдельный слой, а не правка ядра
Никогда не зашивай маскирование в бизнес-логику бота. Сделай его прослойкой между ядром Лизы и адаптером модели:
Пользователь
↓
[Ядро Лизы: роутинг агентов, промпты, контекст]
↓
[СЛОЙ ОБФУСКАЦИИ] ← mask() на входе, unmask() на выходе (вкл/выкл флагом)
↓
[Адаптер модели: Claude | GPTunnel | своя ИИ]
↓
ответ → unmask() → пользователь
Это даёт два бонуса:
- переезд на свою ИИ = смена адаптера + флаг
OBFUSCATION=off, без переписывания бота; - слой можно тестировать и логировать изолированно.
02Что именно маскировать
Маскируем всё, что позволяет опознать человека (PII). Минимальный набор для русскоязычного бота:
| Тип | Пример | Заглушка |
|---|---|---|
| Имя/ФИО | Иван Петров | [PER_1] |
| Телефон | +7 900 123-45-67 | [PHONE_1] |
| ivan@mail.ru | [EMAIL_1] | |
| Telegram-username/id | @ivan, 123456789 | [TG_1] |
| Карта/счёт | 4276 1600 … | [CARD_1] |
| Паспорт/СНИЛС/ИНН | 4509 123456 | [DOC_1] |
| Адрес | г. Москва, ул. … | [ADDR_1] |
| Дата рождения | 14.03.1990 | [DOB_1] |
| Гео-координаты | 55.75, 37.61 | [GEO_1] |
Важно: нумеруем заглушки ([PER_1], [PER_2]), чтобы модель различала разных людей и сохраняла связность ответа.
03Два режима — выбери под задачу
A. Псевдонимизация (обратимая) — рабочий режим по умолчанию
Храним карту заглушка → оригинал локально на время запроса. После ответа модели восстанавливаем реальные значения. Пользователь видит нормальный текст.
- Лиза остаётся полезной (может говорить «Иван, ваша запись на 15:00»).
- Юридически псевдонимизированные данные при строгом прочтении всё ещё могут считаться ПДн — но в Claude уходят уже обезличенные строки, ключ остаётся у тебя.
B. Обезличивание (необратимое)
Маскируем и не восстанавливаем. Применяй для аналитики, логов, обучающих выборок, фоновых задач, где реальные значения не нужны.
- Данные перестают быть ПДн → 152-ФЗ к ним не применяется.
- Не годится для диалога, где надо обращаться к человеку по имени.
Правило: диалог → режим A, логи/аналитика → режим B.
04Жизненный цикл одного запроса
1. Пользователь пишет в Лизу.
2. mask(text) → текст с заглушками + map {заглушка: оригинал}.
3. В Claude уходит ТОЛЬКО маскированный текст. map НИКОГДА не уходит в модель.
4. Модель отвечает заглушками ([PER_1] записан на [PHONE_1]).
5. unmask(answer, map) → реальные значения возвращаются.
6. Пользователь получает нормальный ответ.
7. map уничтожается после запроса (не пишем в долгую память сырьём).
Ключевое: карта соответствия живёт только в оперативной памяти на время обработки и никогда не покидает твой сервер.
05Реализация (Python, псевдокод-референс)
Бот на Python — вот минимальный слой. Адаптируй под свою структуру.
import re
# --- паттерны PII (расширяй под свои данные) ---
PATTERNS = {
"EMAIL": r"[\w.+-]+@[\w-]+\.[\w.-]+",
"PHONE": r"(?:\+7|8)[\s\-]?\(?\d{3}\)?[\s\-]?\d{3}[\s\-]?\d{2}[\s\-]?\d{2}",
"CARD": r"\b(?:\d[ \-]?){13,19}\b",
"TG": r"@[A-Za-z0-9_]{4,32}",
}
def mask(text: str):
"""Возвращает (маскированный_текст, карта_соответствия)."""
mapping = {}
counters = {}
def repl(kind):
def _r(m):
original = m.group(0)
# один и тот же оригинал → одна и та же заглушка
for token, val in mapping.items():
if val == original:
return token
counters[kind] = counters.get(kind, 0) + 1
token = f"[{kind}_{counters[kind]}]"
mapping[token] = original
return token
return _r
for kind, pat in PATTERNS.items():
text = re.sub(pat, repl(kind), text)
return text, mapping
def unmask(text: str, mapping: dict):
"""Возвращает реальные значения по карте."""
for token, original in mapping.items():
text = text.replace(token, original)
return text
Использование в обработчике сообщения:
OBFUSCATION = True # ← флаг. На своей ИИ ставишь False.
async def handle(user_text: str) -> str:
if OBFUSCATION:
safe_text, mapping = mask(user_text)
else:
safe_text, mapping = user_text, {}
answer = await call_model(safe_text) # сюда уходит ТОЛЬКО safe_text
return unmask(answer, mapping) if OBFUSCATION else answer
Для имён, адресов и ФИО регулярками не обойтись — используй NER-библиотеку (natasha для русского языка, spaCy с русской моделью) и добавляй найденные сущности в ту же карту. Регулярки закрывают «структурные» PII (телефон, email, карта), NER — «текстовые» (имена, города, организации).
06Чего НЕЛЬЗЯ делать
- Отправлять
mapping(карту соответствия) в модель — это сводит обфускацию к нулю. - Логировать сырые ПДн или карту в файлы/БД/внешние логгеры. Логируй только маскированную версию.
- Хранить карту дольше, чем длится запрос. Для многоходовых диалогов держи карту в server-side сессии пользователя, не в самом промпте к модели.
- Считать, что обфускация = полная юридическая чистота. Это снижение риска, а не индульгенция (см. раздел 8).
- Класть PII в системный промпт агента (там часто всплывают имя и контакты «для контекста»).
07Тестирование слоя
Минимальный чек перед боем:
- Утечка: прогони реальный запрос с телефоном/именем → проверь, что в payload к модели (перехвати на адаптере) PII отсутствует.
- Обратимость:
unmask(mask(x)[0] …)возвращает исходный текст 1:1. - Связность: один и тот же человек в тексте получает одну заглушку (
[PER_1]везде), не плодит[PER_1] [PER_2]для одного Ивана. - Ответ модели: модель, получив заглушки, корректно их использует в ответе, и они восстанавливаются.
- Флаг: при
OBFUSCATION=Falseбот работает как раньше (для будущей своей ИИ).
08Юридический контекст (коротко, не замена юристу)
Обфускация закрывает техническую сторону, но для шлюза на Claude остаются организационные требования 152-ФЗ:
- Локализация (ст. 18 ч.5): первичная база ПДн россиян должна быть в РФ.
- Трансграничная передача (ст. 12): уведомление в РКН до начала передачи; США — не «адекватная» страна, требования строже.
- Согласие: правовое основание на передачу данных третьему лицу.
Полное необратимое обезличивание выводит данные из-под этих требований. Псевдонимизация — снижает риск, но не гарантирует вывод из-под 152-ФЗ. Перед боевым запуском связку «что маскируем + уведомление РКН + согласие + локализация» проверь с профильным юристом по персональным данным.
09Дорожная карта
- Вынести вызов модели в единый адаптер (
call_model), если ещё не вынесен. - Добавить слой
mask/unmaskс флагомOBFUSCATION. - Регулярки на структурные PII (телефон, email, карта, TG).
- Подключить NER (
natasha) на имена/адреса/организации. - Прогнать чек-лист из раздела 7.
- Почистить логи: убрать сырые ПДн, оставить маскированные.
- Юрчек по разделу 8.
- При переезде на свою ИИ —
OBFUSCATION=False+ сменить адаптер.