🏗️ Архитектура — сверка договоров

Пайплайн: загрузка → парсинг → классификация → группировка → сравнение → аудит


1. Загрузка файлов

Пользователь выбирает .docx / .pdf / .doc / .zip.

Результат: elements_json — массив элементов двух типов:

Документ сохраняется в БД, считается content_hash (SHA-256) — если в этом же батче уже есть файл с таким содержимым, он помечается как duplicate и не дублируется.

📋 Заказчик: «100+ файлов за раз. Файлы: .docx/.pdf, возможно ZIP.
Загрузка из локали (файловая шара / облачный диск), НЕ S3 (конфиденциальность).»

2. Классификация документов

Каждый загруженный файл проходит трёхэтапный фильтр.

📋 Заказчик: «Оставлять только: договоры, доп. соглашения, спецификации.
Игнорировать: акты сверки, счета/счета-фактуры/УПД, акты услуг, платёжки.»

Этап 1 — имя файла 0 токенов

Проверка имени файла на мусорные ключевые слова: «счёт», «акт», «платёж», «УПД», «сверка», «invoice» и др. Совпадение → garbage, дальше не идёт.

Этап 2 — заголовки в тексте 0 токенов

Проверка первых 2000 символов текста на заголовки: «СЧЕТ-ФАКТУРА», «АКТ СВЕРКИ», «АКТ ОКАЗАННЫХ УСЛУГ» и т.п. Совпадение → garbage.

📋 Заказчик: «Названия документов неинформативные. Есть лишние документы.
По всем контрагентам.»

Этап 3 — LLM LLM

Оставшиеся документы отправляются в LLM. Модель получает выжимку текста (первые 1500 символов + строки с маркерами «договор», «соглашение», «спецификация») и возвращает JSON:

📋 Заказчик: «НУБЕС = Исполнитель во всех целевых договорах.»
→ counterparty = другая сторона (Заказчик).

3. Группировка по договорам

Детерминированная (без LLM). Документы группируются по номерам договоров.

📋 Заказчик: «Система сама должна разбираться, кто к кому.
зачем нам базовый договор? Вся информация есть в допниках и спеках.»
«Я не должен распознавать ничего. Система должна сделать всё.»

4. Сравнение — извлечение + дифф

Для каждой группы запускается последовательная обработка.

📋 Заказчик: «Важно. В произвольной, не повторяющейся.» (порядок допников)
«Главное — точность разбора, не UI. Сначала базовая функция → потом юзабельность.»

4a. Сортировка

Документы внутри группы сортируются по doc_date (из классификации), затем по времени загрузки.

4b. Базовый договор (первый в группе) LLM

4c. Дополнительные соглашения LLM

4d. Режим «изложить в новой редакции»

Если допник говорит «изложить в новой редакции» — LLM возвращает полный новый список (full_replace). Все старые строки заменяются новыми.


5. Защита и валидация валидация

📋 Заказчик: «кривых документов можно ожидать.
Если не может разобраться — пусть зовет на помощь юзера.»

6. Event Sourcing — аудит аудит

📋 Заказчик: «Наверно я захочу иметь возможность посмотреть любые промежуточные результаты.
Было бы хорошо пояснить или показать процесс, что в каком порядке происходит.»

7. Промпты LLM

Три роли промптов, хранятся в БД с версионированием:

Роль Назначение
extract Извлечение строк спецификации из договора
diff Сравнение допников с текущей спецификацией
classify Определение типа/номера/даты/контрагента документа

Встроенный редактор с историей версий: сохранил новую версию → она сразу используется LLM. Старые версии остаются в истории — можно откатиться.


8. Стек технологий

Компонент Где Технология
Веб-интерфейс Managed Python (Nubes) Python 3.12, Jinja2, ванильный JS
Механизм обработки Выделенная VM Python 3.12, httpx, pdfplumber, python-docx
База данных VM PostgreSQL 15 JSONB, UUID, advisory locks
LLM api.aillm.ru gpt-oss-120b (бесплатно, OpenAI API)
Деплой Managed Python + VM Dockerfile, Nginx + Let's Encrypt

9. Конечная цель будущее

📋 Заказчик: «Конечная цель: построчное сравнение CRM ↔ фискальная система.
Особый фокус: даты начала услуг.
PAYG (суффикс -m) — особый случай. Сверку с CRM тоже можно делегировать AI.»

Текущий пайплайн завершается на этапе извлечения спецификации из договоров и отслеживания изменений по допникам. Модуль сравнения с CRM — спроектирован как CanonicalRow адаптер, ожидает формата данных от заказчика.


10. Что дальше требует участия Заказчика

📋 Заказчик: «Это всё пока опыты и набивание шишек.
Не надеюсь с первого захода на идеальный результат.»
  1. Золотой набор: 30–50 реальных документов с ручной разметкой — измерить точность LLM
  2. Формат CRM: в каком виде данные из системы учёта клиентов — для модуля сверки
  3. Приоритет: точность vs скорость обработки — влияет на выбор модели LLM (локальная vs облачная)