Files
drhider/History/2026-07-12-sonnet-query.md
T
2026-07-12 09:09:54 +04:00

4.6 KiB
Raw Blame History

Запрос к Соннету — универсальная архитектура DrHider

Контекст

Проект DrHider — обфускация документов (замена персональных данных на фиктивные). Сейчас:

  • Python/Flask, без БД, Managed Flask на платформе Штурвал
  • Двухпроходная архитектура: сбор сущностей → замена
  • Проход 1: regex-паттерны (телефон, email, ИНН, ОГРН, КПП, БИК, счета, паспорт) + LLM NER (ФИО, компании, адреса, паспорта)
  • Проход 2: замена по словарю mapping

Проблема

Архитектура в корне неверна — жёстко привязана к фиксированному списку типов сущностей:

# config.py — жёстко зашитые паттерны
ENTITY_PATTERNS = {
    "phone": r'...',
    "email": r'...',
    "inn_fl": r'ИНН\s*\d{12}',
    ...
}
# 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