pgvector etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster
pgvector etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster

4 Şubat 2026 Çarşamba

Docker Compose ile Yerel Bir RAG (Retrieval-Augmented Generation) Ortamı Kurulumu: PostgreSQL + pgvector + API Katmanı

RAG Nedir ve Neden Yerelde Kurulur?

RAG (Retrieval-Augmented Generation), bir dil modelinin cevabı “uydurmak” yerine önce güvenilir bir kaynaktan ilgili içerikleri bulup (retrieval), ardından bu içeriklerle zenginleştirilmiş bir yanıt üretmesi yaklaşımıdır. Son dönemde kurum içi dokümanlarla çalışan asistanlar, teknik arama kutuları ve destek botları RAG ile daha tutarlı sonuçlar verebiliyor. Yerel (local) kurulum ise hem gizlilik hem de maliyet açısından önemli: veriniz üçüncü taraf servislere gitmez, altyapı kontrolü sizde olur ve test/deneme döngüsü hızlanır.

Bu yazıda Docker Compose kullanarak güncel ve pratik bir RAG altyapısının çekirdeğini kuracağız: PostgreSQL üzerinde pgvector eklentisi ile vektör arama, ve bu veritabanına bağlanan örnek bir API katmanı. Amaç; doküman parçalarını (chunk) vektör olarak saklamak, benzerlik araması yapmak ve uygulamalar için tekrar kullanılabilir bir iskelet oluşturmaktır.

Mimari: Hangi Parçalar Var?

Kurulum üç ana parçadan oluşur: (1) PostgreSQL + pgvector: embedding’leri saklar ve benzerlik araması yapar. (2) API: doküman ekleme ve arama uçlarını sunar. (3) İsterseniz ileride LLM entegrasyonu: burada odak veritabanı ve retrieval tarafı olduğu için LLM kısmını opsiyonel bırakıyoruz. Bu iskelet, ister kendi LLM’inizle ister bir harici model API’si ile kolayca genişletilebilir.

Ön Koşullar

Bilgisayarınızda Docker ve Docker Compose kurulu olmalı. Windows’ta Docker Desktop, macOS’ta Docker Desktop, Linux’ta Docker Engine + Compose eklentisi yeterlidir. Ayrıca komut satırı kullanımı ve temel PostgreSQL kavramlarına aşinalık işinizi kolaylaştırır.

1) Docker Compose Dosyasını Hazırlama

Projeniz için bir klasör açın (ör. rag-local) ve içine docker-compose.yml dosyası oluşturun. Aşağıdaki yapı PostgreSQL’i pgvector etkin şekilde başlatır ve örnek bir API servisini ayağa kaldırır. API tarafını kendi projenize göre değiştirebilirsiniz; burada amaç, servislerin bir arada çalıştığı “omurga”yı kurmak.

docker-compose.yml içeriği:

Not: Aşağıdaki bloğu olduğu gibi ekleyebilirsiniz.

YAML:

version: "3.9"
services:
  db:
    image: pgvector/pgvector:pg16
    container_name: rag_db
    environment:
      POSTGRES_USER: rag
      POSTGRES_PASSWORD: ragpass
      POSTGRES_DB: ragdb
    ports:
      - "5432:5432"
    volumes:
      - rag_pgdata:/var/lib/postgresql/data
  api:
    image: node:20-alpine
    container_name: rag_api
    working_dir: /app
    volumes:
      - ./api:/app
    environment:
      DATABASE_URL: postgres://rag:ragpass@db:5432/ragdb
    command: sh -c "npm i && npm run dev"
    depends_on:
      - db
    ports:
      - "3000:3000"
volumes:
  rag_pgdata:

Burada kritik kısım, veritabanı imajının pgvector destekli olmasıdır. Böylece ayrı bir eklenti kurma süreciyle uğraşmadan vektör tiplerini ve indeksleri kullanabilirsiniz. API servisi için Node.js seçtik; ancak aynı yaklaşımı Python/FastAPI ya da Go ile de uygulayabilirsiniz.

2) Veritabanında Tablo ve İndeks Oluşturma

Şimdi PostgreSQL tarafında pgvector’ı etkinleştirelim ve RAG için temel bir tablo kuralım. Terminalden Compose’u başlatın:

Komut: docker compose up -d

Ardından veritabanı kabuğuna girip SQL çalıştırın:

Komut: docker exec -it rag_db psql -U rag -d ragdb

SQL adımları:

CREATE EXTENSION IF NOT EXISTS vector;

CREATE TABLE IF NOT EXISTS documents (
  id BIGSERIAL PRIMARY KEY,
  source TEXT NOT NULL,
  chunk TEXT NOT NULL,
  embedding vector(768),
  created_at TIMESTAMPTZ DEFAULT NOW()
);

-- Benzerlik araması için ivfflat indeks (embedding dolduktan sonra daha verimli olur)
CREATE INDEX IF NOT EXISTS documents_embedding_idx
ON documents USING ivfflat (embedding vector_cosine_ops) WITH (lists = 100);

Burada vector(768) boyutu örnek bir değerdir. Kullandığınız embedding modeline göre 384, 768, 1024 gibi farklı boyutlar seçebilirsiniz. Boyut ile model çıktısı tutarlı olmak zorunda; aksi halde insert sırasında hata alırsınız.

3) API Katmanını Hızlıca Ayağa Kaldırma

Proje kökünde api adlı klasör oluşturun. İçine basit bir Node.js API koyarak iki uç hazırlayacağız: /ingest (doküman ekleme) ve /search (benzerlik araması). Örnek olması açısından sade tutuldu; prod ortamda doğrulama, rate limit, kuyruk (queue) ve gözlemlenebilirlik eklemek gerekir.

api/package.json:

{
  "name": "rag-api",
  "version": "1.0.0",
  "type": "module",
  "scripts": {
    "dev": "node index.js"
  },
  "dependencies": {
    "express": "^4.19.2",
    "pg": "^8.12.0"
  }
}

api/index.js:

import express from "express";
import pg from "pg";

const app = express();
app.use(express.json({ limit: "2mb" }));

const pool = new pg.Pool({ connectionString: process.env.DATABASE_URL });

// ingest: { source, chunk, embedding: [..] }
app.post("/ingest", async (req, res) => {
  const { source, chunk, embedding } = req.body;
  if (!source || !chunk || !Array.isArray(embedding)) {
    return res.status(400).json({ error: "source, chunk ve embedding (array) zorunlu" });
  }
  const emb = `[${embedding.join(",")}]`;
  await pool.query(
    "INSERT INTO documents(source, chunk, embedding) VALUES ($1, $2, $3::vector)",
    [source, chunk, emb]
  );
  res.json({ ok: true });
});

// search: { embedding: [..], topK: 5 }
app.post("/search", async (req, res) => {
  const { embedding, topK = 5 } = req.body;
  if (!Array.isArray(embedding)) {
    return res.status(400).json({ error: "embedding (array) zorunlu" });
  }
  const emb = `[${embedding.join(",")}]`;
  const { rows } = await pool.query(
    `SELECT id, source, chunk,
      1 - (embedding <=> $1::vector) AS score
      FROM documents
      ORDER BY embedding <=> $1::vector
      LIMIT $2`,
    [emb, topK]
  );
  res.json({ results: rows });
});

app.listen(3000, () => console.log("RAG API 3000 portunda çalışıyor"));

Bu API, embedding üretmez; embedding’i dışarıdan bekler. Böylece hangi embedding modelini kullanacağınızı (yerel bir model, bir CLI aracı veya bir bulut servisi) siz belirlersiniz. RAG projelerinde bu ayrım pratik bir avantaj sağlar: depolama/arama altyapısı sabit kalırken model katmanı kolay değişir.

4) Test: Veri Ekleme ve Arama

Servisler ayaktayken basit bir test yapabilirsiniz. Örnek olarak 768 boyut yerine kısa bir vektörle test etmek istiyorsanız tablo boyutunu da ona göre ayarlamanız gerekir. Gerçek kullanımda modelin ürettiği boyutla aynı vektörü göndermelisiniz. Uygulamada tipik akış şudur: (1) dokümanı parçalara böl, (2) her parça için embedding üret, (3) /ingest ile kaydet, (4) kullanıcı sorusu için embedding üret, (5) /search ile en alakalı parçaları çek, (6) bu parçaları LLM’e bağlam olarak ver.

Benzerlik metriklerinde en sık kullanılan seçenekler cosine ve L2’dir. Burada vector_cosine_ops ve <=> operatörü ile cosine mesafesine dayalı sıralama yapıyoruz. Sonuçtaki score alanı basit bir dönüştürme ile “yakınlık” hissi verir; uygulamanızda eşik (threshold) tanımlayarak düşük skorlu sonuçları elemek iyi bir pratik olabilir.

Performans ve Üretim Notları

Yerel RAG ortamı hızlı sonuç verir ama birkaç noktaya dikkat etmek gerekir. ivfflat indeks, veri büyüdükçe anlamlı hale gelir; küçük veri setlerinde tam tarama bazen daha tutarlı sonuç verebilir. Ayrıca ivfflat için ANALYZE çalıştırmak ve “lists” parametresini veri boyutuna göre ayarlamak önemlidir. Daha ileri seviyede hnsw gibi indeks türlerini ve PostgreSQL ayarlarını (work_mem, maintenance_work_mem) incelemek performansı ciddi şekilde artırabilir.

Güvenlik tarafında ise API’ye kimlik doğrulama eklemek, veritabanı şifresini .env dosyasına almak, ağ izolasyonu yapmak ve logları izlemek temel gereksinimlerdir. Bu iskeleti kendi projelerinize uyarlarken en büyük kazanım, retrieval katmanını standardize etmeniz olur; çünkü RAG projelerinde asıl fark genellikle doğru chunking, iyi embedding seçimi ve doğru indeks/parametre kombinasyonunda ortaya çıkar.

29 Kasım 2025 Cumartesi

pgvector ile RAG Uygulaması: Docker Compose ile PostgreSQL 16 ve Basit Semantik Arama API’si

RAG (Retrieval-Augmented Generation), büyük dil modellerinin (LLM) güncel ve alanınıza özgü verilerle daha doğru yanıtlar üretmesini sağlar. Bu yaklaşımda, soruyu bir vektöre dönüştürür, vektör veritabanından benzer içerikleri geri çağırır ve modeli bu bağlamla beslersiniz. Özel bir vektör veritabanına ihtiyaç duymadan, PostgreSQL 16 + pgvector ile etkili bir semantik arama katmanı kurmak mümkündür. Bu yazıda, Docker Compose ile PostgreSQL’i ayağa kaldıracak, pgvector eklentisini etkinleştirecek ve basit bir API üzerinden semantik arama yapabileceğiz.

Neden PostgreSQL + pgvector? PostgreSQL hâlihazırda üretim ortamlarında yaygın, güvenilir ve güçlü bir ilişkisel veritabanıdır. pgvector eklentisi, vektör tipini, benzerlik metriklerini (cosine, L2, inner product) ve ivfflat/HNSW benzeri indeksleme stratejilerini destekler. Küçük ve orta ölçekli RAG projeleri için tek bir veritabanı üzerinde hem ilişkisel hem de vektörel sorgular yürütmek operasyonel anlamda sade ve maliyet-etkindir.

Önkoşullar: Makinenizde Docker ve Docker Compose kurulu olmalı. Embedding üretimi için OpenAI hesabı (veya yerelde Ollama gibi bir çözüm) işinizi kolaylaştırır. Örneklerde OpenAI’nin “text-embedding-3-small” (1536 boyut) modelini referans vereceğiz; yerel seçenek kullanacaksanız embedding boyutunu ona göre ayarlamalısınız.

Adım 1: Docker Compose ile PostgreSQL 16 ve pgvector
Basit bir docker-compose.yml dosyası oluşturun ve şu servisi tanımlayın:
version: "3.9"
services:
  db:
    image: pgvector/pgvector:pg16
    environment:
      - POSTGRES_USER=rag
      - POSTGRES_PASSWORD=ragpass
      - POSTGRES_DB=ragdb
    ports:
      - "5432:5432"
    volumes:
      - pgdata:/var/lib/postgresql/data
volumes:
  pgdata:
Dosyayı kaydedip docker compose up -d komutunu çalıştırın. Bu imaj, pgvector eklentisi ile birlikte gelir.

Adım 2: pgvector’ü etkinleştirmek ve şema hazırlığı
Veritabanına bağlanın: psql -h localhost -U rag -d ragdb ve şu komutları çalıştırın:
CREATE EXTENSION IF NOT EXISTS vector;
OpenAI’nin “text-embedding-3-small” boyutuna uygun bir tablo oluşturun:
CREATE TABLE docs (
  id BIGSERIAL PRIMARY KEY,
  content TEXT NOT NULL,
  embedding vector(1536)
);
Arama performansı için ivfflat indeksini kurun (cosine metrik popüler bir tercih):
CREATE INDEX ON docs USING ivfflat (embedding vector_cosine_ops) WITH (lists = 100);
İndeksin etkili çalışması için tabloyu analiz edin: ANALYZE docs;

Adım 3: Embedding üretimi ve veri ekleme
Örnek içerikler ekleyelim: ürün açıklamaları, SSS, teknik notlar vs. Python ile kısa bir betik yazabilirsiniz. OpenAI için mantık şu şekildedir:
- Metni al, client.embeddings.create(model="text-embedding-3-small", input=metin) ile vektörü üret.
- Vektörü PostgreSQL’e parametreli bir sorgu ile yaz: INSERT INTO docs(content, embedding) VALUES ($1, $2).
Yerel alternatif isterseniz, Ollama’da ollama pull nomic-embed-text diyerek bir embedding modeli çekebilir, http://localhost:11434/api/embeddings üzerinden benzer bir akış kurabilirsiniz. Dikkat: embedding boyutunu (ör. 768) tablo şemanızla tutarlı yapın.

Adım 4: Semantik arama sorgusu
Kullanıcı sorgusunu da embedding’e çevirin ve ORDER BY embedding <=> $1 ifadesiyle benzerliğe göre sıralayın. Örnek bir SQL:
WITH q AS (SELECT $1::vector AS v)
SELECT id, content
FROM docs, q
ORDER BY docs.embedding <=> q.v
LIMIT 5;
Burada <=>, pgvector’ün benzerlik operatörüdür (cosine için mesafe). Bu sonuçları LLM’e bağlam olarak verip RAG yanıtı oluşturabilirsiniz.

Adım 5: Basit bir API ile uçtan uca akış
Hızlı bir prototip için Python FastAPI idealdir. Akış şöyledir:
1) POST /search: query alır, embedding üretir, PostgreSQL’den top-k döner.
2) POST /ask: query ve top-k bağlamı alır, seçtiğiniz LLM (OpenAI veya yerel) ile yanıt üretir.
Üretimde, sonuçları önbelleğe almak (ör. Redis), indeks lists değerini veri büyüklüğüne göre artırmak ve maintenance_work_mem, shared_buffers gibi PostgreSQL ayarlarını optimize etmek önemlidir.

İleri seviye ipuçları
- HNSW: pgvector 0.7+ sürümlerinde HNSW desteği bulunur; okuma gecikmesini düşürür, ancak indexleme süresi ve bellek kullanımı artar. Benchmark yapmadan geçiş yapmayın.
- Normalize embedding: Cosine benzerliğinde vektörleri normalize etmek sonuç tutarlılığını artırabilir.
- Chunking ve metadata: Belgeleri 300–800 token aralığında parçalara bölün. Kaynak, tarih, başlık gibi metadata alanlarını tabloya ekleyin ve sonuçlarda gösterin.
- Güncelleme stratejisi: Sık değişen veriler için upsert akışı oluşturun; embedding’i yalnızca içerik değiştiğinde güncelleyin.
- Güvenlik: Üretimde veritabanını dışarıya kapatın, SSL kullanın, sıkı rol ve politika tanımları yapın.

Sonuç
PostgreSQL 16 ve pgvector ile, ek bir servis karmaşıklığına girmeden güçlü bir semantik arama ve RAG katmanı kurabilirsiniz. Docker Compose yapılandırması hızlı kurulum sağlar; embedding üretimi için OpenAI veya yerel modelleri kullanabilirsiniz. Üzerine basit bir API ekleyerek hem prototip hem de üretim öncesi pilot projelerinizi hızla hayata geçirmeniz mümkün. Doğru indeks, boyut ve ayarlarla, pgvector küçük-orta ölçekli prodüksiyon yüklerini rahatlıkla karşılayacaktır.

9 Kasım 2025 Pazar

Docker ile PostgreSQL + pgvector Kurulumu ve Semantik Arama Rehberi (2025)

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.

28 Ekim 2025 Salı

PostgreSQL + pgvector ile Semantik Arama ve RAG: Kurulum, İndeks ve Performans Rehberi

Giriş

Semantik arama ve RAG (Retrieval-Augmented Generation) uygulamaları, yalnızca bir metnin kelimelerine değil, anlamına göre sonuç döndürerek daha isabetli yanıtlar verebiliyor. Bu yaklaşımı uygulamak için vektör veritabanı şart. Pek çok ekip, halihazırda kullandıkları PostgreSQL üzerinde pgvector eklentisiyle bu ihtiyacı karşılıyor. Bu yazıda, PostgreSQL + pgvector kombinasyonuyla semantik arama altyapısını nasıl kuracağınızı, indekslemeyi nasıl yapacağınızı ve performansı nasıl optimize edeceğinizi adım adım anlatıyorum.

Neden pgvector?

Pgvector, PostgreSQL’e vektör veri tipi (vector) ve benzerlik aramaları (cosine, L2, inner product) kazandırır. Ayrı bir veritabanı yönetmek yerine tek bir Postgres kümesi üzerinde hem ilişkisel verilerinizi hem de embedding’lerinizi saklayabilirsiniz. Bu, devops maliyetini azaltırken güçlü ACID garantileri ve yedekleme stratejilerinden de yararlanmanızı sağlar.

Önkoşullar

PostgreSQL 14+ önerilir; performans ve özellikler için 15/16 daha iyi. Sunucuda en az 4 CPU, 8 GB RAM başlamak için konfor sağlar. Ayrıca embedding üretmek için bir model (örneğin OpenAI text-embedding-3-small, Instructor, E5-large veya yerel bir model) gereklidir.

Kurulum (Docker ve Yerel)

Docker ile hızlı kurulum: Resmi Postgres imajı yerine pgvector içeren bir imaj kullanabilirsiniz. Örnek:

docker run -d --name pg -e POSTGRES_PASSWORD=secret -p 5432:5432 ankane/pgvector

Yerel kurulum (Ubuntu/Debian): Paket yöneticinizde pgvector olmayabilir. Kaynaktan kurulum tipik akış:

sudo apt-get update && sudo apt-get install -y postgresql postgresql-server-dev-all git make gcc

git clone https://github.com/pgvector/pgvector.git && cd pgvector && make && sudo make install

Veritabanını Hazırlama

Postgres’e bağlandıktan sonra eklentiyi etkinleştirin ve şemanızı oluşturun:

CREATE EXTENSION IF NOT EXISTS vector;

CREATE TABLE documents (id bigserial PRIMARY KEY, title text, body text, embedding vector(1536));

Burada vector(1536) embedding boyutunu temsil ediyor. Kullanacağınız modele göre bu değeri değiştirin (örn. 768, 1024, 1536).

Embedding Üretme ve Veri Ekleme

Embedding’leri uygulama katmanında üretip Postgres’e yazmak en yaygın yaklaşım. Basit akış: metni temizle, cümlelere/segmentlere böl, embedding modeline gönder, sonuç vektörünü tabloya ekle.

Örnek bir ekleme akışı:

INSERT INTO documents (title, body, embedding) VALUES ('KVKK Özeti', 'Kişisel verilerin korunması...', '[0.012, -0.034, ...]');

Not: pgvector, köşeli parantezle vektör alır. Uygulama dilinizde (Python/Node/Go) embedding dizisini string’e çevirip eklemek pratik bir yöntemdir.

Benzerlik İndeksleri: IVFFlat ve HNSW

Büyük veri kümelerinde ham tarama yavaştır. Bu nedenle IVFFlat veya HNSW indeksleri kullanılır. IVFFlat için önce tabloyu kabaca küme merkezlerine göre “eğitmek” gerekir.

-- Koşul: önce yeterince satır eklenmiş olmalı

CREATE INDEX ON documents USING ivfflat (embedding vector_cosine) WITH (lists = 100);

HNSW, eğitime gerek duymaz ve bazı veri setlerinde daha iyi gecikme/kalite dengesi sunabilir:

CREATE INDEX ON documents USING hnsw (embedding vector_cosine) WITH (m = 16, ef_construction = 128);

Metrik seçimi kritiktir: embedding modeliniz cosine ile eğitildiyse vector_cosine seçin. Performans için lists (IVFFlat) ve ef_search (HNSW) değerlerini iş yükünüze göre ayarlayın.

Semantik Arama Sorguları

Arama anında, sorgu metnini embedding’e çevirin ve en yakın komşuları çekin:

-- sorgu_embedding uygulama katmanından parametre olarak gelir

SELECT id, title, body FROM documents ORDER BY embedding <#> :sorgu_embedding LIMIT 5;

<#> operatörü cosine distance’dır. En iyi sonuçları almak için LIMIT’i ve filtre koşullarını (ör. kategori, tarih aralığı) birlikte kullanın.

RAG İçin Basit Bir Akış

- Kullanıcı sorusunu alın ve embedding’e dönüştürün.

- PostgreSQL’den en alakalı 5–10 dokümanı semantik aramayla çekin.

- Cevaplayıcı LLM’e, bu parçaları bağlamsal ek metin (context) olarak verin.

- Kaynakları (title ve id) cevapla birlikte kullanıcıya gösterin. Bu yaklaşım, halüsinasyonları azaltır ve izlenebilirlik sağlar.

Performans ve Ölçek İpuçları

1) İndeks ısınması: Sık aranan sorgu türleri için sistem başladığında birkaç “ısınma” araması yapın. Bu, sayfa önbelleğini doldurur.

2) Paralelleştirme: Toplu embedding üretiminde çoklu iş parçacığı ya da job queue kullanın. Veritabanına batch insert (ör. 100–1000 satır) performans sağlar.

3) Tablo tasarımı: Metin gövdeleri büyükse, embedding’leri ayrı bir tabloda (documents_vec) tutup body’yi object storage’a koymayı değerlendirin; Postgres’te sadece referans saklayın.

4) Bakım: Yoğun yazma/indeks güncellemelerinde VACUUM (ANALYZE) planlayın. Autovacuum ayarlarını (naptime, cost_limit) iş yükünüze göre iyileştirin.

5) IVFFlat ayarları: lists değerini veri büyüklüğüne göre artırmak hatırlama oranını iyileştirir; sorgu anında SET ivfflat.probes = X; ile daha fazla liste tarayıp isabet oranını yükseltebilirsiniz (gecikme artar).

6) HNSW ayarları: SET hnsw.ef_search = 64/128/256 gibi değerlerle kalite/gecikmeyi dengeleyin. Daha yüksek ef_search, daha iyi sonuç ama daha fazla CPU demektir.

7) Sharding/Partitioning: Konu veya müşteri bazlı PARTITION BY LIST ile arama alanını daraltmak ciddi kazanç sağlar.

Güvenlik ve Versiyonlama

Embedding uzayı model güncellemeleriyle değişebilir. Model versiyonunu tabloda saklayın (örn. model_version text) ve farklı versiyonlar için ayrı indeks tutun. Erişim tarafında Row Level Security (RLS) ile müşteri/veri bölümlendirmesini zorunlu kılın.

Hata Ayıklama ve Sık Karşılaşılan Sorunlar

- ERROR: type "vector" does not exist: CREATE EXTENSION vector; komutunun ilgili veritabanında çalıştığından ve eklentinin kurulu olduğundan emin olun.

- IVFFlat “not enough tuples”: İndeksi kurmadan önce yeterli sayıda satır eklenmiş olmalı; aksi halde eğitim yapılamaz.

- Yüksek gecikme: İndeks kullanılmıyor olabilir; EXPLAIN (ANALYZE, BUFFERS) ile planı inceleyin. probes veya ef_search değerlerini ayarlayın.

Sonuç

Pgvector, PostgreSQL’i güçlü bir vektör arama motoruna dönüştürüyor. Doğru indeks ve ayarlarla milyonlarca embedding üzerinde milisaniyeler içinde semantik arama yapılabiliyor. RAG senaryolarında ise hem kaynak yönetimini sadeleştiriyor hem de mevcut Postgres ekosisteminin güvenilirliğinden yararlanmanızı sağlıyor. Küçük bir POC ile başlayıp indeks parametrelerini kademeli ayarlayarak en iyi maliyet/performans noktasını yakalayabilirsiniz.