Kılavuzlara dön
Mimari·25 Mayıs 2026·Son güncelleme: 23 Eylül 2026·14 dk okuma

RAG uygulama rehberi — Claude ve Gemini ile üretimde erişim destekli oluşturma

Gerçekten çalışan bir üretim RAG sistemi oluşturun — yalnızca 100 satırlık bir demo değil. Parçalama stratejisi, embedding modeli seçimi, erişim sıralaması, istem yapısı, halüsinasyon kontrolü ve günde 10.000 sorguda bile aylık maliyeti üç haneli tutma yöntemini kapsar.

Son inceleme tarihi: .

RAG demolarının çoğu üretimde çöker. 10 soruluk demo destesine göre çalışır, kullanıcılar yeni bir şey sorduğu anda bozulurlar. Bu kılavuz, dayanıklı mimari ve kalıpları ele alır: anlamsal sınırları koruyan parçalama, hem bulanık hem de gerçek sorguları yakalayan hibrit erişim, halüsinasyonu önleyen istem yapısı ve ölçek büyürken faturayı sabit tutan maliyet disiplini.

Önem taşıyan beş karar

  1. Parçalama stratejisi — kaliteyi modelden daha fazla etkiler
  2. Embedding modeli — erişim tavanını belirler
  3. Erişim stratejisi — yalnızca vektör yeterli değildir
  4. İstem yapısı — modelin halüsinasyon üretip üretmeyeceğine karar verir
  5. Üretim modeli + önbellekleme — birim ekonomisini belirler

1. Parçalama — zekice olmaktan çok sıkıcı olmak kazanır

Bunu fazla düşünmeyin. Parça başına 1000-1500 karakter ve 100-200 karakter örtüşmeyle özyinelemeli karakter ayırıcı kullanın. Önce paragraf sınırlarında, ardından cümlelerde, sonra kelimelerde bölmeye çalışır. Alanlar arasında kararlıdır:

chunk.py
# Recursive character splitter with overlap — the boring choice that wins
from langchain_text_splitters import RecursiveCharacterTextSplitter

splitter = RecursiveCharacterTextSplitter(
    chunk_size=1200,
    chunk_overlap=200,
    separators=["\n\n", "\n", ". ", " ", ""],
)
chunks = splitter.split_text(document)
# 1200 chars ≈ 300-400 tokens — fits 5+ chunks in a Sonnet context window
# with room for system prompt + question + answer

Daha akıllı görünen ama nadiren yardımcı olan şeyler: cümle farkındalıklı modeller, Markdown farkındalıklı ayırıcılar ve embedding'lerle kayan pencere. Kötü değiller — çok büyük çabayla marjinal olarak daha iyiler. Bu çabayı bunun yerine erişime ayırın.

2. Embedding modeli — text-embedding-3-large varsayılandır

Embedding'ler Kunavo tarafından sunulmaz — bu adım için doğrudan bir embedding sağlayıcısı çağırın. /v1/embeddings arkasında etkin model bulunmayan uygulanmış bir wire formatıdır; bu nedenle ona yönelik istek başarısız olur; GET /v1/models neyin çağrılabilir olduğu konusunda her zaman yetkili kaynaktır. Uygulamada bunun bir RAG işlem hattına maliyeti yalnızca ikinci bir anahtardır: embedding çağrısı ve üretim çağrısı zaten ayrı isteklerdir; dolayısıyla embedding için OpenAI, Voyage veya Cohere'yi, üretim için Kunavo'yu kullanın.

text-embedding-3-large çoğu üretim kullanım senaryosunda çok dillilik + doğruluk açısından ideal noktayı, OpenAI'nin kendi yayımladığı oranla yakalar — bunu burada değil, fiyatlandırma sayfalarında kontrol edin; çünkü ürünü yeniden satmıyoruz ve bir fiyat belirtmemeliyiz. Parçalama stratejisini veya modelin kendisini değiştirdiğinizde yeniden embedding oluşturun; içerik güncellendiğinde değil (yalnızca yeni parçalar ekleyin).

Daha küçük embedding'lerin işe yaradığı istisnalar: yalnızca İngilizce kısa metin erişimi (SSS'ler, ürün kartları). Bunlar için text-embedding-3-small ihmal edilebilir kalite kaybıyla 4 kat daha ucuzdur. Çok dilli veya teknik içerik için büyük modelde kalın.

3. Erişim — salt vektör hibrite yenilir

Vektör benzerliği bulanık anlamsal eşleştirmede harikadır ("nasıl iptal ederim" → "abonelik iptal politikası"). Gerçek terimlerde ("SKU-A92837" veya "sipariş #4729") berbattır. Çözüm hibrittir: BM25 anahtar kelime aramasını paralel çalıştırın, ardından karşılıklı sıra füzyonu uygulayın:

retrieve.py
# Hybrid retrieval: vector similarity + BM25 keyword scoring
# Pure vector misses literal keywords (product SKUs, IDs, dates)
def retrieve(question: str, k: int = 5) -> list[dict]:
    q_embed = embed([question])[0]
    vector_hits = vector_db.similarity_search(q_embed, k=k * 2)
    keyword_hits = bm25_search(question, k=k * 2)

    # Reciprocal rank fusion — simple, robust
    scores: dict[str, float] = {}
    for rank, hit in enumerate(vector_hits):
        scores[hit["id"]] = scores.get(hit["id"], 0) + 1 / (rank + 60)
    for rank, hit in enumerate(keyword_hits):
        scores[hit["id"]] = scores.get(hit["id"], 0) + 1 / (rank + 60)

    top_ids = sorted(scores, key=scores.get, reverse=True)[:k]
    return [chunk_by_id[i] for i in top_ids]

İyi bir embedding modeli seçtikten sonraki en büyük tek kalite artışı budur. 100 soruluk ayrılmış bir değerlendirmede recall@5'i izleyin — BM25 ekledikten sonra %70'ten %90'a çıkıyorsa, "bilmiyorum" hatalarının üçte birini kaldırmışsınız demektir.

4. İstem yapısı — halüsinasyonu önleyen üç kalıp

answer.py
# Final RAG prompt structure — three sections, citations enforced
SYSTEM_PROMPT = """You answer based exclusively on the supplied Context.
- Cite the [doc_id] for each factual claim.
- If the context doesn't answer the question, say "I don't have that
  information" — do not extrapolate or use general knowledge.
- Be concise. No throat-clearing."""

def answer(question: str) -> dict:
    chunks = retrieve(question, k=5)
    context = "\n\n---\n\n".join(
        f"[doc:{c['id']}] {c['text']}" for c in chunks
    )
    resp = client.chat.completions.create(
        model="claude-sonnet-4-6",
        messages=[
            {"role": "system", "content": [{
                "type": "text",
                "text": SYSTEM_PROMPT,
                "cache_control": {"type": "ephemeral"},
            }]},
            {"role": "user", "content": f"# Context\n{context}\n\n# Question\n{question}"},
        ],
        max_tokens=600,
    )
    return {
        "text": resp.choices[0].message.content,
        "sources": [c["id"] for c in chunks],
    }

Sistem istemindeki üç pazarlık konusu olmayan kural:

  • Kaynakları alıntılayın — modelin her iddiaya [doc:42] eklemesini sağlayın. Alıntılanan kimlik gerçek değilse bir halüsinasyon yakaladınız demektir
  • Açıkça reddedin — "bağlam yanıt vermiyorsa, bu bilgiye sahip olmadığınızı söyleyin." Bu olmadan model dünya bilgisinden tamamlar
  • Kısa çıktı — kısa yanıtlar doğru yanıtlarla ilişkilidir. En fazla 600 belirteç iyi bir üretim varsayılanıdır

5. Üretim modeli + önbellekleme — maliyet katmanı

Claude Sonnet 4.6 varsayılandır. Claude Haiku 4.5, maliyet baskısı altındaysanız ucuz geri dönüş seçeneğidir. Sistem istemini her zaman cache_control içine sarın — sistem istemi her çağrıda aynıdır; bu nedenle önbellekleme bu kısmın maliyetini girdi birim ücretinin %10'una indirir.

Üretim ölçeğinde sorgu başına gerçekçi maliyet (5K bağlam, 500 çıktı, önbellekleme açık):

ModelSorgu başına maliyetGünde 10.000 sorgudaSonnet'e göre kalite
claude-sonnet-4-6~$0,007~$70/günTemel
claude-haiku-4-5~$0,001~$10/gün~%85, 4 kat daha ucuz

Günde 10.000 sorgu → Sonnet'te $70/gün, Haiku'da $10/gün. Kritik kullanım senaryolarında (müşteriye dönük, hukuki, tıbbi) Sonnet'i; dahili/toplu işleme için Haiku'yu seçin.

Üretimde ne bozulur (ve nasıl yakalanır)

  • Dağılım kayması: eğitim derlemi gerçek kullanıcı sorularıyla eşleşmeyi bırakır. Haftada 100 sorgudan örnek alın, recall@5'i elle kontrol edin
  • Eski embedding'ler: kaynak belgeler güncellenmiş, ancak embedding'ler yenilenmemiştir. Dizin boyutunu kaynak boyutuna karşı haftalık izleyin
  • Sahte alıntılar: model gerçek görünen belge kimlikleri uydurur. Oluşturmadan önce her [doc:N] değerini erişilen kimliklerin gerçek listesine karşı doğrulayın
  • Gecikme uçurumları: vektör veritabanı bir milyon vektörü aşınca çöker. HNSW indeksleme kullanın, çok kiracılı yapıda kiracıya göre bölümlendirin

4 haftalık üretim yol haritası

  1. 1. hafta: 100 belge, 10 test sorusu ve manuel değerlendirmeyle prototip oluşturun
  2. 2. hafta: tam derleme ölçeğine geçin, hibrit erişim oluşturun, 100 soruluk değerlendirme kümesi yazın
  3. 3. hafta: değerlendirmeyi yineleyerek parçalamayı + sistem istemini ayarlayın, dahili kullanıcılara sunun
  4. 4. hafta: izleme, maliyet bütçesi, kaynak alıntılama arayüzüyle herkese açık sürüm

Sık sorulan sorular

Üretim ortamındaki bir RAG sistemi hangi parça boyutunu kullanmalı?

Parça başına 1.000–1.500 karakter ve 100–200 karakter örtüşme; önce paragraf sınırlarında, ardından cümlelerde, sonra kelimelerde bölünen özyinelemeli bir karakter ayırıcı kullanın. Cümle farkındalıklı modeller, Markdown farkındalıklı ayırıcılar ve kayan pencereler çok daha fazla çabayla marjinal olarak daha iyidir — bu çabayı erişime ayırmak daha fazla karşılık verir.

Bir RAG işlem hattı hangi embedding modelini kullanmalı?

text-embedding-3-large, çok dilli ve teknik içerik için varsayılandır; SSS'ler ve ürün kartları gibi yalnızca İngilizce kısa metin erişiminde text-embedding-3-small yaklaşık 4 kat daha ucuzdur ve kalite kaybı ihmal edilebilir düzeydedir. Embedding'lerin Kunavo tarafından sunulmadığını unutmayın: /v1/embeddings uygulanmış bir wire formatıdır, ancak arkasında etkin bir model yoktur; bu nedenle embedding adımı doğrudan OpenAI, Voyage veya Cohere'yi, üretim adımı ise Kunavo'yu çağırır. İki istek her durumda ayrı olduğundan bunun işlem hattına maliyeti yalnızca ikinci bir anahtardır.

RAG erişimi için yalnızca vektör araması yeterli mi?

Hayır. Vektör benzerliği bulanık anlamsal eşleştirmeyi iyi işler, ancak SKU veya sipariş numarası gibi birebir eşleşmesi gereken terimlerde başarısız olur. BM25 anahtar kelime aramasını paralel çalıştırıp karşılıklı sıra füzyonuyla birleştirmek, recall@5 değerini genellikle yaklaşık %70'ten yaklaşık %90'a çıkarır — iyi bir embedding modeli seçtikten sonraki en büyük tek kalite artışıdır.

Bir RAG sisteminin halüsinasyon üretmesini nasıl engellersiniz?

Sistem isteminde üç kalıp kullanın: her olgusal iddiada bir [doc:N] alıntısı zorunlu kılın, bağlam yanıtı vermiyorsa modelden bilgiyi bilmediğini söylemesini isteyin ve yanıtları kısa tutun — en fazla 600 çıktı belirteci iyi bir üretim varsayılanıdır. Ardından oluşturma işleminden önce alıntılanan her kimliği erişilen kümeye karşı doğrulayın; gerçek olmayan bir kimlik yakalanmış bir halüsinasyondur.

Üretim ortamındaki bir RAG sorgusunun maliyeti ne kadardır?

İstem önbelleklemesi açıkken 5K bağlam ve 500 çıktı belirteciyle: Claude Sonnet 4.6'da sorgu başına yaklaşık $0,007 ve Claude Haiku 4.5'te yaklaşık $0,001 (4 kat daha ucuz, kalitenin yaklaşık %85'i). Günde 10.000 sorguda bu, Sonnet'te yaklaşık $70/gün ve Haiku'da yaklaşık $10/gündür.