Корпоративная RAG-архитектура: база знаний с учётом прав доступа на PostgreSQL и pgvector
Разбиение на фрагменты, эмбеддинги, поиск с фильтрацией по правам и указание источников — как безопасно подключить документы компании к локальной языковой модели, с примерами SQL.
Retrieval-Augmented Generation (RAG), bir dil modelinin yanıt üretirken kurumun kendi belgelerinden ilgili parçaları bulup bağlam olarak kullanmasıdır. Modeli yeniden eğitmeden güncel ve kuruma özgü bilgi sunar. Ancak kurumsal ortamda asıl zorluk "ilgili parçayı bulmak" değil, "yalnızca kullanıcının görmeye yetkili olduğu parçayı bulmak"tır. Bu yazıda PostgreSQL ve pgvector eklentisiyle yetkiye duyarlı bir RAG altyapısının ana hatlarını çiziyoruz.
Neden PostgreSQL?
Ayrı bir vektör veritabanı kurmak yerine pgvector eklentisi, vektör aramayı zaten kullandığınız PostgreSQL'e ekler. Bunun kurumsal açıdan iki büyük avantajı vardır: belge yetkileri ile vektörler aynı işlem (transaction) ve aynı yetki modelinin (Row Level Security) içinde yaşar; yedekleme ve izleme için yeni bir sistem öğrenmek gerekmez.
Adım 1: Belgeleri parçalara ayırmak
Belgeler (sözleşmeler, prosedürler, teknik dokümanlar) model bağlamına sığacak parçalara bölünür. Parçalama stratejisi sonuç kalitesini doğrudan etkiler: başlık sınırlarına saygı duyan, komşu parçalarla kısa örtüşme bırakan bir yaklaşım genellikle sabit karakter sayısıyla bölmekten daha iyi çalışır. Her parça, kaynak belgeye ve belgenin erişim kapsamına (departman, şirket, gizlilik sınıfı) bağlanmalıdır.
create extension if not exists vector;
create table doc_chunks (
id bigserial primary key,
document_id uuid not null references documents (id) on delete cascade,
company_id uuid not null,
scope text not null, -- örn. 'hr', 'finance', 'public'
content text not null,
embedding vector(768) not null, -- boyut, kullanılan gömme modeline göre değişir
created_at timestamptz not null default now()
);
create index on doc_chunks using hnsw (embedding vector_cosine_ops);
Adım 2: Gömme (embedding) üretimi
Her parça için bir gömme modeli sayısal vektör üretir. Yerel kurulumda açık ağırlıklı gömme modelleri kullanılabilir; hangi modelin seçileceği dil desteğine (Türkçe metinlerde kalite önemlidir), vektör boyutuna ve donanıma bağlıdır. Önemli kural: sorgu anında kullanılan gömme modeli ile parçalar indekslenirken kullanılan model aynı olmalıdır; model değişirse tüm parçalar yeniden indekslenir.
Adım 3: Yetki filtreli arama
Asıl kritik adım budur. Vektör benzerlik sorgusu, kullanıcının erişim kapsamıyla birlikte çalıştırılır. RLS açık bir tabloda politika koşulu sorguya otomatik eklenir; böylece uygulama kodu filtreyi unutsa bile veritabanı yetkisiz parçayı döndürmez.
alter table doc_chunks enable row level security;
create policy chunks_read on doc_chunks for select using (
company_id = current_company_id() -- oturumdaki şirket
and scope = any (current_user_scopes()) -- kullanıcının erişim kapsamları
);
-- Sorgu (politika otomatik uygulanır)
select id, document_id, content
from doc_chunks
order by embedding <=> $1 -- $1: sorunun gömme vektörü
limit 8;
RAG sistemlerinde en tehlikeli hata, asistanın kullanıcının açamayacağı bir belgeyi "özetleyerek" ona sunmasıdır. Filtre, modelin önünde değil verinin içinde olmalıdır.
Adım 4: Bağlam oluşturma ve kaynak gösterimi
Bulunan parçalar, soruyla birlikte modele verilir. Yanıt üretildiğinde hangi parçaların kullanıldığı kullanıcıya kaynak olarak gösterilir: belge adı, bölüm ve bağlantı. Kaynak gösterimi iki iş görür: kullanıcı yanıtı doğrulayabilir ve model "uydurduğunda" bunu fark etmek kolaylaşır.
Adım 5: Denetim kaydı
Her sorgu için kullanıcı, zaman, soru, döndürülen parça kimlikleri ve model yanıtı denetim tablosuna yazılır. Bu kayıtlar hem güvenlik incelemeleri hem de kalite iyileştirme için kullanılır. Kayıtların kendisi de kişisel veri içerebileceğinden saklama süresi ve erişim yetkisi tanımlanmalıdır.
Kalite: değerlendirme seti olmadan iyileştirme olmaz
Üretim öncesinde, gerçek kullanıcı sorularından oluşan küçük bir değerlendirme seti hazırlayın: soru, beklenen kaynak belge ve kabul edilebilir yanıt. Parçalama stratejisi, parça sayısı veya model değiştiğinde bu set yeniden çalıştırılır. Sayısal bir hedef vermiyoruz; her kurumun belgeleri ve beklentisi farklıdır. Önemli olan, değişikliklerin ölçülerek yapılmasıdır.
Yerel çalıştırma notları
- Model ve gömme servisi ayrı konteynerlerde çalıştırılıp yalnızca iç ağdan erişilebilir yapılmalıdır.
- Belgeler indekslenirken içerik, gizlilik sınıfına göre etiketlenmeli; "herkese açık" varsayılan olmamalıdır.
- Model çıktısı doğrudan bir işlem tetiklememeli (örneğin kayıt silme); insan onayı araya girmelidir.
Hibrit arama: vektör tek başına yetmez
Vektör benzerliği anlamsal yakınlığı yakalar ama tam eşleşme gerektiren sorgularda (bir sözleşme numarası, bir ürün kodu, bir kişi adı) zayıf kalabilir. PostgreSQL'in tam metin arama özelliği (tsvector) ile vektör aramayı birleştirmek, iki yöntemin sonuçlarını harmanlamak çoğu kurumsal senaryoda daha isabetli sonuç verir. Türkçe için uygun bir sözlük yapılandırması (kök bulma ve durak kelimeler) tam metin tarafının kalitesini belirler.
-- Örnek: tam metin + vektör harmanı (kavramsal)
with lexical as (
select id, ts_rank(search_vector, plainto_tsquery('turkish', $q)) as score
from doc_chunks where search_vector @@ plainto_tsquery('turkish', $q)
order by score desc limit 20
), semantic as (
select id, 1 - (embedding <=> $qvec) as score
from doc_chunks order by embedding <=> $qvec limit 20
)
select coalesce(l.id, s.id) as id,
coalesce(l.score, 0) * 0.4 + coalesce(s.score, 0) * 0.6 as combined
from lexical l full outer join semantic s on s.id = l.id
order by combined desc limit 8;
Ağırlıklar (0.4 / 0.6) örnektir; değerlendirme setiyle kalibre edilmelidir.
Belge güncellendiğinde ne olur?
Kurumsal belgeler değişir: prosedür güncellenir, sözleşme yenilenir. İndeks bu değişikliği izlemelidir; aksi hâlde asistan eski sürümü "güncel" diye sunar. Pratik yöntem: her belge sürümünün bir özet değeri (hash) tutulur, değişen belgenin parçaları silinip yeniden üretilir, eski sürüm arşivde kalır ama aramaya girmez. Silinen belgenin parçaları da indeksten anında kaldırılmalıdır; "artık erişimi olmayan belge" ile "artık var olmayan belge" aynı şekilde ele alınır.
Model seçimi ve donanım
Yerel kurulumda model boyutu, yanıt kalitesi ile donanım maliyeti arasında bir dengedir. Küçük ve orta boy açık ağırlıklı modeller, kaynak gösteren özetleme ve soru-cevap görevlerinde çoğu kurumsal ihtiyaç için yeterli olabilir; karmaşık çok adımlı akıl yürütme gerektiren senaryolar daha büyük model ister. Karar, değerlendirme setindeki gerçek sorularla verilir; genel kıyaslama tablolarıyla değil. Donanım tarafında GPU belleği belirleyicidir ve eşzamanlı kullanıcı sayısı arttıkça kuyruk yönetimi gerekir.
İstem (prompt) tasarımında kurumsal kurallar
- Model yalnızca verilen bağlamdan yanıt vermeli; bağlamda yoksa "bu bilgiye sahip değilim" demeli.
- Her yanıt, kullanılan parça kimliklerini döndürmeli; kaynak gösterimi uygulama tarafında bu kimliklerden üretilir.
- Kişisel veri içeren bağlam, yalnızca yetkili kullanıcıya ve yalnızca sorunun gerektirdiği ölçüde sunulmalı.
- Kullanıcı girdisi, bağlama "talimat" olarak değil "veri" olarak eklenmeli; belgelerin içindeki metinler de talimat sayılmamalı (istem enjeksiyonu).
Kullanıcı deneyimi: güven, arayüzde kurulur
Kaynak bağlantıları tıklanabilir ve belgenin ilgili bölümünü açmalı; yanıtın "model yorumu" olduğu görünür biçimde belirtilmeli; kullanıcı yanıtı derecelendirebilmeli ve bu geri bildirim değerlendirme setine girmeli. RAG sistemleri bir kez kurulup bırakılan değil, geri bildirimle sürekli ayarlanan sistemlerdir.
Cy Logic'in yapay zekâ ve otomasyon hizmetinde RAG kurulumları bu ilkelerle yapılır: yetki veride, kaynak yanıtta, kayıt denetimde.