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

Qdrant troubleshooting в n8n: почему RAG не находит документы и как это чинить

Обновлено: 2026-05-29

Открыть мой план

Короткий ответ

Qdrant troubleshooting в n8n почти всегда сводится к пяти зонам: документы не попали в коллекцию, embeddings сделаны не той моделью или размерностью, metadata filters отрезают нужные chunks, retrieval возвращает нерелевантные фрагменты, а агент неправильно использует найденный context. Чинить нужно не “промптом”, а цепочкой: ingestion log → collection health → sample search → metadata audit → retrieval evaluation → answer validation.

Как Qdrant используется в n8n

Qdrant Vector Store в n8n может использоваться несколькими способами: как обычный node для insert/retrieve документов, как tool для AI Agent, через Vector Store Retriever или через Vector Store Question Answer Tool. От выбранной схемы зависит диагностика. Если Qdrant стоит в обычном flow, вы проверяете входные items и output node. Если Qdrant подключён к агенту как tool, добавляется ещё один слой: агент может вообще не вызвать tool или вызвать его с плохим query.

Поэтому первый вопрос troubleshooting: где именно ломается цепочка? На ingestion, embedding, storage, retrieval, tool selection или generation? Без этого люди часто меняют prompt, хотя проблема в том, что коллекция пустая или фильтр tenant_id не совпадает.

Карта RAG-пайплайна

Production RAG с Qdrant обычно выглядит так:

  1. Source loader получает документы.
  2. Cleaner убирает HTML, мусор, дубли и навигацию.
  3. Chunker режет документ.
  4. Metadata builder добавляет source_id, tenant_id, language, version, access_level.
  5. Embeddings node создаёт векторы.
  6. Qdrant insert/upsert сохраняет chunks.
  7. Query normalizer готовит вопрос.
  8. Retriever ищет chunks.
  9. Rerank/filter выбирает лучшие источники.
  10. LLM отвечает с цитированием source_id.
  11. Evaluation проверяет качество.

Если любой шаг пропущен, RAG может “работать”, но отвечать плохо.

Симптомы и причины

Симптом Вероятная причина Что проверить
всегда пустой ответ коллекция пустая, фильтр слишком строгий count points, sample query, metadata
находятся не те документы плохие chunks, неверная модель embeddings chunk size, overlap, embedding model
часть документов не находится stale index, пропущенный ingestion ingestion log, source version
ошибка размерности разные embedding models vector size collection vs model
ответы без источников generation prompt не требует source_ids retrieved context, output schema
чужие документы metadata/access filters не применены tenant_id, role, access_level
дубли в ответах повторный insert без stable IDs point_id, source_id, version

Проверка ingestion

Начните с журнала загрузки. Для каждого source document нужно знать:

{
  "source_id": "kb_refunds_2026_05",
  "source_url": "https://internal/kb/refunds",
  "source_version": "2026-05-29",
  "chunk_count": 18,
  "embedding_model": "configured_embedding_model",
  "collection": "support_kb_ru",
  "tenant_id": "public",
  "language": "ru",
  "ingested_at": "2026-05-29T10:00:00Z",
  "status": "success"
}

Если нет такого журнала, вы не сможете понять, какие документы в индексе. Особенно опасны “тихие” ошибки: workflow загрузил 100 документов, 20 упали, но execution считается success, потому что ошибка была проигнорирована.

Stable IDs и дубли

Для обновляемой базы знаний используйте стабильные IDs. Если каждый refresh создаёт новые random point IDs, коллекция будет пухнуть дублями. Пользователь спросит “как вернуть оплату”, и retriever принесёт старую и новую политику одновременно.

Пример stable ID:

const crypto = require('crypto');
const sourceId = $json.source_id;
const chunkIndex = $json.chunk_index;
const version = $json.version || 'current';
const pointId = crypto.createHash('sha256')
  .update(`${sourceId}:${chunkIndex}:${version}`)
  .digest('hex');
return [{ json: { ...$json, point_id: pointId } }];

Если нужна только актуальная версия, удаляйте старые points по source_id перед insert или используйте metadata is_current и фильтр.

Metadata filters

Metadata — причина половины “Qdrant ничего не нашёл”. Проблемы бывают такие:

  • tenant_id записан как Tenant_1, а фильтр ищет tenant_1;
  • язык ru-RU, а фильтр ru;
  • access_level хранится строкой, а фильтр ожидает массив;
  • document_type не заполнен;
  • дата refresh устарела;
  • фильтр применён в одном node, но не применяется в tool mode.

Сделайте metadata audit:

{
  "source_id": "kb_shipping",
  "tenant_id": "public",
  "language": "ru",
  "access_level": "public",
  "doc_type": "policy",
  "product": "delivery",
  "is_current": true,
  "updated_at": "2026-05-29"
}

Не храните важные фильтры только в тексте chunk. Они должны быть отдельными metadata fields.

Embeddings mismatch

Если collection создана под одну размерность embeddings, а вы начали использовать другую модель, получите ошибку или плохое качество. Даже если размерность совпала, embedding space может отличаться. Не смешивайте модели в одной коллекции без явной стратегии.

Записывайте embedding_model и embedding_version в metadata. При смене модели лучше создать новую коллекцию или полностью переиндексировать старую. Для migration используйте shadow collection: новая коллекция собирается параллельно, затем evaluation сравнивает старый и новый retrieval.

Диагностика retrieval

Не тестируйте RAG только итоговым ответом LLM. Сначала смотрите raw retrieved chunks:

{
  "query": "как вернуть деньги за заказ",
  "top_k": 5,
  "filters": {"language": "ru", "access_level": "public"},
  "results": [
    {"source_id": "refund_policy", "score": 0.82, "chunk": "..."},
    {"source_id": "delivery_terms", "score": 0.41, "chunk": "..."}
  ]
}

Если top-1 релевантен, но ответ плохой — проблема в prompt/generation. Если top-5 нерелевантны — проблема в retrieval, chunks, embeddings или query rewriting.

Chunking для Qdrant

Слишком большие chunks дают шум, слишком маленькие теряют контекст. Для инструкций и FAQ часто хорошо работают короткие chunks с понятным заголовком и source_id. Для длинных документов добавляйте overlap, но не такой большой, чтобы каждый результат был почти дублем.

Каждый chunk должен содержать локальный смысл: заголовок, подраздел, ответ или процедуру. Не режьте документ по произвольным символам так, чтобы один chunk содержал “Шаг 1”, а следующий — “Шаг 2” без контекста.

Агент не использует Qdrant tool

Если Qdrant подключён как tool к AI Agent, проблема может быть не в Qdrant. Агент может считать, что знает ответ сам. В prompt добавьте policy: для вопросов о внутренних правилах, ценах, документах, клиентах и процедурах agent must use retrieval tool. Для общих вопросов retrieval не нужен.

Смотрите trace: был ли tool call, какой query отправлен, какие filters применены, какие chunks вернулись. Без trace нельзя отличить “Qdrant не нашёл” от “агент не спросил”.

Evaluation

Соберите golden dataset:

{
  "question": "Как отменить заказ после оплаты?",
  "expected_source_id": "cancel_after_payment_policy",
  "must_include": ["статус заказа", "возврат", "срок обработки"],
  "must_not_include": ["ручной refund без проверки"]
}

Метрики:

  • retrieval hit@k;
  • source accuracy;
  • answer faithfulness;
  • no-answer correctness;
  • stale source rate;
  • cross-tenant leakage;
  • average latency;
  • empty result rate.

Runbook: RAG отвечает плохо

  1. Сохранить user query и trace_id.
  2. Посмотреть raw retrieved chunks.
  3. Проверить filters и tenant/access.
  4. Выполнить manual search без фильтров.
  5. Проверить ingestion log source document.
  6. Сравнить embedding model.
  7. Проверить chunk size/overlap.
  8. Проверить prompt: требует ли источники.
  9. Добавить кейс в evaluation dataset.
  10. Переиндексировать или исправить metadata.

Что нельзя делать

Не лечите плохой retrieval длинным prompt: модель не найдёт документ, которого нет в context. Не смешивайте приватные и публичные документы без metadata filters. Не обновляйте базу знаний без версии и журнала. Не давайте агенту отвечать на внутренние вопросы без source_ids. Не используйте in-memory vector store для production, где данные должны переживать рестарт.

FAQ

Почему Qdrant в n8n возвращает пустой результат?
Чаще всего коллекция пустая, фильтр metadata слишком строгий, query не нормализован, документы не были проиндексированы или используется другая коллекция/environment.

Почему RAG на Qdrant находит не те документы?
Проверьте chunking, embedding model, metadata, top-k, query rewriting и raw retrieved chunks. Если retrieval плохой, prompt не исправит проблему.

Можно ли смешивать разные embedding models в одной коллекции?
Нежелательно. Даже при одинаковой размерности качество может просесть. Лучше фиксировать embedding_model в metadata и переиндексировать коллекцию при смене модели.

Как защититься от выдачи чужих документов?
Используйте metadata filters по tenant_id, access_level, role, language и is_current. Проверяйте фильтры в тестах и логируйте source_ids каждого ответа.

Что логировать для Qdrant troubleshooting?
query, normalized_query, collection, top_k, filters, retrieved source_ids, scores, embedding_model, index_version, latency, empty_result и final answer status.