Files
contracts/History/opus-architecture-research-2026-06-27-review.md
T

11 KiB
Raw Blame History

Рецензия DeepSeek V4 Pro на отчёт Opus

Дата: 27.06.2026


Общая оценка: (5/5)

Opus сделал ТО, ЧТО НУЖНО: прочитал код, нашёл расхождения с документацией, не писал код, не рисовал графы. Это эталонный анализ.


Что Opus нашёл такого, чего я НЕ заметил

🔴 КРИТИЧЕСКОЕ: PyPDF2 теряет структуру таблиц

Я читал parse.py, видел PyPDF2, но не осознал что он извлекает текст построчно и не сохраняет колонки. Для спецификаций — это катастрофа. Таблица «наименование | цена | кол-во | сумма | дата» после PyPDF2 станет плоским текстом, и LLM придётся угадывать где какая колонка.

Opus прав на 100%. Это вероятно главный риск точности прямо сейчас. Надо: pdfplumber (для цифровых PDF) или camelot.

🔴 КРИТИЧЕСКОЕ: Кода сверки CRM↔фискальная НЕТ

Я знал это из ответов заказчика, но Opus проверил grep'ом (crm|фискал|fiscal|сверк|PAYG|reconcil) — нашёл только «акт сверки» как тип мусора. Это greenfield. Меняет планирование: не «эволюция», а «новый модуль».

🟡 ВАЖНОЕ: service-description.md устарел

Я дал Opus читать service-description.md как «актуальный». Opus обнаружил что он описывает парсинг через Lucee (Java POI/PDFBox), а реальный код (upload.pyparse.py) парсит на ВМ через PyPDF2/python-docx. Без Java. Без Lucee.

Моя ошибка: я не перепроверил service-description.md на соответствие коду. Надо поправить доку.

🟡 ВАЖНОЕ: llm_prompt.py зависит от Lucee

build_prompt() (основной пайплайн) ходит HTTP в Lucee за активным промптом. А build_classify_prompt() берёт из БД напрямую. Непоследовательно + точка отказа.

🟡 ВАЖНОЕ: chat.cfm содержит захардкоженный API-ключ

Плюс ссылается на spec_rows вместо spec_current — сломан вдвойне.

🟢 Безопасность: verify=False в llm.py

TLS-проверка отключена. Надо включить.


Где Opus прав, а где нет

Тезис Opus Моё мнение
Гипотеза 1 (гибрид): ⚠ частично — «текущий код — чистый pipeline, и это правильно» Согласен. 131 тест на детерминированные функции — сильный аргумент против агентов.
Гипотеза 2 (фильтр мусора): ⚠ частично — «этап 1 по имени файла ненадёжен» Частично. Для имён типа «счет-фактура №123 от 01.01.2025.docx» regex надёжен. Но для «scan001.pdf» — да, бесполезен. Вывод: этап 1 — приоритизация, не жёсткий дроп.
Гипотеза 3 (парсинг на ВМ): отвергнута Полностью согласен. Моя гипотеза была основана на устаревшей документации. Парсинг уже на ВМ.
Гипотеза 4 (трёхуровневый matching): ⚠ частично — «difflib опасен на коротких токенах» Согласен. Примеры «IPv4↔IPv6», «10 кВт↔15 кВт» убедительны. Матчить по структурным атрибутам, не по сырой строке.
Гипотеза 5 (MVP): ⚠ частично — «нужен CRM-прогон уже в v1» Согласен. Иначе v1 будет «готов», а к цели не приблизимся.
Гипотеза 6 (PG-очередь): подтверждена Согласен. Плюс Opus добавил: сейчас очереди нет вообще, in-process ThreadPool.
«LLM бесплатный ≠ быстрый» — не наращивать проходы Согласен. 5-30s × 100+ файлов = узкое место.
«Не отказываться от детерминированного matching» Согласен. Воспроизводимость и аудит важнее «бесплатности».

Единственное где я НЕ согласен:

Opus говорит «не использовать имя файла для фильтрации». Я считаю: regex (сч[её]т|акт|плат[её]ж|УПД|сверк|инвойс|invoice) по имени файла — ДОСТАТОЧНО надёжен для пред-фильтрации. «Счет-фактура №123.docx» — это всегда мусор. Да, «scan001.pdf» не отфильтруется — но он уйдёт на этап 2 (первые 2KB текста). Риск ложного срабатывания на договоре с именем «счет-фактура» — ноль.


Что Opus упустил

  1. testgen/ — в репо есть testgen/generate.py, testgen/pools.py, testgen/templates.py. Это генератор синтетических тестовых данных. Opus предлагает «тестировать матчинг на синтетике», но не знает что инструмент уже есть.

  2. convert_server.py роутинг — Opus не проверил ВСЕ эндпоинты. Например, /api/batch-progress, /api/apply-groups, /api/cleanup, /api/sync — они есть, но не проанализированы.

  3. services/llm.py — расхождение ВМ↔репо — Opus заметил verify=False, но не предложил КАК выяснить какая версия каноническая (репо или ВМ). Я поднимал этот вопрос в opus-plan-review-2026-06-27.md.

  4. LibreOffice — узкое место для .doc/convert-doc запускает LibreOffice subprocess последовательно с таймаутом 30с. На пачке старых .doc файлов это потенциально медленнее даже LLM. Но на практике .doc — редкость (заказчик говорил про docx/pdf).

  5. OCR не нужен — заказчик уточнил: «только текст, сканов не будет». Значит риск «потребуется внешний OCR-сервис» снимается.


Дополнения из второго анализа (подтверждения)

Второй анализ полностью подтвердил выводы Opus. Дополнительно акцентировано:

  • Дрейф документации — не только service-description.md, но и другие .md могут устареть. Правило: код > документация. Всегда проверять.
  • base64 в БДupload.py кладёт файлы как base64 в documents. На 100+ многомегабайтных файлах это раздует БД. Риск масштабирования.
  • Нет устойчивой очередиclassify.py = ThreadPoolExecutor в одном процессе. Падение процесса = потеря прогресса. PG-очередь добавит durability.

Итог: что я беру в работу

Немедленно (следующий чат, по команде «делай»):

  1. Заменить PyPDF2 на pdfplumber в services/parse.py — критично для точности
  2. Починить chat.cfm — убрать ключ, spec_rowsspec_current
  3. Включить verify=True в services/llm.py
  4. Отвязать llm_prompt.py от Luceebuild_promptdb.prompts.get_active()
  5. Поправить service-description.md — парсинг на ВМ, не через Lucee

Вторая очередь:

  1. Детерминированная проверка sum == price*qty — бесплатный сигнал ошибок
  2. Золотой набор — 30-50 реальных документов с ручной разметкой
  3. Метрики — логировать _safe_json_parse срабатывания, UNRESOLVED, латентность

Третья очередь (после золотого набора):

  1. Спроектировать нейтральную CanonicalRow для CRM↔фискальная
  2. Прототип матчинга на синтетике из testgen/

Вывод

Opus дал отличный анализ. Главная ценность — нашёл расхождения кода и документации, которые я пропустил. PyPDF2 — критическая находка. То что кода CRM-сверки нет — меняет приоритеты: не «эволюция», а «новый модуль».

Что отсеялось после двух анализов:

  • OCR не нужен (только текст, без сканов)
  • LLM не использовать агрессивнее (бесплатный ≠ быстрый, 5-30s/вызов)
  • Агенты не нужны (131 тест на pipeline, детерминизм > гибкость)
  • RabbitMQ не нужен (PG-очередь достаточна)

Что осталось в работе (5 немедленных + 3 второй очереди):

  1. pdfplumber вместо PyPDF2
  2. chat.cfm: ключ + таблица
  3. llm.py: verify=True
  4. llm_prompt.py: отвязать от Lucee
  5. service-description.md: поправить
  6. Проверка sum==price*qty
  7. Золотой набор 30-50 документов
  8. Метрики (_safe_json_parse, UNRESOLVED, латентность)

Следующий шаг: команда «делай» → правлю пункты 1-5.