5.9 KiB
Запрос к Sonnet: анализ обфускации
Дата: 2026-07-13
Задача: Найти причину расхождения между ожидаемыми кодами замен и реальными заменами.
Ожидаемое поведение
_next_token() в drhider/scanner.py генерирует коды замен формата:
Технология_0001,Прогресс_0002(для компаний)+7_000_000_0001(для телефонов)email_0001(для email)ИНН_0001(для ИНН)Иванов_0001(для ФИО)
Реальный результат — TMP/mapping.csv
тип_данных,оригинал,замена
phone,+7 (495) 789-41-35,+7 (495) 906-87-80 ← НЕ код замены, реальный номер
email,info@nubes.ru,ypiorej@company.local ← НЕ код замены, реальный email
company,ЗАО ****XXX****001****,АО «Прогресс» ← НЕ код замены, реальное название
company,ЗАО XXX001,ООО «Альянс» ← НЕ код замены, реальное название
inn_ul,ИНН 9706005293,ИНН 1846691249 ← НЕ код замены, реальный ИНН
kpp,КПП 772401001,КПП 350443068 ← НЕ код замены, реальный КПП
ks,Кор/сч 30101810400000000225,Кор/сч 30101201490272090211 ← НЕ код замены
ogrn,ОГРН 1207700098759,ОГРН 1048672318430 ← НЕ код замены
company,ООО "НУБЕС",ООО «Спектр» ← НЕ код замены
text,Исполнителем Заказчику Сторонами,Кузнецов О.В.
text,"Обязанности Заказчика\nСвоевременно",Степанов А.В.
text,"Обязанности Исполнителя\nОказывать",Петров П.Е.
text,"Ответственность Заказчика\nЗаказчик",Новиков А.М.
text,"Ответственность Исполнителя\nИсполнитель",Попов О.М.
company,ПАО Сбербанк,АО «Формат»
Ни одного кода замены формата XXX_0000 в колонке «замена».
Реальный результат — TMP/договор-XXX001-03700_obfuscated.md (первые строки)
**АО «Прогресс»** ... и **ООО **"**НУБЕС**" ... Новиков И.В. ...
Новиков И.В.— НЕ заменён (должен бытьИванов_0001)ООО "НУБЕС"— НЕ заменён в тексте (есть в mapping но замена не применена?)г. Москва, 1-я Стекольная 7с5— адрес не заменён
Файлы для анализа
Обязательно прочитать:
drhider/scanner.py—_next_token(),scan_regex(),scan_llm_ner(), TYPE_POOLS, промпт LLM (строки 109-151)drhider/obfuscator.py— порядок вызова regex → LLM, как объединяется mapping (строки 63-95)drhider/config.py— ENTITY_PATTERNS, COMPANY_PATTERN, PERSON_PATTERNdrhider/llm_client.py—LLMClient.complete()
Прочитать для контекста:
5. TMP/mapping.csv — полный результат
6. TMP/договор-XXX001-03700_obfuscated.md — обфусцированный файл
7. TMP/примеры_договоров_для_ИИ/договор-XXX001-03700.docx — оригинал (для сверки)
Не лезть: builder.py, extractor.py, replacer.py, session.py, templates/, docs/, History/.
Ключевые точки для проверки
1. scanner.py — _next_token() (стр. 63-82)
def _next_token(entity_type, counters):
pool, prefix_key = TYPE_POOLS.get(entity_type, _FALLBACK_POOL)
template = random.choice(pool)
key = f"{prefix_key}_{template}"
counters[key] = counters.get(key, 0) + 1
return f"{template}_{counters[key]:04d}"
Возвращает Технология_0001, +7_000_000_0001. Никак не может вернуть АО «Прогресс» или +7 (495) 906-87-80.
2. scanner.py — scan_regex() (стр. 89-108)
mapping[original] = _next_token(entity_type, counters)
Всегда вызывает _next_token. Результат должен быть кодом замены.
3. scanner.py — scan_llm_ner() (стр. 109-179)
mapping[val] = _next_token(ent_type, counters)
Тоже вызывает _next_token. Результат должен быть кодом замены.
4. obfuscator.py — порядок вызова (стр. 86-92)
scanner.scan_regex(text, self._mapping, self._counters) # сначала
scanner.scan_llm_ner(all_texts, self._mapping, ...) # потом
5. config.py — regex-паттерны:
phone:(?:\+7|8)[\s\-]?\(?\d{3}\)?...— должно матчить+7 (495) 789-41-35email:[a-zA-Z0-9._%+-]+@...— должно матчитьinfo@nubes.ruinn_ul:ИНН\s*\d{10}— должно матчитьИНН 9706005293COMPANY_PATTERN:(?:ООО|ЗАО|...)\s+(?:«[^»]+»|"[^"]+"|...)— должно матчитьООО "НУБЕС"иЗАО "XXX001"PERSON_PATTERN:[А-Я][а-я]+\s+[А-Я]\.[А-Я]\.— должно матчитьНовиков И.В.
Главный вопрос
Каждый путь (regex и LLM) вызывает _next_token(). _next_token() физически не может выдать АО «Прогресс» или +7 (495) 906-87-80. Откуда в mapping.csv берутся реалистичные замены? Кто и где их генерирует В ОБХОД _next_token()?