
Почему разбиение на чанки может испортить хороший поиск
RAG-система отвечает на вопрос по найденным фрагментам документов. Если нужный факт оказался разрезан между двумя фрагментами, поиск может вернуть только половину контекста. Если фрагменты слишком крупные, в результат попадут лишние темы, а важный отрывок затеряется среди соседнего текста.
Поэтому настройку чанкинга нельзя свести к выбору «правильного» числа токенов. Результат зависит от структуры источников, формулировок запросов, способа поиска и лимита контекста модели. Проверять нужно не размер чанка сам по себе, а то, способен ли весь конвейер извлечь информацию, необходимую для ответа.
Этот подход полезен, если вы меняете парсер, стратегию разбиения или базу эмбеддингов и хотите понять, стало ли извлечение лучше. Ниже — воспроизводимый тест на собственных документах, без необходимости сразу запускать полноценный бенчмарк.
Как проверить чанкинг RAG на своих данных
Начните с небольшого набора документов, на которых можно вручную проверить результаты. Для каждой записи сохраните исходный текст, идентификатор документа и, если доступно, заголовки или номера разделов. Не смешивайте в одном тесте разные версии документов: иначе будет трудно понять, изменилось ли качество из-за чанкинга или из-за обновления содержания.
Составьте 20–50 вопросов, ответы на которые подтверждаются конкретными местами в документах. Для каждого вопроса отметьте:
- ожидаемый документ;
- точный фрагмент или раздел с ответом;
- минимальный контекст, необходимый, чтобы ответить корректно;
- возможные формулировки, по которым этот контекст можно найти.
Вопросы должны отражать реальные сценарии: поиск определения, значения настройки, исключения из правила, последовательности шагов и сведений, распределённых по нескольким разделам. Не ограничивайтесь вопросами, где ответ буквально повторяет ключевое слово: такой тест завышает оценку поиска.
Полезно записать эталон не только как текст, но и как ссылку на документ и диапазон символов. Для каждого запроса диапазон показывает, какие исходные слова необходимо сохранить в извлечённом контексте. Если ответ требует двух фрагментов, отметьте оба. Эта разметка помогает отличить ошибку разбиения от ошибки генерации ответа.
Что измерять: полноту контекста и качество ответа отдельно
Основная метрика для этого теста — полнота извлечения на уровне контекста: доля вопросов, для которых среди первых *k* найденных фрагментов присутствует весь размеченный материал, нужный для ответа. Например, при 30 запросах и 21 успешном извлечении полнота при выбранном *k* равна 70%.
Заранее зафиксируйте значение *k* — сколько фрагментов получает генератор ответа. Если приложение передаёт модели пять результатов, тестируйте первые пять, а не подбирайте число заново для каждой конфигурации. Дополнительно можно считать долю найденных эталонных фрагментов: если ответ требует двух частей, система, вернувшая одну из них, получает частичный результат, но не считается полностью успешной.
Не объединяйте эту оценку с качеством ответа модели. Сначала проверьте, попал ли необходимый материал в извлечённый контекст. Затем отдельно оцените, правильно ли генератор использовал найденное. Иначе неверный ответ может быть ошибочно приписан чанкингу, хотя нужный фрагмент был найден, или наоборот.
Исследования по оценке RAG, в том числе RAGAS, предлагают рассматривать качество системы через несколько отдельных измерений. Такая декомпозиция полезна и в небольшом локальном тесте: отдельно проверяйте извлечение, соответствие ответа контексту и полноту ответа. Метрики не заменяют ручной разбор ошибок, особенно если тестовый набор мал.
Сравните размеры, перекрытие и структуру документов
Для первого прогона выберите несколько вариантов разбиения. Например, сравните размер около 300, 600 и 900 токенов с перекрытием 0% и 10–15%. Это не универсальные оптимальные значения, а отправные точки для эксперимента. Если документация состоит из коротких пунктов, чанки в 900 токенов могут склеить независимые инструкции; для длинных объяснений маленькие фрагменты, напротив, способны отделить вывод от его обоснования.
Сохраняйте одинаковыми все остальные условия:
Один и тот же набор исходных документов и вопросов.
Одинаковая модель эмбеддингов и настройки поиска.
3. Одинаковое число результатов *k*.
4. Одинаковый порядок постобработки, например фильтрации по метаданным.
5. Одинаковый лимит контекста для генератора.
Если одновременно поменять размер чанка, модель эмбеддингов и стратегию поиска, причина улучшения останется неизвестной. Сначала сравните стратегии разбиения при неизменной остальной конфигурации, затем отдельно экспериментируйте с поиском.
Попробуйте также разбиение с учётом структуры: сохраняйте заголовки, не отделяйте пункт списка от пояснения и не разрезайте кодовый блок посередине. Документация LlamaIndex описывает парсеры узлов и способы деления текста, а LangChain — разные текстовые разделители. Эти инструменты дают технические варианты, но не определяют, какой из них лучше для ваших данных: ответ даст только сравнение на размеченных запросах.
Проверьте границы чанков на вопросах с несколькими частями
Отдельно выделите вопросы, для которых доказательство ответа находится на границе двух абзацев или в разных разделах. Это наиболее показательный тест на потерю контекста. Например, один раздел может задавать параметр, а следующий — описывать исключение. Если поиск возвращает только значение без условия применения, генератор способен дать формально правдоподобный, но неполный ответ.
Для таких случаев проверяйте не только совпадение текста с эталоном, но и сохранение связей: к какому заголовку относится пункт, какое условие ограничивает правило, к чему относится местоимение или сокращение. Заголовок можно добавлять к содержимому каждого чанка как метаданные или текстовый префикс. После такого изменения повторите тот же тест, не меняя запросы.
Не все системы должны возвращать единый большой фрагмент. Иногда лучше срабатывает извлечение нескольких соседних чанков, но это увеличивает объём контекста и может добавить нерелевантный текст. Сравните два варианта: поиск с фиксированным *k* и расширение найденного фрагмента соседними частями документа. Учитывайте не только полноту, но и число переданных токенов.
Минимальный воспроизводимый прогон
Для каждого варианта разбиения сохраните результаты поиска в CSV или JSONL. Достаточно записывать идентификатор вопроса, конфигурацию, ID найденных чанков, их исходный диапазон, ранг и отметку, найден ли полный эталонный контекст.
Псевдокод оценки может выглядеть так:
python
for question in test_questions:
expected = question[«required_spans»]
results = retrieve(question[«query»], k=5)
retrieved_spans = [
(item[«document_id»], item[«start»], item[«end»])
for item in results
]
success = all(
any(
doc_id == span[«document_id»]
and start <= span["start"]
and end >= span[«end»]
for doc_id, start, end in retrieved_spans
)
for span in expected
)
record(question[«id»], success, results)
В реальной реализации границы чанка могут быть несимметричными: совпадение должно покрывать нужный отрывок, а не обязательно в точности повторять его разметку. Для сложных случаев можно разрешить несколько соседних чанков совместно покрывать диапазон, но правило нужно определить до сравнения конфигураций.
После автоматической оценки вручную просмотрите все провалы и несколько успешных запросов. Классифицируйте причины: эталонный текст разорван, векторный поиск выбрал похожий раздел, парсер потерял заголовок, фильтр исключил документ или запрос неоднозначен. Разные причины требуют разных исправлений; увеличение чанка не исправит неверные метаданные или плохой поисковый запрос.
Сравните качество с ценой контекста
Меньшие чанки могут точнее попадать в тему, но повышают риск разрыва связанных мыслей и увеличивают число элементов в индексе. Крупные фрагменты сохраняют локальный контекст, но занимают больше места в окне модели. Перекрытие помогает удержать текст на границах, одновременно создавая дублирование в хранилище и среди найденных результатов.
Поэтому фиксируйте для каждой конфигурации не только полноту извлечения, но и средний объём переданного контекста, число дубликатов и задержку поиска. Если система использует платную генерацию, оцените токены запроса с найденными фрагментами на одном и том же наборе вопросов. Сравнение только по полноте может выбрать конфигурацию, которая извлекает всё, но тратит слишком много контекста.
Не объявляйте победителем вариант, который улучшил среднее значение на одном-двух вопросах. Посмотрите на разницу по типам задач и на число примеров. Если различие невелико, расширьте набор запросов, особенно для документов, которые чаще всего дают ошибки. Для небольшой внутренней базы ручной просмотр результатов иногда ценнее сложной агрегированной метрики.
Когда тест нужно обновить
Повторяйте проверку после изменения парсера, эмбеддингов, модели, фильтров, шаблона запроса или исходных документов. Зафиксируйте версии и конфигурацию вместе с результатами, иначе сравнение через месяц будет трудно воспроизвести. В тестовый набор добавляйте новые реальные ошибки, но сохраняйте прежние вопросы как контрольную выборку.
Разметка тоже не безошибочна. Если несколько независимых фрагментов могут одинаково хорошо отвечать на вопрос, отметьте допустимые варианты, а не требуйте совпадения с единственным заранее выбранным диапазоном. Для неоднозначных запросов лучше добавить уточнение или исключить их из оценки полноты, чем считать корректный альтернативный источник промахом.
Перед внедрением выберите конфигурацию, которая проходит ваши критические сценарии, затем проверьте её на свежих запросах, не использованных при настройке. Зафиксируйте *k*, размер чанка, перекрытие и долю вопросов с полным контекстом. Если сбои концентрируются на границах разделов, меняйте стратегию парсинга; если найден похожий, но неверный документ — исследуйте поиск и метаданные; если контекст найден, а ответ неверен — разбирайте уже генерацию.










