Автоматизация создания Дополнительных Соглашений (ДС) с помощью локальной модели Qwen (Часть 1: Общая)
В этой статье я расскажу о разработке решения для автоматической генерации Дополнительных Соглашений (ДС) к договорам. Основная задача — избавить юристов и менеджеров от рутины, переложив анализ текста договора и формирование «рыбы» документа на искусственный интеллект.
Это первая часть большой серии, где я опишу процесс в общих чертах, а дальше каждую часть раскрою отдельно. Подписывайся на меня в телеграм, если тоже любишь автоматизировать юридические процессы.
В качестве «мозга» системы была выбрана локальная языковая модель Qwen (в частности версия `qwen3-vl-30b-a3b-thinking`), работающая через локальный API-сервер. Это обеспечивает конфиденциальность данных (тексты договоров не покидают контур компании) и отсутствие затрат на облачные токены.
Архитектура решения
Система написана на Python и состоит из трех основных этапов:
1. Сбор данных: Загрузка исходных данных о договорах из базы SQLite.
2. Интеллектуальный анализ (LLM): Извлечение ключевых параметров (стороны, номера, даты) и логический вывод новых данных (следующий номер пункта, склонение ФИО).
3. Генерация документа: Заполнение шаблона `.docx` полученными данными.
1. Строгая структура данных (JSON Schema)
Одной из главных проблем при работе с LLM является нестабильность вывода. Чтобы модель возвращала данные в четко заданном формате, я использовал Structured Outputs (JSON Schema).
В коде определена схема `ADDENDUM_SCHEMA`, которая жестко диктует модели, какие поля она должна вернуть: `номер_ДС`, `дата_ДС` * `подписант_заказчика_в_родительном падеже` (критично для преамбулы ДС) Блоки для разделов «Предмет», «Оплата», «Сроки» (тип единицы, номер пункта, текст цитаты).
Это позволяет избежать парсинга свободного текста и сразу получать готовый JSON для вставки в шаблон.
Подробнее здесь
2. Техника «Подсказок» (Structural Hints)
Локальные модели, даже мощные, иногда ошибаются в простой арифметике или навигации по большим текстам (например, могут неправильно определить последний пункт в разделе).
Чтобы повысить точность, я реализовал гибридный подход. Вместо того чтобы просить модель саму считать пункты, я делаю это алгоритмически на Python с помощью функции `structural_hints_for_llm`:
1. Скрипт парсит структуру договора (главы, статьи).
2. Находит разделы, содержащие ключевые слова («ПРЕДМЕТ», «ОПЛАТА», «СРОК»).
3. Вычисляет последний номер пункта (например, `2.4`) и генерирует номер для нового пункта (`2.5`).
Эти вычисленные данные передаются модели в поле `hints`. Модели остается лишь «собрать» всё в красивую фразу, например: "дополнить раздел 2 пунктом 2.5 следующего содержания...".
Пример кода подсказок:
Подробнее здесь
3. Работа с русской грамматикой
Для корректного формирования ДС необходимо склонять имена и должности (например, "в лице Генерального директора Иванова..."). В промпте для LLM я использую специальную инструкцию: "Верни грамматически корректные фразы... а также должность и ФИО подписантов в родительном падеже... ВНИМАНИЕ: поля родительного падежа возвращай БЕЗ предлога ‘в лице’".
Дополнительно на стороне Python реализована функция очистки `sanitize_signatory_gen`, которая убирает лишние скобки и мусор, если модель всё-таки добавила их.
Подробнее здесь
4. Взаимодействие с API
Для общения с моделью используется стандартный REST API (совместимый с OpenAI), поднятый локально (например, через LM Studio на порту 1234). Функция `call_llm` отправляет контекст договора, системный промпт и подсказки. Реализован механизм повторных попыток (retries) на случай, если модель не ответит или вернет битый JSON.
Подробнее здесь
5. Генерация DOCX
Финальный этап — подстановка данных в XML-структуру Word-документа. Вместо сложных библиотек шаблонизации используется прямой поиск и замена плейсхолдеров в XML или построение документа с нуля через `python-docx` на основе полученных данных.
Подробнее здесь
Итоги
Использование локальной модели Qwen-30B в связке с алгоритмическим пре-процессингом позволило создать надежный инструмент.
Плюсы: Полная приватность, отсутствие затрат на API, высокая точность благодаря гибридному подходу (Python считает, LLM формулирует).
Сложности: Требуется мощное железо для быстрого инференса модели 30B, но можно обойтись и игровой видеокартой или мощным процессором.
Это решение демонстрирует, что для юридических задач не обязательно использовать ChatGPT — правильно настроенная локальная модель с грамотной обвязкой кода справляется не хуже.
Кому, как и мне, интересно автоматизировать юридические процессы, присоединяйтесь ко мне в телеграме, там я пишу "человеческим языком", а не вот это вот всё)