Когда Claude Code работает с проектом клиента, он отправляет модели всю переписку: текст задачи, прочитанные файлы, вывод команд. В ней бывают имена покупателей, телефоны, пароли из конфигов. Мы сделали claudemask - прокси между Claude Code и моделью. Он заменяет такие значения метками до отправки и подставляет настоящие данные обратно в ответ.
В регламенте работы с ИИ для разработчиков есть запрет: персональные данные клиентов в зарубежные ИИ-сервисы без законного основания не загружаем. В документе запрет держится на внимательности человека в каждом сообщении. Прокси переносит часть правила в код: маскирует каждый запрос, а при сбое маскировки не отправляет его вовсе.
вы написали: Обсудили с Сергеем Петровым сроки, +7 903 123-45-67
модель получила: Обсудили с [hidden-first-1] [hidden-surname-1] сроки, [hidden-phone-1]
на экране: Обсудили с Сергеем Петровым сроки, +7 903 123-45-67Две задачи: спрятать данные и не испортить код
У прокси перед ИИ-агентом, который правит код, две задачи. Первая - не выпустить данные. Вторая - вернуть ответ модели без порчи. Агент записывает ответ в файлы проекта, а инструмент правки ищет в файле строку знак в знак. Если прокси вернёт хоть одну букву иначе, правка не найдёт, что менять.
Поэтому 734 автоматические проверки собраны вокруг двух вопросов.
- →Утечка. Проверка берёт корпус значений и прогоняет его через одиннадцать путей, которыми Claude Code передаёт текст модели. В корпусе имена во всех падежах, телефоны, почта, ИНН, СНИЛС, ОГРН, паспорт, карты и счета, адреса, IP, ключи AWS, Anthropic, OpenAI, GitHub и Slack, приватные ключи, пароли, строки подключения. Среди путей - набранное в терминале, прочитанное из файла, вложенное в параметры вызова инструмента, полученное от подключённого сервиса, записанное в служебный файл проекта, прошлый ответ модели. Смотрит проверка на те байты, которые прокси отправляет в сеть.
- →Порча. Текст проходит путь туда и обратно и возвращается знак в знак. Код, JSON, YAML, SQL, регулярные выражения, эмодзи, иероглифы и пути к файлам остаются нетронутыми. Сценарий правки файла проверяется целиком, а поток ответа проверка сто раз режет случайным образом - и каждый раз текст собирается без потерь.
Проверили и на живом Claude Code 2.1.270 с подпиской: чтение файлов, правка с точным совпадением строки, многоходовые задачи, команды оболочки, потоковый ответ, кеш промптов, продолжение сессии, вход в аккаунт.
Пять правил маски
- →Метка держится за значение. Номер закрепляется в таблице соответствий и больше не меняется: Петров остаётся [hidden-surname-1] и сегодня, и через неделю. Модель видит одного человека, в каком бы падеже его ни упомянули.
- →Разворачиваются только свои метки. Модель иногда пишет метку, которой в запросе не было, например [hidden-surname-12]. Пока таблица маленькая, выдуманный номер ни с чем не совпадает. Когда таблица вырастет, он совпадёт с настоящим, и на месте выдумки оказался бы человек из другого разговора. Поэтому прокси запоминает, какие метки отправил в каждом запросе, и возвращает значения только им.
- →У каждого сотрудника своя таблица. В общей таблице метка, которую модель придумала в разговоре одного человека, развернулась бы в данные другого. Таблица привязана к личному ключу доступа: идентификатор учётки клиент присылает сам и его можно подменить, ключ - нельзя.
- →Прокси трогает только текст переписки. Названия инструментов, схемы параметров, идентификаторы блоков, подписи размышлений, картинки и заголовки проходят байт в байт. Правка служебных полей Claude Code ломает вход в аккаунт.
- →Сбой останавливает запрос. Если маскировка упала или хранилище недоступно, прокси запрос не отправляет, а разработчик получает ошибку с объяснением.
Так это выглядит в отладочном отчёте прокси:
скрыто 28:
секреты 10 пароль 9 · ключ 1
контакты 7 почта 4 · телефон 2 · ник 1
люди 7 фамилия 4 · имя 3
развёрнуто в этом ответе 2:
имя [hidden-first-3] -> Сергей
фамилия [hidden-surname-7] -> Петров
МОДЕЛЬ ВЫДУМАЛА МЕТКИ, оставлены как есть:
[hidden-surname-12]Значения находит rumask - наша библиотека для русского текста. Свои форматы дописываются правилом: номер договора, внутренний код. Сотрудников компании можно подменять ролью - "Сергей Петров" становится "Руководителем", и обратно такая замена не разворачивается.
Почему постоянная метка экономит деньги
Claude Code на каждом ходу отправляет модели всю переписку заново. Пока метки не меняются, начало запроса совпадает с прошлым байт в байт. На совпадающем начале работает кеш промптов Anthropic, а он вдесятеро дешевле обычного ввода. В журнале прокси это видно так:
токены: вход 8, из кеша 23456, записано в кеш 172Метки, которые менялись бы от хода к ходу, сбрасывали бы этот кеш на каждом запросе.
Насколько прокси замедляет работу
Числа - с замеров на ноутбуке, один процесс прокси. Вместо модели в замере стоит заглушка, которая отвечает мгновенно, поэтому в цифрах только работа самого прокси.
| Что | Сколько |
|---|---|
| Накладные на ход при прогретом кеше | +2...7 мс |
| Первое сообщение сессии (117 КБ переписки) | 480 мс |
| Первое сообщение на тяжёлой переписке (330 КБ) | 3,5 с |
| Потолок пропускной способности | около 130 запросов в секунду |
| Восемь сотрудников начали разом | последний ждёт 2 с |
| Память | 120 МБ плюс десятки мегабайт на активную учётку |
Дорого обходится только первое сообщение: кеш пуст, и маскировать приходится всю переписку. Дальше Claude Code дописывает к переписке по блоку, и прокси маскирует только новый. Разворот ответа на 2 520 знаков с 80 метками занимает 6 мс; в ответе без меток разворот не запускается вовсе, на это уходит 120 микросекунд.
Узкое место одно: маскировка упирается в процессор и идёт по одному запросу. Шестнадцать одновременных запросов дают 300 мс по медиане вместо 20 у одного. Нагрузку при этом считают ходами: Claude Code присылает один запрос раз в десятки секунд на человека, поэтому даже сотня активных сотрудников даёт единицы запросов в секунду. Если одного прокси не хватает, ставят отдельный на группу сотрудников.
Чего claudemask не находит
Прокси прячет то, что нашла библиотека, поэтому пробелы rumask становятся пробелами прокси. Известные записаны в тестах: закроется пробел или появится новый - проверка это заметит. Вот список целиком.
Не скрывает намеренно
- →Город, название компании, адрес сайта. Человека по ним не опознать. На них держится смысл разговора: рынок, логистика, часовой пояс созвонов.
- →Имя пользователя в путях к файлам: путь обязан вернуться в правку файла байт в байт. При этом путь вида /Users/i.petrov/ стоит в каждом втором вызове инструмента, поэтому имя пользователя закрывают своим правилом в первую очередь.
Не узнаёт в такой записи
- →IPv6: распознаватель адресов знает только IPv4.
- →Ник в пути ссылки без символа @.
- →Телефон и номер карты через точки. Записанные через пробелы и дефисы находит.
- →ИНН парами цифр через пробел, как печатают в бланках.
- →Почту, спрятанную от роботов: "имя @ домен", "имя(собака)домен".
- →"Пароль от админки: X", если между словом и двоеточием стоит другое слово.
- →Значение в другой кодировке - base64, url-кодировка, html-сущности, экранированный юникод: распознаватель ищет буквы, а в закодированной строке их нет.
- →Слово с невидимым знаком внутри: символ нулевой ширины или мягкий перенос разрывает слово.
- →Улицу без слова "улица".
Путается в именах
- →Редкое имя со строчной буквы: "меня зовут артемий" не закрывается, а в терминале строчными пишут постоянно.
- →Редкую фамилию без имени рядом: опознание держится на паре.
- →Фамилию, которая совпадает с обычным словом: Мельник, Столяр.
- →Английские имена и адреса: rumask написана для русского текста. Телефоны, почту, ключи и номера документов она находит на любом языке.
Отдельно искали утечки, которые зависят от пути текста к модели: 64 пробы против одиннадцати путей. Значение либо находится на всех путях, либо не находится ни на одном. Пробелы - в распознавании, в передаче их нет.
Три оговорки к развороту
- →Падеж возвращается не всегда. Метка стоит за человека, и падеж прокси восстанавливает по предлогу слева. "Обсудили с Сергеем Петровым" возвращается как было, а "Напиши письмо Петрову" превращается в "Напиши письмо Петров": предлога нет. В замере rumask падеж верный в 88,5% разворотов. Числа, контакты, документы и секреты возвращаются точно всегда - прокси берёт их из таблицы строкой, без морфологии.
- →Модель знает про метки. Договорённость о метках прокси дописывает в системную инструкцию, без неё модель "чинит" метки правдоподобными числами. Иногда модель упоминает эту договорённость в ответе. Её можно отключить, но разворот станет хуже.
- →Модель выдумывает метки в 1% случаев. В рабочем журнале из 1 289 запросов метки встретились в ответах 624 раза, выдуманные - 6. Половина из них - метка, которую модель привела как пример. У остальных одна причина: одно значение не замаскировалось, вокруг сплошные метки, и модель достроила разметку по образцу. Выдуманная метка остаётся меткой, чужие данные на её место не встают.
Когда данные нельзя отдавать даже под метками
Маска нужна, когда модель работает в облаке. Если данные нельзя передавать наружу совсем, модель ставят внутри контура компании: так устроены ИИ-бот техподдержки, у которого данные не уходят в облако, и протоколы созвонов на локальных моделях.
Так с ИИ работает наша команда сопровождения: что можно отдавать модели и кто отвечает за код перед клиентом - записано в регламенте, персональные данные клиента прокси закрывает до отправки.



