Розроблення RAG з векторною базою даних pgvector (PostgreSQL)
pgvector — це розширення PostgreSQL, яке додає тип даних vector та операції векторного пошуку. Якщо ваші основні дані вже знаходяться в PostgreSQL, pgvector дозволяє реалізувати RAG без введення окремої векторної БД. Підходить для помірних обсягів (до 1–5M векторів) та команд, які не хочуть додавати новий компонент інфраструктури.
Встановлення pgvector
-- Встановлення розширення
CREATE EXTENSION IF NOT EXISTS vector;
-- Таблиця для фрагментів документів
CREATE TABLE document_chunks (
id BIGSERIAL PRIMARY KEY,
content TEXT NOT NULL,
source VARCHAR(512),
doc_type VARCHAR(64),
page_number INTEGER DEFAULT 0,
metadata JSONB,
embedding vector(1536), -- розмір = модель embedding
created_at TIMESTAMP DEFAULT NOW()
);
-- HNSW індекс для швидкого пошуку
CREATE INDEX ON document_chunks USING hnsw (embedding vector_cosine_ops)
WITH (m = 16, ef_construction = 64);
Індексування через Python
import psycopg2
from openai import OpenAI
import json
conn = psycopg2.connect("postgresql://user:pass@localhost:5432/ragdb")
openai_client = OpenAI()
def index_chunk(text: str, source: str, doc_type: str, metadata: dict):
# Отримуємо embedding
response = openai_client.embeddings.create(
model="text-embedding-3-small",
input=text,
)
embedding = response.data[0].embedding
with conn.cursor() as cur:
cur.execute("""
INSERT INTO document_chunks (content, source, doc_type, metadata, embedding)
VALUES (%s, %s, %s, %s, %s)
""", (text, source, doc_type, json.dumps(metadata), embedding))
conn.commit()
Векторний пошук із фільтруванням
def search_similar(query: str, doc_type: str = None, limit: int = 5) -> list:
query_embedding = openai_client.embeddings.create(
model="text-embedding-3-small",
input=query,
).data[0].embedding
sql = """
SELECT content, source, doc_type, metadata,
1 - (embedding <=> %s::vector) AS similarity
FROM document_chunks
WHERE ($2::text IS NULL OR doc_type = $2)
ORDER BY embedding <=> %s::vector
LIMIT %s
"""
with conn.cursor() as cur:
cur.execute(sql, (query_embedding, doc_type, query_embedding, limit))
results = cur.fetchall()
return [
{"text": r[0], "source": r[1], "similarity": r[4]}
for r in results
]
Оператори pgvector:
-
<=>— косинусна відстань -
<->— евклідова відстань -
<#>— внутрішній добуток (від'ємний)
Часові рамки
- Налаштування pgvector + таблиця: 1 день
- Pipeline розповсюдження: 2–4 дні
- RAG pipeline: 3–5 днів
- Всього: 1–2 тижні







