LLM API и интеграция

Как разбить документ на части для нейросети

Как разбить документ на части для нейросети

Документ делят на части по одному из трёх принципов: по структуре самого документа, по смысловым блокам или по фиксированному размеру с перекрытием. Деление по структуре почти всегда даёт лучший результат, фиксированный размер берут только там, где структуры нет вовсе, а рабочая точка отсчёта — 500–1000 токенов на кусок при перекрытии 10–15 %. Дальше размер подбирается замером на своих вопросах.

Задача обычно формулируется одним из двух способов: документ не влезает в запрос или влезает, но ответы по нему стали хуже, чем по короткому фрагменту. Лечится это одинаково — материал делят и подают модели порциями. Ниже: чем способы деления отличаются, что ломается на границах кусков, как это чинят и как убедиться, что стало лучше, а не хуже.

Когда документ пора делить

Три признака, каждого по отдельности достаточно.

Запрос не проходит. Сервер возвращает ошибку о превышении длины. Тут вариантов нет.

Ответы стали поверхностными. Модель отвечает общими словами, пропускает детали из середины файла, путает похожие пункты. Это отдельный эффект со своими причинами: почему модель тупеет на больших документах.

Дорого. Документ едет в модель целиком при каждом вопросе. Десять уточнений по договору на двадцать страниц — это двести тысяч входных токенов вместо двадцати. Что именно уезжает в запросе, разобрано в статье что такое контекстное окно.

Три способа деления и когда какой подходит

СпособКогда подходитГлавный риск
По структуре документаЕсть разделы, статьи, пункты, заголовкиРаздел сам по себе слишком велик
По смысловым блокамСтруктура формальная или отсутствует, но темы различимыГраницу определяет человек или модель — дорого и непостоянно
Фиксированный размер с перекрытиемСтруктуры нет: стенограмма, чат, слитый текстРежет по живому, не глядя на содержание

Порядок выбора простой: сначала пробуют структуру, при её отсутствии — смысловые блоки, фиксированный размер остаётся запасным вариантом. На практике чаще всего получается гибрид: делим по разделам, а слишком крупные разделы дорезаем фиксированным размером.

Деление по структуре документа

Лучший вариант, когда он доступен, потому что границы кусков совпадают с границами мысли автора.

Что берут за границу: статью договора, пункт регламента, раздел инструкции, подзаголовок статьи, ячейку «вопрос — ответ» в справочнике. Для кода — функцию или класс, а не строки.

Что это даёт: кусок отвечает на вопрос целиком и не требует соседей. Пункт 4.2 договора — это законченная норма, её можно показать модели одну и получить корректный ответ.

Где ломается: когда раздел объёмный сам по себе. Статья на пятнадцать страниц — это уже не кусок, а документ. Её дорезают внутренними подзаголовками или абзацами, сохраняя в каждом куске указание на родительскую статью.

Деление по смысловым блокам

Применяют там, где формальная структура не отражает содержания: протоколы совещаний, интервью, длинная переписка, расшифровки.

Границу проводят по смене темы, а не по абзацу. Обсуждение бюджета закончилось, началось обсуждение сроков — здесь граница.

Стоит учитывать цену: если границы расставляет модель, вы платите за прочтение всего документа ради разметки. Разово это оправданно, на потоке из тысяч документов — считайте отдельно. Разметка через дешёвую позицию за 1 ₽ или 3 ₽ за миллион токенов обходится в копейки на документ, но умножается на тираж.

Второй недостаток: результат непостоянен. Одна и та же модель на одном и том же файле может расставить границы чуть иначе, а значит, повторный прогон даст другую базу.

Фиксированный размер с перекрытием

Механический способ: режем каждые N токенов, соседние куски перекрываются на M токенов.

Работает без всякого понимания документа и потому применим везде. Ровно поэтому же он и режет по живому: граница попадает в середину предложения, таблицы, определения.

Перекрытие — способ снизить ущерб. Если последние 15 % первого куска повторяются в начале второго, предложение с границы целиком присутствует хотя бы в одном месте. Платите вы за это объёмом хранения и небольшим дублированием при выдаче.

Точка отсчёта: 500–1000 токенов на кусок, перекрытие 10–15 %. Дальше подбирается под материал. Плотный юридический текст режут мельче, повествовательный — крупнее. Про подсчёт объёма в токенах: как считать токены.

Что ломается на границе куска

Четыре типовых дефекта. Все четыре в ответе выглядят как галлюцинация модели, хотя на деле это дефект подготовки данных.

Таблица, разрезанная пополам. Шапка осталась в первом куске, строки — во втором. Модель, получившая второй кусок, видит колонку чисел без названий колонок и честно пытается их интерпретировать. Результат — уверенно сформулированная выдумка.

Пункт, потерявший заголовок раздела. Текст «срок составляет 10 рабочих дней» без родительского заголовка «Возврат товара» применим к чему угодно. Модель подставит контекст из вопроса, а не из документа.

Ссылка «см. выше», указывающая в другой кусок. Отсылки вида «в порядке, предусмотренном пунктом 3.1», «как указано выше», «см. приложение 2» внутри куска превращаются в тупик.

Определение, оторванное от употребления. Термин определён в начале документа, используется на двадцатой странице. Кусок с употреблением не содержит определения, и модель подставляет общепринятое значение вместо договорного.

Отдельная категория — сканы и PDF с колонками, где текст вообще извлекается в неверном порядке ещё до всякого деления. Это чинится раньше: как обработать PDF через API и как подготовить данные для нейросети.

Как это чинят

Три приёма, которые закрывают почти все перечисленные дефекты.

Метаданные куска. К каждому куску прикладывается служебная шапка: источник, редакция, раздел, номер пункта, дата. Она стоит десятки токенов и снимает половину проблем — модель видит, откуда фрагмент, и может это процитировать.

Повтор заголовков. В начало каждого куска дописывается цепочка родительских заголовков: «Договор поставки № 12 → Раздел 4. Ответственность сторон → 4.2». Кусок перестаёт быть безымянным обрывком.

Перекрытие. Описано выше. Работает против разрезанных предложений, не работает против разрезанных таблиц.

Для таблиц приём отдельный: таблицу не режут, а либо кладут целиком одним куском, либо разворачивают в строки формата «поле: значение», где каждая строка самодостаточна. Если таблица не влезает целиком, в каждый кусок повторяют шапку.

Для ссылок «см. выше» — либо разворачивают отсылку в текст при подготовке, либо кладут в метаданные номера связанных пунктов, чтобы поиск мог подтянуть их вместе.

Какого размера делать куски

Ответ зависит от того, что вы делаете с кусками дальше.

Если куски ищутся поиском и подставляются в запрос по нескольку штук — мельче лучше: точнее попадание, меньше мусора в окне. Конструкция целиком разобрана в статьях поиск по своей базе и эмбеддинги и rerank.

Если куски обрабатываются подряд, по одному, и результаты потом сводятся — крупнее лучше: меньше проходов, меньше швов, дешевле.

Общее правило одно: кусок должен отвечать на вопрос без соседей. Если для понимания фрагмента нужно заглянуть в предыдущий — граница проведена неверно.

Как проверить, что деление не испортило ответы

Это обязательный шаг, и делается он до перехода, а не после жалоб.

  1. Соберите список вопросов с известными ответами. Двадцать-тридцать штук, ответы на которые вы знаете сами. Обязательно включите вопросы к серединам документа, к таблицам и к пунктам со ссылками «см. выше».
  2. Прогоните их по целому документу. Запишите ответы дословно. Это база «до». Без неё сравнивать не с чем.
  3. Прогоните тот же список после деления. Та же модель, тот же промпт, те же вопросы.
  4. Сравните построчно. Смотрите не на «похоже», а на три вещи: факт совпал, факт потерян, факт выдуман.
  5. Разберите расхождения по причине. Потерянный факт — нужный кусок не дошёл. Выдуманный — кусок дошёл оборванным.

Один и тот же набор вопросов прогоняется потом при каждом изменении размера куска или способа деления. Общая методика замеров разобрана в статье как тестировать нейросеть.

Такой прогон дёшев. Тридцать вопросов по документу на двадцать страниц — это порядка миллиона входных токенов в варианте «целиком» и заметно меньше в варианте с кусками. На позиции за 1 ₽ за миллион оба прогона обходятся в несколько рублей. В KeyDealer один ключ открывает весь каталог — 57 позиций в живой выдаче, 44 доступны, — поэтому замер «до и после» делается на той же модели, что и в бою, без отдельного стенда и без второй интеграции.

Частые ошибки при делении

Резать по количеству символов вместо токенов. Граница уезжает непредсказуемо, а на русском тексте и на коде расхождение доходит до полутора раз.

Выбрасывать метаданные ради экономии. Шапка куска стоит десятки токенов и экономит часы разбирательств, почему модель сослалась не на тот пункт.

Делить один раз и забыть. Документ обновился — куски устарели. Редакцию кладут в метаданные и переделывают деление вместе с исходником.

Менять сразу размер куска, перекрытие и промпт. Тогда непонятно, что именно повлияло. Меняется один параметр за прогон.

Проверять на вопросах, ответы на которые никто не знает. Контрольный список должен состоять из вопросов с заранее известным ответом, иначе сравнивать нечего.

Чего мы не утверждаем

Универсального размера куска нет. Числа выше — точка отсчёта для первого прогона, а не рекомендация. Проверяется на ваших данных и ваших вопросах.

Деление не лечит плохой исходник. Если текст извлечён из скана с ошибками, любые границы кусков будут проведены по мусору.

Скидку за кэш не обещаем. В живой выдаче каталога prompt_cache.status у текстовых позиций стоит unsupported — это «не подтверждено», а не «точно не работает».

Что нужно, чтобы попробовать

Ключ заводится за минуту на keydealer.ru/login — почта и пароль, без документов и без зарубежной карты. Оплата российской картой в рублях, один ключ на весь каталог.

Ставки и статусы видны в GET /v1/models без ключа и без регистрации. Пять текстовых позиций с нулевой ставкой открываются после первого платного пополнения и дальше не тарифицируются — на них удобно гонять список контрольных вопросов, пока подбираете размер куска.

Что держать в голове

Структура документа — лучшая граница из возможных. Механическое деление по размеру берут тогда, когда структуры нет, а не потому, что так проще написать код.

Дефекты деления не выглядят как ошибки деления. Они выглядят как выдумки модели: разрезанная таблица, осиротевший пункт и повисшая ссылка дают уверенный неверный ответ, а не сообщение о проблеме.

Любое изменение в делении проверяется одним и тем же списком вопросов с известными ответами, прогнанным до и после. Всё остальное — ощущения, которые через неделю превращаются в спор без фактов.

Как мы проверяем факты и что храним из запросов — на странице о проекте и в llms.txt. Собрать свой замер: keydealer.ru/login.

Частые вопросы

Зачем вообще делить документ, если он помещается в окно?

Потому что помещается и работает — разные вещи. На длинном вводе модель хуже находит детали в середине, и точечный вопрос по нужному разделу часто даёт более полный ответ, чем тот же вопрос по всему файлу.

Какого размера делать куски?

Начинайте с 500–1000 токенов на кусок при перекрытии около 10–15 %. Это рабочая точка отсчёта, а не универсальное число: под таблицы и договоры размер подбирают отдельно и проверяют замером.

Какой способ деления выбрать?

Если у документа есть разделы, пункты или статьи — делите по ним. Фиксированный размер с перекрытием берут только там, где структуры нет: стенограммы, переписка, слитый текст без заголовков.

Что чаще всего ломается при делении?

Таблица, разрезанная между кусками, пункт, потерявший заголовок своего раздела, и ссылка «см. выше», которая указывает в соседний кусок. Все три дефекта выглядят как галлюцинация модели.

Зачем нужно перекрытие кусков?

Чтобы предложение или мысль, попавшая на границу, целиком присутствовала хотя бы в одном куске. Перекрытие увеличивает объём хранения, но дешевле, чем потерянный на стыке факт.

Как понять, что деление не испортило ответы?

Прогнать один и тот же список вопросов с известными ответами до и после деления и сравнить построчно. Без замера «до» любое сравнение превращается в ощущение.

Источники