Головна / Статті

Семантичний пошук у PostgreSQL за допомогою pgvector та Node.js — без необхідності в LLM

Семантичний пошук у PostgreSQL за допомогою pgvector та Node.js без ШІ: ембеддинги MiniLM, чанки, індекс IVFFlat, оператори відстані та спосіб читання оцінок.

Видавець: REACTAPP.TOP8 хв читання1884 слів

Джерела: 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 року“. Однак сучасні додатки також мають справу з документами, розмовами, зображеннями та аудіо. Точне зіставлення майже нічого не дає у цих випадках.

Векторна база даних зберігає ембеддинги разом із даними та знаходить елементи за схожістю та контекстом. Тож замість того, щоб шукати документи, які містять слово „error“, можна шукати документи про проблеми з автентифікацією та отримати їх навіть у тому випадку, якщо слово „error“ ніколи не з’являється. Порівняння відбувається за математичною відстанню між векторами, а не за зіставленням тексту.

Звичайний процес виглядає так:

  1. Надходить сирий контент: документи, тикети чи щось інше.
  2. Модель ембеддингу перетворює його на вектори.
  3. Вектори зберігаються, наприклад, у PostgreSQL за допомогою pgvector.
  4. Індекс найближчих сусідів (ANN) забезпечує швидке пошукове запитування.
  5. Запит користувача також перетворюється на вектор.
  6. База даних повертає вектори, які знаходяться найближче до нього, тобто ті, що мають найбільшу схожість за значенням.

Що це дозволяє:

  • Семантичний пошук, заснований на значенні запиту, а не лише на його точних словах.
  • Довгострокову пам’ять для 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, що також є актуальним, але з меншою схожістю.

Ви також можете помітити кілька результатів із майже ідентичним текстом. Це цілком очікувано. Вихідний документ був розділений на фрагменти, сусідні фрагменти перекриваються або повторюють схожий контент, і кожен з них має власне вбудовування.

Що показує результат

Навіть у відсутності LLM під час запиту система все одно розуміла сенс, а не лише ключові слова, знаходила текст, який відповідав контексту, та ранжувала його за векторною схожістю. Отримані уривки були згруповані навколо моделей генеративного ШІ, рівня моделі та архітектури машинного навчання, тож пошук чітко функціонував на рівні концепцій, а не точних слів.

Результатом є семантичний пошуковий двигун, який існує всередині PostgreSQL. Для виконання запитів не потрібен LLM, немає окремої векторної бази даних, а ембеддинги разом із pgvector виконують усю роботу.

Пов’язана література

  • Що насправді керує нейронною мережею: компілятори ШІ під Python — Простежте шлях моделі від виразу на Python через графи обчислень, злиття операторів, IR у стилі MLIR та перетворення на код для CPU, GPU та прискорювачів.
  • Ваша семантична модель — це API: надання агентам сертифікованих метрик — Чому агенти ШІ створюють власні визначення доходу та запасів, та як керована семантична модель із деталізацією, власниками та правилами відмови надає їм єдиний контракт.
  • Vectorless RAG: Як PageIndex читає документи без вбудованих ембеддингів — Пошук за векторами розділяє довгі документи на частини, що призводить до втрати контексту. Дізнайтеся, як індекс у вигляді дерева, заснований на логічних міркуваннях, знаходить відповіді у складних звітах, разом із кодом.
  • Розширений RAG у Milvus: гібридний пошук, HyDE, переписування запитів та переранжування — Створіть потік обробки даних RAG у Milvus крок за кроком: щільні та BM25 вектори, гібридний пошук RRF, фільтри метаданих, переписування запитів, HyDE, декомпозиція та переранжування за допомогою крос-енкодерів.