
Bir LLM uygulaması geliştirirken büyük ihtimalle şunu yaşadınız: prompt’u ince ayarlıyorsunuz, model güncelleniyor ve her şey yeniden bozuluyor. Yeni model için prompt’u baştan yazıyorsunuz. Bir başka model entegre etmek istediğinizde aynı döngü tekrar başlıyor. Ekip büyüdükçe “bu prompt neden bu şekilde yazılmış?” sorusu yanıtsız kalıyor.
DSPy (Declarative Self-improving Language Programs), Stanford NLP grubunun bu probleme verdiği yanıttır. Temel fikir şu: LLM’e ne yapmasını istediğinizi prompt metni olarak değil, programatik tanım olarak bildirirsiniz; framework optimizasyonu sizin yerinize üstlenir. Prompt mühendisliğini elle yapmak yerine, davranışı tanımlarsınız ve DSPy bunu hangi modele uyarlanacaksa buna göre otomatik çevirir.
Bu ayrım kulağa ince gelebilir ama uygulamada köklü bir fark yaratır. Prompt yazarken modelin iç mantığına göre cümleler kurarsınız. DSPy ile program yazarsınız; modelin iç mantığını framework halleder.
Editorial tech-magazine cover illustration about DSPy LLM programming framework, automated prompt optimization pipeline with feedback loops, abstract artificial-intelligence motifs (glowing neural networks, flowing data, subtle circuitry), sophisticated modern concept art, clean balanced composition, soft cinematic studio lighting, rich depth of field, premium color grading in deep navy blues with cyan and magenta accents, highly detailed, polished editorial 8k. No text, no words, no letters, no captions, no logos, no watermark, no UI.
DSPy’ın Temel Yapı Taşları
DSPy’ı anlamak için dört kavramı bilmek yeterli: Signature, Module, Metric ve Optimizer.
Signature: Girdi-Çıktı Tanımı
Signature, LLM çağrısının ne yapmasını beklediğinizi bildiren kısa bir tanımdır. Soru-cevap için:
"soru -> cevap"
Belgeye dayalı soru cevaplama için:
"bağlam, soru -> cevap"
Daha uzun, açıklamalı bir biçim de mümkün:
class QASignature(dspy.Signature):
"""Verilen bağlamı kullanarak soruyu kısa yanıtla."""
context = dspy.InputField(desc="İlgili belge parçacıkları")
question = dspy.InputField(desc="Kullanıcının sorusu")
answer = dspy.OutputField(desc="Özlü, kaynaklara dayalı yanıt")
DSPy bu Signature’ı alır, altındaki LLM’e uygun bir prompt şablonuna dönüştürür. Modeli değiştirdiğinizde Signature değişmez; framework yeni model için uygun şablonu üretir.
Module: Yeniden Kullanılabilir LLM Blokları
Module, bir ya da birden fazla LLM çağrısını kapsülleyen yapıdır. Hazır modüller şunlardır:
dspy.Predict: temel tahmin; prompt + LLM çağrısıdspy.ChainOfThought: ara akıl yürütme adımları üretir (chain-of-thought prompting nedir tekniğini otomatik uygular)dspy.ReAct: araç çağrısı + akıl yürütmeyi döngüsel olarak birleştirirdspy.ProgramOfThought: Python kodu üretip çalıştırır, sonucu cevaba entegre eder
import dspy
lm = dspy.LM("openai/gpt-4o-mini")
dspy.configure(lm=lm)
class QA(dspy.Module):
def __init__(self):
self.predict = dspy.ChainOfThought("soru -> cevap")
def forward(self, soru):
return self.predict(soru=soru)
qa = QA()
print(qa("Python'da liste ile tuple arasındaki temel fark nedir?").cevap)
Burada kritik olan şu: dspy.ChainOfThought çağrısı, modele açıkça “adım adım düşün” demez. DSPy, Signature’a ve seçilen modüle göre uygun prompt kalıbını kendisi oluşturur.
Metric: Optimizasyonun Pusulası
Metric, programınızın ürettiği çıktının ne kadar iyi olduğunu ölçen fonksiyondur. Optimizer, bu fonksiyonu rehber alarak parametreleri iyileştirir.
def dogru_mu(example, pred, trace=None):
return example.cevap.lower() == pred.cevap.lower()
Metric her zaman bu kadar basit olmak zorunda değildir. Başka bir LLM’i jüri olarak kullanabilirsiniz (LLM-as-a-Judge yöntemi), BLEU veya F1 gibi metriklerle karşılaştırabilir ya da birden fazla kriteri birleştirebilirsiniz.
Optimizer: Otomatik Prompt İyileştirme
Optimizer (eski adıyla Teleprompter), elinizde bir veri kümesi ve bir metric olduğunda programınızı otomatik olarak iyileştiren bileşendir.
BootstrapFewShotmevcut veriyle few-shot örnekler üretir ve bunları prompt’a eklerMIPROtalimat ve örnek aramasını çok adımlı yürütür; karmaşık pipeline’larda daha etkilidirBayesianSignatureOptimizerBayesian arama yöntemiyle talimatları iyileştirirBootstrapFinetunepipeline çalışma izlerinden sentetik eğitim verisi üretir ve altındaki modeli fine-tune eder
Klasik Prompt Engineering ile Fark
Prompt engineering yaklaşımında şablonlar elle yazılır, sınır durumlar tek tek test edilir ve farklı modeller için ayrı prompt setleri yönetilir. Geliştirme süreci öngörüsüz ve zaman alıcıdır.
DSPy’de ise süreç tersine çevrilir:
| Klasik Prompt Engineering | DSPy | |
|---|---|---|
| Tanım | Elle yazılan metin şablonu | Programatik Signature |
| Optimizasyon | Manuel deneme-yanılma | Otomatik (metric + veri) |
| Model değişimi | Sıfırdan yeniden yazma | Yeniden compile |
| Yeniden kullanım | Kopyala-yapıştır | Module olarak import |
Kod üzerinden somutlaştıralım. Naive QA:
# Klasik yaklaşım
prompt = f"""Aşağıdaki soruyu kısa ve net yanıtla.
Soru: {soru}
Cevap:"""
cevap = llm.call(prompt)
Aynı işlev DSPy ile:
qa = dspy.Predict("soru -> cevap")
cevap = qa(soru=soru).cevap
İkincisinin avantajı soyutlamada değil, optimize edilebilirlikte. Bir optimizer çalıştırdığınızda qa nesnesi otomatik olarak daha iyi few-shot örneklere ve talimatlara kavuşur.
DSPy ile RAG Pipeline
DSPy’ın en güçlü olduğu alan, retrieval artırımlı üretim (RAG) pipeline’larıdır. RAG nedir yazısında ele aldığımız retriever + generator yapısını DSPy ile şöyle kurarsınız:
import dspy
class RAGPipeline(dspy.Module):
def __init__(self, retriever, k=3):
self.retrieve = dspy.Retrieve(k=k)
self.generate = dspy.ChainOfThought("bağlam, soru -> cevap")
self.retriever = retriever
def forward(self, soru):
belgeler = self.retrieve(soru).passages
baglamli_cevap = self.generate(
bağlam="\n".join(belgeler),
soru=soru
)
return baglamli_cevap
Bu pipeline’ı BootstrapFewShot ile optimize etmek için:
from dspy.teleprompt import BootstrapFewShot
optimizer = BootstrapFewShot(metric=dogru_mu, max_bootstrapped_demos=4)
optimize_edilmis = optimizer.compile(RAGPipeline(retriever), trainset=egitim_seti)
Optimizer, eğitim setindeki sorularda yüksek metrik değeri veren few-shot örnekleri bulur ve pipeline’a entegre eder. Sonuç, elle seçilmiş örneklerden genellikle daha iyi performans verir.
Optimizer’lar: Hangisi Ne Zaman Kullanılır
BootstrapFewShot başlangıç için ideal seçimdir. 20-50 etiketli örnek yeterlidir; birkaç dakika içinde tamamlanır. Basit Predict ve ChainOfThought modülleri için belirgin kazanım sağlar.
MIPRO, hem talimatları hem örnekleri aynı anda arar. Daha güçlü ama 100+ etiketli örnek ve daha uzun çalışma süresi gerektirir. Karmaşık çok adımlı pipeline’larda BootstrapFewShot’tan daha iyi sonuç verir.
BootstrapFinetune ise başka bir yaklaşım izler: optimizer, pipeline’ın başarılı çalışma izlerinden sentetik eğitim verisi üretir ve bu veriyle altındaki modeli fine-tune eder. Çıktı artık prompt değil, özelleştirilmiş bir model ağırlık dosyasıdır.
Pratik kural: etiketli veriniz 50’nin altındaysa BootstrapFewShot; 100-500 arasındaysa MIPRO deneyin. Her iki durumda da metriği doğru tanımlamak, optimizer seçiminden daha kritiktir.
Hangi LLM’lerle Çalışır?
DSPy model-agnostiktir. OpenAI, Anthropic, Google ve yerel Ollama modellerini tek satırla tanımlarsınız:
# OpenAI
dspy.configure(lm=dspy.LM("openai/gpt-4o-mini"))
# Anthropic
dspy.configure(lm=dspy.LM("anthropic/claude-sonnet-4-5"))
# Yerel Ollama
dspy.configure(lm=dspy.LM("ollama/llama3.2"))
Model değiştirdiğinizde Signature ve Module kodunuz aynen kalır. Tek değişen şey dspy.configure satırıdır. Üretimde modeli değiştirip optimizasyonu yeniden çalıştırarak her model için özelleştirilmiş bir program elde edebilirsiniz.
DSPy vs LangChain vs LlamaIndex
Üç framework de LLM uygulaması geliştirmek için kullanılır ama farklı odak noktaları vardır:
DSPy, prompt optimizasyonu üzerine kuruludur. Az boilerplate, güçlü otomatik iyileştirme, ama hazır connector ve entegrasyon ekosistemi daha sınırlıdır.
LangChain, zengin bileşen ekosistemi ve esnek orchestration ile öne çıkar. Araç entegrasyonları, hafıza yönetimi ve agent zincirleri için olgun bir kütüphane. Prompt optimizasyonu ise DSPy kadar güçlü değildir.
LlamaIndex, veri indexleme ve retrieval’a odaklanır. Büyük belge koleksiyonlarını verimli biçimde sorgulamak için özelleştirilmiştir. RAG pipeline’ının retriever tarafında LlamaIndex, optimizer tarafında DSPy bir arada kullanılabilir.
DSPy’yı tercih edin: otomatik prompt optimizasyonu önceliğinizse, production’da farklı modelleri test edecekseniz ya da karmaşık çok adımlı pipeline’larda manuel prompt bakım yükünden kaçınmak istiyorsanız.
Gerçek Kullanım Senaryoları
JetBlue, müşteri destek botunu DSPy ile optimize etti ve manuel prompt bakım yükünü önemli ölçüde düşürdü. VMware, altyapı belgelerini sorgulayan bir RAG sisteminde DSPy optimizer’larını kullanarak doğruluk oranını yükseltti. Databricks ise dahili veri analizi ve kod üretimi pipeline’larını DSPy tabanlı optimize ediyor.
Akademik tarafta DSPy, RLHF nedir ve fine-tuning araştırmalarında sentetik veri üretimi için de kullanılır. Structured outputs gerektiren sınıflandırma, özetleme ve bilgi çıkarımı görevlerinde DSPy Signature’larının tipli çıktıları (typed outputs) belirleyici bir avantaj sunar.
Başlarken: İlk 5 Satır
pip install dspy
import dspy
dspy.configure(lm=dspy.LM("openai/gpt-4o-mini", api_key="sk-..."))
qa = dspy.ChainOfThought("soru -> cevap")
print(qa(soru="DSPy ile LangChain arasındaki temel fark nedir?").cevap)
Bir sonraki adım: gerçek bir veri kümesi ve metric tanımlamak, ardından BootstrapFewShot ile ilk optimizasyonu çalıştırmak. Resmi belgeler dspy.ai adresinde, GitHub’da stanfordnlp/dspy reposunda.
Mantıklı bir ilerleme sırası: basit dspy.Predict → dspy.ChainOfThought → RAG pipeline → optimizer entegrasyonu. Optimizer’ı gerçek bir probleme bağlamadan önce deneyin; ne zaman fark yarattığı ancak o zaman görülür.



