Семантический поиск в PostgreSQL с использованием pgvector и Node.js: нет необходимости в LLM
Семантический поиск в PostgreSQL с использованием pgvector и Node.js без ИИ-моделей: эмбеддинги MiniLM, разбиение данных на чанки, индекс IVFFlat, операторы расстояний и способы чтения оценок.
Источники: Talk to Your Database Like a Human — No LLM Required: Semantic Search with Node.js + PostgreSQL
База данных может отвечать на вопросы, сформулированные на обычном английском языке, без использования каких-либо языковых моделей. Это становится возможным благодаря векторному поиску. С помощью Node.js, PostgreSQL и расширения pgvector можно создать систему, которая ищет по смыслу вопроса, а не по ключевым словам; единственной используемой моделью является небольшая модель вкладки, преобразующая текст в числа.
Реляционные базы данных всегда отлично справлялись с хранением и извлечением данных, при условии, что задавались точно правильные вопросы. Точное совпадение, фильтры и структурированные запросы — мощные инструменты, но они ограничены. Векторные базы данных, по-видимому, решают другую проблему: поиск в неструктурированном контенте по его смыслу, а не по содержащимся в нем словам.
Четыре термина, которые стоит прояснить
Токен. Самая маленькая единица текста, с которой работает модель. Токены не всегда являются целыми словами. Токен может быть полным словом, таким как «hello», фрагментом (например, «unbelievable» может разделиться на «un», «believ» и «able»), отдельным символом, таким как «!», или небольшой частью знаков препинания или пробелов. Фраза вроде «ChatGPT is great» может быть разделена на «Chat», «G», «PT», «is» и «great».
Фрагмент. Небольшой самодостаточный участок более крупного документа, обычно несколько предложений или один абзац. Передача всего документа за один раз работает плохо, поэтому его сначала делят на фрагменты. Разделение на фрагменты ускоряет обработку, повышает точность поиска и обеспечивает релевантность результатов запросу.
Эмбеддинг. Числовой аналог текста, изображения или аудиофайла, отражающий его смысл. Его генерирует модель машинного обучения, например MiniLM. Эмбеддинг можно рассматривать как суть данных.
Вектор. Форма, в которой хранится эмбеддинг: массив чисел.
[0.2, -0.5, 0.9, ...]
Это форма, которая сохраняется в памяти и в PostgreSQL после установки такого расширения, как pgvector.
В общем, суть заключается в следующем: слова, предложения или изображения преобразуются в эмбеддинги. Объекты с похожими значениями оказываются рядом друг с другом в векторном пространстве, а несвязанные объекты — дальше друг от друга. Строка вроде «Hello world» превращается в длинный список чисел с плавающей точкой:
// "Hello world" turns into this embedding:
const embedding = [0.01, -0.42, 0.15, ..., 0.99]; // ← this is a vector
И этот список затем сохраняется рядом с исходным текстом:
INSERT INTO documents (content, embedding)
VALUES ('Hello world', embedding);
Почему реляционная база данных недостаточна
Традиционная RDBMS работает с таблицами, строками и столбцами. Она без труда обрабатывает запросы вроде «все тикеты со статусом OPEN» или «пользователи, созданные после 2024 года». Однако современные приложения также работают с документами, разговорами, изображениями и аудиофайлами. Точное совпадение здесь малоэффективно.
Векторная база данных хранит эмбеддинги вместе с данными и находит элементы по сходству и контексту. Таким образом, вместо запроса на документы, содержащие слово «ошибка», можно запросить документы о проблемах аутентификации, и они будут получены даже в том случае, если слово «ошибка» там вообще не встречается. Сравнение осуществляется по математическому расстоянию между векторами, а не по совпадению текста.
Типичная схема работы выглядит следующим образом:
- Поступает сырой контент: документы, тикеты или что-либо ещё.
- Модель вживления преобразует текст в векторы.
- Эти векторы хранятся, например, в PostgreSQL с использованием pgvector.
- Индекс приблизительного ближайшего соседа (ANN) обеспечивает быстрые поиски.
- Запрос пользователя также преобразуется в вектор.
- База данных возвращает векторы, наиболее близкие к нему, то есть имеющие наибольшее сходство по смыслу.
Что это позволяет:
- Семантический поиск, основанный на смысле запроса, а не только на его точных словах.
- Долгосрочную память для LLM путем хранения прошлых взаимодействий, документов или фактов, которые модель может вспомнить, даже если они отсутствовали в её обучающих данных.
- Рекомендации путем нахождения элементов или поведений, схожих друг с другом в пространстве вживления.
- Поиск сходства в тексте, изображениях, аудио или видео.
PostgreSQL как хранилище векторов
Для всего этого вам не обязательно подбирать новую базу данных. Благодаря pgvector PostgreSQL может хранить эмбеддинги напрямую, выполнять запросы на поиск сходства и использовать такие индексы, как IVFFlat, чтобы сохранять высокую скорость работы. Ваша существующая база данных просто приобретает новую функциональность — от хранения данных до возможности сравнения их смысла. Поиск теперь заключается не в совпадении слов, а в совпадении смыслов.
Пошаговая настройка
1. Установите PostgreSQL и включите pgvector. Скачайте PostgreSQL с официальной страницы загрузки, подключитесь к базе и включите дополнение:
CREATE EXTENSION IF NOT EXISTS vector;
2. Создайте таблицу документов. В ней хранится сырой текст и его эмбеддинг. Число 384 в определении указывает на размер выходных данных модели all-MiniLM-L6-v2.
-- Note: 384 is the embedding size output by all-MiniLM-L6-v2
CREATE TABLE documents (
id SERIAL PRIMARY KEY,
content TEXT,
embedding VECTOR(384)
);
3. Добавьте векторный индекс. Чтобы обеспечить эффективность поиска по сходству, используйте индекс приблизительного ближайшего соседа:
CREATE INDEX documents_embedding_idx
ON documents
USING ivfflat (embedding vector_l2_ops)
WITH (lists = 100);
Здесь используется IVFFlat для быстрых приблизительных поисков, измерения производится с учётом расстояния L2 (евклидова), а векторы делятся на 100 кластеров.
4. Соотнесите оператор запроса с индексом. Оператор в вашем запросе должен совпадать с классом операторов, с использованием которого был построен индекс. pgvector предлагает несколько операторов, каждый из которых соответствует своему классу. В приведённом примере используется оператор <#>, а также настраивается параметр vector_l2_ops. Обратите внимание, что в документации pgvector расстояние L2 обычно обозначается с помощью <->, а <#> — отрицательное скалярное произведение; поэтому убедитесь, что ваш запрос и индекс согласуются между собой.
5. Запустите проект. Полный рабочий пример находится в репозитории GitHub под названием vectorgarquer/vectorized-database-embeddings. Клонируйте или форкните его, затем установите необходимые зависимости:
npm install
Скопируйте файл .env.example в файл .env в корне проекта и укажите там детали подключения к PostgreSQL. Затем запустите его:
npm start
6. Наблюдайте за процессом поиска. После запуска программа подключается, вставляет эмбеддинги и выполняет семантический поиск без дополнительных вводов. Затем вы можете подавать ей собственные данные и запросы. В примере показан поиск фразы «Что означает генеративный ИИ?», а найденные в базе данных результаты отображаются следующим образом:
Search Results:
[1] Distance: -0.7562
n be represented in another modality such as text.
2.2 A Model-, System-, and Application-Level View
of Generative AI
2.2.1 Model-Level View
A generative AI model is a type of machine learning
architecture that uses AI algorithms to create novel data
instances, drawing upon the patterns and relationships
observed in the training data. A generative AI model is of
critically central yet incomplete nature, as it requires fur-
ther fine-tuning to specific tasks thro
[2] Distance: -0.7562
n be represented in another modality such as text.
2.2 A Model-, System-, and Application-Level View
of Generative AI
2.2.1 Model-Level View
A generative AI model is a type of machine learning
architecture that uses AI algorithms to create novel data
instances, drawing upon the patterns and relationships
observed in the training data. A generative AI model is of
critically central yet incomplete nature, as it requires fur-
ther fine-tuning to specific tasks thro
[3] Distance: -0.7562
n be represented in another modality such as text.
2.2 A Model-, System-, and Application-Level View
of Generative AI
2.2.1 Model-Level View
A generative AI model is a type of machine learning
architecture that uses AI algorithms to create novel data
instances, drawing upon the patterns and relationships
observed in the training data. A generative AI model is of
critically central yet incomplete nature, as it requires fur-
ther fine-tuning to specific tasks thro
[4] Distance: -0.7562
n be represented in another modality such as text.
2.2 A Model-, System-, and Application-Level View
of Generative AI
2.2.1 Model-Level View
A generative AI model is a type of machine learning
architecture that uses AI algorithms to create novel data
instances, drawing upon the patterns and relationships
observed in the training data. A generative AI model is of
critically central yet incomplete nature, as it requires fur-
ther fine-tuning to specific tasks thro
[5] Distance: -0.7094
assistants, personalized education and service, and digital
art. As such, generative AI has substantial implications for
BISE practitioners and scholars as an interdisciplinary
research community. In our Catchword article, we offered
a conceptualization of the principles of generative AI along
a model-, system-, and application-level view as well as a
social-technical view and described limitations of current
generative AI. Ultimately, we provided an impactful
rese
Чтение результата
После выполнения программы вы получаете список вот такого вида:
Search Results:
[1] Distance: -0.7562
...
[5] Distance: -0.7094
...
Расстояние показывает, насколько близок сохранённый фрагмент к эмбеддингу запроса. И фрагмент, и запрос преобразуются в векторы, после чего PostgreSQL с pgvector определяет их расстояние друг от друга. Правило простое: чем меньше расстояние, тем больше сходство содержимого.
Значения бывают отрицательными, например:
-0.7562
Это происходит потому, что оператор <#> возвращает отрицательное значение, благодаря чему обычный сортировщик размещает наиболее близкие к результату строки в начале списка. На практике чем более отрицательное число, тем более близкое и релевантное совпадение, а число, близкое к нулю, указывает на менее сильную релевантность.
Если посмотреть на рейтинг, результаты с номерами 1 по 4 имеют одинаковый балл — -0.7562, поэтому они одинаково релевантны запросу. Результат с номером 5 имеет балл -0.7094, что также свидетельствует о релевантности, но с меньшей степенью сходства.
Вы также можете заметить несколько результатов с практически идентичным текстом. Это ожидаемо: исходный документ был разделен на фрагменты, соседние фрагменты перекрываются или содержат повторяющийся похожий контент, причем у каждого фрагмента есть своя векторная представление.
Что показывают результаты
Даже при отсутствии ЯЗЫКОВЫХ МОДЕЛЕЙ в момент поиска система всё равно понимала смысл, а не только ключевые слова, находила текст, соответствующий контексту, и ранжировала его по векторному сходству. Возвращаемые фрагменты сосредотачивались вокруг моделей генеративного ИИ, уровня модели и архитектуры машинного обучения, так что поиск явно работал на уровне концепций, а не точных слов.
Результатом стал семантический поисковик, встроенный в PostgreSQL. Для выполнения запросов не требуется ЯЗЫКОВАЯ МОДЕЛЬ, отдельной векторной базы данных тоже нет — всю работу выполняют эмбеддинги вместе с pgvector.
Связанные материалы
- Семантическое кэширование для агентов LLM с использованием Redis: сокращение затрат и задержек — Как семантическое кэширование снижает расходы и задержки при работе с LLM: использование эмбеддингов, пороговых значений, Redis и RedisVL, настройка точности, а также кэширование подзадач внутри рабочих процессов агентов.
- Почему агентам для анализа данных в AI нужен семантический слой вместо чистого SQL — Преобразование текста в SQL на основе сырых таблиц хранилища приводит к созданию некорректных метрик и игнорированию прав доступа. Узнайте, как семантический слой вроде Cube в сочетании с MCP придаёт агентам управляемый бизнес-смысл.