Приносят выгрузку по дебиторке. Триста строк, глазами не видно ничего. Мысль очевидная: кинуть в чат и спросить, кто главный должник и почему по этому контрагенту вечно расхождения. Модель такое разбирает за секунды.
И тут вспоминаешь, что в выгрузке ФИО, БИН, телефоны и суммы. А в компании есть положение о персональных данных, и там написано, что выносить это за контур нельзя.
Дальше два пути, и оба плохие. Первый: не спрашивать, разбирать руками, потратить час вместо минуты. Второй: скопировать и никому не сказать. Так делают чаще, чем признаются, и я не буду делать вид, что не понимаю почему.
Эта статья про третий путь. Про то, почему очевидные способы обезличивания не работают, и что должно быть устроено иначе, чтобы результат остался пригодным для анализа.
Почему «просто удалить ФИО» не работает
Первое, что приходит в голову: вырезать имена, оставить цифры. Получается каша.
Модель теряет связи. Была таблица, где Иванов ведёт четырёх контрагентов, стало четыре строки без владельца. Спросишь, на ком больше просрочки, а отвечать не из чего. Половина осмысленных вопросов к таблице устроена как раз вокруг того, кто с кем связан.
Второе, что приходит в голову: заменить каждое имя случайной строкой. Выходит хуже. Один и тот же Иванов в сорока строках получит сорок разных псевдонимов, и модель уверенно сообщит, что у вас сорок менеджеров и каждый ведёт по одному клиенту.
Отсюда первое требование, на котором держится вся конструкция.
Одно исходное значение получает один и тот же фейк во всей выгрузке. Иначе группировки разъезжаются, и анализировать становится нечего.
Технически это называется согласованной псевдонимизацией, и делается она детерминированно: хеш от значения и от случайной соли сеанса выбирает фейк из встроенного списка. Одинаковый вход даёт одинаковый выход в пределах сеанса, а две разные выгрузки одних и тех же данных дают разные фейки, и по одной нельзя восстановить другую.
Требование, про которое обычно забывают
Допустим, обезличили и спросили. Модель отвечает:
Наибольшая задолженность у Юдина Г.Д., 3 072 156,33, это 31 процент от общей суммы. Второй по величине должник просрочил на 45 дней.
И что с этим делать? Кто такой Юдин, вы не знаете. Сумма выдуманная. Ответ формально верный и практически бесполезный.
Можно, конечно, держать рядом блокнот со списком замен и переводить руками. Ровно один раз, потом надоест.
Значит, нужна обратная операция: взять ответ модели и вернуть в него настоящие имена и настоящие числа. Половина инструментов этого класса умеет только маскировать, и в этом их главная слабость: они решают половину задачи, а вторую перекладывают на человека.
Что делать с суммами
С суммами интереснее всего, и тут очевидное решение тоже неверное.
Заменить их случайными числами нельзя: пропадут пропорции, доли и выбросы, а именно на них модель и строит выводы. Спросите про структуру задолженности по случайным числам и получите уверенный ответ про несуществующую структуру.
Оставить как есть тоже нельзя. Выручка компании это ровно то, что не должно уезжать в облако, часто даже строже, чем имена.
Рабочий вариант простой до неприличия: все суммы умножаются на один секретный коэффициент сеанса. Пропорции целы, доли целы, динамика цела, выбросы на месте. Модель делает правильные выводы. А абсолютные значения не настоящие.
И тут вылезает приятный побочный эффект, ради которого стоило всё затевать.
Умножение линейно, поэтому обратно делится не только то, что мы меняли, но и итоги, которые модель посчитала сама. Она сложила пять строк и выдала сумму, которой в исходных данных не было, и эта сумма расшифруется правильно.
Замена случайными числами это свойство убивает начисто. Поэтому её и не рассматриваем.
Одна арифметическая деталь, которая стоила отладки
Коэффициент здесь всегда больше единицы, и это не вкусовщина.
При умножении сумма округляется до копеек, ошибка округления не превышает полукопейки. При обратном делении эта ошибка умножается на 1/k. Если k больше единицы, ошибка только убывает и число возвращается копейка в копейку. Если k меньше единицы, ошибка растёт и может перевалить за полкопейки, а тогда результат уедет на копейку.
Я это не вывел заранее, а поймал прогоном: часть проверок возвращала сумму на копейку меньше, часть возвращала точно. Разбор по коэффициентам показал закономерность сразу: все промахи случались при k меньше единицы, все точные прогоны при k больше. После сужения диапазона до 1,15 - 3,40 обратимость стала точной по построению, а не по везению.
Где взять список настоящих имён
Теперь главный вопрос: как вообще понять, что вот это слово в тексте - имя человека?
Внешнему инструменту приходится угадывать, и для этого тащить локальную языковую модель. Прямой аналог на Инфостарте так и устроен: требует Ollama и qwen2.5. Логика понятна, но она разбивается о жизнь. Человек, который боится отдать данные в облако, ровно так же не поставит стороннюю нейросеть на сервер: у него та же служба безопасности и тот же согласованный список ПО.
Нам угадывать не надо. Мы внутри 1С, и у нас есть то, чего нет ни у одного внешнего инструмента: настоящий список имён. Он лежит в справочниках.
Обработка читает наименования физлиц, контрагентов, пользователей и сотрудников, кладёт их в соответствие и ищет хешем. Точное совпадение вместо догадки, один проход по тексту даже на полумиллионе записей. Проверяются фразы из трёх, двух и одного слова, чтобы «Иванов Иван Иванович» нашлось целиком, а не тремя отдельными кусками.
Эвристика остаётся подстраховкой для того, чего в базе нет. Шаблон «Иванов И.И.» в данных 1С самый надёжный признак ФИО, а наименования организаций ловятся по кавычкам-ёлочкам после правовой формы: ТОО, ООО, АО и ещё полтора десятка.
Тут была отдельная ловушка. Прямые кавычки для поиска названий брать нельзя: в JSON в них завёрнуто каждое значение, и по такому признаку заменился бы весь файл целиком. Ёлочки в русских данных 1С однозначны, поэтому ловим по ним.
Контрольная сумма как фильтр, а не как украшение
Найти двенадцать цифр подряд легко. Беда в том, что двенадцать цифр подряд это не только БИН, но и артикул, номер накладной, штрихкод и десяток других вещей, которые заменять нельзя.
Поэтому каждая цифровая находка проходит проверку контрольной суммы: ИНН на 10 и на 12 знаков по российскому алгоритму, ИИН и БИН Казахстана, карты по алгоритму Луна. Не сошлось - не трогаем.
Проверка простая и наглядная: артикул 123456789012 не заменяется, а настоящий ИНН 7707083893 заменяется. Причём фейк генерируется тоже с корректной контрольной суммой, чтобы модель не спотыкалась о заведомо неправильный номер и не начала рассуждать про ошибки в данных.
Даты и версии: почему точка не десятичный разделитель
Ещё одно место, где легко испортить данные молча.
Если считать точку десятичным разделителем, то под замену уедут дата 01.08.2026 и номер версии 8.3.14. Модель получит выгрузку с искажёнными датами и сделает выводы про сроки, которых не было.
Поэтому по умолчанию суммой считается только число с запятой и одним или двумя знаками после неё. Целые числа без дробной части тоже не суммы: сроки просрочки, количества и номера строк остаются как есть.
Но в JSON и XML дробная часть всегда пишется точкой. Там суммы иначе останутся настоящими, что для инструмента по безопасности недопустимо. Решение: отдельный режим, в котором точка допускается, но с двумя ограничениями. Точка должна быть ровно одна (у даты и версии их две, они отсеиваются), и цифр должно быть не меньше трёх, чтобы 8.3 и 2.2 не сошли за деньги. При загрузке json или xml обработка включает этот режим сама: расширение файла она знает, и спрашивать об этом человека незачем.
Как это складывается вместе
Цикл из трёх шагов, и словарь замен связывает их в одно целое.

Первый шаг меняет имена и масштабирует суммы. Второй отдаёт результат модели, которая видит связи и доли, но не видит ни людей, ни выручки. Третий возвращает настоящие значения в её ответ.
Словарь при этом не обязан жить только в памяти формы. Он сохраняется в файл и загружается обратно, поэтому цикл спокойно разрывается на несколько дней: обезличил сегодня, спросил, вернулся через неделю и расшифровал.
Одна деталь, без которой третий шаг ломается на ровном месте. В вопрос к модели стоит добавить строку «имена и суммы пиши ровно как в таблице, не склоняй и не сокращай». Если модель напишет «у Абрамова наибольшая задолженность» вместо «Абрамов Ю.Г.», обратная подстановка такую форму не найдёт, и в расшифрованном ответе останется псевдоним. Готовый шаблон вопроса и пошаговый порядок работы лежат в описании обработки.
Что можно скормить на вход

Отдельно про кодировку. CSV из русского Excel почти всегда в windows-1251, а выгрузки из веба в UTF-8. Спрашивать об этом пользователя незачем: при неверной кодировке платформа подставляет символ с кодом 65533, и по нему видно, что надо перечитать файл иначе. Проверено, что кириллица в cp1251, прочитанная как UTF-8, даёт этот символ на каждой букве, так что признак надёжный.
Разделители в тексте вообще не важны. Обработка ищет значения, а не колонки, поэтому годится и таблица с табуляцией, и строка через точку с запятой, и просто текст письма с комментарием менеджера.
Как это проверялось
Тут стоит рассказать подробнее, потому что тест поймал три ошибки, которые чтением кода не находятся.
Собранный файл обработки загружается через ВнешниеОбработки.Создать и вызывается его экспортный интерфейс. То есть проверяется ровно тот код, который уйдёт пользователю, а не его копия в тестовом окружении. Дальше по каждому файлу: прочитать, обезличить, прогнать словарь через выгрузку в JSON и загрузку обратно, расшифровать, сравнить с оригиналом посимвольно.
Прогон словаря через файл здесь принципиален: это имитация сценария «сохранил словарь, закрыл форму, вернулся завтра». Если бы обратная операция втихую опиралась на что-то, что живёт только в памяти формы, тест бы это показал.
Что нашлось.
Первое: обратная операция теряла пробелы между разрядами. 1 245 300,50 возвращалось как 1245300,50. Значение верное, вид нет, а дальше весь текст съезжает на символ, и посимвольное сравнение показывает сотни расхождений там, где дефект один. Причина оказалась в том, что Формат с параметром ЧГ=0 группировку не ставит, а выключает. Разряды теперь расставляются вручную тем разделителем, который стоял в исходном числе.
Второе: та самая копейка при коэффициенте меньше единицы, про которую написано выше.
Третье, самое неприятное: детектор почты съедал кавычки. В JSON адрес стоит в кавычках, а токен резался по пробелам и запятым, поэтому в находку попадала строка вместе с обрамлением. На выходе получалось "почта": client8988@example.com, без кавычек, и такой JSON модель уже не разберёт. Теперь края находки обрезаются по составу символов адреса, а в тесте обезличенный JSON скармливается штатному ПрочитатьJSON: не разобрался - тест провален.
Итог после правок: 72 прогона на шести форматах, 1 332 замены, ноль неточных возвратов.
Четвёртое нашлось только на живой модели
Автотест гоняет цикл на своих же данных и потому слеп к одной вещи: он не знает, как выглядит ответ нейросети. А выглядит он так:
Крупнейший должник - ООО «Восход Альянс» с долгом 6 334 620,00, что составляет примерно 54,2% от строки «Итого» (11 695 051,73).
После обратного прохода тот же абзац читается так:
Крупнейший должник - ООО «Северный ветер» с долгом 2 130 000,00, что составляет примерно 54,2% от строки «Итого» (3 932 431,65).
Доля посчитана верно: по настоящим числам 2 130 000 / 3 932 431,65 это ровно 54,2 процента. Модель нашла нужного контрагента, не зная его имени, и посчитала долю на выдуманных суммах правильно. Лучшего подтверждения, что масштабирование не врёт, придумать сложно.
А теперь смотрим на 54,2 глазами детектора. Число с запятой и одним знаком после неё. То есть сумма. При обратном проходе доля честно поделилась бы на коэффициент и превратилась в 18,2 процента.
Ошибка из самых неприятных: тихая. Число на месте, выглядит правдоподобно, а вывод уже неверный. Никакого исключения, никакого предупреждения.
Лечится заглядыванием на два символа вперёд: если сразу за числом стоит знак процента, деньгами оно не является. Работает в обе стороны, потому что процент нельзя масштабировать и при обезличивании тоже.
Мораль простая. Автотест проверяет то, что вы придумали проверить. Один прогон через настоящую модель нашёл то, чего не нашли семьдесят два синтетических.
Отдельно проверялось, что настоящих названий в результате не остаётся: поиск подстрок из исходных данных по обезличенному тексту даёт ноль вхождений во всех форматах.
Чего этот подход не делает
Здесь надо быть честным, потому что в этой теме преувеличение опаснее, чем в любой другой.
Обезличивание убирает прямые идентификаторы, а не контекст. Одна редкая должность в маленьком филиале узнаётся и без имени, а строка «единственный поставщик оборудования в городе» идентифицирует не хуже БИН. Против такого не помогает никакая замена значений.
Автоматика ловит не всё. Просматривать результат глазами перед отправкой всё равно надо, и это не формальная отговорка: в свободном тексте всегда найдётся что-то, чего детектор не знает. Именно поэтому обезличенный текст показывается рядом с исходным, а не уезжает никуда сам.
И главное, про что забывают: файл словаря замен - это ключ. Он содержит соответствие фейков оригиналам, то есть по нему восстанавливается всё. Хранить его надо там же и так же, как хранились бы сами данные, а не в загрузках рядом с браузером.
Итого
Задача выглядит простой ровно до момента, когда начинаешь её решать. Удалить имена мало, заменить случайно хуже, чем не заменять, а без обратной расшифровки инструмент делает половину работы и оставляет вам вторую.
Рабочая конструкция получается такой: согласованная замена по словарю из самой базы, контрольные суммы как фильтр ложных срабатываний, масштабирование сумм вместо подмены и обратный проход по сохранённому словарю. Ничего экзотического, но каждый пункт здесь появился не из красоты, а потому что без него ломается что-то конкретное.
Готовая обработка со всем описанным лежит отдельной публикацией. Работает на любой конфигурации от 8.3.14, ставить ничего не надо, код открыт.
Соседняя обработка той же линейки - Выгрузка структуры метаданных 1С для нейросети. Она решает вторую половину той же задачи: отдаёт модели устройство базы, чтобы запросы писались по настоящим именам таблиц. Метаданные объясняют модели, как устроена база, анонимизатор позволяет безопасно дать ей сами данные.
Другие наши инструменты для связки 1С и нейросетей:
- Выгрузка структуры метаданных 1С для нейросети - компактное дерево конфигурации для вставки в чат.
Вступайте в нашу телеграмм-группу Инфостарт