RAG chunking в n8n: как резать документы, чтобы ответы были точными ¶
Обновлено: 2026-05-29
Короткий ответ ¶
RAG chunking — это способ разделить документы на фрагменты, которые vector store сможет находить и передавать модели. В n8n chunking обычно настраивается в ingestion workflow через loader и text splitter. Хороший chunk содержит одну завершённую мысль, сохраняет заголовок и источник, не смешивает разные темы и достаточно короткий, чтобы помещаться в context window вместе с другими источниками. Плохой chunking делает RAG бесполезным: retrieval возвращает куски без ответа, модель додумывает, источники теряются, а стоимость растёт.
Почему нельзя просто загрузить документ целиком ¶
Если загрузить длинную страницу как один документ, vector store будет искать по огромному блоку. Он может вернуть фрагмент, где релевантная информация есть где-то внутри, но модель получит слишком много шума. Если нарезать слишком мелко, chunk потеряет смысл: “нажмите кнопку” без названия кнопки, “это значение” без того, что именно значение означает. Chunking — это баланс между полнотой и точностью.
Для сайта Nodbot типовые документы — playbook, runbook, diagnostics, AI guide, checklist. У них есть заголовки, таблицы, команды, JSON-примеры и FAQ. Один размер chunk для всего сайта будет работать хуже, чем стратегия по типу контента.
Базовые принципы хорошего chunk ¶
Хороший chunk:
- отвечает на один конкретный вопрос;
- содержит заголовок или путь к разделу;
- не обрывает команду, JSON или таблицу;
- имеет source_url и section_heading;
- не превышает разумный лимит символов;
- не смешивает разные интенты;
- содержит enough context, чтобы модель поняла фрагмент без всей страницы.
Плохой chunk:
- начинается с “это”, “такой”, “следующий шаг” без контекста;
- содержит половину таблицы;
- объединяет security, pricing и troubleshooting;
- не имеет metadata;
- слишком длинный и вытесняет другие источники;
- слишком короткий и не содержит ответа.
Стартовые размеры ¶
| Тип контента | Размер chunk | Overlap | Почему |
|---|---|---|---|
| FAQ | 300–700 символов | 0–100 | вопрос и ответ должны быть вместе |
| Диагностика ошибки | 800–1400 | 100–200 | симптом, причина, проверка |
| Runbook | 1000–1800 | 150–300 | шаги должны сохранять порядок |
| Tutorial | 1200–2200 | 200–350 | нужна связность действий |
| API/JSON schema | не резать внутри блока | 0 | schema должна быть целой |
| Таблица | по строкам или целиком | 0–150 | строка не должна терять заголовки |
Это стартовые значения, не догма. Проверяйте их retrieval-тестами.
Как строить ingestion workflow в n8n ¶
Практичная схема:
- Получить страницы: filesystem, HTTP Request, GitHub, CMS или sitemap.
- Очистить HTML: убрать навигацию, footer, breadcrumbs, кнопки.
- Разбить страницу на sections по H2/H3.
- Сохранить metadata: URL, title, section_heading, doc_type, language, updated_at.
- Для длинных sections применить text splitter.
- Не резать code blocks и JSON schema внутри.
- Вставить chunks в vector store с embeddings.
- Записать registry: source_id, checksum, chunk_count, indexed_at.
Главный выигрыш даёт не сам splitter, а предварительное разделение по смысловым секциям.
Пример подготовки sections ¶
const html = $json.html || '';
const url = $json.url;
const title = $json.title;
const clean = html
.replace(/<nav[\s\S]*?<\/nav>/gi, '')
.replace(/<footer[\s\S]*?<\/footer>/gi, '')
.replace(/<script[\s\S]*?<\/script>/gi, '')
.replace(/<style[\s\S]*?<\/style>/gi, '')
.replace(/<[^>]+>/g, '\n')
.replace(/\n{3,}/g, '\n\n')
.trim();
const parts = clean.split(/\n(?=#{1,3}\s+|[А-ЯA-Z][^\n]{5,80}\n)/g);
return parts
.filter(p => p.trim().length > 200)
.map((text, index) => ({
json: {
pageContent: text.trim(),
metadata: {
source_url: url,
title,
chunk_order: index,
language: 'ru',
status: 'published'
}
}
}));
Это упрощённый пример. В production лучше использовать HTML parser, чтобы аккуратно сохранять H2/H3 и code blocks.
Что делать с заголовками ¶
Заголовок должен попадать в каждый chunk. Если section называется “Почему webhook возвращает 404”, chunk без этого заголовка может выглядеть как общий текст. Добавляйте section_heading в metadata и, при необходимости, в начало pageContent:
Страница: Webhook production checklist
Раздел: Почему production URL возвращает 404
Если workflow не активирован, production URL не будет обрабатывать запросы...
Это повышает шанс, что модель правильно интерпретирует фрагмент.
Что делать с таблицами ¶
Таблицы часто ломаются при chunking. Если таблица “симптом → причина → решение” разрезана посередине, retrieval вернёт симптом без решения. Для таблиц есть три подхода:
- Хранить таблицу целиком, если она небольшая.
- Превратить каждую строку в отдельный chunk с повторением заголовков колонок.
- Сделать summary таблицы и хранить его рядом с оригиналом.
Для troubleshooting лучше второй вариант:
Таблица: Webhook errors
Симптом: 404 на production URL
Причина: workflow не активирован или URL скопирован из test mode
Решение: активировать workflow и использовать Production URL
Такой chunk хорошо находится по симптомам.
Что делать с кодом и JSON ¶
Команду, JSON schema или curl-пример нельзя резать внутри. Если блок большой, добавьте краткое описание перед ним и храните как отдельный chunk. Например:
Раздел: Пример JSON Schema для structured output
Назначение: проверяет category, priority, confidence и needs_human.
{ ... schema ... }
Если код слишком длинный, лучше хранить summary в vector store, а сам код отдавать по ссылке. RAG не должен превращать context window в архив всего проекта.
Overlap: когда нужен, а когда мешает ¶
Overlap помогает, когда фраза на границе chunk теряет контекст. Но большой overlap создаёт дубли: retrieval возвращает 5 почти одинаковых фрагментов, модель думает, что это важнее, чем есть на самом деле, и тратит токены.
Используйте overlap 10–20% от размера chunk. Для FAQ overlap почти не нужен. Для tutorials и runbooks полезен небольшой overlap, чтобы шаги не теряли связность.
Metadata для chunking ¶
Каждый chunk должен иметь:
{
"source_id": "rag_chunking_guide",
"source_url": "https://nodbot.ru/ai/rag-chunking/",
"title": "RAG chunking в n8n",
"section_heading": "Что делать с таблицами",
"chunk_id": "rag_chunking_guide#07",
"chunk_order": 7,
"doc_type": "ai_guide",
"language": "ru",
"updated_at": "2026-05-29"
}
chunk_order полезен для ответа “продолжи следующий шаг” и для debug. section_heading нужен для цитирования. doc_type нужен для фильтров.
Как понять, что chunking плохой ¶
Признаки:
- RAG часто отвечает “в документах нет информации”, хотя она есть;
- источники правильные, но фрагменты не содержат ответа;
- ответы ссылаются на старые страницы;
- top-k возвращает дубли;
- модель пересказывает заголовки, но не даёт решение;
- ответы становятся слишком общими;
- модель смешивает две инструкции из разных разделов;
- пользователи задают follow-up “а как именно?”.
Это не всегда проблема модели. Часто проблема в том, что chunk не содержит complete answer.
Retrieval evaluation ¶
Сделайте dataset вопросов и ожидаемых chunks:
| question | expected_source_id | expected_section |
|---|---|---|
| Почему webhook production URL даёт 404? | webhook_production | 404 production URL |
| Как проверить Redis в queue mode? | queue_mode | Redis unavailable |
| Почему RAG отвечает устаревшей инструкцией? | metadata_design | freshness |
Запускайте retrieval без generation и проверяйте, попал ли нужный source в top-3/top-5. Если retrieval не нашёл правильный chunk, prompt не спасёт.
Generation evaluation ¶
После retrieval проверяйте финальный ответ:
- отвечает ли на вопрос;
- использует ли источник;
- не добавляет ли факты вне источника;
- говорит ли “не найдено”, когда источника нет;
- цитирует ли правильный URL;
- не смешивает ли старую и новую версию.
RAG quality = retrieval quality × generation discipline. Оба множителя нужны.
FAQ ¶
Какой размер chunk выбрать для начала? ¶
Для практических статей начните с 1000–1500 символов и overlap 150–250. Для FAQ меньше, для tutorials больше. Затем проверьте retrieval dataset.
Нужно ли резать по словам или по заголовкам? ¶
Сначала по заголовкам и смысловым блокам, потом по размеру. Резка только по символам часто ломает таблицы и инструкции.
Что делать с короткими страницами? ¶
Не дробить. Если страница сама 500–800 слов и хорошо структурирована, можно хранить её как 1–3 chunks по H2.
Почему RAG возвращает одинаковые chunks? ¶
Слишком большой overlap, дубли страниц, одинаковые шаблонные абзацы или отсутствие deduplication. Уменьшите overlap и уберите boilerplate до индексации.
Можно ли менять chunking без переиндексации? ¶
Нет. Chunking применяется при загрузке документов. После изменения стратегии нужно переиндексировать affected sources и обновить registry.