Всё началось с простой задачи — хранить эмбеддинги. Звучит несложно. Но я потратил недели три, прежде чем понял: выбор базы — это не технический вопрос. Это вопрос о том, чего именно ты хочешь от системы.
Попробовал три варианта: Pinecone, Weaviate и pgvector. У каждого нашлись свои странности.
Pinecone: когда всё работает, пока не нужно что-то нестандартное
Начал с Pinecone — его рекомендовали везде. Зарегистрировался, получил API-ключ, загрузил первую тысячу векторов. Всё правда полетело. Первый поиск по схожести я сделал минут за двадцать, включая время на чтение документации.
Потом начались вопросы.
Мне нужна была фильтрация по метаданным: отбирать документы из конкретного временного промежутка и одновременно искать по близости вектора. В теории Pinecone это умеет. На практике я наткнулся на ограничение — если фильтр слишком жёсткий и отсеивает большую часть индекса, качество поиска падает. Есть даже термин для этого: "filter narrowing". Pinecone честно пишет об этом в документации, но когда сталкиваешься впервые, это неприятный сюрприз.
Дело в том, что Pinecone — полностью управляемый сервис. Self-hosted варианта нет. Данные лежат у них. Для прототипа это нормально, но если нужна изоляция или политика компании запрещает внешние сервисы — выбора не будет.
Бесплатный тир: один индекс, два гигабайта. Я упирался в него регулярно. Платный план начинается от 70 долларов в месяц — для пет-проекта ощутимо.
Weaviate: мощно, но входной порог выше
После Pinecone решил попробовать Weaviate. Первые полчаса смотрел на схему данных и думал, что выбрал не то.
Weaviate строится вокруг концепции объектов со схемой — что-то среднее между документной базой и векторным хранилищем. Перед загрузкой векторов нужно описать класс: поля, типы, конфигурацию индексирования. Лишние шаги в начале, зато потом появляется гибкость, которой в Pinecone нет.
Что по-настоящему зацепило — гибридный поиск из коробки. Weaviate сочетает BM25 с векторным поиском в одном запросе, параметром alpha управляешь балансом между ними. Для поиска по документам это часто работает лучше, чем чистый семантический поиск. Не всегда, но заметно часто.
Self-hosted вариант есть и работает. Я запускал через Docker: docker-compose.yml из документации, пара команд — и локально всё крутится.
Одна вещь регулярно раздражала: GraphQL API. Weaviate исторически использует его как основной интерфейс, и синтаксис своеобразный. Несколько раз писал запрос, который выглядел правильным, но падал из-за какой-то тонкости в структуре фильтра. REST API тоже есть, но покрывает не всё. В последних версиях появился нормальный Python-клиент, который прячет GraphQL под капотом — с ним стало лучше.
Производительность на больших объёмах хорошая. Под капотом HNSW-индекс, параметры можно настраивать довольно тонко.
pgvector: «а зачем нам вообще отдельная база»
pgvector я рассматривал как запасной вариант. В итоге именно он остался у меня для большинства задач.
Это расширение для PostgreSQL, которое добавляет тип данных vector и операторы поиска — по косинусному расстоянию, евклидову, скалярному произведению. Если PostgreSQL уже есть, установка занимает одну команду:
CREATE EXTENSION vector;
Дальше создаёшь таблицу с колонкой vector(1536) — число это размерность, для эмбеддингов OpenAI Ada это 1536 — и всё. Обычный INSERT, обычный SELECT, только с векторным оператором в WHERE или ORDER BY.
Суть вот в чём: весь остальной SQL работает как всегда. Мне нужна была фильтрация по дате, по пользователю, по статусу документа — плюс поиск по схожести вектора. В pgvector это просто обычные WHERE-условия рядом с векторным поиском. Никакого "filter narrowing", никакой отдельной схемы.
Если Postgres уже в инфраструктуре, pgvector — это буквально ноль дополнительных сервисов. Миграции через Alembic или что там уже есть, бэкапы теми же инструментами, мониторинг тот же. Я потратил день на интеграцию вместо недели.
Где pgvector проигрывает — масштаб. При миллионах векторов и высокой нагрузке специализированные базы окажутся быстрее. HNSW-индекс появился в версии 0.5.0 и сильно улучшил ситуацию, но Pinecone или Weaviate на больших объёмах всё равно обгонят. И ещё: если векторы — это вся суть системы и реляционных данных вокруг нет, тащить PostgreSQL ради векторов избыточно.
Как я в итоге выбираю
Примерно такое правило у меня сложилось. Если уже есть Postgres и задача средних размеров — pgvector, без вопросов. Если нужен гибридный поиск или сложная мультивекторная логика — смотрю на Weaviate. Если хочется быстро запустить прототип и не думать об инфраструктуре — Pinecone, но с пониманием, что потом, возможно, придётся переезжать.
Отдельная история — Qdrant, который я не трогал в этом разборе. Он активно развивается и в некоторых бенчмарках смотрится интересно. Может, в следующий раз.
Что оказалось важнее, чем я думал
Когда читаешь сравнения векторных баз, все смотрят на скорость поиска и точность ANN. Это важно. Но не это оказалось узким местом в моей работе.
Узким местом оказалась интеграция с остальной системой. Как хранить метаданные рядом с вектором. Как делать транзакции, если нужно обновить и вектор, и связанный документ атомарно. Как откатываться, если что-то пошло не так при загрузке.
В Pinecone и Weaviate это отдельные системы, и синхронизация с основной базой — твоя головная боль. В pgvector этой проблемы просто нет: всё в одной базе.
Это не делает pgvector лучшим выбором по умолчанию. Это просто означает, что вопрос "какая база быстрее ищет" — далеко не единственный, который стоит задать.
