Перейти к содержанию

Диагностика 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:

  1. получить документ;
  2. очистить HTML/Markdown/PDF-текст;
  3. нарезать на chunks;
  4. добавить metadata;
  5. создать embeddings;
  6. записать в Qdrant/Supabase/PGVector/Simple Vector Store;
  7. сохранить doc_id, version, source_url, дату индексации.

Answering workflow:

  1. получить вопрос;
  2. нормализовать запрос;
  3. выполнить retrieval;
  4. проверить найденные chunks;
  5. передать контекст в LLM;
  6. вернуть ответ с источниками или 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 не сможет стабильно восстановить отсутствующий факт.