Загрузчики документов и сплиттеры
Урок про первый шаг RAG: превратить файлы в управляемые куски текста.
Chunk (чанк) — небольшой фрагмент документа, на которые текст режут перед индексацией для поиска.
Зачем загрузчики и сплиттеры
Чтобы модель отвечала по вашим данным, эти данные надо сначала загрузить и нарезать. DocumentLoader читает источник (PDF, веб-страницу, CSV, Markdown) и возвращает список объектов Document с текстом и метаданными. Но целый документ слишком велик для контекста и для точного поиска, поэтому его режут на чанки сплиттером.
Почему именно чанки
Если искать по целым документам, в контекст модели попадёт много лишнего, а релевантный кусок «размоется». Маленькие чанки дают точечное попадание. Но слишком мелкие теряют смысл. Отсюда два параметра: chunk_size (размер куска) и chunk_overlap (нахлёст соседних кусков, чтобы не разрезать мысль на границе).
from langchain_text_splitters import RecursiveCharacterTextSplitter
splitter = RecursiveCharacterTextSplitter(
chunk_size=500,
chunk_overlap=50,
)
chunks = splitter.split_documents(documents)Принцип нарезки с нахлёстом легко показать на чистом Python:
def split(text, size, overlap):
chunks, start = [], 0
while start < len(text):
chunks.append(text[start:start + size])
start += size - overlap
return chunks
parts = split("abcdefghijklmno", size=6, overlap=2)
for p in parts:
print(p)Вывод:
abcdef efghij ijklmn mno
Как работает под капотом
RecursiveCharacterTextSplitter режет текст не вслепую: он пробует разбивать по «крупным» разделителям сначала (абзацы, затем строки, затем предложения, затем слова), стараясь не рвать смысловые единицы. Нахлёст chunk_overlap повторяет конец предыдущего чанка в начале следующего — так фраза, попавшая на стык, целиком окажется хотя бы в одном чанке. Хорошая нарезка напрямую влияет на качество будущего поиска: мусорные границы дают мусорные ответы.
Частые ошибки
- Слишком большие чанки. Поиск теряет точность, в контекст лезет лишнее.
- Нулевой overlap на связном тексте. Мысль рвётся на границе, и ни один чанк её не содержит целиком.
- Игнорировать метаданные. Источник и страница в
metadataпригодятся для ссылок в ответе.
Итог
- Загрузчик превращает источник в
Documentс текстом и метаданными. - Сплиттер режет документы на чанки для точного поиска.
- Ключевые параметры —
chunk_sizeиchunk_overlap. RecursiveCharacterTextSplitterстарается не рвать смысловые единицы.