СОЗДАНИЕ ДС С ЛОКАЛЬНОЙ LLM. ЧАСТЬ 3: ТЕХНИКА «ПОДСКАЗОК» (STRUCTURAL HINTS)
В предыдущих частях мы настроили LLM на выдачу строгого JSON. Но структура — это только полдела. Если модель вернет технически валидный JSON, в котором написано "2 + 2 = 5" или придуман несуществующий пункт договора, автоматизация принесет больше вреда, чем пользы.
Это третья часть большой серии, где я опишу подробно каждый раздел из общей части. Подписывайся на меня в телеграм, если тоже любишь автоматизировать юридические процессы.
Языковые модели — это "гуманитарии". Они отлично генерируют связный текст, но часто ошибаются в арифметике и строгой навигации по большим документам. Попросить модель "найди последний пункт в разделе 3 и добавь следующий" — это риск. Она может пропустить пункт 3.12 и решить, что последний — 3.9, создав дубликат или дыру в нумерации.
РЕШЕНИЕ: ГИБРИДНЫЙ ИНТЕЛЛЕКТ (PYTHON + LLM)
Чтобы исключить галлюцинации в цифрах, я применил подход "Structural Hints" (структурные подсказки). Идея проста: всю "математику", навигацию и анализ структуры берет на себя жесткий алгоритм на Python, а LLM занимается только лингвистической частью и упаковкой данных.
АЛГОРИТМ ДЕЙСТВИЙ
1. Парсинг структуры. Python пробегает по JSON-представлению договора (которое мы получили из базы данных) и строит карту: какие есть разделы, какие в них пункты.
2. Вычисление следующего шага. Скрипт находит последний пункт в нужном разделе (например, 5.4) и математически вычисляет номер следующего (5.5).
3. Формирование подсказки. Эти точные, проверенные данные передаются модели вместе с текстом договора.
РЕАЛИЗАЦИЯ В КОДЕ
В функции `structural_hints_for_llm` скрипт ищет ключевые разделы с помощью регулярных выражений (Regex): - "ПРЕДМЕТ" - "ЦЕНА" или "ОПЛАТА" - "СРОК"
Для каждого найденного раздела вычисляется набор параметров: - Тип единицы (Статья, Раздел, Глава) - Текущий номер раздела - Номер последнего существующего пункта - Номер НОВОГО пункта (last + 1)
Пример логики вычисления номера (упрощенно):
ГЕНЕРАЦИЯ ГРАММАТИКИ
Здесь же Python готовит фразы в нужных падежах, чтобы разгрузить модель от лишних размышлений. Функция `acc_phrase` проверяет тип раздела: - Если "Статья" -> возвращает "статью 5" (Винительный падеж) - Если "Раздел" -> возвращает "раздел 5"
ИНЪЕКЦИЯ В ПРОМПТ
Все вычисленные данные собираются в объект `hints` и добавляются в конец пользовательского промпта:
Модели остается только взять эти значения и положить их в соответствующие поля JSON-ответа. Ей не нужно искать, считать или думать. Ей нужно просто "переписать" наши подсказки в финальный формат.
РЕЗУЛЬТАТ
1. 100% точность нумерации. Мы никогда не создадим пункт 2.5, если в договоре уже есть 2.6. Алгоритм видит всё.
2. Скорость. Модели не нужно сканировать весь текст договора и держать его структуру в "голове". Мы даем ей готовый ответ, что ускоряет генерацию.
3. Надежность на слабых моделях. Даже если использовать менее мощную квантованную модель, она справится с задачей, потому что творческая задача "придумать номер" заменена на механическую задачу "скопировать номер из подсказки".
Кому, как и мне, интересно автоматизировать юридические процессы, присоединяйтесь ко мне в телеграме, там я пишу "человеческим языком", а не вот это вот всё)