Dify gibi platformlar aracılığıyla Büyük Dil Modeli (LLM) uygulamalarının dağıtımı, yapay zekanın iş iş akışlarına entegrasyonunu kolaylaştırmıştır. Ancak, tek kiracılı bir prototipten çok kiracılı bir SaaS mimarisine geçişte iki kritik zorluk ortaya çıkar: veri izolasyonu ve kaynak adaleti. Kiracı A'nın verileri Kiracı B'nin arama sonuçlarına sızarsa veya tek bir yoğun tüketici herkesin deneyimini bozarsa, platform başarısız olur. Bu kılavuz, Dify kullanarak sağlam bir çok kiracılı sistem nasıl tasarlanacağını, izole vektör depolarına ve gelişmiş, kullanım tabanlı hız sınırlandırmaya odaklanarak ele alır.
İzole Vektör Depolarının Gerekli Oluşu
Varsayılan olarak, RAG (Arama Destekli Üretim) hatlarında kullanılan vektör veritabanları (Weaviate, Qdrant veya Milvus gibi) genellikle tek bir ad alanını veya koleksiyonu paylaşır. Çok kiracılı bir ortamda bu, bir güvenlik kabusu demektir. "tenant_123" sorgusu asla "tenant_456"ya ait belgeleri döndürmemelidir. Dify özel meta veri filtrelemesine izin verse de, yalnızca uygulama düzeyi filtrelemeye güvenmek kırılgandır. En güvenli yaklaşım, depolama katmanında mimari izolasyondur.
Yüksek güvenlik gerektiren kiracılar için, "kiracı başına veritabanı" veya "kiracı başına koleksiyon" stratejisi uygulamayı öneriyoruz. Bu, Dify'nin arama iş akışına dinamik bir filtre enjekte edilerek gerçekleştirilebilir. Aşağıda, Dify özel bir eklentisi içinde veya API orta katmanı aracılığıyla arama mantığını nasıl değiştirebileceğiniz ve sıkı ad alanı izolasyonunu nasıl uygulayacağınızın bir örneği verilmiştir.
from dify import DifyClient
from contextlib import contextmanager
def execute_isolated_retrieval(tenant_id: str, query: str, client: DifyClient):
"""
Belirli bir kiracıya sıkı bir şekilde sınırlanmış bir RAG arama sorgusu çalıştırır.
Bu, vektör veritabanı aramasının 'tenant_id' meta verisine göre filtrelenmesini sağlar.
"""
# Dify'de bilgi tabanı düğümüne değişkenler geçebilirsiniz.
# Veri setinizin 'metadata.tenant_id'yi bu değişkene eşleyecek şekilde yapılandırıldığından emin olun.
params = {
"inputs": {
"query": query,
"tenant_id": tenant_id # Kritik: Bu, filtre anahtarı olarak görev yapar
},
"response_mode": "blocking"
}
try:
response = client.chat_messages(params)
return response["answer"], response.get("metadata", {}).get("sources")
except Exception as e:
raise SecurityError(f"Kiracı {tenant_id} için izole veri alınamadı: {e}")
Daha sıkı bir izolasyon için, birden fazla Dify örneği çalıştırıyorsanız, Dify'nin çalışma alanı başına farklı vektör veritabanı bağlantı noktalarını desteklemesinden yararlanabilirsiniz. Ancak, birçok kiracı için tek bir Dify örneği çalıştırıyorsanız, vektör veritabanı sürücünüzün, uygulama girdilerinde geçirilen `tenant_id`'ye dayalı zorunlu bir `filter` ifadesi uygulayacak şekilde yapılandırıldığından emin olun. Bu, arama filtrelerini aşmaya çalışan "istifade enjeksiyonu" saldırılarını önler.
Kullanım Tabanlı Hız Sınırlandırmanın Uygulanması
İzolasyon yalnızca savaşın yarısıdır; diğer yarısı kaynak yönetimidir. Bir SaaS modelinde, genellikle kademeli planlar (ör. Ücretsiz, Pro, Kurumsal) sunarsınız. Ücretsiz kademesi sınırlı token kullanımına sahip olabilirken, Kurumsal kademesi yüksek bir veri aktarımına sahiptir. Dify'nin yerel hız sınırlandırması genellikle statiktir, bu nedenle API geçidinde veya özel bir orta katman içinde dinamik, kayan pencere hız sınırlandırması uygulamamız gerekir.
Bunun için Redis kullanmanızı öneriyoruz, çünkü yüksek eşzamanlılıkta hız sınırlandırması için gerekli atomik işlemleri sağlar. Mantık, kullanıcının abonelik kademesini kontrol etmeli, kota belirlemeli ve sayacı azaltmalıdır. Kota aşıldığında, istek `429 Too Many Requests` durumuyla reddedilir.
import redis
import time
r = redis.Redis(host='localhost', port=6379, db=0)
# Kademe yapılandırmaları: [dakika başına maksimum istek, gün başına maksimum token]
TIERS = {
"free": [10, 1000],
"pro": [100, 10000],
"enterprise": [1000, 100000]
}
def check_rate_limit(user_id: str, tier: str, estimated_tokens: int = 100) -> bool:
"""
İstekler için kayan pencere ve tokenlar için günlük sayaç kullanarak kullanıcının hız sınırında olup olmadığını kontrol eder.
"""
now = time.time()
one_minute_ago = now - 60
today_key = f"token_usage:{user_id}:{int(now // 86400)}"
request_key = f"req_window:{user_id}:{int(now)}"
max_req, max_tok = TIERS.get(tier, TIERS["free"])
# 1. Token Kota Kontrolü (Günlük)
current_tokens = r.get(today_key) or 0
if int(current_tokens) + estimated_tokens > max_tok:
return False
# 2. İstek Hızı Kontrolü (Kayan Pencere 1 dakika)
# Hassas kayan pencere için ZSET (Sıralı Küme) kullanmak daha iyidir,
# ancak basitlik için burada sabit pencere sayacı kullanıyoruz.
pipe = r.pipeline()
pipe.incr(request_key)
pipe.expire(request_key, 60)
current_requests = pipe.execute()[0]
if current_requests > max_req:
return False
# Sınırlar içindeyse, token sayısını güncelle
r.incrby(today_key, estimated_tokens)
# Token anahtarını gün sonunda sonlandır
r.expireat(today_key, int((now // 86400 + 1) * 86400))
return True
Bu kontrolü, isteği LLM'ye göndermeden önce Dify API sarmalayıcınıza entegre edin. İstek öncesi token kullanımını tahmin ederek (istem uzunluğuna ve beklenen çıktıya dayalı), arka uç hesaplama kaynaklarını israf etmeden aşırı tüketen kiracıları proaktif olarak engelleyebilirsiniz.
Sonuç
Dify üzerinde çok kiracılı bir SaaS inşa etmek, basit istifade mühendisliğinin ötesine geçerek sağlam altyapı tasarımı gerektirir. Meta veri filtrelemesi aracılığıyla sıkı vektör deposu izolasyonu uygulayarak ve dinamik, kademe tabanlı hız sınırlandırması uygulayarak güvenlik, adalet ve ölçeklenebilirliği sağlarsınız. Veri arama hattınızı olası sızıntılar için denetlemeye başlayın, ardından iş modelinize dayalı kaynak kısıtlamalarını ekleyin. Kullanıcı tabanınız büyüdükçe, bu mimari kararlar platformunuzun performansını koruyup korumayacağını veya kendi başarısının ağırlığı altında çökeceğini belirleyecektir.