- Формат
- Разбор архитектурного решения + методология выбора
- Контекст
- Self-hosted PostgreSQL + Hasura, русскоязычная ПСД, тысячи проектов
- Цель
- Институциональная память → «цифровой инженер» с RAG и обязательными цитатами
- Кандидаты
- pgvector · Qdrant · pgvectorscale · ParadeDB · Milvus / Weaviate
- Эмбеддинги
- bge-m3 · multilingual-e5 · DashScope · 1024-dim
- Свежесть
- Ландшафт 2025–2026, источники с датами в конце
Неправильный первый вопрос
Когда команда хочет «умный поиск по архиву проектов», первым обычно звучит вопрос про инструмент: Qdrant, pgvector, Pinecone, Milvus? Это понятно — выбирать технологию приятнее, чем разбираться в задаче. Но если начать отсюда, почти гарантированно получишь красивую векторную базу, которая отвечает не на те вопросы.
Я предлагаю молодым коллегам другой порядок. Сначала — что ищут и что храним. Потом — критерии выбора. И только в самом конце — название продукта. Девять из десяти «споров о векторной базе» растворяются, как только сделаешь первые два шага. Пройдём их вместе.
Сначала разберись, что на самом деле ищут
Соблазн — представить поиск как фильтр по числам: «сваи длиной больше 15 метров», «плиты толщиной свыше 500 мм». Такие запросы бывают, но это редкий, вспомогательный случай. Настоящее переиспользование инженерного опыта идёт по соответствию условий и ограничений:
- тип и характеристики грунтов, гидрогеология, сейсмичность, особые условия (просадочность, карст, подтопление, мерзлота);
- ограничения, выявленные в ходе инженерных изысканий и на площадке: стеснённость, близость существующих зданий и сетей, охранные зоны, геотехнические риски;
- планировка и функциональный тип объекта;
- и просто семантика текста пояснительных записок и проектных решений.
Инженер спрашивает не «дай мне позиции с числом больше X», а «как мы решали при похожих условиях и ограничениях, и что в итоге сработало». Это так называемый case-based reasoning — подбор прецедентов по профилю условий.
Отсюда сразу два вывода. Первый: семантический поиск — ведущий, а не приправа к SQL. Второй, и более важный: ценность определяет не векторная база, а то, насколько качественно ты извлёк из документов «профиль условий и решений» — грунты, ограничения изысканий, планировку, применённые решения и их результат. Плохая экстракция — и никакой Qdrant не спасёт. Сюда идут главный риск и основные усилия.
Ландшафт 2026 без рекламы
Теперь, держа задачу в голове, посмотрим на инструменты честно — с трейд-оффами, а не лозунгами.
pgvector — вектора прямо внутри PostgreSQL, дефакто-стандарт.
Версия 0.8.2, требует PostgreSQL 13+. Тип vector
индексируется до 2000 измерений, halfvec — до 4000.
Два индекса: HNSW (быстрее запрос, дороже сборка и память в 2–5 раз)
и IVFFlat (наоборот). Гибрид с полнотекстом собирается вручную и
сливается формулой RRF.
Экосистема вокруг Postgres. pgvectorscale добавляет индекс StreamingDiskANN с выносом части данных на диск. ParadeDB / pg_search даёт настоящий BM25 прямо в Postgres (это расширение, а не форк) — полезно, когда важны точные шифры и ГОСТ. VectorChord — нативный BM25 плюс вектора с акцентом на баланс память/диск. Громкий маркетинговый бенчмарк «pgvectorscale в 28 раз быстрее Pinecone» я при проверке отбросил как невоспроизводимый — отношусь к нему как к рекламе.
Qdrant — выделенный движок на Rust. С версии 1.10 есть Query API с нативным гибридом dense+sparse и встроенным RRF — внешний BM25 не нужен. Сильные стороны: квантизация (скалярная −4×, бинарная −32×, оригиналы на диске) и изоляция данных по коллекциям. Это важно, когда у тебя продукт с многими клиентами. Цена — отдельный сервис в эксплуатации.
Milvus и Weaviate — мощные, но их профиль это распределённые кластеры и миллиарды векторов. Для одного-нескольких узлов это избыточный операционный вес. Chroma — хороша для прототипа, но как основное хранилище под серьёзный архив слабовата.
Как выбирать: критерии, а не хайп
Технология должна следовать из ограничений. И тут есть тонкость, которую я всегда подсвечиваю: рамка задачи меняет ответ. Если это внутренний инструмент на одном сервере — побеждает простота эксплуатации, и часто хватает pgvector. Если это продукт (SaaS плюс поставка on-prem), где качество поиска и есть ценность для пользователя, — веса критериев смещаются: на первый план выходят качество подбора, изоляция клиентов и готовность расти.
Полезное упражнение — выписать критерии и честно проставить веса под свою рамку, а не под чужую статью. У продукта с тысячами проектов это выглядит примерно так:
- Качество семантического подбора по условиям — самый тяжёлый критерий, это товар.
- Изоляция клиентов (мультитенантность) — обязательна для SaaS.
- Точный поиск по шифрам и ГОСТ — BM25 рядом с векторами.
- Память и ресурсы — особенно для скромных on-prem-инсталляций.
- Простота эксплуатации — каждая лишняя система это бэкап, мониторинг и точка отказа.
- Готовность к дообучению — об этом ниже, но закладывать надо сразу.
Архитектура «инженерной памяти»
Ключевая мысль, которую я хочу передать: хранить надо не файлы, а извлечённые знания. Архив превращается в память не тогда, когда лежит в красивой базе, а когда из каждого проекта вынут профиль условий и решений. Поэтому правильная картинка — многослойная:
- Озеро документов (MinIO / S3). Оригиналы PDF, DWG, RVT, IFC, XLSX лежат отдельно. On-prem, дёшево, масштабируемо.
- Извлечение (парсер + LLM-экстрактор). Главный слой и главный риск: достаём профиль условий, ограничений, применённых решений и результата. BIM/IFC берём структурно, а не превращаем в текст.
- Структура и метаданные (PostgreSQL + Hasura). Категории условий (грунты, сейсмичность), фасеты-фильтры, точные шифры и ГОСТ (BM25), происхождение данных. Этот слой не выбрасываем.
- Семантика (Qdrant или pgvector). Подбор прецедентов по соответствию условий, гибрид dense+sparse, изоляция по клиентам, квантизация под скромную память.
- Связи (граф — фаза зрелости). «Условия → применённые решения → результат». Старт можно на реляционке в Postgres, полноценный граф (Apache AGE → Neo4j) — когда обходы связей реально понадобятся.
- Ответ (reranker + LLM). Переранжирование и синтез ответа с обязательными цитатами на источник. Плюс сбор обратной связи — он же датасет для будущего дообучения.
Обрати внимание: векторная база здесь — лишь один из шести слоёв. Поэтому спор «Qdrant или pgvector» и стоит на четвёртом месте, а не на первом.
Развилка: одно хранилище или два — и что делать со старым Postgres
Под продуктовые критерии (много клиентов, поиск это ценность, рост до миллионов фрагментов) семантический слой я бы строил на Qdrant: изоляция коллекциями, фильтрация по полям вместе с вектором, квантизация под on-prem, нативный гибрид. Но — и это принципиально — PostgreSQL из схемы не убираем: он несёт точные коды, категории условий и происхождение данных. То есть здесь два хранилища оправданы.
Честная оговорка без хайпа: для малых on-prem-инсталляций (один институт, десятки тысяч фрагментов) pgvector внутри Postgres достаточен и дешевле в эксплуатации. Поэтому правильная стратегия — абстракция векторного слоя: крупные инсталляции едут на Qdrant, лёгкие — на pgvector. Ложная дилемма «или-или» снимается.
| Критерий | Qdrant (основной слой) | pgvector (лёгкий on-prem) |
|---|---|---|
| Изоляция клиентов | Коллекция на клиента | Схема / RLS в Postgres |
| Фильтр + вектор | Нативно, в одном запросе | Через SQL-условия |
| Экономия памяти | Квантизация −4× / −32× | halfvec −2×, binary −16× |
| Нативный гибрид | dense+sparse+RRF из коробки | tsvector / ParadeDB + RRF вручную |
| Простота поставки | Отдельный сервис | В той же БД, рядом с Hasura |
Отдельная история — старый PostgreSQL 12, на котором
нередко стоит прод. Его надо обновлять независимо от векторов: он
достиг конца жизненного цикла в ноябре 2024 года, без обновлений
безопасности. И частый страх «апгрейд это долгий простой и полный
dump/restore» — миф: pg_upgrade делает мажорный апгрейд
на месте, напрямую с версии 9.2 и выше, а Hasura поддерживает все
актуальные версии. Раз обновлять всё равно нужно — заодно исчезает
единственный блокер pgvector (ему требуется 13+).
Эмбеддинги для русского и прицел на дообучение
Размерность вектора — это про память и индекс, а не только про
качество. 1024 измерения — хороший баланс; 1536 или
4096 раздувают индекс без явного выигрыша на нашем масштабе. Если
памяти мало — halfvec ужимает хранение вдвое.
Ориентиры по русскому языку даёт бенчмарк ruMTEB: инструктивные мультиязычные e5 показывают 64.7–64.9, BGE-M3 — 60.8, ru-en-RoSBERTa и multilingual-e5-large — по 60.4. BGE-M3 удобна тем, что умеет dense, sparse и late-interaction в одной модели — это хорошо ложится на технический текст; deepvk/USER-bge-m3 дотюнена под русский. Облачный DashScope text-embedding-v3 удобен для быстрого старта без своего GPU, но его нет в ruMTEB — качество на русской документации стоит проверить на своих запросах с шифрами, прежде чем закладывать в прод. Reranker (bge-reranker-v2-m3, Qwen3-Reranker) поверх первых полусотни результатов оправдан, раз качество поиска это товар.
И самое важное для тех, кто думает на шаг вперёд про дообучение модели. Оно начинается не с дорогого fine-tune самой LLM, а с дешёвого шага — доменной адаптации эмбеддингов на парах «запрос ↔ релевантный фрагмент». Чтобы эти пары были, структуру данных надо закладывать с первого дня: храни raw-документ, извлечённые сущности, фрагменты, версию модели и экстрактора, происхождение (проект, файл, страница), оценки пользователей «релевантно / нет» и финальные пары «вопрос → ответ с цитатами». Это одновременно обучающий и проверочный наборы.
Эксплуатация, о которой забывают на старте
- Бэкап двух хранилищ. Postgres — обычный
pg_dumpи PITR; Qdrant — снапшоты коллекций. Источник истины — Postgres, вектора пересобираемы, поэтому консистентность держится идемпотентным пайплайном. - Версии эмбеддингов. Сменил модель — изменилось векторное пространство, старые и новые вектора несравнимы. Храни версию модели в записи, а смену планируй как переэмбеддинг всего архива (пишем в новую коллекцию, потом переключаемся).
- Ребилд индекса. Сборка HNSW памятозатратна: делай её в нерабочее окно с поднятым
maintenance_work_mem; квантизация и halfvec снижают давление.
Что я в итоге советую
Если свести разбор к нескольким мыслям, которые я хотел бы, чтобы молодой коллега унёс с собой:
- Начинай не с базы, а с задачи. На инженерном архиве ищут по соответствию условий и ограничений — это семантика, и она в ядре.
- Главная работа — извлечение профиля условий и решений, а не выбор движка. Плохая экстракция обесценивает любую базу.
- Не выбрасывай Postgres. Точные коды, категории и происхождение данных живут там; вектор и граф его дополняют, а не заменяют.
- Qdrant — для продукта и крупных инсталляций, pgvector — для лёгких, через общую абстракцию. Конкретный движок это заменяемая деталь.
- Старый Postgres обновляй на месте — это не страшно и всё равно нужно.
- Думаешь о дообучении — готовь данные сразу, с версиями, провенансом и разделением по клиентам.
Этот разбор вырос из работы над ПИР-Системой — платформой для проектно-изыскательских работ с ИИ-помощником вокруг исходно-разрешительной документации. Там вопрос «как хранить и искать инженерные знания» стоит не в теории, а на проде.
Источники
- pgvector — README (0.8.2, требования PG13+, halfvec, гибрид + RRF) — акт. 2026
- J. Katz — скалярная и бинарная квантизация в pgvector
- pgvectorscale — индекс StreamingDiskANN
- ParadeDB / pg_search — нативный BM25 в Postgres
- VectorChord — гибрид BM25 + вектора в Postgres
- Qdrant — нативный гибрид, Query API v1.10, RRF
- Qdrant — квантизация (scalar −4×, binary −32×)
- PostgreSQL — политика версий и конец жизни PG12 (ноябрь 2024)
- pg_upgrade — апгрейд на месте с версии 9.2+
- Hasura — поддержка версий PostgreSQL
- ruMTEB / ru-en-RoSBERTa — бенчмарк русских эмбеддингов
- deepvk/USER-bge-m3 — эмбеддинги под русский
- MinIO — S3-совместимое объектное хранилище on-prem
Помечено как «требует проверки»: качество DashScope text-embedding-v3 на русском (нет в ruMTEB); качество русских reranker-моделей; recall Qdrant на 1024-dim (доступная цифра относится к 1536-dim).