# Сверка договоров — описание сервиса ## Что делает Сервис автоматически сравнивает договоры и дополнительные документы облачного провайдера (colocation, ЦОД). Юрист загружает файлы (.docx/.doc/.pdf), система извлекает спецификации услуг и при помощи LLM находит изменения: что добавилось, изменилось, удалилось. ## Как устроен пайплайн ``` Загрузка → Парсинг → Порядок → LLM-сравнение → Результаты ``` 1. **Загрузка** — файлы принимаются через веб-интерфейс. Поддерживаются .docx, .doc (старый Word), .pdf, а также .zip с несколькими файлами. 2. **Парсинг** — каждый файл автоматически разбирается: извлекаются таблицы и текст. Используется Apache POI (Java) для Word-документов и PDFBox для PDF. Результат — структурированный JSON (elements_json) и текстовое представление. 3. **Порядок** — файлы можно переставить стрелками ↕. Первый в списке считается базовым договором, остальные — дополнительные документы к нему. 4. **LLM-сравнение** — каждый дополнительный документ последовательно сравнивается с текущей спецификацией. Модель (gpt-oss-120b) получает промпт с текущим списком услуг, текстом дополнительного документа и возвращает операции: - **ADD** — новая услуга - **UPDATE** — изменение цены, количества, названия - **DELETE** — услуга исключена - **UNRESOLVED** — не удалось однозначно сопоставить 5. **Результаты** — накапливаются по цепочке дополнительных документов (Event Sourcing). Каждый следующий дополнительный документ учитывает изменения из предыдущих. Итоговая спецификация — сумма всех применённых операций. ## Архитектура ``` Браузер (index.cfm + JS) │ ├── загрузка файлов ──→ VM (Python, convert_server.py) │ │ │ ├── /convert-doc ──→ Lucee (parser.cfm) │ ├── /process-v2 ───→ Lucee (apply_events.cfm) │ └── LLM (api.aillm.ru, gpt-oss-120b) │ └── API ──→ Lucee (CFML на k8s) │ └── PostgreSQL 15 (документы, спецификации, события, промпты) ``` | Компонент | Где | Технология | |-----------|-----|------------| | Веб-интерфейс | Lucee 6.0 (k8s) | CFML + JavaScript | | База данных | Внутренний PostgreSQL 15 | JSONB, UUID, advisory locks | | Парсинг документов | Lucee | Apache POI (HWPF/XWPF), PDFBox | | LLM-анализ | Внешняя VM (5.172.178.213) | Python 3, httpx, SSE-стриминг | | Модель | api.aillm.ru | gpt-oss-120b (бесплатно, 8000 токенов) | ## Event Sourcing Изменения не перезаписывают спецификацию — каждая операция сохраняется как событие в `spec_events`. Текущее состояние (`spec_current`) — материализованное представление всех событий. Это даёт: - **Аудит** — кто/when/откуда каждая строка - **Откат** — можно пересобрать состояние на любой момент - **Provenance** — ссылка на документ-источник, версию промпта, полный ответ LLM ## Промпты Промпты для LLM хранятся в БД и версионируются. Есть два: для первого документа (извлечение) и для сравнения дополнительных документов. Встроенный редактор с историей версий позволяет улучшать промпты без правки кода: сохранил новую версию → она сразу используется LLM. Старые версии остаются в истории, можно откатиться. ## Стек - **Backend**: Lucee 6.0 (CFML) на Kubernetes - **База**: PostgreSQL 15 (JSONB, UUID, window functions) - **Парсинг**: Apache POI (Java, встроен в Lucee) - **LLM-прокси**: Python 3 + httpx + threading (SSE) - **Модель**: gpt-oss-120b (OpenAI-совместимый API) - **Фронтенд**: ванильный JS + Lucide иконки