Диагностика RAG-сценариев n8n: индексы, чанки и поиск ¶
Обновлено: 2026-05-29
Короткий ответ ¶
Если RAG в n8n не находит правильные ответы, проверяйте не только модель, а весь pipeline: ingestion документов, chunking, embedding model, vector store, metadata, retrieval settings и финальный prompt. Частая причина — документы загружены, но chunks слишком большие, без заголовков, без metadata или были проиндексированы одной embedding model, а ищутся другой. Для диагностики нужен контрольный набор вопросов: ожидаемый документ, ожидаемый chunk, top-k, confidence и финальный ответ с источником. Без такого набора RAG “кажется плохим”, но непонятно, сломан поиск, контекст или генерация.
Быстрая развилка по симптомам ¶
| Симптом | Вероятная причина | Что проверить первым |
|---|---|---|
| RAG не находит очевидный документ | ingestion не загрузил текст или не тот collection | список документов в vector store |
| Возвращаются похожие, но не те chunks | плохой chunking или нет metadata filter | размер chunks, overlap, source |
| Ответ без источников | prompt не требует citations или metadata не передана | include metadata и финальный шаблон |
| После обновления базы ответы старые | нет переиндексации или дубли chunks | doc_id, version, delete/update |
| Результаты стали хуже после смены модели | embedding model не совпадает | модель при insert и retrieve |
| Дорого и медленно | слишком большой top-k или длинные chunks | top-k, chunk size, rerank |
Шаг 1. Разделите ingestion и answering workflow ¶
Самая частая архитектурная ошибка — пытаться загружать документы и отвечать пользователю в одном workflow без контроля версий. Лучше разделить два процесса.
Ingestion workflow:
- получить документ;
- очистить HTML/Markdown/PDF-текст;
- нарезать на chunks;
- добавить metadata;
- создать embeddings;
- записать в Qdrant/Supabase/PGVector/Simple Vector Store;
- сохранить
doc_id,version,source_url, дату индексации.
Answering workflow:
- получить вопрос;
- нормализовать запрос;
- выполнить retrieval;
- проверить найденные chunks;
- передать контекст в LLM;
- вернуть ответ с источниками или fallback.
Так проще понять, где ошибка: на этапе загрузки, поиска или генерации ответа.
Шаг 2. Проверьте, что документы реально проиндексированы ¶
Перед настройкой prompt убедитесь, что vector store содержит ожидаемые документы. Для каждого важного документа храните metadata:
{
"doc_id": "pricing-2026",
"source": "docs/pricing.md",
"title": "Тарифы 2026",
"section": "Возвраты",
"version": "2026-05-29",
"language": "ru"
}
Если metadata нет, RAG не сможет объяснить, откуда взялся ответ, а вы не сможете фильтровать результаты по языку, категории, версии или типу документа.
Шаг 3. Chunking важнее, чем кажется ¶
Слишком большие chunks дают много лишнего текста и размывают смысл. Слишком маленькие chunks теряют контекст: заголовок отдельно, ответ отдельно, условие отдельно. Для инструкций, FAQ и технических документов обычно лучше сохранять заголовок внутри каждого chunk.
Плохой chunk:
... эта настройка обязательна. Если значение не указано, workflow не будет выполнен корректно.
Хороший chunk:
Section: OAuth redirect URL
If n8n runs behind a reverse proxy, set the public editor URL and webhook URL so OAuth providers receive the correct redirect URI.
Для русскоязычного сайта обязательно проверяйте, что текст не испорчен при очистке HTML: не исчезли заголовки, таблицы, code blocks и списки.
Шаг 4. Одинаковая embedding model при записи и поиске ¶
Если документы были проиндексированы одной embedding model, а запросы отправляются другой, качество может резко упасть или поиск вообще перестанет работать из-за несовместимой размерности векторов. После смены embedding model коллекцию часто нужно переиндексировать.
В журнал ingestion добавьте:
{
"embedding_model": "text-embedding-example",
"embedding_dimensions": 1536,
"chunk_size": 700,
"chunk_overlap": 120,
"indexed_at": "2026-05-29T10:00:00Z"
}
Это поможет через месяц понять, почему старые документы ищутся иначе, чем новые.
Шаг 5. Metadata filters вместо надежды на similarity ¶
Векторный поиск хорошо ищет смысловую близость, но плохо понимает бизнес-ограничения без metadata. Если пользователь спрашивает про “тариф для self-hosted”, retrieval может вернуть общий chunk про тарифы. Если есть metadata product=self-hosted, можно отфильтровать лишнее до передачи в LLM.
Полезные поля metadata:
language;product;section;source_url;doc_type;version;date_modified;audience;region.
Не пытайтесь решить metadata-фильтрацию prompt-ом после retrieval. Если лишние chunks уже попали в контекст, модель может использовать их в ответе.
Шаг 6. Top-k и rerank ¶
top_k=1 часто слишком мало: нужный ответ может быть во втором или третьем chunk. top_k=20 часто слишком много: модель получает шум и начинает смешивать документы. Начните с 4–6 chunks для FAQ/документации и измеряйте качество на тестовом наборе.
Если база большая и темы близкие, добавьте reranking или второй этап фильтрации: сначала vector search, потом rerank по вопросу и заголовкам, потом LLM. Для маленькой базы можно начать без rerank, но обязательно логировать, какие chunks были переданы модели.
Шаг 7. Ответ должен показывать источники ¶
RAG без источников сложно отлаживать. Финальный ответ должен включать не только текст, но и откуда он взят:
{
"answer": "...",
"sources": [
{"title":"OAuth redirect URL", "source":"docs/oauth.md", "section":"Reverse proxy"}
],
"confidence": 0.78
}
Если источников нет или confidence низкий, workflow не должен уверенно отвечать. Лучше вернуть: “В базе знаний не найдено достаточно данных” и предложить передать вопрос человеку.
Шаг 8. Дубли и устаревшие chunks ¶
После обновления документа старые chunks могут остаться в vector store. Тогда retrieval вернёт одновременно новую и старую версию, а модель смешает их в ответе. Для каждого документа нужен doc_id и стратегия обновления: удалить старые chunks по doc_id, затем вставить новую версию.
Контрольные поля:
{
"doc_id": "security-guide",
"chunk_id": "security-guide:v3:012",
"version": "v3",
"is_current": true
}
Если vector store не поддерживает удобный update, делайте delete + insert. Главное — не копить вечные версии без фильтра is_current.
Контрольный набор вопросов ¶
Для RAG нужен мини-бенчмарк из 20–50 вопросов. Для каждого вопроса укажите ожидаемый источник:
{
"question": "Какой redirect URL нужен для OAuth за reverse proxy?",
"expected_source": "oauth-reverse-proxy.md",
"expected_section": "Redirect URL",
"must_contain": ["WEBHOOK_URL", "N8N_EDITOR_BASE_URL"]
}
После изменения chunking, embedding model, top-k или prompt прогоняйте этот набор и сравнивайте: найден ли правильный chunk, попал ли он в контекст, дал ли LLM корректный ответ.
Что не делать ¶
Не загружайте весь документ одним chunk. Не меняйте embedding model без переиндексации. Не удаляйте metadata ради “чистого текста”. Не отдавайте пользователю ответ без источников, если вопрос требует фактов. Не храните старые и новые версии документов без version и is_current. Не пытайтесь исправить плохой retrieval длинным prompt-ом.
FAQ ¶
Почему RAG возвращает похожий, но неправильный ответ?
Чаще всего chunks слишком общие или нет metadata-фильтров. Добавьте заголовки в chunks и фильтруйте по продукту, языку, версии или разделу.
Какой chunk size выбрать?
Универсального числа нет. Для документации начните с 500–900 слов/токенов эквивалентного размера с overlap и проверьте на тестовых вопросах.
Нужно ли использовать Qdrant вместо Simple Vector Store?
Для локального теста можно начать проще. Для production, больших коллекций и фильтров удобнее полноценный vector store с metadata и управлением версиями.
Почему после обновления документа RAG отвечает по-старому?
Старые chunks могли остаться в коллекции. Удаляйте старую версию по doc_id или фильтруйте is_current=true.
Что важнее: prompt или retrieval?
Сначала retrieval. Если правильный chunk не попал в контекст, prompt не сможет стабильно восстановить отсутствующий факт.