Как я построил модульную систему промптов для YandexGPT, почему GPT из коробки галлюцинирует на юридических документах, и что из этого получилось.
Предыстория
Год назад я чуть не потерял 200 тысяч на аренде офиса. Договор выглядел стандартно, но в п. 5.3 мелким шрифтом было написано: «Депозит не возвращается при расторжении по инициативе Арендатора». Заметил случайно, когда перечитывал в третий раз.
После этого я стал параноиком: читал каждую запятую, гуглил каждый пункт. А потом подумал — почему бы не автоматизировать эту паранойю?
Проблема: GPT из коробки не работает
Первая попытка была наивной: закинул договор в YandexGPT с промптом «найди риски в этом договоре».
Результат:
Галлюцинации: модель «находила» риски, которых в тексте не было
Пропуски: очевидные ловушки (пеня 1% в день = 365% годовых) игнорировались
Общие фразы: «рекомендуется проконсультироваться с юристом» — спасибо, кэп
Главная проблема — контекст. Договор франшизы и договор аренды — это разные вселенные. Риски разные, нормы рынка разные, даже терминология разная. Один промпт на всё не работает.
Решение: модульная архитектура промптов
Я разбил систему на три слоя:
┌─────────────────────────────────────────────┐
│ Финальный промпт (~10KB) │
├─────────────────────────────────────────────┤
│ Base Prompt │ ~3KB │ Методология │
│ Common Traps │ ~4KB │ Универсальные │
│ Theme Prompt │ ~3KB │ Специфичные │
└─────────────────────────────────────────────┘
1. Base Prompt — методология анализа
Это ядро системы. Здесь я описываю:
Роль модели («независимый судебный эксперт»)
Принцип нейтральности (PARTY1/PARTY2 вместо «вы» и «они»)
Калибровку по рынку (что нормально, что нет)
Формат вывода (строгий JSON)
Фрагмент:
РОЛЬ: Независимый судебный эксперт по договорному праву РФ
с 20-летним опытом.
ЗАДАЧА: Проанализируй договор, определи РЕАЛЬНЫЕ асимметричные
условия. НЕ ФЛАГОВАТЬ сбалансированные условия.
ПРИНЦИП НЕЙТРАЛЬНОСТИ:
- Констатируй факты, не защищай ни одну сторону
- PARTY1 = первая сторона в преамбуле договора
- PARTY2 = вторая сторона в преамбуле договора
- Указывай КТО в зоне риска (affectedParty)
2. Детекторы конкретных паттернов
Главный инсайт: GPT нужны конкретные инструкции, а не общие пожелания.
Вместо «найди асимметричные условия» я пишу детектор:
═══════════════════════════════════════════════════════════════
ДЕТЕКТОР АСИММЕТРИИ ПЕНЕЙ/НЕУСТОЕК
ОБЯЗАТЕЛЬНО сравни пени/неустойки для КАЖДОЙ стороны:
1. Найд�� все упоминания пени/неустойки
2. Запиши: Пеня PARTY1 = X%, Пеня PARTY2 = Y%
3. Вычисли соотношение X/Y или Y/X
⚠️ ВАЖНО: СРАВНИВАЙ ТОЛЬКО ОДНОТИПНЫЕ САНКЦИИ!
• НЕУСТОЙКА/ПЕНЯ = конкретный % за каждый день просрочки
• ОТВЕТСТВЕННОСТЬ ЗА УБЫТКИ = ограничение суммы
• ШТРАФ = фиксированная сумма
НЕ СРАВНИВАТЬ:
✗ Пеню 0,1%/день vs Ответственность "в пределах стоимости"
→ Это РАЗНЫЕ категории санкций, не "асимметрия"
ПРАВИЛА АСИММЕТРИИ:
• Если соотношение > 5:1 → CRITICAL
• Если соотношение 3:1 - 5:1 → HIGH
• Если соотношение < 3:1 → НЕ флаговать
═══════════════════════════════════════════════════════════════
Такие детекторы я написал для:
Асимметрии пеней
Размытых условий («ориентировочно», «по факту»)
Авто-приёмки («молчание = согласие»)
Vendor lock-in
KPI без гарантий поддержки
И ещё ~15 паттернов
3. Тематические промпты
Для каждого типа договора — свой набор специфичных рисков.
Пример: франшиза
═══════════════════════════════════════════════════════════════
ОБЯЗАТЕЛЬНЫЙ ДЕТЕКТОР #1: "ЛИЦЕНЗИЯ" ВМЕСТО "КОММЕРЧЕСКОЙ КОНЦЕССИИ"
!!! ГЛАВНАЯ ЛОВУШКА ВО ФРАНШИЗЕ !!!
Если договор по сути — франшиза, но назван "лицензионным",
покупатель ЛИШАЕТСЯ важных прав из Главы 54 ГК РФ:
• Субсидиарная ответственность правообладателя (ст. 1034 ГК)
• Преимущественное право на новый договор (ст. 1035 ГК)
ЧЕКЛИСТ — 4 ПРИЗНАКА КОНЦЕССИИ:
1. Товарный знак передаётся?
2. Есть бизнес-система/модель?
3. Комплексное использование?
4. Коммерческая цель?
ЕСЛИ 3+ признака = ДА, но договор назван "лицензионный" → CRITICAL
═══════════════════════════════════════════════════════════════
На данный момент у меня 31 тематический промпт:
Категория | Темы |
|---|---|
Купля-продажа | Авто, недвижимость, поставка |
Аренда | Жилая, коммерческая, лизинг |
Услуги | IT, медицина, образование, ремонт техники |
Подряд | Строительство, бытовой подряд |
Финансы | Кредит, страхование, банковские услуги |
Франшиза | Лицензия, коммерческая концессия |
Трудовые | Трудовой договор, NDA |
Прочее | Агентский, хранение, перевозка, госзакупки... |
Классификатор темы
Перед анализом нужно понять, какой это договор. Я использую keyword-based классификатор:
export function detectThemeFromKeywords(contractText: string): {
theme: ContractTheme;
confidence: number;
} {
// Ищем ключевые слова и считаем веса
// "франчайзи", "паушальный", "роялти" → franchise
// "арендодатель", "арендная плата" → rental
// ...
}
Простой подход, но работает для 90%+ договоров. Если уверенность низкая — использую general тему.
Формат вывода
Модель возвращает структурированный JSON:
{
"redFlags": [
{
"flag": "Асимметрия пеней 10:1 в пользу Подрядчика",
"danger": "CRITICAL",
"affectedParty": "PARTY1",
"favoredParty": "PARTY2",
"location": "п. 7.2",
"quote": "Заказчик уплачивает пени 1% в день...",
"legalReference": "ст. 333 ГК РФ",
"suggestion": "Требуйте симметричных условий"
}
],
"overallRisk": "CRITICAL",
"classification": {
"contractType": "B2B",
"party1Type": "LEGAL_ENTITY",
"party2Type": "INDIVIDUAL_ENTREPRENEUR"
},
"extractedPenalties": [...]
}
Это позволяет:
Показывать риски в UI с цветовой кодировкой
Фильтровать по уровню опасности
Ссылаться на конкретные пункты договора
Тестирование
Формального бенчмарка с размеченным датасетом у меня нет — для этого нужна разметка от юристов с ground truth рисками.
Но я прогнал через систему ~100 реальных договоров: свои, друзей, из открытых источников. Разные типы: аренда, подряд, франшизы, IT-услуги, поставка. На каждом итеративно правил промпты — убирал ложные срабатывания, добавлял пропущенные паттерны.
Валидация на кейсах с реальными потерями
Отдельно взял 5 историй с VC и Т-Ж, где люди реально потеряли деньги — чтобы проверить, нашла бы система те риски, которые стоили им денег:
Я воссоздал похожие договоры по описаниям из статей и прогнал через систему.
Результаты
Кейс 1: Хостел (франшиза)
Проблемы из статьи:
Лицензионный договор вместо концессии
Невозвратный паушальный взнос
Роялти от выручки
Что нашла система: 9 рисков, 7 критических
✅ Лицензия вместо концессии — нашла
✅ Невозвратный взнос — нашла
✅ Роялти от выручки — нашла
✅ Роялти при форс-мажоре — нашла (бонус)
Кейс 4: Лестница (подряд)
Главная проблема из статьи — скрытая асимметрия штрафов.
Что нашла система:
Пеня за просрочку заказчика: 1% в день
Пеня за просрочку подрядчика: 0.1% в день
→ Соотношение 10:1 → CRITICAL
Именно это стоило заказчику денег.
Сводка
Кейс | Задокументированных проблем | Найдено системой |
|---|---|---|
Хостел | 3 | 9 (включая 3 из статьи) |
IT-школа | 4 | 7 (включая 4 из статьи) |
Аренда | 7 | 9 (включая 6 из статьи) |
Лестница | 2 | 7 (включая 2 из статьи) |
Барбершоп | 3 | 8 (включая 3 из статьи) |
Система нашла все задокументированные проблемы из статей + дополнительные риски, которые авторы не упоминали.
Важно: ~100 договоров — это итеративная разработка, не формальный бенчмарк. Для честной оценки precision/recall нужен размеченный датасет с участием юристов. Пока его нет.
Грабли, на которые я наступил
1. Ложные срабатывания на симметричных условиях
Первые версии флаговали «Неустойка 0.1% в день» как риск. Но если это условие для ОБЕИХ сторон — это баланс, не риск.
Решение: добавил проверку симметричности перед флагом.
2. Сравнение разных типов санкций
Модель сравнивала «пеню 0.1%/день» с «ответственностью в пределах стоимости договора» и кричала «асимметрия!». Но это разные категории.
Решение: явно прописал в промпте, что сравнивать можно только однотипные санкции.
3. Галлюцинации на редких типах договоров
Для договора ренты с пожизненным содержанием модель выдумывала риски из договоров аренды.
Решение: добавил больше тематических промптов. Сейчас их 31.
4. Калибровка по рынку
«Предоплата 50%» — это риск или норма? «Пеня 0.1% в день» — кабальное условие или стандарт?
Без калибровки система флагует всё подряд.
Решение: добавил пороговые значения на основе ГК РФ и общепринятой практики:
ст. 333 ГК РФ — суды регулярно снижают неустойки выше 0.3-0.5% в день
ст. 395 ГК РФ — ключевая ставка ЦБ как ориентир «нормальной» пени
ст. 314 ГК РФ — «разумный срок» = 7 дней
Например, пеня 0.1% в день для B2B — это стандарт рынка, не риск. А 1% в день (365% годовых) — суды признают кабальным.
Технические детали
Модель: YandexGPT (yandexgpt-32k для длинных договоров)
Температура: 0.1 (минимум креативности, максимум точности)
Размер промпта: ~10KB (base + common + theme)
Контекст с договором: ~25KB = ~8-10K токенов
Время анализа: 15-30 секунд
Архитектура:
Upload → Classify Theme → Build Prompt → YandexGPT → Parse JSON → Store
Обработка асинхронная через BullMQ — договор может быть большим, таймауты API не резиновые.
Что дальше
Собрать датасет — нужна разметка от юристов для честного бенчмарка
Fine-tuning — возможно, дообучение на юридических текстах улучшит качество
Больше тем — есть ещё типы договоров, которые я не покрыл
Выводы
GPT из коробки не работает для специализированных задач. Нужны детальные инструкции.
Модульная архитектура — ключ к масштабированию. Base + Theme промпты позволяют добавлять новые типы договоров без переписывания всего.
Детекторы > общие инструкции. «Найди асимметрию» не работает. «Сравни пени для каждой стороны, вычисли соотношение, если >5:1 — флаг» — работает.
Калибровка по рынку критична. Без неё будет море ложных срабатываний.
Качественная проверка лучше, чем ничего. Пока нет формального бенчмарка, реальные кейсы — хороший способ валидации.
Если интересно попробовать — сервис доступен на legalparser.ru. 2 бесплатных анализа при регистрации.
Вопросы и критика — в комментариях. Особенно интересно мнение тех, кто работал с LLM для анализа документов.
