Шлюз стоит между вашим кодом и моделью. Он находит в запросе чувствительные данные и подменяет их заглушками. Модель работает с обезличенным текстом. В ответе заглушки разворачиваются обратно, и вы получаете настоящие данные.
ФИО находятся по отчеству или инициалам. Фамилия без них останется в тексте — почему.
Запрос в зарубежную модель — это передача текста за пределы вашего контура. Всё, что попало в промпт, попало и туда.
Если в промпте нет персональных данных, вопрос об их передаче за границу не возникает вовсе. Это проще, чем обосновывать такую передачу.
Запрос хранится у провайдера модели столько, сколько написано в его политике, и читается его сотрудниками при разборе инцидентов. Заглушку читать бесполезно.
Данные утекают не только из кода: их вставляют в промпт руками, копируют из письма, шлют в поддержку. Шлюз чистит запрос независимо от того, кто его составил.
Соответствие «заглушка → оригинал» живёт только в памяти одного запроса. На диск оно не пишется и в журнал не попадает.
Тот же код, тот же SDK, тот же ключ. Изменился только адрес, на который идёт запрос.
Одно и то же значение получает одну и ту же заглушку во всём запросе — модель понимает, что это один и тот же человек, и отвечает связно.
В ответе заглушки разворачиваются обратно — в том числе в потоковом режиме, по мере поступления кусков. Ваш код получает готовый ответ с настоящими данными.
Всё, что можно проверить контрольной суммой или строгим форматом, проверяется. Поэтому «заказ 1234567890» не будет принят за ИНН, а «версия 1.2.3» — за IP-адрес. У ФИО контрольной суммы нет, поэтому их ищем только по жёсткому признаку — отчеству или инициалам. Ложное срабатывание ломает работающую задачу молча, и мы предпочитаем его не допускать.
Не только в тексте сообщений. Данные утекают и через системную инструкцию, и через результат вызова инструмента, поэтому проверяется всё, что прочитает модель.
Сообщения всех ролей, текстовые части, аргументы tool_calls и function_call, ответы инструментов, описания инструментов.
system, текстовые блоки, входные данные tool_use, результаты tool_result вместе с вложенными блоками, текстовые документы.
instructions, сообщения в input, аргументы function_call и вывод function_call_output.
Обратно заглушки разворачиваются в тех же местах ответа, в том числе в потоке. Не трогаем название модели, роли, идентификаторы, имена инструментов, ссылки и содержимое картинок, аудио и файлов.
ФИО ловим только там, где есть отчество или инициалы. Фамилия сама по себе («Иванов сказал»), имя с фамилией без отчества («Анна Каренина»), имена латиницей не маскируются: правило, достаточно широкое, чтобы поймать просто «Петров», поймает заодно «Готов» и половину заголовков — и молча испортит запрос.
Один человек в разных падежах получает разные заглушки: «Иванов Иван Иванович» и «Ивановым Иваном Ивановичем» для модели — два разных значения. Обратно подставляется та форма, что была в запросе, поэтому в ответе падеж может не совпасть.
Рассуждения модели (thinking, reasoning) не трогаем ни в запросе, ни в ответе: у части моделей они подписаны, и правка ломает следующий шаг диалога. Если модель упомянет в рассуждениях заглушку, вы увидите её как есть.
Адреса и названия компаний не распознаются. Их, как и ФИО без отчества, будет находить отдельная модель на нашей стороне — во второй очереди.
Мы говорим об этом прямо, потому что маскирование, которому нельзя доверять, опаснее его отсутствия: на него полагаются и перестают проверять.
Меняется адрес — всё остальное остаётся как было. Для OpenAI SDK это https://api.kosareva.cloud/guard/v1 — и для Chat Completions, и для Responses. Для Anthropic SDK — https://api.kosareva.cloud/guard, путь /v1/messages SDK допишет сам.
from openai import OpenAI
client = OpenAI(
api_key="ВАШ_КЛЮЧ",
base_url="https://api.kosareva.cloud/guard/v1",
)
resp = client.chat.completions.create(
model="gpt-4o",
messages=[{
"role": "user",
"content": "Клиент petrov@acme.ru, ИНН 7707083893",
}],
)
curl https://api.kosareva.cloud/guard/v1/chat/completions
-H "Authorization: Bearer ВАШ_КЛЮЧ"
-H "Content-Type: application/json"
-d '{
"model": "gpt-4o",
"messages": [
{"role": "user", "content": "Клиент petrov@acme.ru"}
]
}'
Отдельный адрес показывает, что будет замаскировано, и никуда не обращается. Прогоните на нём свои настоящие промпты до того, как переключите боевой трафик.
POST /guard/v1/guard/preview
{"found": [{"type": "EMAIL", "value": "petrov@acme.ru"}],
"preview": ["Клиент [[EMAIL_1]]"]}
Таблица «заглушка — оригинал» существует, пока обрабатывается запрос, и исчезает вместе с ним. Базы масок нет.
Ни текст запроса, ни найденные значения не логируются. Шлюз не должен сам стать тем местом утечки, от которого защищает.
Аргументы вызовов и то, что вернул инструмент, чистятся так же, как текст сообщений: через них данные утекают ровно тем же способом.
Шлюз передаёт ваш ключ дальше нетронутым и ничего о вас не знает. Лимиты, баланс и статистика считаются как раньше.
В API маскирование включается только адресом /guard/v1. На обычном /v1 запрос проходит без изменений.
Это наш код, а не чужой сервис под нашей вывеской. Данные не уходят ещё и третьей стороне «на проверку».
Одинаковые значения получают одинаковые заглушки, поэтому связи в тексте сохраняются: модель видит, что в первом абзаце и в третьем — один и тот же адрес. Смысловая часть промпта не меняется вовсе.
Разворачиваются только те заглушки, которые шлюз сам поставил в этом запросе. Незнакомая останется в ответе просто текстом — подставить вместо неё чужие данные невозможно.
Да, в Chat Completions, Responses и формате Anthropic. Заглушка почти всегда разрывается между кусками ответа, поэтому шлюз придерживает хвост от незакрытой скобки до следующего куска — и в тексте, и в аргументах вызова инструмента. Задержка — один кусок, на глаз незаметна.
Заголовок X-Guard-Off: true пропускает конкретный запрос без изменений, а X-Guard-Types оставляет маскирование только для нужных типов.
Нет. Классическая DLP закрывает почту, файлы и съёмные носители. API Guard закрывает один конкретный канал — запросы к языковым моделям, который обычная DLP не видит: для неё это просто HTTPS к внешнему API.
Маскирование работает с любым ключом kosareva.cloud. Начните с предпросмотра: он покажет, что нашлось бы в ваших промптах, ничего никуда не отправляя.