Привет, Хабр! На связи Мария Старцева и Катерина Пославская из команды R&D в Just AI.

Наша компания специализируется на NLP технологиях, и мы помогаем клиентам трансформировать их бизнес-процессы через внедрение умных ассистентов и сложных мультиагентных систем. Один из наиболее востребованных запросов — модель должна крутиться локально (on-premise). Обращение к удалённым закрытым моделям по API несет скрытую угрозу: данные из пользовательских запросов могут сохраняться и попадать в последующие ответы модели, а если речь идёт ещё и о конфиденциальных персональных данных... мысли о таком повороте событий лишили сна уже не одного безопасника! 

При этом именно проприетарные LLM модели чаще всего демонстрируют SOTA качество для большинства задач. И вот заказчик сталкивается с дилеммой: либо внедрять топовые инструменты, либо рисковать безопасностью, выпуская информацию из контура организации. А тут ещё усилилось государственное давление по защите персональных данных: внесены изменения в 152-ФЗ «О персональных данных» и в КоАП РФ (ст. 13.11). В 2025 г. существенно повысилась административная ответственность за нарушения в области персональных данных, особенно, в разрезе трансграничной пересылки данных пользователей. При этом размер штрафов за нарушение измеряется миллионами и даже процентами от годовой выручки компании. Один крупный инцидент способен многократно превысить затраты на внедрение средств защиты. А ведь кроме прямых финансовых рисков существуют и косвенные, вызванные репутационными/имиджевыми потерями. Произошёл сдвиг парадигмы: комплексная анонимизация перестает быть просто статьей расходов на соответствие требованиям, а становится финансово обоснованной стратегией защиты капитала компании.

Как устроена динамическая анонимизация данных

Как обеспечить сотрудникам доступ к мощным внешним LLM-сервисам и при этом не допустить утечки конфиденциальной информации? Оптимальным архитектурным решением стал промежуточный прокси-сервер, который перед отправкой запроса во внешние API выполняет анонимизацию «на лету». Такой подход с использованием Personally Identifiable Information (PII) filtering/redacting proxy стал стандартом динамической защиты данных при работе с внешними LLM. Его принцип работы следующий:

  1. Перехват (Interception): запрос пользователя в интерфейсе чат-бота перехватывается специальным прокси-сервером до отправки во внешнюю модель.

  2. Обнаружение (Detection): прокси анализирует текст запроса и ищет персональные данные. Для этого используется комбинация методов:

    • Распознавание именованных сущностей (задача Named Entity Recognition, NER): выделение имен (PER), организаций (ORG), геолокаций (LOC) и других; 

    • Регулярные выражения: поиск структурированных шаблонов (для номеров телефонов, URL, emails, паспортных данных, ИНН, банковских карт); 

    • Правила и словари: обнаружение специфичных для компании терминов, кодов, артефактов. 

  3. Трансформация (Transformation): все найденные фрагменты, содержащие персональные данные, заменяются на специальные метки-плейсхолдеры. Одновременно сохраняется таблица соответствия (lookup table) между оригинальными значениями и сгенерированными метками.

  4. Безопасная отправка (Secure Forwarding): очищенный от реальных данных запрос уходит во внешнее LLM API: реальные персональные данные остаются в контуре организации (см. Рисунок 1).

  5. Деанонимизация ответа (De-Anonymization): получив ответ от LLM, прокси возвращает исходные значения на место плейсхолдеров, используя ранее сохраненную таблицу. Сотрудник получает осмысленный ответ с реальными названиями/именами, даже не подозревая, что исходный промпт обрабатывался искаженным.

Рис. 1. Схема анонимизации персональных данных в реальном времени
Рис. 1. Схема анонимизации персональных данных в реальном времени

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

Jay Guard – шлюз безопасности для LLM

Под задачу анонимизации и фильтрации чувствительных данных в работе с закрытыми LLM мы в Just AI разработали Jay Guard. Он представляет собой интеллектуального «охранника», который минимизирует риски использования проприетарных моделей (ChatGPT, GPT-4, Claude, Google Gemini), в том числе российские решения (YandexGPT, Sber GigaChat).

Как это работает на практике?

Jay Guard выступает умным прокси между клиентом и моделью: когда сотрудник отправляет в чат запрос, Jay Guard перехватывает его и сканирует на наличие персональных данных. 

Здесь мы используем гибридный метод поиска: сочетаем регулярно обновляемый набор правил (регулярные выражения, словари) и модели машинного обучения для задачи NER. Обнаружив в тексте, например, ФИО, телефон или адрес, Jay Guard не удаляет их полностью, а заменяет псевдонимами — специальными метками-плейсхолдерами (placeholders), сохраняющими структуру предложения. Например, фраза:

«Клиент Иван Иванов, телефон 8-926-123-45-67, просит выставить счет»

превратится в:

«Клиент [PERSON_1], телефон [PHONE_1], просит выставить счет».

Обезличенный запрос уходит в LLM. Модель, получив синтаксически корректный текст, легко понимает, что речь о клиенте и его номере, и нормально обрабатывает запрос. Для дополнительного регулирования работы LLM мы включаем в системный промпт пояснение, как интерпретировать placeholders. Когда ответ от LLM возвращается, Jay Guard выполняет обратную операцию — деанонимизацию, подставляя оригинальное имя и телефон обратно в текст ответа.

Альтернативные решения

Мы не единственные, кто решает проблему обезличивания данных. Альтернативы есть, и у каждого решения свои ниша и профиль. Фокус продуктов может быть как на обезличивании данных в таблицах и статических базах данных (ARX Data Anonymization Tool, Amnesia или отечественный D-Mask), так и на изображениях (модуль графической анонимизации в Microsoft Presidio). Также решения могут ориентироваться на конкретные домены (медицину, финансовые данные и прочее). Наших клиентов интересует использование Jay Guard в виртуальных ассистентах, поэтому нам близок сценарий с текстовыми данными. 

На рынке достаточно много и open-source, и проприетарных решений для динамического обезличивания текстов (см. Таблицу 1). Некоторые из них ориентированы на специфический домен клинических или юридических данных (AInonymize, Docbyte). Другие поддерживают только английский язык (Strac, Digital Guardian и другие). А решения, которые позиционируются многоязычными, как правило, плохо работают с русским: они требуют либо дообучения (open-source LLM Guard, Microsoft Presidio), либо дополнительной кастомизации проприетарных систем (поскольку качество работы с русским неизвестно). Например, dslim/bert-large-NER, который стоит по умолчанию в LLM Guard, файнтьюнилась на англоязычном датасете, из-за чего для работы в русском тексте она, увы, не годится.

Таблица 1. Сравнительная таблица решений для динамического обезличивания текстовых данных

Инструмент

Тип лицензии

Ключевые методы анонимизации

Поддержка языков

Интеграция с LLM/API

Комментарий

LLM Guard

Open-Source

dslim/bert-large-NER, Regex

Многоязычная

REST API, Python SDK

Требует дообучения моделей

Microsoft Presidio

Open-Source

spaCy, flair, HF Transformers, Regex

Многоязычная

REST API, Python SDK

Требует дообучения для доменных задач

NVIDIA NeMo Guardrails

Open-Source

Miscrosoft Presidio, Regex

Многоязычная

Python SDK 

Фреймворк оркестратор для комплексной защиты

Guardrails AI

Open-Source

Miscrosoft Presidio, Regex

Многоязычная

REST API, Python SDK

Низкая производительность (доп. циклы LLM), сложность настройки

Amazon Bedrock Guardrails

Проприетарный

AI/ML, Regex

Многоязычная

API Amazon Bedrock, ApplyGuardrail API, интеграция с агентами Bedrock, RAG-системами 

Привязка к экосистеме AWS, стоимость использования, ограниченная кастомизация по сравнению с open-source решениями

Hive Trace

Проприетарный

Regex, AI/ML(?)

Многоязычная

REST API

Комплексный подход к защите генеративных систем

Lakera Guard

Проприетарный

AI/ML, Regex

Многоязычная

REST API

Комплексный подход к защите генеративных моделей/систем, высокая скорость работы 

Eden AI API

Проприетарный

AI/ML, OCR (для изображений), шаблоны

Многоязычная

REST API, Python

Платный, зависимость от провайдера

ManageEngine DLP

Проприетарный

Шаблоны, политики доступа, мониторинг

Многоязычная

REST API, Outlook, агенты на устройства

Нет облачной версии

Docbyte

Проприетарный

AI/ML, OCR, обработка изображений и текста

Многоязычная

REST API

Ориентация на медицинские/юридические тексты

Strac

Проприетарный

AI/ML в рамках no-code платформы

Английский

REST API, no-code

Высокая стоимость, ограниченная кастомизация

Digital Guardian DLP

Проприетарный

DLP-политики, ML, контроль доступа

Английский

SaaS, API, интеграция с облаками

Сложная настройка, высокая цена

AInonymize (Gramener)

Проприетарный

Mistral 7B fine-tuned на клинических данных

Английский

REST API

Специализирован под медицинские данные

Nightfall Security

Проприетарный

ML, обнаружение PII в облачных сервисах

Английский

REST API, Python SDK

Высокая цена

Кроме того, в отличие от Jay Guard ни одно из существующих решений не учитывает стандарты российских документов, например, форматы паспорта РФ, СНИЛС, ИНН и других. Поэтому использование альтернативных систем потребует не только дообучения NER-моделей, но и создания собственных шаблонов правил regex. 

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

Jay Guard под капотом: выбор модели NER

Центральный компонент Jay Guard – движок NLP, который находит целевые именованные сущности (например, имена людей, адреса) в тексте. От его качества напрямую зависит надежность анонимизации: пропущенная сущность = утечка персональных данных, а ложное срабатывание может исказить смысл запроса.

Для проверки качества моделей на наших задачах мы создали бенчмарк внутренних данных и прогнали на нём популярные решения «из коробки». В этой статье мы представляем метрики только по публичной (анонимизированной) версии этого бенчмарка, чтобы любой мог ознакомиться с форматом данных и воспроизвести наши метрики. Датасет залит на Hugging Face: https://huggingface.co/datasets/just-ai/jayguard-ner-benchmark.

Результаты показали, что идеального решения для наших сложных данных не существует (см. Таблицу 2). Все модели без дообучения, включая модели, созданные специально для русского языка, а также модели, встроенные в топовые open-source системы (Hugging Face Transformers, spaCy и flair), недостаточно хорошо справляются с задачей поиска имён и адресов в сложных данных — рабочих чатах, логах обращений, разговорной речи. 

Таблица 2. Сравнение качества модели на нашем публичном датасете

Модель

Язык

Лейбл PersonF1/Precision/Recall

Лейбл Street_AddressF1/Precision/Recall

Natasha (SlovNet)

русскоязычная

0.64 / 0.63 / 0.68

0 / 0 / 0

spaCy (ru_core_news)

русскоязычная

0.73 / 0.73 / 0.76

0 / 0 / 0

spaCy (xx_ent_wiki_sm)

мультилингвальная

0.43 / 0.34 / 0.62 

0.06 / 0.03 / 0.24

DeepPavlov/ruBERT-base-cased

русскоязычная

0.58 / 0.59 / 0.59

0.41 / 0.40 / 0.42

flair

мультилингвальная

0.86 / 0.86 / 0.87

0.47 / 0.47 / 0.48

GLiNER

мультилингвальная

0.45 / 0.44 / 0.53 

0.46 / 0.46 / 0.46

Одни решения (Natasha, spaCy) излишне осторожны и пропускают важные сущности, другие (flair, GLiNER) — берут почти всё подходящее, но при этом захватывают кучу лишнего. Для нашего прокси нам нужна была «золотая середина» — максимально полный поиск персональных данных при приемлемом уровне ложных срабатываний. Поэтому мы решили взять flair и spaCy — лучших кандидатов по метрике полноты Recall для лейбла PERSON, и обучить их распознавать только те сущности, которые подходят нашим клиентам.

К слову, кроме базового качества разметки, мы учитывали производительность моделей (Рисунок 2). Из-за больших задержек мы исключили модель GLiNER, хоть она и имела неплохой потенциал в определении целевых классов.

Рис. 2. Сравнение производительности моделей
Рис. 2. Сравнение производительности моделей

Отдельным достоинством spaCy, помимо топовой производительности на GPU, является способность модели эффективно работать на CPU мощностях. Для дообучения мы выбрали мультилингвальную версию модели, поскольку нам нужно распознавать сущности в текстах, где присутствует как кириллица, так и латиница.

Работа с реальными данными

В создании размеченных данных для дообучения моделей есть несколько ключевых тонкостей, которые, к сожалению, мало обсуждаются в отчётах, докладах и статьях. Главные из них — определение границ сущностей, создание к ним инструкций с примерами, а также постоянная валидация согласованности ручных разметок специалистов. Поскольку самыми ключевыми для динамической анонимизации для нас являются сущности “личность” (PERSON) и “адрес” (STREET_ADDRESS), в примерах ниже мы остановимся именно на них.

Сущности и их границы

Без единых подробных правил разметки два носителя языка или даже один и тот же специалист в разное время будут по-разному классифицировать одни и те же случаи. Поэтому, во-первых, требовалось чётко и однозначно сформулировать определение сущностей и их границы. 

Например, нам было нужно ответить на вопрос, являются ли “личностями” вымышленные персонажи или публичные персоны? 

Вносим ли мы в адрес типа “улица Ленинский проспект, д.144к5, кв. 13” слово “улица” или его аналоги (“ул.”, “просп.”, “бульвар” и другие). А также размечаем ли весь адрес одной сущностью или делим на составляющие (например, 3 сущности: “улица Ленинский проспект”, “д.144к5”, “кв. 13”)? 

Как мы поступаем с омонимией, в контекстах типа «улица Пушкина» против «стихи Пушкина»? У нас была забавная ситуация, когда в контексте “план обучения на четырёх Юриков” пришлось обращать внимание разметчиков, что это не четыре тёзки, а неверно (с большой буквы) написанное слово “юрик”, то есть юридическое лицо.

Составление руководства и инструктаж

После согласования формулировок и границ, мы составили подробное руководство, доступное специалистам в любой момент для самоконтроля. По мере необходимости руководство можно дополнить примерами сложных кейсов: у нас есть общий чат разметчиков, где мы обсуждаем их и приходим к общему знаменателю. Фрагмент сводной таблицы из руководства на Рисунке 2 даёт примерное представление о формате инструкции: 

Рис. 3. Фрагмент руководства по разметке сущностей PERSON и STREET_ADDRESS
Рис. 3. Фрагмент руководства по разметке сущностей PERSON и STREET_ADDRESS

За всё время исследования нам помогало более 10 разных разметчиков. Без координации и обучения процесс мог превратиться в хаос. Мы стандартизировали инструктаж каждого нового члена команды: сначала специалист самостоятельно знакомился с руководством, затем в ходе 45-минутной встречи наш эксперт обращал внимание на важные моменты, отвечал на вопросы и демонстрировал процесс разметки через интерфейс LabelStudio. 

Валидация разметки

Даже при очень чётких инструкциях и грамотном инструктаже без постоянного контроля разметка неизбежно будет плыть и сдвигаться. Для сохранения согласованности разметки мы используем метод валидации на отложенной выборке между разметчиками (аналог измерения inter-rater agreement). Каждая новая порция размеченных данных добавляется в основной тренировочный датасет, только если разметка лейблов и их границ на примерах валидации близко совпадают: по метрике F1 ≥ 0.9. 

Работа с синтетическими данными

Главная проблема при обучении NER-модели под свой домен – это нехватка размеченных вариативных данных. Можно потратить месяцы на ручную разметку сырых логов, но мы пошли другим путём, комбинируя разметку экспертов с генерацией синтетического корпуса с помощью стохастического генератора данных и LLM (см. Рисунок 4).

Рис. 3. Схема процедуры создания синтетического датасета
Рис. 3. Схема процедуры создания синтетического датасета

Стохастический генератор персональных данных 

C помощью библиотеки mimesis мы создали вымышленные имена, адреса, телефоны, должности и прочие данные. Причём имена как на кириллице, так и транслитом (латиницей), адреса в различных форматах (с индексом в начале/конце, с разными сокращениями: ул., пр-т, пл., пос., д.). Это дало богатый набор реалистичных сущностей.

LLM для создания контекста 

Чтобы вставить эти сущности в живой текст, мы использовали LLM как помощника для генерации предложений и диалогов. Мы передавали в модель заготовленные фрагменты текста (из открытых источников, либо шаблоны, созданные на основе наших логов) и просили её заменить реальные данные на сгенерированные псевдоданные. Одновременно с этим мы варьировали стиль текстов, чтобы каждое сгенерированное предложение было максимально уникальным. Для нашего бизнес-контекста были релевантны следующие стили:

  • Неформальный чат (разговорная речь, включая сленг, эмодзи);

  • Официальное письмо (деловой стиль, обращения по имени и отчеству);

  • Фрагмент документа или новости (профессиональный жаргон и термины, более сложные конструкции);

  • Лог файлы/структурированные записи (короткие телеграфные сообщения, метаданные);

  • Расшифровка телефонного разговора (сплошной текст без заглавных букв, с опечатками, без пунктуации).

NER, который уже подходит для прода

После пары циклов генерации и обучения мы значительно подняли качество NER по ключевым для анонимизации категориям – PERSON и STREET_ADDRESS. Сначала у нас был получен промежуточный вариант для flair,который по детекции класса PERSON опережал spaCy (F1 = 0.91, Recall 0.93 против F1 = 0.63, Recall = 0.76). Этот вариант попал на прод в первую очередь — правда, только для определения класса PERSON. 

Таблица 3. Итеративное улучшение метрик для моделей spaCy и flair

Лейбл

Итерация

Лейбл Person F1/Precision/Recall

Лейбл Street_Address F1/Precision/Recall

spaCy

Baseline

0.43 / 0.34 / 0.62 

0.06 / 0.03 / 0.24

Промежуточный результат

0.63 / 0.54 / 0.76

0.82 / 0.85 / 0.81

Итоговая модель

0.93 / 0.94 / 0.91

0.91 / 0.89 / 0.92

flair

Baseline

0.76 / 0.63 / 0.94

0.23 / 0.13 / 0.87

Промежуточный результат

0.91 / 0.89 / 0.93 

0.78 / 0.73 / 0.83 

Однако для качественного дообучения flair требуется значительно больше данных, чем для spaCy, поэтому вскоре spaCy догнал и перегнал своего собрата для обоих целевых классов и выкатился в прод! 

В настоящее время, мы работаем над более тонким разделением классов людей и локаций, а именно улучшаем качество детекции более редких классов, типа “публичная персона”, “вымышленный персонаж”, которые не должны скрываться в текстах. Кроме того, мы продолжаем работать над совершенствованием качества обеих моделей на более сложных и разнообразных внутренних датасетах, поскольку «язык всегда богаче наших представлений о нём» — всех кейсов за раз никаким публичным датасетом не ухватить. 

Дальнейшие шаги и выводы

В перспективе мы хотим, чтобы Jay Guard поддерживал другие языки, востребованные у наших клиентов, например, казахский и узбекский. Принципиальных препятствий нет: нужно собрать или сгенерировать корпуса имен и адресов для новых языков и дообучить модели. Кроме того, мы рассматриваем интеграцию Vision API для распознавания персональных данных на изображениях (сканах документов, фотографиях экрана), чтобы анонимизировать не только текст, но и картинки.

Наш опыт показал, что создание надёжной системы анонимизации требует сочетания грамотно выстроенного процесса разметки, итеративного дообучения и качественных синтетических данных. Если вы внедряете NER-модель в продакшн и столкнулись с её «слепыми зонами», попробуйте наш подход. 

Дообучение и совершенствование – процесс творческий и бесконечный! Главное, чтобы качественные промежуточные версии находили своё место на проде. С нашими текущими достижениями вы можете ознакомиться внутри экосистемы Just AI, а мы тем временем продолжаем совершенствоваться: доразмечаем данные и дообучаемся, проводим эксперименты с active learning и LLM для разметки данных, и многое другое. Так что оставайтесь на связи! :) 

Благодарности

Cпасибо большое всем специалистам, которые помогли нам с разметкой данных: нашим коллегам из команды Just R&D и сотрудникам отдела компьютерной лингвистики и разговорного AI. Ваш вклад в работу стал ключевой частью этого исследования!

Комментарии (0)