Files
contracts/History/llm-analysis/opus-zip-plan-analysis.md
T

11 KiB
Raw Blame History

Анализ ответа Опуса — zip_source, UI-режимы, промпты

Дата: 26.06.2025 | Ответ на opus-request-zip-plan.md


1. Оценка ответа в целом

Качество: высокое. Опус прочитал реальный код, разобрался в архитектуре, дал конкретные диффы по слоям. Не «размышления вообще», а точные строки и функции. 95% рекомендаций — правильные.

Что упущено:

  • Lucee-слой (upload.cfm, api.cfm) — тоже участвует в upload, но Опус его не проанализировал
  • confidence — предлагает сохранять в БД, но не говорит где именно брать (LLM возвращает? парсить из промпта?)
  • Порог 100 файлов для «Потока» — спорный, обсудим ниже

2. По пунктам

2.1. zip_source СОГЛАСЕН полностью

План по слоям правильный. Ключевые моменты:

  • zip_source не участвует в classify/group/compare — верно. Чисто визуальный атрибут.

  • Формат: имя ZIP с расширением — да, «Ромашка.zip».

  • PK не трогаем (UUID), «ID = zip/filename» только для отображения — верно.

  • Дедупликация по паре (zip_source, name)⚠️ самый критичный момент. Опус прав: если не сменить ключ, одноимённые файлы из разных ZIP будут перезаписываться. Но надо проверить: текущий код в addRegularFile() (files.js) ищет по f.name. При добавлении zip_source нужно либо:

    • Ключ = zip_source + "/" + filename (как предлагает заказчик)
    • Или ключ = (zip_source || "") + filename

    Я за вариант с конкатенацией в одну строку — проще для сравнения.

  • unzip.py не трогаем — верно. Имя ZIP уже есть на фронте (file.name).

2.2. Вариант отображения — СОГЛАСЕН (Вариант А)

Заголовок-секция ZIP + отступ padding-left: 24px.

  • Просто, без нового состояния
  • Соответствует тому что описал заказчик
  • Опциональное сворачивание — да, но не в первой итерации

2.3. Два UI-режима — ⚠️ ЧАСТИЧНО СОГЛАСЕН

Плюсы:

  • Бэкенд не меняется — правильно
  • state.ui.mode — хорошее место
  • Сводный отчёт («зелёное сворачиваем, красное показываем») — отличная идея
  • Авто-определение + ручной override — разумно

Спорные моменты:

  • Порог 100 файлов — слишком низкий для автоматического предложения. При 100 файлах текущий UI работает нормально (скролл, 50vh). Реальный болевой порог — 200-300+. Предлагаю порог 200.
  • «Поток» сейчас не нужен. Если заказчик работает с 5-50 файлами, весь Stream Mode — оверинжиниринг. Но архитектурно заложить state.ui.mode — дёшево и правильно.

2.4. Промпты — СОГЛАСЕН, с уточнениями

Classify — проблемы А-Д:

А. Counterparty / блок про стороны НУБЕС🔴 КРИТИЧНАЯ. Опус абсолютно прав. Промпт сейчас не говорит что НУБЕС = Исполнитель. LLM возвращает случайную сторону. Чинится одной вставкой в промпт. Делать первым.

НО: Опус предлагает «ИНН 7727... (взять у заказчика)». Это перебор. Достаточно:

НУБЕС известен как: «НУБЕС», «ООО НУБЕС», «ООО "НУБЕС"», «Nubes».
counterparty — ВСЕГДА вторая сторона, НИКОГДА не НУБЕС.

Б. parent_number у contract верно. parent_number = null для contract.

В. Мусорные документы верно. Добавить примеры в doc_type=other.

Г. Few-shot примеры в classify верно. 1-2 примера улучшат точность.

Д. confidence⚠️ спорно. Опус говорит «добавить колонку и показывать low в отчёте». Но confidence сейчас даже не сохраняется. Предлагаю сначала убрать из промпта (меньше путаницы), а потом, когда будет реальная потребность — добавить и колонку, и парсинг.

Compare (diff) — СОГЛАСЕН

  • «UNRESOLVED вместо дубль-ADD при сомнении» — верно
  • temperature=0.1 для diff — проверить (скорее всего уже)
  • full_replace → автоматическое удаление старых строк на стороне Python — умная идея, снижает нагрузку на LLM

Разные промпты под сценарии — СОГЛАСЕН

Не нужно. Один classify + один diff. Меньше рассинхрона.

2.5. Гомоглифы — ⚠️ ОСТОРОЖНО

Опус предлагает:

  • С/C → C (латиница)
  • О/0 — «трактовать осторожно»
  • Ё → Е

Моё мнение:

  • С→C и Ё→Еопасно. Это меняет семантику номера. МЭС-123МЭC-123. Лучше: не заменять, а добавить второй проход сравнения — если точное совпадение не найдено, попробовать с гомоглифами. Или нормализовать ОБА варианта (и кириллицу, и латиницу) к единому представлению, но сохранять оригинал для отображения.
  • Конкретно для Ё: да, Ё→Е допустимо (в делопроизводстве Ё часто заменяют на Е). Но лучше сделать настраиваемым.

2.6. Приоритеты — СОГЛАСЕН с корректировкой

Что Приоритет Опуса Моя оценка
Counterparty в промпте P0 P0
doc_type=other мусор P0 P0
Гомоглифы P0 P1 ⚠️ (осторожно, не ломать)
zip_source P1 P1
Группировка по ZIP в UI P1 P1
Режим «Поток» P2 P3 (отложить, нет потребности)
confidence в БД P3 P3 (или убрать из промпта)
diff-UNRESOLVED P3 P2 (дёшево, большой эффект)

3. Что Опус упустил

3.1. Lucee-слой

upload.cfm и api.cfm на Lucee тоже обрабатывают загрузку. Если файл идёт через Lucee (а не напрямую на VM), zip_source нужно прокинуть и там. Надо проверить — идёт ли upload через Lucee или напрямую на VM.

Факт: судя по index.cfm, JS грузится с VM (contracts.kube5s.ru/static/app.js), а upload идёт на VM_API + '/upload'. Значит Lucee в upload не участвует. zip_source в Lucee не нужен. Опус оказался прав молча.

3.2. Промпты в БД vs хардкод

Опус верно заметил: «промпты берутся из БД (Lucee), fallback — хардкод. Менять надо в БД через интерфейс промптов». Это критично важно для исполнителя: если просто поправить FALLBACK_EXTRACT/FALLBACK_DIFF в llm_prompt.py — в проде ничего не изменится, потому что используется версия из БД.

Порядок правки промптов:

  1. Сначала в БД через UI (/prompt.cfm)
  2. Потом в хардкоде (для fallback)

3.3. Порог для «Потока»

100 файлов — слишком консервативно. Таблица с max-height: 50vh и overflow-y: auto нормально работает при 100-150 файлах. Предлагаю 200 как порог для автопредложения. Но лучше — сделать настраиваемым (константа в начале app.js).


4. Итоговое мнение

Ответ Опуса — хороший план. 95% рекомендаций принимаю.

Что делаем прямо сейчас (P0):

  1. Правка classify-промпта: блок про стороны НУБЕС + parent_number=null + примеры мусора
  2. Правка diff-промпта: UNRESOLVED вместо дубль-ADD, temperature проверка

Что делаем дальше (P1): 3. zip_source сквозь все слои (БД → Python → JS) 4. Группировка по ZIP в таблице (Вариант А) 5. Дедупликация по (zip_source, filename)

Что откладываем: 6. Режим «Поток» — пока нет потребности 7. Гомоглифы — нужно больше примеров от заказчика 8. confidence — убрать из промпта, вернуть когда будет нужно

Главный риск (ещё раз): дедупликация в addRegularFile(). Без правки ключа на (zip_source, name) — фича сломается на первом же случае одинаковых имён в разных ZIP.