11 KiB
Анализ ответа Опуса — 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 — в проде ничего не изменится, потому что используется версия из БД.
Порядок правки промптов:
- Сначала в БД через UI (
/prompt.cfm) - Потом в хардкоде (для fallback)
3.3. Порог для «Потока»
100 файлов — слишком консервативно. Таблица с max-height: 50vh и overflow-y: auto нормально работает при 100-150 файлах. Предлагаю 200 как порог для автопредложения. Но лучше — сделать настраиваемым (константа в начале app.js).
4. Итоговое мнение
Ответ Опуса — хороший план. 95% рекомендаций принимаю.
Что делаем прямо сейчас (P0):
- Правка classify-промпта: блок про стороны НУБЕС + parent_number=null + примеры мусора
- Правка 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.