Нарезка документов для RAG: почему чанки важнее модели
Плохой ответ RAG-системы почти всегда родом не из модели, а из нарезки. Разбираем, как резать регламенты, договоры, PDF-сканы и тикеты поддержки, что ломается на корпусе из десятков тысяч длинных документов и как понять, что виновата именно нарезка.
9 мин чтения
Качество ответа решается до модели
В RAG модель отвечает только по тем кускам, которые ей принесли. Если нужный абзац не попал в выборку, никакая замена модели этого не исправит: она не знает, что чего-то не хватает, и уверенно отвечает по тому, что есть.
Поэтому диагностику стоит начинать не с промпта, а с вопроса «а был ли правильный кусок в выдаче поиска вообще». В большинстве проектов, которые мы разбирали, ответ на этот вопрос и был диагнозом.
Что именно ломает длинный документ
Корпус из десятков тысяч длинных документов ломает две вещи сразу. Первая: у длинного текста один вектор бесполезен — усреднённый смысл стостраничного регламента не похож ни на один конкретный вопрос. Вторая: чем мельче куски, тем больше их всего, и тем чаще похожие по формулировке, но разные по смыслу фрагменты вытесняют друг друга из топа.
Отсюда практический ориентир: резать по смысловым границам документа, а не по числу символов, и держать размер куска таким, чтобы он отвечал на один вопрос целиком. Перекрытие между соседними кусками нужно ровно для того, чтобы мысль не разрывалась пополам — а не «на всякий случай».
Четыре стратегии нарезки, которые действительно различаются
Разница между ними не в моде, а в том, что становится единицей смысла.
- По структуре документа — заголовки, пункты, статьи договора. Лучший вариант для регламентов и нормативки: границы уже расставлены автором.
- Скользящее окно с перекрытием — когда структуры нет: расшифровки, переписка, старые PDF без разметки.
- Родитель и потомок — ищем по мелким кускам, а в модель отдаём объемлющий раздел. Снимает конфликт «искать удобно мелким, отвечать нужно крупным».
- Отдельная нарезка таблиц — строка с заголовками столбцов рядом. Таблица, разрезанная как текст, теряет смысл полностью и при этом продолжает уверенно находиться.
Разные источники — разные правила
Единая нарезка для всего корпуса — самая частая причина того, что «в целом работает, но на половине вопросов мимо». Тип источника определяет и границы, и то, что нужно положить рядом с текстом.
- Регламенты и договоры: границы по пунктам, в метаданных — версия и дата вступления в силу, иначе система отвечает по отменённой редакции.
- Тикеты поддержки: вопрос и решение в одном куске. Разрезанные по сообщениям, они превращаются в набор реплик без ответа.
- Сканы и PDF: сначала распознавание и восстановление порядка колонок, только потом нарезка. Мусор на входе не лечится ни размером куска, ни моделью.
- Вики и база знаний продукта: страница как единица, заголовок раздела как обязательный префикс куска.
Метаданные важнее ещё одного эмбеддинга
К каждому куску стоит хранить источник, раздел, версию, дату и права доступа. Это даёт три вещи сразу: фильтрацию до векторного поиска, честную ссылку в ответе и возможность не показывать сотруднику то, что ему не положено.
Фильтр по метаданным обычно даёт больший прирост точности, чем переход на более дорогую модель эмбеддингов, и стоит несопоставимо дешевле в эксплуатации.
Как понять, что дело в нарезке
Нужен небольшой набор реальных вопросов с указанием, в каком документе лежит ответ. Дальше проверяется одно: попадает ли нужный фрагмент в топ выдачи поиска. Если попадает, а ответ всё равно плохой — проблема в промпте или модели. Если не попадает — виновата нарезка или индекс, и менять модель бессмысленно.
Такой набор из тридцати-пятидесяти вопросов собирается за день и потом окупается на каждом изменении конвейера. Без него любые правки нарезки — это спор двух мнений.