PII-Guard: открытый детектор персональных данных для русского текста
Персональные данные регулярно оказываются внутри запросов к языковым моделям. Пользователи передают рабочую переписку, заявки, договоры и отчёты, не всегда замечая, что вместе с текстом отправляются имена, номера телефонов, реквизиты документов, адреса и другие чувствительные сведения. Для бизнеса такая практика создаёт риск утечки информации и требует отдельного защитного слоя.
Один из распространённых подходов - предварительно обезличивать текст перед отправкой в модель. Однако простая замена персональных данных на специальные метки часто нарушает рабочий сценарий. Модель видит уже изменённый текст и возвращает ответ с теми же маркерами. Пользователю приходится вручную восстанавливать исходные значения, а автоматизировать этот процесс бывает сложно.
Поэтому полноценная система защиты должна решать две задачи одновременно: находить персональные данные во входном тексте и возвращать исходные значения в ответ, сохраняя структуру результата. Именно на этой идее построен PII-Guard - открытый детектор персональных данных для русского языка. Его задача не ограничивается поиском подозрительных фрагментов: система определяет тип найденной сущности, оценивает уверенность и помогает безопасно обрабатывать текст в связке с языковой моделью.
Почему регулярных выражений недостаточно
Первую версию детектора логично было создать на основе регулярных выражений. Многие виды персональных данных имеют узнаваемый формат: телефон состоит из определённого количества цифр, ИНН подчиняется фиксированной длине, банковская карта содержит последовательность цифр, а паспортный номер обычно записывается по установленной схеме.
Такой подход позволяет быстро получить работающий прототип. Но реальные тексты быстро выявляют его ограничения. Пользователи пишут номера с пробелами, дефисами, скобками и лишними символами, допускают опечатки, меняют порядок частей и используют разные варианты сокращений. Чтобы охватить все случаи, приходится постоянно расширять набор выражений. В результате правила начинают пересекаться, конфликтовать и порождать новые ошибки.
Есть и более фундаментальная проблема: формат сам по себе не объясняет значение последовательности. Шестнадцать цифр могут быть номером банковской карты, идентификатором заказа или внутренним кодом. Десятизначное число способно оказаться ИНН, частью паспортных данных, номером заявки или случайным числовым значением. Регулярное выражение лишь фиксирует совпадение с шаблоном, но не понимает, что именно обнаружило.
Цена ошибки высока в обоих направлениях. Пропуск номера карты или документа создаёт угрозу утечки. Ложное срабатывание портит текст, мешает пользователю и может привести к потере смысла исходного запроса.
Контрольные суммы как дополнительный фильтр
Снизить число ложных срабатываний помогают контрольные суммы. Например, последний разряд номера банковской карты вычисляется на основе остальных цифр по алгоритму Луна. Если изменить одну цифру, проверка обычно перестаёт сходиться. Поэтому случайная шестнадцатизначная последовательность проходит такой фильтр лишь примерно в одном случае из десяти.
Похожие механизмы существуют и у других идентификаторов. Для ИНН и СНИЛС применяются собственные формулы взвешенной суммы, а для полиса ОМС также может использоваться алгоритм Луна. Если контрольной цифры нет, система проверяет структурные признаки. Для БИК анализируются начальные разряды и допустимый диапазон, для почтового индекса - характерные серии и префиксы.
После добавления математических проверок количество ложных совпадений заметно уменьшается. Кроме того, находка становится объяснимой: можно показать, что значение прошло проверку длины, структуры или контрольной суммы. Это важно при отладке и последующем улучшении детектора.
Но даже корректная контрольная сумма не доказывает, что перед нами персональные данные. Число из накладной может случайно совпасть с форматом ИНН, а случайная последовательность - пройти проверку. Для окончательного решения нужен контекст.
Как анализируется окружение кандидата
Рядом с персональными данными часто находятся слова-подсказки: "паспорт", "ИНН", "полис", "счёт", "телефон", "адрес" и другие обозначения. Поэтому система анализирует окно текста вокруг найденной последовательности и ищет лексические признаки нужного типа сущности.
Простого поиска ключевого слова оказалось недостаточно. Например, во фразе "Паспорт мы выслали ещё вчера, трек-номер 1234567890" слово "паспорт" не относится к расположенным рядом цифрам. Если анализировать слишком большой фрагмент, в него попадёт множество случайных подсказок, что увеличит число ошибочных классификаций.
PII-Guard учитывает расстояние между ключевым словом и кандидатом, а также направление их расположения. Для каждого типа данных задаётся собственный допустимый предел. В случае БИК, например, информативным считается очень близкий контекст. Если рядом обнаружено несколько возможных подсказок, они конкурируют между собой, а преимущество получает ближайшая и наиболее релевантная.
Отдельно учитываются запрещающие слова. Они могут отменять классификацию, если показывают, что числовая последовательность относится к другой сущности. При этом универсальный список запретов оказался неэффективным: разные слова имеют разную силу, а их значение зависит от позиции и конкретного типа данных. Поэтому правила приходится настраивать с учётом контекста, а не применять одинаково ко всем форматам.
Баллы уверенности и порядок правил
Каждая проверка возвращает не только факт совпадения, но и оценку уверенности. Она складывается из нескольких факторов: соответствия формату, результата контрольной суммы, расстояния до ключевых слов, наличия отрицательных признаков и конкуренции с другими типами сущностей.
Проверки выполняются в определённом порядке - от наиболее узнаваемых форматов к более неоднозначным. Это помогает избежать ситуации, когда общий шаблон перехватывает значение, которое можно точнее определить по специализированному правилу.
Для практического применения полезно вводить несколько порогов. Высокая уверенность позволяет автоматически маскировать найденное значение. Средний уровень можно отправлять на дополнительную проверку или обрабатывать более осторожно. Низкоуверенные совпадения лучше сохранять как предупреждения, не изменяя исходный текст без необходимости.
Маскирование и восстановление данных
Сам детектор не обязан подменять найденные значения случайными строками. Его задача - выделить сущности, определить их тип и передать результат следующему компоненту системы. На этапе маскирования исходное значение можно заменить стабильным идентификатором, например `PERSON_1`, `PHONE_1` или `DOCUMENT_1`.
Ключевое требование к такому идентификатору - однозначность. Если одно и то же имя или номер встречается несколько раз, желательно использовать одинаковую замену. Тогда модель сохранит связи между фрагментами текста и сможет корректно обработать повторяющиеся данные.
После получения ответа от модели выполняется обратная подстановка. Маркеры заменяются исходными значениями из защищённого хранилища соответствий. При этом важно контролировать границы сущностей, склонение, изменение регистра и возможное редактирование маркеров моделью. Чем стабильнее формат заменителей, тем надёжнее работает восстановление.
Что важно учитывать при внедрении
Перед использованием в корпоративном контуре детектор необходимо проверять на собственных данных. Форматы документов, внутренние идентификаторы и особенности деловой переписки могут заметно отличаться от общих примеров. Отдельный набор тестов стоит подготовить для имён, адресов, телефонов, банковских реквизитов, медицинских сведений и смешанных русско-английских текстов.
Нужно измерять не только общую точность, но и полноту обнаружения. Для критичных типов данных пропуск часто опаснее лишнего срабатывания, тогда как для некритичных числовых последовательностей чрезмерная маскировка может ухудшить удобство работы. Поэтому пороги уверенности следует настраивать отдельно для разных классов сущностей.
Полезно сохранять обезличенные журналы срабатываний: тип найденных данных, применённое правило, оценку уверенности и причину классификации. Такие сведения помогают находить слабые места алгоритма, не записывая сами персональные данные. При обновлении правил тесты должны запускаться повторно, чтобы новые изменения не ухудшали уже работающие сценарии.
PII-Guard показывает, что надёжное обнаружение персональных данных строится не на одном механизме. Регулярные выражения хорошо находят кандидатов, контрольные суммы отсекают часть случайных совпадений, а контекст помогает понять назначение найденного значения. Комбинация этих подходов делает систему практичнее и позволяет безопаснее использовать языковые модели в работе с русскоязычными документами.
