TL; DR
- Начиналось как внутренний research-инструмент, выросло в продукт: врач в Европе ежедневно готовит документы через облачную LLM, не отдавая ей ни одного персонального данного. Агентская часть той же истории — в кейсе про агента.
- Обезличивание обратимо: PDF → структурный Markdown → токенизация → LLM → восстановление → готовый PDF. Имена и адреса уходят кодами (
PERS_001), даты — сдвигаются с точным сохранением возраста и интервалов, а на обратном пути всё восстанавливается байт-в-байт. - Распознавание — ансамбль из трёх слоёв, и вклад каждого измерен на реальных документах, а не принят на веру: лишний слой после замера выключен.
- Обезличивание одного документа: вместо часа руками — около 5 минут вместе с проверкой.

Контекст
Клиент — врач с частной практикой в Европе, готовит объёмные медицинские заключения. LLM сильно ускоряет работу с текстом, но есть жёсткое ограничение: персональные данные пациентов нельзя отдавать в облачные модели — врачебная тайна защищена уголовным правом, а не только регламентами.
Задача: врач работает с настоящим документом, облачная модель — с обезличенным двойником, и после работы модели данные возвращаются на место. Всё — локально, на компьютере врача.
Проблема
Первый прототип «LLM сама обезличивает» провалился предсказуемо: модель оставляла имена «по контексту», плейсхолдеры разъезжались, повторный прогон давал другой результат. Для медицины это стоп-фактор.
Но и «просто заменить имена кодами» недостаточно. Настоящие грабли глубже:
- Даты нельзя токенизировать. Модель, получившая
DATE_003вместо даты рождения, не может рассуждать о возрасте и давности болезни — а это половина клинического смысла. - PDF превращается в кашу. Наивное извлечение текста убивает заголовки, списки и структуру — врач получает на ревью «стену текста», а на выходе — документ без форматирования.
- LLM ошибается в токенах. Модель может опечататься в коде (
PERS_01вместоPERS_001) — и битый код молча уедет в финальный документ.
Подход
Принцип тот же, что в прототипе — модель там, где нужна, код там, где можно без неё — но реализация взрослая:
- Ансамбль распознавания. NER-модель находит имена и адреса по смыслу, детерминированные правила ловят жёсткие форматы (номера дел, IBAN, телефоны), память запоминает подтверждённые врачом решения. Каждый слой оставляет след: видно, кто нашёл каждую сущность.
- Замер вместо веры. На реальных (анонимизированных) документах измерил вклад каждого слоя: основная модель покрывает 95% находок, а второй нейрослой давал ~1% уникального — и тот шум. Выключил его по умолчанию: минус четверть времени прогона, ноль потерь. Ансамбль — это то, что доказало пользу замером, а не то, что накидали «на всякий случай».
- Обратимость через хранилище токенов. Каждой сущности — стабильный код, таблица замен живёт только на компьютере врача. Даты не кодируются, а сдвигаются на единый случайный сдвиг: возраст пациента и интервалы между визитами сохраняются с точностью до дня, но настоящих дат модель не видит.
- Структура выживает весь круг. Из PDF аккуратно выделяются заголовки, списки и выделения и переносятся в Markdown-разметку — модель работает со структурным текстом, а не со «стеной», и заголовки переживают обработку. После работы модели Markdown собирается обратно в PDF со всей разметкой. Внешний вид финального PDF задаётся отдельным шаблоном стиля: нужен другой дизайн — это настройка, а не переделка.
- Защита от ошибок модели. Если LLM исковеркала или выдумала токен — при восстановлении врач видит красное предупреждение со списком битых кодов, а не молча испорченный документ.
- Сначала прототип, потом движок. Первая версия интерфейса вышла перегруженной — врач в ней терялся. Со второй итерации я перевернул порядок: собрал в Claude полностью кликабельный прототип с реалистичными данными, показал врачу и утвердил, как ему удобно работать, — и только под утверждённое строил начинку. Утверждали не макет, а ощущение работы — вместо сферического коня в вакууме. Бонус: прототип продаёт идею лучше любых слов — не «представьте, будет так», а вот, нажимайте. У заказчика это вызвало вау-эффект.
- Ревью как рабочее место. Веб-интерфейс: подсветка находок в документе, карточка каждого токена (сменить тип, убрать ложное срабатывание, добавить в словарь), привязка к пациенту, журнал раскрытий.
Результат
- Обезличивание документа: около 5 минут вместе с ревью — против часа руками.
- Круг «PDF → обезличить → LLM → восстановить → PDF» проверен end-to-end: восстановление байт-в-байт, утечек на пробах — ноль.
- Врач ставит обновления сам, двумя кликами; 350+ автотестов держат каждое изменение.
- Инструмент стал частью ежедневного потока: в связке с агентом врач формулирует задачу один раз — и работает с готовым результатом.
Что бы сделал иначе
Гонял бы кандидатов на реальных документах с первого дня — и не верил бы чужим цифрам. Обе попытки выбрать модель «по карточке» провалились одинаково: сначала известная модель с сильным бенчмарком оказалась вдвое медленнее и слабее на немецком, потом её замена, выбранная по лидерборду, выдала пять минут на один PDF. Решил вопрос автоматический замер на настоящих документах: он занял вечер, показал, что второй слой даёт шесть уникальных находок из четырёхсот — и все шум, — и слой уехал из дефолта через три дня после включения. Теперь любой вопрос «нужен ли этот компонент» стоит один прогон, а не неделю споров.