Урок курса
Чанкинг для RAG: размер чанка и overlap
Vector DB & RAG DeveloperЧанкинг — разбиение документа на фрагменты перед вычислением эмбеддингов. От границ чанка зависит, сможет ли поиск вернуть точный ответ вместе с необходимым контекстом.
Почему нельзя индексировать документ целиком
Один вектор для длинного документа усредняет сразу несколько тем. Вопрос про конкретный пункт договора может оказаться близок к документу в целом, но модель получит десятки нерелевантных страниц. Слишком маленькие чанки дают обратную проблему: нужная фраза находится, но определение, условие или заголовок остаётся в соседнем фрагменте.
Базовые параметры:
- chunk size — максимальный размер фрагмента в токенах или символах;
- overlap — часть текста, повторяющаяся между соседними чанками;
- separator — предпочтительные границы: раздел, абзац, предложение, пробел.
Универсального числа нет. Для FAQ подойдут короткие фрагменты, для юридических условий и технических инструкций часто нужен больший контекст.
Стратегии разбиения
Фиксированный размер прост и быстр, но может разрезать мысль посередине. Recursive splitting сначала пытается делить по заголовкам и абзацам, затем по предложениям и только потом по символам. Это хороший baseline для обычного текста.
Структурный чанкинг учитывает Markdown-заголовки, HTML, страницы PDF, функции в коде или строки таблицы. Семантический чанкинг ищет изменение темы по эмбеддингам предложений, но требует больше вычислений и сложнее отлаживается.
В parent-child схеме поиск идёт по маленьким дочерним фрагментам, а в контекст возвращается более крупный родительский блок. Так точность retrieval сочетается с целостным контекстом.
Overlap страхует границы, но его избыток создаёт дубликаты в top-k, увеличивает индекс и стоимость. Начинать разумно с небольшого overlap, а не с половины чанка.
Как подобрать размер экспериментально
Соберите 30–100 реальных вопросов и отметьте фрагменты, в которых лежит ответ. Затем сравните несколько конфигураций на одинаковой embedding-модели: например, короткие, средние и крупные чанки с разным overlap.
Смотрите не только Recall@k. Проверяйте дубли, среднее число токенов в контексте и качество финального ответа. Если нужный чанк находится, но модель не понимает его без соседнего раздела, увеличьте контекст или примените parent-child. Если top-k заполнен похожими копиями, уменьшите overlap либо добавьте дедупликацию.
Сохраняйте в metadata заголовок раздела, путь документа, страницу и идентификатор родителя. Эти поля пригодятся для фильтрации, цитирования и восстановления расширенного контекста.
Хороший чанкинг — не тот, где выбран популярный размер, а тот, который стабильно возвращает доказательство на вашем тестовом наборе.
Проверяем границы чанков на коротком тексте
Начать можно с простого разбиения по словам и overlap в два слова. Это учебный splitter, а не токенизатор LLM: реальные лимиты модели измеряются её токенами. Код показывает, какие слова повторяются и как убедиться, что последний фрагмент не пропал.
def chunks_by_words(text, size=6, overlap=2):
if not 0 <= overlap < size:
raise ValueError("Нужно 0 <= overlap < size")
words = text.split()
out = []
for start in range(0, len(words), size-overlap):
out.append(" ".join(words[start:start+size]))
if start+size >= len(words):
break
return out
text = "Возврат товара возможен в течение четырнадцати дней после покупки при сохранении чека"
parts = chunks_by_words(text)
print(parts)
assert parts[0].split()[-2:] == parts[1].split()[:2]
assert parts[-1].endswith("чека")
Посмотрите, в какой фрагмент попали срок и условие сохранения чека. Если retrieval вернул только первую часть, ответ может потерять ограничение. Для реального документа сохраняйте заголовок и идентификатор родителя, размечайте несколько контрольных вопросов и сравнивайте качество при разных границах. Увеличение overlap повторяет текст и не гарантирует правильный ответ.
Продолжите разбор: Метрики качества RAG: Recall, MRR и Faithfulness.
Задача 1
Какое преимущество даёт parent-child чанкинг?
Продолжить с сохранением прогресса
Перейдите к уроку в учебном кабинете.
