Сравнение документов нейросетью: найти смысловые отличия версий
Совмещаем обычный дифф по тексту и смысловой разбор модели, чтобы увидеть, какие правки меняют условия, а какие косметические. Код, формат отчёта и цена.
5 мин · · автоматизация · бизнес
Нейросеть для сравнения документов решает проблему, с которой не справляется обычный редактор: он показывает все изменения подряд, а вам нужно понять, какие из них меняют смысл. Переставленный абзац, исправленная запятая и новый срок оплаты выглядят в диффе одинаково. Рабочая схема из двух шагов: скрипт точно находит, что изменилось, а модель объясняет, что это значит. Ниже код на Python, формат отчёта и расчёт стоимости. Для анализа документов в целом такой подход тоже годится: сначала надёжно извлекаем факты, потом просим интерпретацию.
Почему не просто «сравни два файла»
Можно отправить модели обе версии и попросить найти различия. Для небольших текстов это работает, но есть риски:
- модель может пропустить мелкое изменение, например цифру в сумме или одно слово «не»;
- она может «найти» изменение, которого нет;
- результат нельзя воспроизвести и проверить построчно.
Поэтому факты об изменениях берём из алгоритма (он детерминирован и ничего не придумывает), а модели отдаём только интерпретацию найденных фрагментов. Это дешевле и надёжнее.
Шаг 1. Дифф по тексту
В стандартной библиотеке Python есть difflib. Разобьём документы на абзацы и найдём изменённые блоки:
import difflib
def load_paragraphs(path: str) -> list[str]:
text = open(path, encoding="utf-8").read()
return [p.strip() for p in text.split("\n\n") if p.strip()]
def changed_blocks(old: list[str], new: list[str]):
matcher = difflib.SequenceMatcher(a=old, b=new, autojunk=False)
blocks = []
for tag, i1, i2, j1, j2 in matcher.get_opcodes():
if tag == "equal":
continue
blocks.append({
"тип": {"replace": "изменено", "delete": "удалено", "insert": "добавлено"}[tag],Если ваши документы в Word или PDF, сначала извлеките текст (способы разобраны в статье извлечение структурированных данных из документов). Для сканов сначала понадобится распознавание текста.
Важно: сравнение по абзацам подходит для текстов с одинаковой структурой. Если в новой версии абзацы объединили или разбили, дифф покажет их как «изменено», и модель разберёт это по смыслу.
Шаг 2. Прикидываем размер запроса
Перед отправкой полезно посчитать токены. Для Anthropic-формата есть отдельный метод подсчёта токенов, см. описание count_tokens:
import json
import anthropic
claude = anthropic.Anthropic(base_url="https://api.zukko.pro", api_key="fetch_ваш_ключ")
payload = json.dumps(blocks, ensure_ascii=False)
count = claude.messages.count_tokens(
model="claude-sonnet-5-5",
messages=[{"role": "user", "content": payload}],
)
print("токенов в блоках изменений:", count.input_tokens)Обратите внимание: у Anthropic SDK адрес указывается без /v1, SDK добавляет путь сам.
Шаг 3. Смысловой разбор модели
Передаём блоки изменений и просим для каждого оценить влияние. Используем OpenAI SDK для Python:
import json
from openai import OpenAI
client = OpenAI(base_url="https://api.zukko.pro/v1", api_key="fetch_ваш_ключ")
SYSTEM = """Тебе даны блоки изменений между двумя версиями документа: было / стало.
Для каждого блока верни объект JSON:
{"номер": N, "суть": "что изменилось одной фразой",
"категория": "срок|сумма|ответственность|стороны|порядок действий|терминология|редакционная правка|другое",
"влияние": "высокое|среднее|низкое|нет",
"комментарий": "почему это важно, только по тексту блока"}
Не добавляй выводов, которых нет в тексте блока. Не давай юридических оценок законности.
Ответ: JSON-массив, без пояснений."""
Сортировка по влиянию выводит наверх правки, которые читать нужно первыми. Если JSON ответа окажется невалидным, оберните json.loads в try, как в статье про структурированный JSON-ответ.
Формат отчёта
Для людей удобна таблица. Пример строки итогового отчёта:
| № | Раздел | Было | Стало | Категория | Влияние |
|---|---|---|---|---|---|
| 3 | Оплата | 10 рабочих дней | 5 рабочих дней | срок | высокое |
| 7 | Определения | «Заказчик» | «Покупатель» | терминология | среднее |
| 12 | Реквизиты | запятая после города | без запятой | редакционная правка | нет |
Добавьте в отчёт номер блока и цитату «было / стало», чтобы человек находил место за несколько секунд.
Что проверяет человек
- Все блоки с высоким и средним влиянием, а лучше весь отчёт целиком.
- Блоки, где модель пишет «нет влияния»: убедитесь, что она не пропустила смысл за косметикой.
- Перестановки: если абзац переехал в другой раздел, смысл мог измениться из-за контекста.
- Юридическую силу изменений: модель описывает различия, но не оценивает их законность. Для договоров с реальными последствиями покажите отчёт юристу. Похожий подход к анализу есть в статье анализ договоров с помощью ИИ.
Сколько стоит сравнение
Цены на 18 октября 2026, $ за 1M токенов (вход / выход): claude-sonnet-5-5 0.4 / 2, claude-opus-5-5 0.8 / 4, gpt-6.1-sol 0.27 / 1.32.
Пример: два договора по 15 000 токенов, изменённых блоков набралось на 4 000 токенов входа вместе с инструкцией, отчёт 1 500 токенов. Запрос через OpenAI-формат, без кэша. Формула: (вход × цена входа + выход × цена выхода) / 1 000 000.
Вариант А, только изменённые блоки (рекомендуемый):
claude-sonnet-5-5: 4 000 × 0.4 + 1 500 × 2 = 1 600 + 3 000 = 4 600, то есть $0.0046gpt-6.1-sol: 4 000 × 0.27 + 1 500 × 1.32 = 1 080 + 1 980 = 3 060, то есть $0.00306
Вариант Б, обе версии целиком (30 000 токенов) и просьба найти отличия:
- вход: 30 000 + 500 инструкции = 30 500 токенов
claude-sonnet-5-5: 30 500 × 0.4 + 1 500 × 2 = 12 200 + 3 000 = 15 200, то есть $0.0152claude-opus-5-5: 30 500 × 0.8 + 1 500 × 4 = 24 400 + 6 000 = 30 400, то есть $0.0304
Вариант А дешевле примерно втрое на этих допущениях и надёжнее по точности. Для сотни пар документов в месяц вариант А на claude-sonnet-5-5 даёт 100 × 0.0046 = $0.46. Хватит ли средней модели для ваших договоров, проверьте на нескольких парах с известными изменениями. Актуальные цены: GET https://api.zukko.pro/v1/models или страница «Модели» в кабинете.
Чтобы попробовать, создайте ключ в кабинете и сравните две версии любого неконфиденциального документа.
Частые вопросы
Достаточно ли просто отправить модели две версии целиком?
Для коротких текстов возможно, но модель может пропустить мелкую правку или выдумать несуществующую. Надёжнее найти изменения алгоритмом и отдать модели только интерпретацию.
Подойдёт ли метод для PDF и Word?
Да, если сначала извлечь из них текст. Для сканов нужно распознавание. Следите, чтобы нумерация и таблицы не потерялись при извлечении.
Можно ли доверять оценке «нет влияния»?
Проверяйте выборочно. Модель может принять смысловую правку за редакционную, поэтому важные документы читайте целиком по отчёту.
Не опасно ли отправлять договоры в модель?
Отправляйте только то, что вправе передавать внешнему сервису. Персональные данные и коммерческую тайну обезличивайте. Решение о допустимости принимает ваша организация.
zukko
Платите в 25×
меньше
за Claude Code & ChatGPT
Один ключ fetch_* и base URL api.zukko.pro — в Cursor, Claude Code, Codex и любом SDK.
Похожие статьи
- Нейросеть для тестировщика: тест-кейсы, чек-листы и баг-репортыКак QA-инженеру использовать модель для тест-кейсов, чек-листов и баг-репортов, проверять полноту покрытия и не получить придуманные требования.
- Обезличивание данных перед отправкой в нейросеть: практический подходПерсональные данные не нужно отправлять модели, чтобы она обработала документ. Показываем, как заменять их метками, возвращать в ответ и проверять, что ничего не просочилось.
- Нейросеть для HR: вакансии, письма кандидатам и разбор резюмеМодель может готовить черновики вакансий и писем и делать первичный разбор резюме. Разбираем, что отдавать, как работать с персональными данными кандидатов и как не допустить предвзятых решений.
- Генерация FAQ нейросетью: вопросы из обращений и ответы по базе знанийХороший FAQ строится на том, что клиенты правда спрашивают. Показываем пайплайн: группируем обращения, отвечаем по базе знаний со ссылкой на источник и проверяем результат.