# Чанкинг документов

> Разбиение документов на фрагменты (чанки) для индексации и поиска в RAG-системах; стратегии, размеры, перекрытие и типичные ошибки.

Источник: https://llmdocs.ru/wiki/chunking/ · обновлено 2026-11-09 · лицензия CC BY-SA 4.0

- **Применение**: RAG, семантический поиск, суммаризация длинных текстов
- **Типичный размер**: 200–1000 токенов
- **Перекрытие**: 10–20% от размера чанка
- **Стратегии**: фиксированная длина, рекурсивная, по структуре, семантическая
- **Инструменты**: LangChain text splitters, LlamaIndex node parsers, Unstructured, Docling
**Чанкинг** (англ. *chunking*) — разбиение документов на небольшие фрагменты, **чанки**, которые затем по отдельности индексируются и находятся поиском. Это первый и один из самых влиятельных этапов в системах [RAG](https://llmdocs.ru/wiki/rag.md): модель отвечает на основе найденных чанков, и если нужный факт разрезан пополам или утонул в слишком большом фрагменте, качество ответа падает независимо от того, насколько хороша сама [языковая модель](https://llmdocs.ru/wiki/llm.md).[4]

## Зачем разбивать

- **Точность поиска.** [Эмбеддинг](https://llmdocs.ru/wiki/embedding.md) длинного текста усредняет много тем и плохо совпадает с конкретным вопросом; эмбеддинг короткого фрагмента выражает одну мысль.
- **Ограничения моделей.** У моделей эмбеддингов есть предел входа (часто 512–8192 [токенов](https://llmdocs.ru/wiki/tokenization.md)), а [контекстное окно](https://llmdocs.ru/wiki/context-window.md) генератора не безгранично и стоит денег.
- **Цитирование.** Маленький фрагмент можно показать пользователю как источник ответа.

Противоположная крайность — слишком мелкие чанки: они теряют контекст («он», «этот метод», «см. выше») и не содержат полного ответа. Выбор размера — компромисс между точностью поиска и полнотой фрагмента.

## Стратегии

| Стратегия | Как режет | Плюсы и минусы |
|---|---|---|
| Фиксированная длина | каждые N символов или токенов | просто, но рвёт предложения |
| Рекурсивная | по абзацам, затем предложениям, затем словам — пока кусок не влезет | хороший вариант по умолчанию |
| По структуре | по заголовкам [Markdown](https://llmdocs.ru/wiki/markdown.md) или HTML, функциям в коде, строкам таблицы | сохраняет смысловые границы |
| Семантическая | там, где резко меняется смысл соседних предложений по эмбеддингам | дороже, выигрыш нестабилен |
| Агентная / LLM | модель сама выделяет смысловые блоки | качественно, но медленно и дорого |

Рекурсивный разделитель — стандарт в библиотеках LangChain и LlamaIndex.[1][2] Для документации и вики лучше всего работает разбиение по структуре: раздел с заголовком — естественная единица смысла.

```python
from langchain_text_splitters import (MarkdownHeaderTextSplitter,
                                      RecursiveCharacterTextSplitter)

md = open("tls.md").read()
by_headers = MarkdownHeaderTextSplitter(
    headers_to_split_on=[("#", "h1"), ("##", "h2"), ("###", "h3")]
).split_text(md)

splitter = RecursiveCharacterTextSplitter(chunk_size=1200, chunk_overlap=150)
chunks = splitter.split_documents(by_headers)   # заголовки сохраняются в metadata
```

## Перекрытие и метаданные

**Перекрытие** (overlap) — соседние чанки делят 10–20% текста, чтобы факт на границе попал целиком хотя бы в один из них. **Метаданные** — источник, заголовки раздела, дата, язык — хранятся вместе с чанком: их используют для фильтрации, цитирования и для добавления в сам текст перед вычислением эмбеддинга.

## Контекст для чанка

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

- **Заголовочная цепочка** — к тексту чанка приписывается путь «Документ → Раздел → Подраздел».
- **Контекстный поиск** (contextual retrieval) — языковая модель пишет к каждому чанку одно-два предложения о его месте в документе; по данным Anthropic, это заметно сокращает число неудачных извлечений, особенно в сочетании с ключевым поиском BM25.[3]
- **Позднее разбиение** (late chunking) — эмбеддинги токенов вычисляются по всему документу длинноконтекстной моделью и только потом усредняются по чанкам.[5]
- **Родитель–потомок** — ищут по мелким чанкам, а модели отдают крупный родительский фрагмент.

## Подготовка исходников

Качество чанкинга упирается в извлечение текста. PDF с колонками, таблицами и колонтитулами превращается в кашу, если читать его наивно; инструменты вроде Docling и Unstructured восстанавливают структуру, таблицы и порядок чтения.[6] Поэтому документация, изначально написанная в Markdown, — лучший вход для RAG (см. [Markdown как формат для LLM](https://llmdocs.ru/wiki/markdown-for-llm.md) и [Документация для ИИ: как подготовить](https://llmdocs.ru/wiki/docs-for-ai.md)).

## Как подобрать параметры

Универсального размера нет. Разумный старт — 500–1000 токенов с перекрытием 10–15% и разбиением по заголовкам. Дальше параметры подбирают на наборе реальных вопросов с известными ответами, измеряя долю найденных нужных фрагментов (recall@k) — см. [Оценка LLM (evals)](https://llmdocs.ru/wiki/llm-evals.md). С ростом контекстных окон часть задач решается вообще без разбиения: небольшой корпус целиком помещают в промпт с [кэшированием](https://llmdocs.ru/wiki/prompt-caching.md).

## См. также

- [RAG (генерация с дополнением поиском)](https://llmdocs.ru/wiki/rag.md)
- [Векторный поиск](https://llmdocs.ru/wiki/vector-search.md)
- [Эмбеддинг](https://llmdocs.ru/wiki/embedding.md)
- [Markdown как формат для LLM](https://llmdocs.ru/wiki/markdown-for-llm.md)
- [llms.txt](https://llmdocs.ru/wiki/llms-txt.md)

## Источники

1. [LangChain — Text splitters](https://python.langchain.com/docs/concepts/text_splitters/)
2. [LlamaIndex — Node Parser Modules](https://docs.llamaindex.ai/en/stable/module_guides/loading/node_parsers/modules/)
3. [Anthropic — Introducing Contextual Retrieval (2024)](https://www.anthropic.com/news/contextual-retrieval)
4. [Pinecone — Chunking Strategies for LLM Applications](https://www.pinecone.io/learn/chunking-strategies/)
5. [Günther et al. — Late Chunking: Contextual Chunk Embeddings (2024)](https://arxiv.org/abs/2409.04701)
6. [Docling — документация](https://docling-project.github.io/docling/)
