ADG Оставить заявку
Блог Данные и аналитика 5 мин чтения

Векторные БД для корпоративного поиска: pgvector против выделенных решений

Строим RAG-систему и упираемся в вопрос хранения эмбеддингов. Сравниваем pgvector, Chroma и Weaviate - и почему для старта выбрали расширение PostgreSQL.

Контекст момента

Векторные базы данных (Chroma, Weaviate, pgvector) становятся инфраструктурным компонентом LLM-систем

После того как мы собрали первый RAG-прототип с LangChain и Chroma для поиска по корпоративным регламентам, заказчик задал логичный вопрос: «А это будет работать на нормальном объёме?». Chroma в режиме embedded - это удобно для прототипа, но не для продакшна с несколькими источниками данных и возможным ростом корпуса. Пришлось садиться и разбираться с тем, что вообще есть на рынке векторных хранилищ и как это соотносится с нашей инфраструктурой.

Спойлер: выбрали pgvector. Не потому что он лучший по всем параметрам, а потому что оказался достаточным - и это важное различие.

Зачем вообще нужна отдельная БД для векторов

Чтобы не тратить время читателя: эмбеддинги - это числовые векторы в нескольких сотнях или тысячах измерений, которые кодируют смысл текста. При поиске мы ищем не по ключевым словам, а по близости векторов в многомерном пространстве. Обычная реляционная база для этого не приспособлена: посчитать косинусное расстояние между двумя массивами из 1536 float-чисел для тысяч записей в честном SQL - это либо медленно, либо не работает без специального индекса.

Отсюда и появились специализированные векторные БД.

Что смотрели

На момент нашего разбора основные кандидаты выглядели так:

Chroma - то, с чего мы начали. Embedded-режим разворачивается в Python-процессе без сервера, персистит на диск. Есть и клиент-серверный режим. Активно развивается, API ещё не устоялся, документация за кодом не успевает. Для прототипа - отлично, для продакшна нужно внимательно смотреть.

Weaviate - выделенный сервис с GraphQL API, поддержкой мультимодальных данных и встроенными модулями для генерации эмбеддингов прямо внутри БД. Серьёзный продукт с богатыми возможностями. Разворачивается через Docker, есть Kubernetes Helm-чарт. Если нужен полноценный векторный магазин с гибкими схемами данных - это сильный вариант. Цена: отдельный сервис в инфраструктуре, который надо администрировать, мониторить и бэкапить.

Qdrant - ещё один выделенный сервис, написан на Rust, позиционируется как высокопроизводительный. Более свежий проект, чем Weaviate, но API понятный, документация приличная. Тоже требует отдельного деплоя.

pgvector - расширение для PostgreSQL. Добавляет тип vector(N) и индекс IVFFlat для приближённого поиска. Запросы пишутся на обычном SQL через операторы близости (<-> для L2, <=> для косинусного расстояния). Актуальная версия на момент написания - 0.4.0 (январь 2023).

Почему остановились на pgvector

Контекст проекта: у клиента уже стоит PostgreSQL 15 в продакшне, настроен нормально, есть резервирование, мониторинг, бэкапы. Команда умеет с ним работать.

Добавление pgvector - это CREATE EXTENSION vector; и несколько минут. Новый компонент в инфраструктуре не появляется. Бэкап векторов едет вместе с остальными данными в pg_dump или в потоковую репликацию. Это чертовски важно, если команда не большая и администрировать «ещё одну базу данных» особо некому.

Что проверяли практически:

  • Индекс IVFFlat строится с параметром lists - количество списков кластеров. Для корпуса в несколько десятков тысяч документов с размерностью 1536 (ada-002) время ответа получается приемлемым. Не мгновенным, но приемлемым - поиск top-5 в пределах секунды.
  • Точность поиска в сравнении с Chroma на том же корпусе оказалась практически одинаковой на нашей тестовой выборке вопросов. ANN-алгоритмы обоих решений дают похожие результаты при умеренных размерах базы.
  • SQL как язык запросов - это неожиданный плюс. Можно фильтровать по метаданным прямо в одном запросе: поиск ближайших векторов среди документов определённого отдела, с датой не раньше заданной - это обычный WHERE, без изучения чужого API.

Где pgvector проигрывает: при очень большом корпусе (миллионы векторов) и требованиях к латентности в десятки миллисекунд выделенные решения начинают выигрывать. У Weaviate и Qdrant HNSW-индексы встроены глубже, тюнинг под производительность богаче. Но это не наш случай прямо сейчас.

Практика хранения: что важно

Независимо от выбора векторной БД, мы зафиксировали несколько вещей, которые горели на прототипе:

  • Метаданные хранить рядом с вектором, обязательно. Источник документа, дата, раздел - без этого ответ системы не верифицируем. В pgvector это просто колонки той же таблицы.
  • Document ID и переиндексация. При обновлении документа нужно удалить старые векторы и добавить новые. Инкрементальное обновление требует стабильных идентификаторов чанков - если генерировать их на лету без привязки к исходному контенту, при переиндексации получим дубли.
  • Размер чанка влияет на качество поиска сильнее, чем выбор БД. Это неочевидный вывод, но он честный: правильная стратегия разбивки документов даёт больший прирост качества ответов, чем переход с одного хранилища на другое.

Где сейчас

Архитектуру с pgvector развернули на тестовом стенде клиента. Postgres-инстанс тот же, расширение установлено, таблица document_chunks с колонкой embedding vector(1536) и метаданными работает. LangChain подключается через PGVector-интегратор - он есть в составе langchain, без дополнительных зависимостей.

Следующий шаг - нагрузочный тест на реальном объёме документов и решение про инкрементальное обновление индекса. Если корпус вырастет кратно - будем смотреть на Weaviate отдельно. Пока оснований переезжать нет.

Задача по аналитической инфраструктуре и работе с данными часто упирается именно в такие выборы: не «какой инструмент лучший», а «какой инструмент достаточен при нашем операционном контексте».

Контакт

Нужна такая же инженерная работа?

Опишите задачу и контекст. Ответим в течение рабочего дня, при необходимости подпишем NDA.