# Запрос к Соннету — универсальная архитектура DrHider ## Контекст Проект DrHider — обфускация документов (замена персональных данных на фиктивные). Сейчас: - Python/Flask, без БД, Managed Flask на платформе Штурвал - Двухпроходная архитектура: сбор сущностей → замена - Проход 1: regex-паттерны (телефон, email, ИНН, ОГРН, КПП, БИК, счета, паспорт) + LLM NER (ФИО, компании, адреса, паспорта) - Проход 2: замена по словарю mapping ## Проблема Архитектура **в корне неверна** — жёстко привязана к фиксированному списку типов сущностей: ```python # config.py — жёстко зашитые паттерны ENTITY_PATTERNS = { "phone": r'...', "email": r'...', "inn_fl": r'ИНН\s*\d{12}', ... } ``` ```python # scanner.py — жёстко зашитый промпт prompt = ( "Найди ВСЕ следующие сущности:\n" "1. ФИО\n2. Компании\n3. Адреса\n4. Паспортные данные\n" ) ``` Если новый документ содержит СНИЛС, водительское удостоверение, номер договора, ИНН без префикса «ИНН» — система их НЕ обнаружит. Надо править config, generators, scanner, маппинги. ## Что нужно **Универсальная архитектура**, где система САМА определяет что скрывать в любом документе: 1. Не привязана к списку типов 2. Не требует добавления паттернов под каждый новый вид данных 3. LLM сама решает что является персональными/конфиденциальными данными 4. Генерация фиктивных значений — тоже универсальная (не 11 отдельных функций) ## Текущая структура (полная) ``` drhider/ ├── config.py # ENTITY_PATTERNS (10 regex), словари имён/городов ├── checksum.py # Контрольные суммы ИНН/ОГРН ├── random_utils.py # random_digits, random_letters ├── generators/ # 11 файлов: phone, email, inn, ogrn, kpp, bik, accounts, passport, company, person, address ├── llm_client.py # HTTP-клиент к LLM API ├── extractor.py # Извлечение текста + expand_zips + convert_pdfs_to_docx ├── scanner.py # scan_regex (regex) + scan_llm_ner (LLM NER с жёстким промптом) ├── replacer.py # apply_replacements, replace_in_docx, replace_in_text ├── builder.py # build_zip, build_mapping_csv ├── obfuscator.py # TwoPassObfuscator — оркестратор ├── site/app.py # Flask (3 blueprint'а) └── site/templates/ # HTML-интерфейс ``` ## Вопросы к Соннету 1. Как перестроить архитектуру чтобы обнаружение было универсальным (LLM сама решает что скрывать)? 2. Нужен ли regex вообще или достаточно одного LLM с правильным промптом? 3. Как сделать генерацию фиктивных значений универсальной? (Не 11 функций под каждый тип, а что-то общее) 4. Двухпроходная схема (сбор→замена) — сохранять или перейти на однопроходную (LLM сразу возвращает обфусцированный текст)? 5. Как должен выглядеть промпт чтобы LLM возвращала структурированный результат (что найдено + на что заменить)? 6. Стоит ли сохранять DOCX-форматирование (сейчас runs склеиваются-разделяются) или проще отдать LLM plain text? ## Ограничения - Документы до 200 MB - Форматы: .docx, .pdf, .txt, .zip - LLM: OpenAI-совместимое API (aillm.ru, модель gpt-oss-120b, 8000 токенов) - Без БД, всё в памяти - Платформа: Managed Flask на Kubernetes