Разработка 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), -- dimension = модель 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:
-
<=>— косинусное расстояние -
<->— евклидово расстояние -
<#>— inner product (отрицательное)
Сроки
- Настройка pgvector + таблица: 1 день
- Ingestion pipeline: 2–4 дня
- RAG-пайплайн: 3–5 дней
- Итого: 1–2 недели







