Доброго! Docling взяли не как OCR, а как document understanding — он сохраняет структуру (таблицы, заголовки, секции), без которой чанкинг теряет контекст. MinerU заточен под академические PDF и слабее на корпоративных документах. DeepSeek — это LLM, а не парсер; запускать её на каждый файл при индексации нецелесообразно. Qwen2.5-VL используется точечно — только для тяжёлых сканов, где Docling не справляется.
По Voyage vs Cohere: voyage-rerank-2 выше на MTEB Reranking при меньшей latency. Cohere сильнее в широкой многоязычности — если бы система была мультиязычной, он был бы равным кандидатом. В данном случае приоритет был у точности реранкинга.
Хороший вопрос, у нас хэши используются исключительно в audit log и только для integrity check — то есть доказать что конкретный текст был именно таким в момент отправки в AI. Для адресации PII в базе хэши вообще не используются — там зашифрованные поля AES-256-GCM, поиск по ним не предусмотрен.
Теперь про перец. Концептуально он решает ту же задачу что и HMAC-ключ — добавляет секрет, который хранится отдельно от базы. Разница в том, что pepper обычно применяется к хэшам паролей (bcrypt + pepper), а HMAC изначально спроектирован именно как «хэш с ключом» и стандартизирован для таких сценариев. В нашем случае originalHmac = HMAC(text, SECRET_KEY) — это уже и есть pepper по своей природе, только без лишней самодеятельности.
Идея про несколько ключей — валидная для key rotation: когда меняешь ключ, старые записи верифицируются старым, новые — новым. Это запланировано, но отложено — ключ пока ни разу не менялся, задача на будущее.
Так что спасибо за ссылку, но pepper здесь уже есть — он просто называется HMAC-ключом.
Да, length extension attack — реальная штука, и SHA-3 её действительно лишён. Но проблема с SHA-256(email) совсем в другом. Email-адреса — это данные с катастрофически низкой энтропией. Берёшь утёкшую базу на 100 млн адресов, прогоняешь все через SHA-256 — получаешь радужную таблицу за несколько часов. SHA-3 от той же проблемы не спасёт вообще никак, просто хэши будут другие, а перебор работает идентично.
HMAC решает именно это — не потому что SHA-2 «слабее», а потому что секретный ключ добавляет ту энтропию, которой у email от природы нет. Без ключа задача перебора становится физически неразрешимой. Так что вопрос не в том, какой алгоритм хэширования выбрать — а в том, есть ли ключ вообще. Это принципиально разные вещи.
Честно — замечание попадает в реальную дыру. Пользователь может написать «мой прораб Иван Петрович, звони ему напрямую» — и никакой regex это имя не поймает. По 152-ФЗ это всё равно персональные данные третьего лица, и ответственность с оператора не снимается. РКН за такое при плановой проверке скорее всего не докопается — но если случится утечка и в ней окажутся такие данные, вопрос «почему не фильтровали» встанет в полный рост.
Решается это не переработкой архитектуры, а добавлением одного слоя — локальной NER-модели для русского языка. Например natasha: 50MB, работает на CPU, ~10ms на сообщение, ставится через pip. Она умеет находить имена людей в свободном тексте включая падежные формы — «Петровичу», «Ромашки» — и заменять их на [REDACTED_NAME_1] до отправки в Gemini. Ничего наружу не уходит, всё крутится на том же сервере. Это не замена текущей архитектуры — это закрытие одной конкретной дыры одним небольшим инструментом, который как раз кейс с GigaChat, только без видеокарты и внешних зависимостей.
Спасибо за замечание, но здесь есть важный нюанс — мы с вами решаем разные задачи.
GigaChat для детекции PII — это окей идея, я даже согласен что для Layer 2 (имена третьих лиц) что-то подобное было бы уместно. Но вся остальная архитектура — это не про «поймать данные», это про доказуемо доказать что ты их не передал.
Квантованная 10b-модель — вероятностная. У неё будут false negatives. В spam-фильтре — норм. Но когда приходит РКН и спрашивает «а вы точно не гнали персоналку в Google?» — ответ «ну модель обычно ловит процентов девяносто пять» не очень работает.
Наш Layer 1 детерминирован именно потому что данные уже известны системе заранее — это не детекция, это механическая подстановка. GigaChat сюда просто не нужен физически.
Про GPU в продакшне — RTX 5060 Ti для экспериментов отличная штука, но это единая точка отказа без автоскейлинга и SLA. Для стартапа это не «проще и дешевле», это другая статья расходов — только платишь не деньгами, а временем и нервами.
HMAC audit log, data retention, схема верификации — это не overengineering ради overengineering. Это доказательная база. Видеокарта её не заменит.
Так что — интересное дополнение к одному конкретному слою? Да. Замена всей архитектуры? Нет, потому что архитектура решает юридическую задачу, а не только техническую.
Хороший вопрос — намеренно не раскрыл это в статье…
Рассматривал три варианта:
Microsoft Presidio — самый зрелый фреймворк, но для моего кейса не подошёл: требует Python-сайдкар к NestJS-стеку, NER на русском даёт 70–85% точности (модель обучена на новостях, а не на бизнес-переписке), плюс 20–100 мс латентности на каждое сообщение при стриминге — это ощутимо.
Google Cloud DLP — отличный API, но есть ирония: отправляем PII в Google, чтобы не отправлять PII в Google Gemini. Юридически та же трансграничная передача.
Почему в итоге regex, а не NER. Ключевой инсайт, который я недостаточно раскрыл в статье: выбор зависит не от того, «что точнее», а от того, откуда приходят PII.
В моём кейсе AI-консультант сам запрашивает email, телефон и телеграм через структурированный флоу — к моменту sanitization система уже знает все данные пользователя. Дальше это тривиальный String.replace() с ~99% надёжностью и нулевой латентностью. Regex-guard нужен только для данных третьих лиц (email, телефоны, ИНН с валидацией контрольных цифр).
Если у вас другой кейс — анализ произвольных документов, где PII заранее не известны — без NER не обойтись. Тогда смотрите в сторону Presidio + DeepPavlov BERT для русского, или Stanza (точнее spaCy из коробки, но медленнее). Для JS/TS — ONNX Runtime с экспортированной моделью, но честно: зрелых решений под русский NER в этой экосистеме пока нет.
Сразу уточню: используется Gemini 2.5 Flash, не Pro — по соотношению качество/цена на этой задаче он вне конкуренции.
По пунктам:
Локальный инференс — рабочий вариант, но цена входа высокая. Качественный reasoning на русскоязычном строительном контексте начинается от 70B-моделей, это ~40 ГБ VRAM + инфраструктура + обслуживание. Для стартапа на ранней стадии — overhead без очевидной отдачи.
Российские провайдеры — честная альтернатива по 152-ФЗ, данные не покидают правовое поле без доп. усилий. Единственный нюанс: YandexGPT и GigaChat пока уступают по структурированному выводу и многошаговому reasoning на специализированных задачах. Это не навсегда — слежу за развитием.
Но главное, что статья не про выбор модели. Описанный паттерн PII-изоляции одинаково работает с любым провайдером — Gemini, YandexGPT, локальной Llama. Слой санитизации отделён от транспорта: смена провайдера = замена одного адаптера, архитектура не меняется. В этом и есть суть подхода.
Доброго!
Docling взяли не как OCR, а как document understanding — он сохраняет структуру (таблицы, заголовки, секции), без которой чанкинг теряет контекст. MinerU заточен под академические PDF и слабее на корпоративных документах. DeepSeek — это LLM, а не парсер; запускать её на каждый файл при индексации нецелесообразно. Qwen2.5-VL используется точечно — только для тяжёлых сканов, где Docling не справляется.
По Voyage vs Cohere: voyage-rerank-2 выше на MTEB Reranking при меньшей latency. Cohere сильнее в широкой многоязычности — если бы система была мультиязычной, он был бы равным кандидатом. В данном случае приоритет был у точности реранкинга.
Хороший вопрос, у нас хэши используются исключительно в audit log и только для integrity check — то есть доказать что конкретный текст был именно таким в момент отправки в AI. Для адресации PII в базе хэши вообще не используются — там зашифрованные поля AES-256-GCM, поиск по ним не предусмотрен.
Теперь про перец. Концептуально он решает ту же задачу что и HMAC-ключ — добавляет секрет, который хранится отдельно от базы. Разница в том, что pepper обычно применяется к хэшам паролей (bcrypt + pepper), а HMAC изначально спроектирован именно как «хэш с ключом» и стандартизирован для таких сценариев. В нашем случае
originalHmac = HMAC(text, SECRET_KEY)— это уже и есть pepper по своей природе, только без лишней самодеятельности.Идея про несколько ключей — валидная для key rotation: когда меняешь ключ, старые записи верифицируются старым, новые — новым. Это запланировано, но отложено — ключ пока ни разу не менялся, задача на будущее.
Так что спасибо за ссылку, но pepper здесь уже есть — он просто называется HMAC-ключом.
Да, length extension attack — реальная штука, и SHA-3 её действительно лишён. Но проблема с SHA-256(email) совсем в другом. Email-адреса — это данные с катастрофически низкой энтропией. Берёшь утёкшую базу на 100 млн адресов, прогоняешь все через SHA-256 — получаешь радужную таблицу за несколько часов. SHA-3 от той же проблемы не спасёт вообще никак, просто хэши будут другие, а перебор работает идентично.
HMAC решает именно это — не потому что SHA-2 «слабее», а потому что секретный ключ добавляет ту энтропию, которой у email от природы нет. Без ключа задача перебора становится физически неразрешимой. Так что вопрос не в том, какой алгоритм хэширования выбрать — а в том, есть ли ключ вообще. Это принципиально разные вещи.
Честно — замечание попадает в реальную дыру. Пользователь может написать «мой прораб Иван Петрович, звони ему напрямую» — и никакой regex это имя не поймает. По 152-ФЗ это всё равно персональные данные третьего лица, и ответственность с оператора не снимается. РКН за такое при плановой проверке скорее всего не докопается — но если случится утечка и в ней окажутся такие данные, вопрос «почему не фильтровали» встанет в полный рост.
Решается это не переработкой архитектуры, а добавлением одного слоя — локальной NER-модели для русского языка. Например
natasha: 50MB, работает на CPU, ~10ms на сообщение, ставится через pip. Она умеет находить имена людей в свободном тексте включая падежные формы — «Петровичу», «Ромашки» — и заменять их на[REDACTED_NAME_1]до отправки в Gemini. Ничего наружу не уходит, всё крутится на том же сервере. Это не замена текущей архитектуры — это закрытие одной конкретной дыры одним небольшим инструментом, который как раз кейс с GigaChat, только без видеокарты и внешних зависимостей.Спасибо за замечание, но здесь есть важный нюанс — мы с вами решаем разные задачи.
GigaChat для детекции PII — это окей идея, я даже согласен что для Layer 2 (имена третьих лиц) что-то подобное было бы уместно. Но вся остальная архитектура — это не про «поймать данные», это про доказуемо доказать что ты их не передал.
Квантованная 10b-модель — вероятностная. У неё будут false negatives. В spam-фильтре — норм. Но когда приходит РКН и спрашивает «а вы точно не гнали персоналку в Google?» — ответ «ну модель обычно ловит процентов девяносто пять» не очень работает.
Наш Layer 1 детерминирован именно потому что данные уже известны системе заранее — это не детекция, это механическая подстановка. GigaChat сюда просто не нужен физически.
Про GPU в продакшне — RTX 5060 Ti для экспериментов отличная штука, но это единая точка отказа без автоскейлинга и SLA. Для стартапа это не «проще и дешевле», это другая статья расходов — только платишь не деньгами, а временем и нервами.
HMAC audit log, data retention, схема верификации — это не overengineering ради overengineering. Это доказательная база. Видеокарта её не заменит.
Так что — интересное дополнение к одному конкретному слою? Да. Замена всей архитектуры? Нет, потому что архитектура решает юридическую задачу, а не только техническую.
Хороший вопрос — намеренно не раскрыл это в статье…
Рассматривал три варианта:
Microsoft Presidio — самый зрелый фреймворк, но для моего кейса не подошёл: требует Python-сайдкар к NestJS-стеку, NER на русском даёт 70–85% точности (модель обучена на новостях, а не на бизнес-переписке), плюс 20–100 мс латентности на каждое сообщение при стриминге — это ощутимо.
Google Cloud DLP — отличный API, но есть ирония: отправляем PII в Google, чтобы не отправлять PII в Google Gemini. Юридически та же трансграничная передача.
Почему в итоге regex, а не NER. Ключевой инсайт, который я недостаточно раскрыл в статье: выбор зависит не от того, «что точнее», а от того, откуда приходят PII.
В моём кейсе AI-консультант сам запрашивает email, телефон и телеграм через структурированный флоу — к моменту sanitization система уже знает все данные пользователя. Дальше это тривиальный
String.replace()с ~99% надёжностью и нулевой латентностью. Regex-guard нужен только для данных третьих лиц (email, телефоны, ИНН с валидацией контрольных цифр).Если у вас другой кейс — анализ произвольных документов, где PII заранее не известны — без NER не обойтись. Тогда смотрите в сторону Presidio + DeepPavlov BERT для русского, или Stanza (точнее spaCy из коробки, но медленнее). Для JS/TS — ONNX Runtime с экспортированной моделью, но честно: зрелых решений под русский NER в этой экосистеме пока нет.
Сразу уточню: используется Gemini 2.5 Flash, не Pro — по соотношению качество/цена на этой задаче он вне конкуренции.
По пунктам:
Локальный инференс — рабочий вариант, но цена входа высокая. Качественный reasoning на русскоязычном строительном контексте начинается от 70B-моделей, это ~40 ГБ VRAM + инфраструктура + обслуживание. Для стартапа на ранней стадии — overhead без очевидной отдачи.
Российские провайдеры — честная альтернатива по 152-ФЗ, данные не покидают правовое поле без доп. усилий. Единственный нюанс: YandexGPT и GigaChat пока уступают по структурированному выводу и многошаговому reasoning на специализированных задачах. Это не навсегда — слежу за развитием.
Но главное, что статья не про выбор модели. Описанный паттерн PII-изоляции одинаково работает с любым провайдером — Gemini, YandexGPT, локальной Llama. Слой санитизации отделён от транспорта: смена провайдера = замена одного адаптера, архитектура не меняется. В этом и есть суть подхода.