Конспект 3: Qdrant в N8N
Оглавление
- Введение в Qdrant
- Архитектура Qdrant
- Концепции и термины
- Подключение Qdrant к N8N
- Узел Qdrant в N8N
- Операции с коллекциями
- Работа с данными (Points)
- Поиск (Query)
- Фильтрация и метаданные
- Оптимизация и индексирование
- Практические примеры N8N workflows
- Развертывание и конфигурация
- Лучшие практики
Введение в Qdrant
Что такое Qdrant?
Определение: Qdrant (от англ. Quadrant) — это высокопроизводительная, открытая векторная база данных, оптимизированная для быстрого поиска семантически похожих данных в многомерном пространстве.
Основные назначения: - Хранение векторных представлений (эмбеддингов) - Поиск по сходству на основе косинусного расстояния или других метрик - Фильтрация результатов по метаданным (payload) - Рекомендации, дедупликация, анализ данных
Ключевые преимущества Qdrant
- Высокая производительность — быстрый поиск миллионов векторов
- Гибкая фильтрация — встроенная поддержка комплексных условий
- Масштабируемость — работает с неограниченным количеством данных
- Открытый исходный код — можно развернуть локально
- Облачный вариант — управляемое решение Qdrant Cloud
- Встроенная интеграция в N8N — официальный узел для автоматизации
Сравнение Qdrant с альтернативами
| Характеристика | Qdrant | Pinecone | Milvus | ChromaDB | Weaviate |
|---|---|---|---|---|---|
| Тип | Open-source + Cloud | Облачный сервис | Open-source | Open-source | Open-source + Cloud |
| Локальное развертывание | ✅ Да | ❌ Нет | ✅ Да | ✅ Да | ✅ Да |
| Фильтрация | ✅ Мощная | ✅ Есть | ✅ Есть | ✅ Базовая | ✅ Есть |
| Производительность | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐ |
| Масштабируемость | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐ | ⭐⭐⭐⭐ |
| Интеграция с N8N | ✅ Встроена | ⚠️ Частично | ⚠️ HTTP | ⚠️ HTTP | ✅ Встроена |
| Бесплатный вариант | ✅ Да | ✅ Есть | ✅ Да | ✅ Да | ✅ Да |
Архитектура Qdrant
Иерархия структур
Qdrant Instance (Инстанс)
│
├─ Collection 1 (Коллекция)
│ ├─ Point 1 (Точка)
│ │ ├─ Vector (Вектор) [0.23, -0.15, 0.87, ...]
│ │ └─ Payload (Метаданные) {name, date, category...}
│ ├─ Point 2
│ └─ Point N
│
├─ Collection 2
│ └─ [Points...]
│
└─ Collection N
└─ [Points...]
Основные компоненты
1. Collection (Коллекция)
Определение: Контейнер для хранения векторов и связанных с ними метаданных. Похожа на таблицу в обычной БД.
Параметры при создании: - Vector size — размерность вектора (384, 768, 1536 и т.д.) - Distance metric — метрика расстояния (COSINE, EUCLID, MANHATTAN, DOT_PRODUCT) - Vectors config — конфигурация для одного или нескольких векторов
Пример: Коллекция "documents" с размером вектора 1536 токенов для хранения текстовых эмбеддингов
2. Point (Точка)
Определение: Отдельный элемент в коллекции, состоящий из ID, вектора и опциональных метаданных.
Структура:
{
"id": "12345",
"vector": [0.23, -0.15, 0.87, ..., 0.42],
"payload": {
"title": "N8N - платформа автоматизации",
"author": "Иван",
"date": "2025-11-26",
"category": "AI",
"language": "ru",
"embedding_model": "text-embedding-3-small"
}
}
3. Vector (Вектор)
Определение: Массив чисел фиксированной длины, представляющий эмбеддинг данных.
Типы: - Dense vector — полный вектор со всеми значениями - Sparse vector — вектор с только ненулевыми значениями (экономит память)
Метрики расстояния:
| Метрика | Формула | Применение | Диапазон |
|---|---|---|---|
| COSINE | 1 - (A·B)/(‖A‖·‖B‖) |
Текст, общий случай | 0-2 |
| EUCLID | √(Σ(ai - bi)²) |
Геометрические данные | 0-∞ |
| MANHATTAN | Σ\|ai - bi\| |
Быстрый поиск, сеть | 0-∞ |
| DOT_PRODUCT | A·B |
Нормализованные векторы | -∞-∞ |
Рекомендация: Для текста используйте COSINE, это стандарт в NLP
4. Payload (Полезная нагрузка / Метаданные)
Определение: Дополнительные данные, привязанные к каждому вектору, используемые для фильтрации, поиска и контекста.
Типы данных в Payload:
| Тип | Описание | Пример |
|---|---|---|
| Keyword | Строки, категории | "category": "AI" |
| Integer | Целые числа | "priority": 5 |
| Float | Дробные числа | "relevance": 0.87 |
| Boolean | Логические значения | "in_stock": true |
| Geo | Географические координаты | "location": {"lat": 52.52, "lon": 13.40} |
| DateTime | Дата и время | "created": "2025-11-26T15:30:00" |
| Text | Полнотекстовый поиск | "content": "N8N помогает автоматизировать..." |
| UUID | Уникальные идентификаторы | "doc_id": "550e8400-e29b-41d4-a716-446655440000" |
| Array | Массивы значений | "tags": ["automation", "AI", "n8n"] |
Хранение данных
Структура диска:
Qdrant Storage
├─ collection_name/
│ ├─ vectors.dat (сами векторы)
│ ├─ vectors.idx (индекс для быстрого поиска)
│ ├─ payload/ (метаданные)
│ └─ config.json (параметры коллекции)
└─ [другие коллекции...]
Концепции и термины
HNSW (Hierarchical Navigable Small World Graph)
Определение: Алгоритм индексирования для приблизительного векторного поиска, использует иерархическую структуру графа.
Как работает: 1. Векторы организуются в многоуровневый граф 2. Поиск начинается с верхних уровней 3. Постепенно спускается к более детальным уровням 4. На каждом уровне выбираются ближайшие соседи
Преимущества: - Быстрый поиск даже с миллионами векторов - Логарифмическая сложность O(log n) - Балансирование между скоростью и точностью
Параметры HNSW:
{
"m": 16, // Количество соединений на каждом уровне
"ef_construct": 200, // Качество построения индекса
"ef": 150 // Глубина поиска при запросе
}
ANN (Approximate Nearest Neighbors) Search
Определение: Поиск приблизительно ближайших соседей (в отличие от точного поиска).
Преимущества: - Скорость: в 1000+ раз быстрее полного перебора - Приемлемая точность для большинства задач
Точность vs Скорость:
ef параметр увеличиваем → точность ↑, скорость ↓
ef параметр уменьшаем → точность ↓, скорость ↑
Фильтрация с условиями
Определение: Ограничение поиска по значениям в payload перед началом векторного поиска.
Логические операции: - must — ВСЕ условия ДОЛЖНЫ быть истинны (AND) - should — ХОТя бы ОДНО условие должно быть истинно (OR) - must_not — ЭТИ условия НЕ ДОЛЖНЫ быть истинны (NOT)
Payload Indexing
Определение: Создание индекса по полям payload для ускорения фильтрованного поиска.
Когда создавать индекс: - Часто фильтруете по этому полю - Поле содержит много уникальных значений - Нужна быстрая фильтрация
Когда это замедлит: - Редко фильтруете по полю - Поле имеет мало уникальных значений - Нужно экономить память
Подключение Qdrant к N8N
Способ 1: Qdrant Cloud (Облачный вариант)
Шаг 1: Создание аккаунта Qdrant Cloud
- Перейти на cloud.qdrant.io
- Зарегистрироваться через GitHub, Google или email
- Создать новый проект (Cluster)
- Выбрать регион и тариф
Шаг 2: Получение учетных данных
- В Dashboard выбрать кластер
- Нажать "Cluster Details"
- Скопировать Endpoint (URL):
- Формат:
https://xxxxxx-your-cluster.eu-west-1.qdrant.cloud:6333 - Перейти на вкладку API Keys
- Скопировать API Key
Шаг 3: Подключение в N8N
- Открыть N8N → Create New Workflow
- Добавить узел Qdrant
- Кликнуть на "Create New Credential"
- Выбрать QdrantApi
- Заполнить поля:
- Qdrant URL:
https://xxxxxx-your-cluster.eu-west-1.qdrant.cloud:6333 - API Key:
sk-xxxxxxxxxxxxx - Сохранить
Проверка подключения: - Если подключение успешно, в узле Qdrant появятся доступные коллекции
Способ 2: Локальный Qdrant (Docker)
Запуск контейнера
docker run -it --rm \
-p 6333:6333 \
-v qdrant_storage:/qdrant/storage \
qdrant/qdrant
Параметры:
- -p 6333:6333 — порт для API
- -v qdrant_storage:/qdrant/storage — сохранение данных
- Доступ: http://localhost:6333
С API Key (для безопасности)
docker run -it --rm \
-p 6333:6333 \
-v qdrant_storage:/qdrant/storage \
-e QDRANT_API_KEY=test_key_12345 \
qdrant/qdrant
Подключение в N8N
- Добавить узел Qdrant
- Создать новый credential
- Заполнить:
- Qdrant URL:
http://localhost:6333илиhttp://qdrant:6333(если в Docker Compose) - API Key:
test_key_12345(если установлен) - Сохранить
Способ 3: N8N Self-hosted AI Starter Kit
Docker Compose с предустановкой:
version: '3.8'
services:
n8n:
image: n8nio/n8n
ports:
- "5678:5678"
environment:
- N8N_BASIC_AUTH_ACTIVE=true
- N8N_BASIC_AUTH_USER=admin
- N8N_BASIC_AUTH_PASSWORD=password123
networks:
- demo
qdrant:
image: qdrant/qdrant
hostname: qdrant
ports:
- "6333:6333"
environment:
- QDRANT_API_KEY=test
volumes:
- qdrant_storage:/qdrant/storage
networks:
- demo
volumes:
qdrant_storage:
networks:
demo:
driver: bridge
Запуск:
docker-compose up -d
Подключение в N8N:
- Qdrant URL: http://qdrant:6333
- API Key: test
Узел Qdrant в N8N
Структура узла Qdrant
Qdrant Node
├─ Credentials (учетные данные)
├─ Resource (тип операции)
├─ Operation (конкретная операция)
└─ Parameters (параметры)
Доступные ресурсы и операции
1. Collections (Коллекции)
| Операция | Описание |
|---|---|
| List Collections | Получить список всех коллекций |
| Create Collection | Создать новую коллекцию |
| Update Collection | Изменить параметры коллекции |
| Get Collection | Получить информацию о коллекции |
| Check If Collection Exists | Проверить существование коллекции |
| Delete Collection | Удалить коллекцию |
2. Points (Точки/Данные)
| Операция | Описание |
|---|---|
| Upsert Points | Вставить или обновить точки |
| Retrieve Point | Получить одну точку по ID |
| Retrieve Points | Получить несколько точек по ID |
| Delete Points | Удалить точки по ID или фильтру |
| Count Points | Подсчитать точки по условиям |
| Scroll Points | Получить точки постранично |
| Batch Update Points | Пакетное обновление точек |
3. Vectors (Векторы)
| Операция | Описание |
|---|---|
| Update Vectors | Обновить векторы для точек |
| Delete Vectors | Удалить векторы из точек |
4. Payload (Метаданные)
| Операция | Описание |
|---|---|
| Set Payload | Установить/обновить поля payload |
| Overwrite Payload | Полностью заменить payload |
| Delete Payload | Удалить поля из payload |
| Clear Payload | Удалить весь payload |
| Create Payload Index | Создать индекс по полю |
| Delete Payload Index | Удалить индекс |
| Payload Facets | Получить статистику по полю |
5. Query (Поиск)
| Операция | Описание |
|---|---|
| Query Points | Поиск похожих точек |
| Query Batch Points | Пакетный поиск |
| Query Points Groups | Поиск с группировкой результатов |
6. Matrix (Матрицы расстояний)
| Операция | Описание |
|---|---|
| Matrix Pairs | Матрица попарных расстояний |
| Matrix Offsets | Матрица расстояний с смещениями |
Операции с коллекциями
Создание коллекции
Параметры:
{
"collectionName": "documents",
"vectorSize": 1536,
"distanceMetric": "Cosine",
"onVectorSizeMismatch": "error"
}
Описание параметров: - collectionName — уникальное имя коллекции - vectorSize — размер вектора (должен совпадать с эмбеддером) - distanceMetric — метрика расстояния (Cosine, Euclid, Manhattan, DotProduct) - onVectorSizeMismatch — что делать при несовпадении размера (error/warning)
Пример на Python (для понимания):
from qdrant_client import QdrantClient, models
client = QdrantClient(url="http://localhost:6333", api_key="test")
client.create_collection(
collection_name="documents",
vectors_config=models.VectorParams(
size=1536,
distance=models.Distance.COSINE
)
)
Получение информации о коллекции
Возвращает:
{
"name": "documents",
"vectors": 1000,
"status": "green",
"config": {
"params": {
"vectors": {
"size": 1536,
"distance": "Cosine"
}
}
}
}
Обновление параметров коллекции
Что можно менять: - Параметры оптимизации (ef, m для HNSW) - Timeout для операций
Пример:
{
"collectionName": "documents",
"hnsw": {
"ef": 200,
"m": 16
}
}
Удаление коллекции
Внимание: операция необратима!
Параметры:
{
"collectionName": "documents"
}
Работа с данными (Points)
Вставка и обновление точек (Upsert)
UPSERT = UPDATE + INSERT (обновить, если существует; вставить, если нет)
Структура данных:
{
"collectionName": "documents",
"points": [
{
"id": 1,
"vector": [0.23, -0.15, 0.87, ..., 0.42],
"payload": {
"title": "N8N - платформа автоматизации",
"author": "Иван",
"date": "2025-11-26",
"category": "AI",
"embedding_model": "text-embedding-3-small"
}
},
{
"id": 2,
"vector": [0.45, 0.12, -0.34, ..., 0.21],
"payload": {
"title": "Qdrant для N8N",
"author": "Мария",
"date": "2025-11-25",
"category": "Database"
}
}
]
}
Типы ID: - Integer — быстрее, занимает меньше памяти - UUID/String — более гибко, если нужны текстовые ID
Получение точки по ID
Один запрос — одна точка:
{
"collectionName": "documents",
"pointId": 1
}
Возвращает:
{
"id": 1,
"vector": [0.23, -0.15, 0.87, ..., 0.42],
"payload": {
"title": "N8N - платформа автоматизации",
...
}
}
Получение нескольких точек
Параметры:
{
"collectionName": "documents",
"pointIds": [1, 2, 3, 5]
}
Результат:
{
"points": [
{ "id": 1, "vector": [...], "payload": {...} },
{ "id": 2, "vector": [...], "payload": {...} },
{ "id": 3, "vector": [...], "payload": {...} },
{ "id": 5, "vector": [...], "payload": {...} }
]
}
Удаление точек
По ID:
{
"collectionName": "documents",
"pointIds": [1, 2, 3]
}
По фильтру (удалить всё, что соответствует условию):
{
"collectionName": "documents",
"filter": {
"must": [
{
"key": "category",
"match": { "value": "old_content" }
}
]
}
}
Подсчет точек
Получить количество всех точек:
{
"collectionName": "documents"
}
С условием (только активные точки):
{
"collectionName": "documents",
"filter": {
"must": [
{
"key": "is_active",
"match": { "value": true }
}
]
}
}
Пакетное обновление
Одновременное обновление векторов и payload:
{
"collectionName": "documents",
"points": [
{
"id": 1,
"vector": [0.23, -0.15, 0.87, ..., 0.42],
"payload": {
"status": "updated",
"updated_at": "2025-11-26"
}
}
]
}
Поиск (Query)
Поиск похожих точек
Базовый поиск:
{
"collectionName": "documents",
"vector": [0.23, -0.15, 0.87, ..., 0.42],
"limit": 10,
"scoreThreshold": 0.7
}
Параметры: - vector — вектор запроса (должен быть того же размера, что и коллекция) - limit — количество результатов - scoreThreshold — минимальный порог сходства (0.0-1.0 для COSINE) - withPayload — включить ли метаданные (по умолчанию true) - withVector — включить ли вектор в результат (по умолчанию false, для экономии)
Результат:
{
"result": [
{
"id": 5,
"score": 0.92,
"payload": {
"title": "N8N - платформа автоматизации",
"category": "AI"
}
},
{
"id": 3,
"score": 0.85,
"payload": {
"title": "Qdrant для N8N",
"category": "Database"
}
}
]
}
Поиск по имени вектора
Если коллекция содержит несколько векторов:
{
"collectionName": "documents",
"vector": {
"name": "description_vector",
"vector": [0.23, -0.15, 0.87, ..., 0.42]
},
"limit": 5
}
Поиск с использованием других точек
Найти похожие на существующую точку:
{
"collectionName": "documents",
"pointId": 1,
"limit": 5
}
Пакетный поиск
Несколько запросов одновременно:
{
"collectionName": "documents",
"searches": [
{
"vector": [0.23, -0.15, 0.87, ..., 0.42],
"limit": 5
},
{
"vector": [0.45, 0.12, -0.34, ..., 0.21],
"limit": 3
}
]
}
Возвращает:
{
"results": [
{
"result": [
{ "id": 5, "score": 0.92, "payload": {...} }
]
},
{
"result": [
{ "id": 3, "score": 0.88, "payload": {...} }
]
}
]
}
Поиск с группировкой
Группировка результатов по полю payload:
{
"collectionName": "documents",
"vector": [0.23, -0.15, 0.87, ..., 0.42],
"groupBy": "category",
"groupSize": 2,
"limit": 10
}
Параметры: - groupBy — поле для группировки - groupSize — максимум результатов в одной группе - limit — общий лимит результатов
Результат:
{
"groups": [
{
"id": "AI",
"hits": [
{ "id": 5, "score": 0.92, "payload": {...} },
{ "id": 8, "score": 0.87, "payload": {...} }
]
},
{
"id": "Database",
"hits": [
{ "id": 3, "score": 0.88, "payload": {...} }
]
}
]
}
Фильтрация и метаданные
Структура фильтра
{
"must": [
// Все условия должны быть истинны (AND)
],
"should": [
// Хотя бы одно условие должно быть истинно (OR)
],
"must_not": [
// Эти условия НЕ должны быть истинны (NOT)
]
}
Типы условий
Точное совпадение (Match)
{
"key": "category",
"match": {
"value": "AI"
}
}
Диапазон значений (Range)
{
"key": "price",
"range": {
"gte": 100,
"lte": 1000
}
}
Параметры:
- gt — больше (>)
- gte — больше или равно (≥)
- lt — меньше (<)
- lte — меньше или равно (≤)
Множественное соответствие
{
"key": "tags",
"match": {
"any": ["automation", "AI", "python"]
}
}
Географическая фильтрация
{
"key": "location",
"geo_radius": {
"center": {
"lat": 52.52,
"lon": 13.40
},
"radius": 2000 // в метрах
}
}
Полнотекстовый поиск
{
"key": "content",
"text": {
"query": "N8N автоматизация"
}
}
Пример комплексной фильтрации
"Найти документы по AI, опубликованные в 2025, от авторов Иван или Мария, и исключить архивные":
{
"must": [
{
"key": "category",
"match": { "value": "AI" }
},
{
"key": "date",
"range": {
"gte": "2025-01-01",
"lte": "2025-12-31"
}
}
],
"should": [
{ "key": "author", "match": { "value": "Иван" } },
{ "key": "author", "match": { "value": "Мария" } }
],
"must_not": [
{ "key": "status", "match": { "value": "archived" } }
]
}
Поиск с фильтрацией
В узле Query Points:
{
"collectionName": "documents",
"vector": [0.23, -0.15, 0.87, ..., 0.42],
"filter": {
"must": [
{ "key": "category", "match": { "value": "AI" } }
]
},
"limit": 10
}
Процесс: 1. Применить фильтр (отобрать только AI документы) 2. Вычислить расстояние до запроса 3. Вернуть top-10 по сходству
Управление метаданными (Payload)
Set Payload (установить/добавить поля)
{
"collectionName": "documents",
"pointIds": [1, 2, 3],
"payload": {
"status": "processed",
"last_updated": "2025-11-26"
}
}
Результат: добавляет новые поля, оставляет старые
Overwrite Payload (полностью заменить)
{
"collectionName": "documents",
"pointIds": [1, 2, 3],
"payload": {
"status": "archived",
"reason": "old content"
}
}
Результат: удаляет все старые поля, оставляет только новые
Delete Payload (удалить поля)
{
"collectionName": "documents",
"pointIds": [1, 2, 3],
"keys": ["status", "last_updated"]
}
Результат: удаляет только указанные поля
Создание индекса по payload
Для ускорения фильтрации:
{
"collectionName": "documents",
"fieldName": "category",
"fieldSchema": "keyword"
}
Типы индексов:
| Схема | Тип данных | Операции |
|---|---|---|
| keyword | String | Match, Any |
| integer | Int | Match, Range |
| float | Float | Match, Range |
| bool | Boolean | Match |
| geo | Geo | Radius, BoundingBox |
| datetime | DateTime | Range |
| text | String | FullText |
| uuid | UUID | Match |
После создания индекса фильтрация работает в 10-100 раз быстрее!
Faceted Search (получение статистики)
Узнать, сколько документов в каждой категории:
{
"collectionName": "documents",
"field": "category"
}
Результат:
{
"facets": [
{ "value": "AI", "count": 150 },
{ "value": "Database", "count": 87 },
{ "value": "Automation", "count": 203 }
]
}
Применение: создание фильтров в UI, статистика
Оптимизация и индексирование
HNSW Параметры
Где настраивать: при создании коллекции
{
"hnsw": {
"m": 16, // Quantity connections per node (8-64)
"ef_construct": 200, // Indexing quality (128-2048)
"ef": 150, // Search depth (128-4096)
"full_scan_threshold": 10000, // Когда перейти на полный поиск
"max_indexing_threads": 4 // Потоки для индексирования
}
}
Рекомендации:
| Сценарий | m | ef_construct | ef |
|---|---|---|---|
| Быстрый прототип | 8 | 128 | 100 |
| Сбалансированный | 16 | 200 | 150 |
| Высокая точность | 24 | 500 | 250 |
| Огромный объем (млн+) | 16 | 200 | 150 |
Оптимизация памяти
Компрессия векторов:
{
"quantization": {
"scalar": {
"type": "int8",
"quantile": 0.99,
"always_ram": false
}
}
}
Результат: экономия памяти в 4 раза (32-бит → 8-бит)
Стратегия индексирования
1. Индексировать часто используемые поля:
// Создать индексы
- category (keyword)
- date (datetime)
- author (keyword)
- is_active (bool)
2. Не индексировать: - Редко используемые поля - Поля с очень большим количеством уникальных значений - Очень длинные строки
3. Профилирование: - Мониторить время поиска - Добавлять индексы на медленные фильтры - Удалять неиспользуемые индексы
Масштабирование
Когда переходить на большие объемы:
| Размер | Рекомендация |
|---|---|
| < 1M точек | Локальный Qdrant достаточно |
| 1M - 100M | Один сервер Qdrant, возможна репликация |
| 100M - 1B | Qdrant Cloud с высоким тарифом, или собственный кластер |
| 1B+ | Мультиузловой кластер, сегментирование |
Практические примеры N8N workflows
Пример 1: RAG Workflow (базовый)
Сценарий: Обработка входящего вопроса, поиск релевантных документов в Qdrant, генерация ответа с GPT
[Webhook trigger]
↓
[HTTP Request → OpenAI Embedding]
↓
[Qdrant Query Points]
↓
[Function → Формирование контекста]
↓
[HTTP Request → OpenAI Chat]
↓
[HTTP Request → Отправка ответа]
N8N Nodes:
1. Webhook Trigger:
Method: POST
Authentication: None
2. OpenAI Embedding:
Используем: Function node или HTTP Request
Input: $json.body.question
Output: vector array
3. Qdrant Query Points:
Resource: Query
Operation: Query Points
collectionName: "kb_documents"
vector: $json.embedding
limit: 5
scoreThreshold: 0.7
filter: {
"must": [
{ "key": "status", "match": { "value": "active" } }
]
}
4. Function Node (JavaScript):
// Формирование контекста из результатов
const items = $input.all()[0].json.result;
const context = items
.map(item => `${item.payload.title}\n${item.payload.content}`)
.join('\n\n');
return { context };
5. OpenAI Chat:
System prompt: "Ты помощник. Ответь на вопрос используя контекст"
Context: $json.context
Question: $json.body.question
Пример 2: Document Indexing Workflow
Сценарий: Загрузка новых документов, их чанкирование, генерация эмбеддингов, добавление в Qdrant
[Google Drive New File Trigger]
↓
[PDF Parser]
↓
[Function → Чанкирование текста]
↓
[HTTP Request → OpenAI Embedding]
↓
[Qdrant Upsert Points]
↓
[Notification → Email]
Nodes:
1. Trigger: Google Drive New File
2. PDF Parser:
Input: file from trigger
Output: raw text
3. Function Node (Text Chunking):
const text = $input.first().json.text;
const chunkSize = 1024; // токены
const chunkOverlap = 100;
const chunks = [];
let start = 0;
while (start < text.length) {
let end = start + chunkSize;
if (end < text.length && text[end] !== ' ') {
end = text.lastIndexOf(' ', end);
}
chunks.push(text.substring(start, end));
start = end - chunkOverlap;
}
return chunks.map((chunk, i) => ({
"chunk_id": i,
"content": chunk,
"source": $input.first().json.fileName
}));
4. HTTP Request (Embedding):
Method: POST
URL: https://api.openai.com/v1/embeddings
Headers: Authorization: Bearer sk-...
Body: {
"input": $json.content,
"model": "text-embedding-3-small"
}
5. Qdrant Upsert Points:
Resource: Points
Operation: Upsert Points
collectionName: "documents"
points: [
{
"id": $json.chunk_id,
"vector": $input.previous().json.data[0].embedding,
"payload": {
"content": $json.content,
"source": $json.source,
"indexed_at": new Date().toISOString(),
"document_id": $input.first().json.fileId
}
}
]
Пример 3: Фильтрованный поиск с метаданными
Сценарий: Поиск документов по категориям и датам
[Webhook trigger с параметрами]
↓
[Qdrant Query Points + Filter]
↓
[Presentation форматирования]
↓
[HTTP Response]
Qdrant Query Node:
collectionName: "documents"
vector: $json.embedding
filter: {
"must": [
{
"key": "category",
"match": { "value": $json.category }
},
{
"key": "date",
"range": {
"gte": $json.startDate,
"lte": $json.endDate
}
}
]
}
limit: 10
scoreThreshold: 0.75
Пример 4: Мониторинг и обновление метаданных
Сценарий: Проверка актуальности документов каждый день, обновление метаданных
[Schedule trigger (ежедневно)]
↓
[Qdrant Scroll Points]
↓
[Function → Проверка актуальности]
↓
[Qdrant Set Payload (обновить метаданные)]
↓
[Logging]
Nodes:
1. Schedule: Cron 0 0 * * * (каждый день в полночь)
2. Qdrant Scroll Points:
collectionName: "documents"
limit: 100
3. Function Node:
const today = new Date();
const oneMonthAgo = new Date(today.getTime() - 30 * 24 * 60 * 60 * 1000);
const oldItems = $input.all()
.filter(item => {
const docDate = new Date(item.json.payload.indexed_at);
return docDate < oneMonthAgo;
});
return oldItems.map(item => ({
pointId: item.json.id,
status: "stale",
needs_review: true
}));
4. Qdrant Set Payload:
collectionName: "documents"
pointIds: $json.pointIds
payload: {
"status": "stale",
"needs_review": true,
"last_checked": new Date().toISOString()
}
Пример 5: Рекомендации на основе Qdrant
Сценарий: Если пользователь просмотрел документ X, показать похожие
[User view event webhook]
↓
[Qdrant Retrieve Point (получить вектор просмотренного документа)]
↓
[Qdrant Query Points (найти похожие)]
↓
[Filter excluding similar (исключить само себя)]
↓
[HTTP Response → Recommendations]
Nodes:
1. Webhook:
{
"user_id": "123",
"document_id": 5
}
2. Qdrant Retrieve Point:
collectionName: "documents"
pointId: $json.document_id
3. Qdrant Query Points:
collectionName: "documents"
vector: $input.previous().json.vector
filter: {
"must_not": [
{ "key": "id", "match": { "value": $json.document_id } }
]
}
limit: 5
Развертывание и конфигурация
Локальное развертывание (Docker)
Базовый docker-compose.yml:
version: '3.8'
services:
qdrant:
image: qdrant/qdrant:latest
container_name: qdrant
ports:
- "6333:6333"
volumes:
- ./qdrant_storage:/qdrant/storage
environment:
QDRANT_HTTP_API_KEY: "test_api_key_12345"
restart: unless-stopped
n8n:
image: n8nio/n8n:latest
container_name: n8n
ports:
- "5678:5678"
environment:
- N8N_BASIC_AUTH_ACTIVE=true
- N8N_BASIC_AUTH_USER=admin
- N8N_BASIC_AUTH_PASSWORD=password123
- N8N_HOST=localhost
- N8N_PORT=5678
volumes:
- ./n8n_data:/home/node/.n8n
depends_on:
- qdrant
restart: unless-stopped
volumes:
qdrant_storage:
n8n_data:
Запуск:
docker-compose up -d
# Проверка
docker ps
docker logs qdrant
docker logs n8n
Доступ: - N8N: http://localhost:5678 (admin/password123) - Qdrant API: http://localhost:6333
Qdrant Cloud (Облачное развертывание)
Процесс: 1. Регистрация на cloud.qdrant.io 2. Создание кластера 3. Получение endpoint и API key 4. Подключение в N8N
Преимущества облака: - Автоматические резервные копии - Масштабируемость - Мониторинг - Поддержка Qdrant
Стоимость: - Free: до 1 млн точек - Professional: от $29/месяц - Enterprise: договорная цена
Мониторинг и логирование
Qdrant Web UI:
http://localhost:6333/dashboard
Доступные статистики: - Количество коллекций - Размер данных - Состояние индексов - Производительность поиска
Логи N8N:
docker logs -f n8n
Логи Qdrant:
docker logs -f qdrant
Лучшие практики
Проектирование коллекции
Правила: 1. Размер вектора должен соответствовать модели эмбеддинга 2. Метрика расстояния: - Текст → COSINE - Изображения → EUCLID или COSINE - Специализированные → попробовать DOT_PRODUCT 3. Payload: только нужные метаданные (экономит память) 4. Индексы: создавать только для часто используемых фильтров
Подготовка данных
- Качество эмбеддингов:
- Использовать консистентный эмбеддер
- Нормализовать входные данные
-
Проверять размер вектора
-
Чанкирование:
- Размер 256-1024 токена
- Overlap 10-20%
-
Граница по логическим разделам
-
Метаданные:
- Включать источник (для контекста)
- Дату и версию
- Статус актуальности
Оптимизация производительности
| Проблема | Решение |
|---|---|
| Медленный поиск | Увеличить ef, создать индексы |
| Высокое потребление памяти | Квантизация, удалить старые данные |
| Неточные результаты | Увеличить чанк overlap, проверить эмбеддер |
| Медленное индексирование | Батчинг, увеличить потоки |
Обработка ошибок в N8N
1. Проверка подключения:
Qdrant node → "List Collections"
Если пусто → проверить credentials
2. Размер вектора:
// Проверка перед Upsert
if (embedding.length !== 1536) {
throw new Error("Vector size mismatch");
}
3. Обработка исключений:
Qdrant Query → Try/Catch → Fallback action
Резервные копии
Qdrant:
# Снятие снимка
curl -X POST http://localhost:6333/collections/documents/snapshots
# Восстановление
curl -X PUT http://localhost:6333/collections/documents/snapshots/restore \
-F snapshot=@snapshot.tar
Стратегия: - Еженедельные снимки - Хранить в S3 или облаке - Регулярно проверять восстановление
Масштабирование
Когда нужна оптимизация: - 100M+ точек → рассмотреть кластер - 1B+ точек → многоузловая архитектура - 10B+ точек → горизонтальное масштабирование
Стратегии: 1. Сегментирование по категориям 2. Мультиузловой кластер Qdrant 3. Фильтрование на уровне приложения
Безопасность
Обязательно: - Установить API key в production - Использовать HTTPS - Ограничить доступ по IP - Мониторить логи доступа
API Key в N8N:
Не сохранять в коде
Использовать N8N credentials
Ротировать ежемесячно
Шпаргалка: Быстрая справка
Создание и управление
List Collections → Получить все коллекции
Create Collection → Создать новую (указать имя, размер вектора, метрику)
Get Collection → Информация о коллекции
Delete Collection → Удалить (необратимо!)
Добавление данных
Upsert Points → Вставить или обновить точки
Structure: {id, vector, payload}
Поиск
Query Points → Поиск похожих
+ Filter → ограничение по условиям
Работа с метаданными
Set Payload → добавить/обновить поля
Create Payload Index → ускорить фильтрацию
Faceted Search → статистика по полям
Оптимизация
Индексы на часто фильтруемые поля
Квантизация для экономии памяти
Батчинг для массовых операций
Дополнительные ресурсы
Официальная документация
- Qdrant Docs: https://qdrant.tech/documentation/
- N8N Qdrant Integration: https://n8n.io/integrations/qdrant/
- N8N Docs: https://docs.n8n.io/
Python Клиент
pip install qdrant-client
Обучающие материалы
- YouTube: "Qdrant Tutorial"
- GitHub: qdrant/qdrant-examples
- Habr: статьи про Qdrant и RAG
Дата создания: November 2025
Версия: 1.0
Язык: Русский
Для кого: Разработчики, автоматизаторы, Data scientists