📝 LLM и AI

Нарезка документов на чанки для RAG

P
Автор
Pyland
📅
Опубликовано
30.06.2026
⏱️
Время чтения
1 мин
👁️
Просмотров
103
📊
Уровень
Статья
🐦 💼 ✈️

Эмбеддинг длинного текста усредняет смыслы — конкретный вопрос не найдёт нужный абзац. Решение: нарезать документ на чанки и индексировать каждый отдельно.

Базовая нарезка с перекрытием

def chunk_text(text: str, chunk_size: int = 500, overlap: int = 50) -> list[str]:
    """Нарезает текст на чанки с перекрытием."""
    chunks = []
    step = chunk_size - overlap  # шаг меньше размера → перекрытие
    start = 0

    while start < len(text):
        end = start + chunk_size
        chunks.append(text[start:end])
        start += step

    return chunks

Пример:
- chunk_size=500, overlap=50step=450
- Чанк 1: символы 0–500
- Чанк 2: символы 450–950
- Чанк 3: символы 900–1400

Перекрытие гарантирует что смысл на границе чанка не теряется.

Почему нельзя один большой чанк

# ❌ Плохо: весь документ как один чанк
collection.add(documents=[full_text], ids=["doc"])
# Эмбеддинг = среднее всех смыслов → поиск неточный

# ✅ Хорошо: нарезать на куски
chunks = chunk_text(full_text)
collection.add(
    documents=chunks,
    ids=[f"doc_chunk_{i}" for i in range(len(chunks))]
)

Метаданные для трассировки

def chunk_document(text: str, source: str, chunk_size=500, overlap=50) -> list[dict]:
    chunks = chunk_text(text, chunk_size, overlap)
    return [
        {
            "text": chunk,
            "id": f"{source}_chunk_{i}",
            "metadata": {
                "source": source,
                "chunk_index": i,
                "total_chunks": len(chunks)
            }
        }
        for i, chunk in enumerate(chunks)
    ]

Загрузка папки с документами

from pathlib import Path

def load_documents(folder: str) -> list[dict]:
    docs = []
    for path in Path(folder).iterdir():
        if path.suffix in (".txt", ".md"):
            text = path.read_text(encoding="utf-8")
            docs.extend(chunk_document(text, source=path.name))
    return docs

Параметры нарезки

chunk_size overlap Когда использовать
200–300 20–30 Точный поиск по коротким фактам
500–800 50–100 Баланс (большинство случаев)
1000–2000 100–200 Длинные рассуждения, контекст

Слишком маленький чанк теряет контекст. Слишком большой — размывает смысл.

Ваша реакция на статью

💬 Комментарии (0)

🔐 Войдите в систему, чтобы оставить комментарий
🚪 Войти
💭

Комментариев пока нет

Станьте первым, кто поделится мнением об этой статье!

🔗 Похожие

Похожие статьи

Продолжите изучение с этими материалами

📝

httpx: современный HTTP-клиент для Python

httpx — HTTP-клиент нового поколения. Интерфейс похож на requests, но с поддержкой async/await из коробки.

📅 30.06.2026 👁️ 108
📝

AI-агенты: ReAct loop и автономные действия

Чат-бот отвечает на вопросы. Агент — действует: вызывает инструменты, получает реальные данные и использует их...

📅 30.06.2026 👁️ 103
📝

Typer: CLI-приложения без boilerplate

Typer создаёт CLI из аннотаций типов Python. Никаких argparse, никакого ручного парсинга — только декораторы...

📅 30.06.2026 👁️ 88

Понравилась статья?

Подпишитесь на наши обновления и получайте новые статьи первыми. Развивайтесь вместе с PyLand!