pgvector nedir ve neden önemlidir?
Semantik arama, metnin anlamını kavrayarak benzer içerikleri bulmayı hedefleyen modern bir yaklaşım. Bu yaklaşımın kalbinde ise metinleri yüksek boyutlu sayısal vektörlere dönüştürmek ve bu vektörler arasında en benzer olanları hızlıca bulmak yer alır. pgvector, PostgreSQL üzerinde vektör veri tipini ve benzerlik aramalarını destekleyen bir eklenti olarak, ek bir vektör veritabanı yönetmek zorunda kalmadan güçlü semantik arama çözümleri geliştirmenize imkan tanır.
Bu rehberde, Docker kullanarak PostgreSQL 16 + pgvector kurulumunu gerçekleştirecek, örnek bir şema ile HNSW veya IVFFlat indeksleri üzerinden hızlı arama yapacak ve üretim ortamı için ayar önerileri sunacağız. RAG (Retrieval Augmented Generation) gibi yapay zekâ uygulamalarında performanslı ve ölçeklenebilir bir temel oluşturmayı hedefliyoruz.
Önkoşullar
- Docker ve Docker Compose yüklü bir makine (Linux, macOS veya Windows).
- Terminal/komut satırına erişim ve temel PostgreSQL bilgisi.
- Embedding üretmek için bir model (ör. Sentence-Transformers veya bir LLM sağlayıcısı). Bu rehberde örnek olarak sabit vektörlerle ilerleyeceğiz; gerçek projede modelden gelen boyutlarla eşleşecek şekilde tabloyu kurmalısınız.
Kurulum: Docker ile PostgreSQL + pgvector
Hızlı başlamak için resmi pgvector imajını kullanacağız. Aşağıdaki komut PostgreSQL 16 ve pgvector eklentisini içeren bir konteyneri ayağa kaldırır:
docker run --name pgvector -e POSTGRES_PASSWORD=secret -p 5432:5432 -d pgvector/pgvector:pg16
Veritabanına bağlanmak için psql kullanabilirsiniz:
psql -h localhost -U postgres
Bağlandıktan sonra eklentiyi etkinleştirin:
CREATE EXTENSION IF NOT EXISTS vector;
Şema tasarımı ve örnek veri
Gerçekte embedding boyutunuz seçtiğiniz modele göre değişir (ör. 384, 768, 1024). Anlatımı basitleştirmek adına burada 3 boyutlu bir örnek kullanacağız; siz kendi projelerinizde doğru boyutu tablo tanımında belirtin.
CREATE TABLE docs (id BIGSERIAL PRIMARY KEY, title TEXT, content TEXT, embedding VECTOR(3));
Benzerlik aramalarını hızlandırmak için iki popüler indeks tipinden birini ekleyebilirsiniz. HNSW genel olarak yüksek doğruluk ve iyi performans sunarken, IVFFlat kurulum ve ayar açısından daha basittir.
-- HNSW + Kosinüs uzaklığı
CREATE INDEX docs_embedding_hnsw ON docs USING hnsw (embedding vector_cosine_ops);
Örnek verileri ekleyelim:
INSERT INTO docs (title, content, embedding) VALUES
('PostgreSQL Rehberi', 'Indeks, performans ve yedekleme ipuçları.', '[0.10, 0.85, 0.20]'),
('Vektör Veritabanları', 'pgvector, HNSW ve benzerlik metrikleri.', '[0.12, 0.80, 0.25]'),
('Docker ile Kurulum', 'Kapsayıcı tabanlı veritabanı dağıtımı.', '[0.60, 0.10, 0.30]');
Semantik arama sorguları
Kullanacağınız benzerlik ölçütü projeye göre değişir. Çoğu metin embedding’inde kosinüs uzaklığı iyi sonuç verir. Kosinüs mesafesi için pgvector’da <=> operatörü kullanılır; mesafe ne kadar düşükse benzerlik o kadar yüksektir. Dilerseniz skor olarak benzerliği görmek için 1 - mesafe hesaplayabilirsiniz.
-- Sorgu vektörü örnek: '[0.12, 0.88, 0.33]'
SELECT id, title, 1 - (embedding <=> '[0.12, 0.88, 0.33]') AS cosine_similarity
FROM docs
ORDER BY embedding <=> '[0.12, 0.88, 0.33]'
LIMIT 5;
IVFFlat indeksi tercih edecekseniz, eğitim gerektirir ve arama-doğruluk dengesi için probes parametresi önemlidir:
CREATE INDEX docs_embedding_ivf ON docs USING ivfflat (embedding vector_cosine_ops) WITH (lists = 100);
SET ivfflat.probes = 10;
Üretim için en iyi uygulamalar
- Boyut tutarlılığı: Tablo tanımındaki vektör boyutu embedding modeli ile birebir aynı olmalı. Modeli değiştirirseniz yeni bir alan veya tablo kullanın.
- Normalizasyon: Kosinüs benzerliği kullanırken embedding’leri uygulama katmanında birim uzunluğa normalize etmek sonuçların tutarlılığını artırır.
- Toplu yüklemeler: Büyük veri yüklerken indeksleri en son oluşturun ve synchronous_commit = off ile yüklemeyi hızlandırmayı değerlendirin (kritik verilerde dikkatli olun).
- Bakım: Veri dağılımı değiştikçe ANALYZE ve gerekirse REINDEX yapın. IVFFlat için doğru lists ve probes değerlerini veri setinizde deneyerek belirleyin.
- Bellek ve önbellek: PostgreSQL yapılandırmasında genel öneriler: shared_buffers RAM’in %25’i civarı, effective_cache_size %50–75, indeks oluştururken maintenance_work_mem’i yüksek tutun, sorgu başına work_mem değerini gözlemleyerek ayarlayın.
- Yedekleme ve göç: Şema değişiklikleri ve büyük indeksler söz konusu olduğunda pg_dump ve pg_restore stratejinizi test edin; depolama IOPS kapasitesini göz önünde bulundurun.
RAG ve uygulama entegrasyonu
RAG mimarisinde tipik akış, sorgu metnini embedding’e çevirip PostgreSQL’de en benzer içerikleri bulmak ve bu içerikleri LLM’e bağlam olarak sunmaktır. Uygulamada sıklıkla yapılan optimizasyon, hem title hem de content alanlarını birleştirip tek embedding üretmek ya da çok alanlı senaryoda iki ayrı embedding sütunu ile ağırlıklı birleştirme yapmaktır. İhtiyaçlarınıza göre HNSW ile yüksek doğrulukta, IVFFlat ile daha düşük gecikmede cevaplar elde edebilirsiniz.
Sonuç olarak, pgvector ile PostgreSQL’i bir vektör veritabanına dönüştürmek hem yönetim yükünü azaltır hem de üretim tecrübesi kanıtlanmış bir ekosistemden yararlanmanızı sağlar. Doğru indeks, metrik ve donanım ayarlarıyla semantik arama ve RAG uygulamalarınızı güvenle ölçekleyebilirsiniz.