DSPy ile Prompt Optimizasyonu: Elle Prompt Yazmaktan Programlanabilir Pipeline'lara
DSPy ile elle prompt yazmaktan programlanabilir pipeline'lara geçiş: signature, module, optimizer kavramları, kod örnekleri, metrik tanımı, Türkçe görev ve KVKK-uyumlu üretim.
TL;DR — DSPy, Stanford kaynaklı açık kaynak bir çerçeve; LLM etkileşimlerini elle ayarlanan prompt metinleri yerine programlanabilir modüller olarak ele alıyor. Tipli imzalarla (typed signatures) çok adımlı pipeline'lar kurup, prompt'ları (ve isteğe bağlı model ağırlıklarını) göreve özgü metriklere karşı otomatik optimize ediyorsunuz. Yapılandırılmış görevlerde elle prompt'a kıyasla benchmark'larda %10-40 kalite artışı raporlanıyor; 25 binden fazla GitHub yıldızıyla Cursor, Mistral, Databricks gibi ekiplerde üretimde kullanılıyor. Bu yazıda neden elle prompt yazmanın ölçeklenmediğini, signature/module/optimizer kavramlarını, gerçek kod örneklerini, metrik tanımlamayı, Türkçe bir görev örneğini, ne zaman DSPy'a başvurup ne zaman uzak durmanız gerektiğini ve KVKK-uyumlu üretim pratiğini anlatıyorum.
İtiraf edeyim: Yıllarca prompt'ları elle yazdım, elle ayarladım ve her model güncellemesinde hepsini baştan elden geçirdim. Bir müşteride 40'tan fazla prompt'ın olduğu bir sistemi devraldığımda, bunların bir Word dosyasında, sürümsüz, testsiz, "en son kim değiştirdi belli değil" halde durduğunu gördüm. Yeni bir modele geçmek istediğimizde herkesin içine bir korku düştü, çünkü hangi prompt'ın nerede kırılacağını kimse bilmiyordu. İşte o gün, prompt mühendisliğinin "sanat" olmaktan çıkıp "mühendislik" olması gerektiğini net gördüm. DSPy tam da bu boşluğu dolduruyor.
Neden elle prompt tuning ölçeklenmiyor
Elle prompt yazmak küçük ölçekte harika çalışır. Bir görev, bir prompt, birkaç deneme ve iş biter. Ama sistem büyüdükçe bu yaklaşım çöker. Nedenini birkaç başlıkta toplayayım.
Birincisi, kırılganlık. Elle yazılmış bir prompt, o anki modele, o anki örneklere ve prompt'u yazan kişinin sezgisine göre şekillenir. Modeli değiştirdiğinizde (ki artık her birkaç ayda bir yeni model çıkıyor) prompt'un davranışı değişir ve çoğu zaman kötüleşir. Elinizde onlarca prompt varsa, her model geçişi bir kâbusa dönüşür.
İkincisi, ölçülemezlik. "Bu prompt daha mı iyi?" sorusuna çoğu ekip gözle bakarak, birkaç örnek deneyerek cevap verir. Bu bilimsel değildir. Bir prompt'un gerçekten daha iyi olup olmadığını ancak tanımlı bir metrik ve bir değerlendirme setiyle söyleyebilirsiniz. Elle süreçte bu disiplin neredeyse hiç kurulmaz.
Üçüncüsü, birleştirme sorunu. Gerçek uygulamalar tek bir prompt değildir; birden çok adımın zinciridir — önce soruyu yeniden yaz, sonra belge getir, sonra cevap üret, sonra doğrula. Bu adımları elle prompt'larla birbirine bağladığınızda, bir adımı iyileştirmek diğerini bozabilir ve bütünü optimize etmek imkânsız hale gelir.
"Sahadan bir gözlem: Elle prompt tuning'in gizli maliyeti zaman değil, cesaretsizliktir. Ekipler çalışan bir prompt'a dokunmaktan korkar hale gelir; "bozulur" diye iyileştirme yapılmaz. Sistem donar. DSPy'ın en büyük getirisi belki de bu korkuyu ortadan kaldırması: metrik ve optimizasyon olduğunda, değişiklik yapmak güvenli hale gelir.
DSPy nedir: prompt'tan programa zihniyet değişimi
DSPy'ın temel fikri şaşırtıcı derecede basit ama güçlü: LLM'e ne yapacağını uzun bir metinle anlatmak yerine, ne istediğinizi bir program olarak tanımlarsınız ve prompt'un nasıl yazılacağını çerçeveye bırakırsınız. Yani siz "girdim şu, çıktım şu olsun" dersiniz; DSPy bunu gerçekleştirecek prompt'u kendisi kurar ve optimize eder.
Bunu geleneksel yazılıma benzetebiliriz. Eskiden makine koduyla uğraşırdık; sonra derleyiciler geldi ve biz yüksek seviye dilde yazdık, derleyici alt seviyeyi halletti. DSPy, LLM programlaması için bir tür derleyici gibi düşünülebilir: siz niyeti yazarsınız, DSPy prompt'u derler. Bu yüzden DSPy ekibi çerçeveyi "prompt yazmak yerine programlama" olarak tanımlıyor.
Pratikte üç temel yapıtaşı var: Signature (imza), Module (modül) ve Optimizer (optimize edici). Şimdi bunları tek tek açalım.
Üç temel kavram: Signature, Module, Optimizer
Signature (tipli imza): Bir görevin girdi ve çıktılarını bildirimsel olarak tanımlar. Örneğin "soru -> cevap" ya da "belge -> özet". Signature, prompt'un ne yapacağını değil, ne alıp ne vereceğini söyler. Bu, fonksiyon imzasına benzer: türleri ve alanları belirlersiniz, gerisini çerçeve halleder.
Module (modül): Signature'ı belirli bir akıl yürütme stratejisiyle çalıştıran bileşen. En bilinenleri Predict (düz tahmin), ChainOfThought (adım adım düşün), ReAct (araç kullanarak akıl yürüt). Aynı signature'ı farklı modüllerle çalıştırabilirsiniz; örneğin bir soru-cevap görevini önce Predict, sonra ChainOfThought ile deneyip hangisinin daha iyi olduğunu ölçebilirsiniz.
Optimizer (optimize edici): İşin sihirli kısmı burada. Optimizer, elinizdeki örnekler ve tanımladığınız metrik üzerinden prompt'ları (few-shot örnekleri, talimatları) ve isteğe bağlı olarak model ağırlıklarını otomatik iyileştirir. Yani siz metriği tanımlarsınız, optimizer en iyi prompt'u arar. Elle deneme yanılmanın yerini sistematik bir arama alır.
Bu üçlünün gücü, birbirine geçmesinde. Signature'la ne istediğinizi söylersiniz, modülle nasıl düşüneceğini seçersiniz, optimizer'la da bunu verinize göre en iyi hale getirirsiniz.
Basit kod örneği: ilk DSPy programınız
Somutlaştıralım. DSPy 2.x API'siyle basit bir soru-cevap modülü şöyle görünür:
import dspy
# 1) Modeli tanımla
lm = dspy.LM("openai/gpt-4o-mini")
dspy.configure(lm=lm)
# 2) Signature: girdi -> çıktı bildirimi
class SoruCevap(dspy.Signature):
"""Soruyu kısa ve doğru biçimde yanıtla."""
soru: str = dspy.InputField()
cevap: str = dspy.OutputField(desc="tek cümlelik yanıt")
# 3) Module: akıl yürütme stratejisi seç
qa = dspy.ChainOfThought(SoruCevap)
# 4) Çalıştır
sonuc = qa(soru="Kestirimci bakımın önleyici bakımdan farkı nedir?")
print(sonuc.cevap)
Burada dikkat edin: Hiçbir yerde "sen bir uzmansın, şöyle davran, adım adım düşün" gibi elle yazılmış bir prompt yok. Signature niyeti söylüyor, ChainOfThought modülü akıl yürütme biçimini ekliyor, DSPy da arka planda prompt'u kendisi kuruyor. Model değiştirmek istediğinizde sadece ilk satırı değiştirirsiniz; program aynı kalır.
Optimize ediciler: BootstrapFewShot, MIPROv2, COPRO, OPRO
Asıl kazanç optimizasyonda. DSPy birkaç optimize edici sunuyor; her biri farklı bir stratejiyle prompt'u iyileştirir. En çok kullanılanları özetleyeyim:
| Optimize edici | Ne yapar | Ne zaman uygun |
|---|---|---|
| BootstrapFewShot | Programı örneklerle çalıştırıp başarılı izleri few-shot örneği olarak toplar | Az veriyle hızlı başlangıç |
| MIPROv2 | Talimatları ve few-shot örneklerini birlikte, Bayesçi arama ile optimize eder | Kalite en kritikse, orta-büyük veri |
| COPRO | Talimatları koordineli biçimde yeniden yazıp iyileştirir | Talimat metnini keskinleştirmek için |
| OPRO | LLM'i bir optimize edici gibi kullanıp prompt'ları öneren yaklaşım | Talimat arama deneyleri için |
Kullanım örüntüsü şöyle. Önce bir eğitim seti ve bir metrik hazırlarsınız. Sonra optimizer'ı programınıza uygularsınız:
from dspy.teleprompt import MIPROv2
# metrik: cevap doğru mu? (basit örnek)
def dogruluk(ornek, tahmin, iz=None):
return ornek.cevap.lower() in tahmin.cevap.lower()
optimizer = MIPROv2(metric=dogruluk, auto="light")
optimize_edilmis_qa = optimizer.compile(
qa,
trainset=egitim_seti,
)
Buradaki compile çağrısı, elle yaptığınız onlarca saatlik deneme yanılmayı sistematik bir aramaya dönüştürür. Yapılandırılmış görevlerde bu yaklaşımın elle prompt'a kıyasla benchmark'larda %10-40 kalite artışı sağladığı raporlanıyor.
Metrik tanımlama: DSPy'ın gerçek kalbi
DSPy'ı ilk kez kullananların en çok şaşırdığı gerçek şu: işin zor kısmı DSPy'ı öğrenmek değil, iyi bir metrik tanımlamak. Optimizer ancak metriğiniz kadar akıllıdır. Metriği yanlış tanımlarsanız, optimizer yanlış hedefe koşar.
Metrik, bir çıktının ne kadar "iyi" olduğunu sayıya çeviren bir fonksiyondur. Basit görevlerde bu bir eşleşme kontrolü olabilir (cevap doğru mu?). Ama gerçek görevlerde çoğu zaman daha incelikli olması gerekir: özet hem doğru hem kısa mı? Sınıflandırma doğru etikete mi düştü? Üretilen metin istenen formatta mı? Bazı durumlarda metriğin kendisi bir LLM olabilir — "LLM-as-a-judge" dediğimiz, bir modelin çıktıyı puanladığı yaklaşım.
"Uyarı: Metriğinizi mümkün olduğunca işin gerçek başarısına yakın tanımlayın. "Kelime örtüşmesi" gibi kolay metrikler ölçmesi kolaydır ama gerçek kaliteyi yansıtmayabilir. Yanlış metrik, optimizer'ı gerçek işe değil, metriği kandırmaya iter. Sahada gördüğüm en pahalı hata budur.
Türkçe bir görev örneği: müşteri talebi sınıflandırma
Türkçe görevlerde DSPy'ın nasıl işe yaradığını somut bir örnekle göstereyim. Diyelim bir e-ticaret firmasının müşteri mesajlarını üç sınıfa ayırmak istiyoruz: "iade", "kargo", "ürün bilgisi". Elle prompt yazsanız, Türkçenin inceliklerini (ekler, deyimler, argo) tek tek prompt'a eklemeye çalışır ve yine de yeni ifadelerde tökezlerdiniz. DSPy ile bunun yerine örneklerden öğrenirsiniz:
class TalepSinifla(dspy.Signature):
"""Müşteri mesajını iade, kargo veya ürün bilgisi olarak sınıflandır."""
mesaj: str = dspy.InputField()
sinif: str = dspy.OutputField(desc="iade | kargo | urun_bilgisi")
siniflandirici = dspy.Predict(TalepSinifla)
# Etiketli Türkçe örneklerle optimize et
from dspy.teleprompt import BootstrapFewShot
opt = BootstrapFewShot(metric=lambda o, t, iz=None: o.sinif == t.sinif)
egitilmis = opt.compile(siniflandirici, trainset=turkce_ornekler)
Burada kritik nokta, metriği ve değerlendirme setini Türkçe gerçek verinizle kurmanız. DSPy'ın gücü, Türkçenin dilbilgisel özelliklerini sizin elle tarif etmenize gerek kalmadan, verideki örüntüyü örneklerden yakalamasıdır. Yeni bir argo ifade geldiğinde, birkaç örnek ekleyip yeniden derlemeniz yeterli; prompt'u elle yeniden yazmanıza gerek kalmaz.
Ne zaman DSPy, ne zaman değil
DSPy güçlü ama her çiviye vurulacak bir çekiç değil. Dürüst olmak gerekirse, bazı durumlarda gereksiz karmaşıklık getirir. Ne zaman başvurup ne zaman uzak durmanız gerektiğini netleştireyim.
DSPy'a başvurun: Görev yapılandırılmışsa (sınıflandırma, çıkarım, çok adımlı akıl yürütme, RAG); tanımlı bir başarı metriğiniz ve değerlendirme veriniz varsa; birden çok prompt'u bir arada optimize etmeniz gerekiyorsa; sık sık model değiştiriyorsanız ve her seferinde prompt'ları elden geçirmek istemiyorsanız; kaliteyi sistematik ölçüp iyileştirmek istiyorsanız.
DSPy'dan uzak durun: Tek seferlik, basit bir prompt yeterliyse (koca bir çerçeve kurmaya değmez); değerlendirme veriniz veya net bir metriğiniz yoksa (optimizer'ın besleneceği bir şey olmaz); görev tamamen yaratıcı ve öznelse, ölçülebilir bir hedef yoksa; ekibinizin Python ve LLMOps olgunluğu henüz yoksa. Bu son madde önemli: DSPy bir mühendislik disiplini gerektirir; ekibiniz henüz oraya gelmediyse, önce basit ve ölçülü başlayın.
Üretim pratiği: versiyonlama, CI ve LLMOps
DSPy'ı üretime almak, sadece kod yazmak değil; bir süreç kurmaktır. Türkiye'de ekiplere önerdiğim pratikleri paylaşayım.
Prompt ve program versiyonlama. DSPy'ın güzelliği, prompt'u bir metin dosyası olmaktan çıkarıp koda gömmesidir. Böylece prompt'larınız git ile versiyonlanır, kod incelemesinden (code review) geçer ve değişiklik geçmişi tutulur. Artık "en son kim değiştirdi belli değil" durumu ortadan kalkar.
CI süreçlerine değerlendirme entegre edin. Her kod değişikliğinde, tanımladığınız metrik üzerinden bir değerlendirme (evaluation) otomatik çalışsın. Bir geliştirici bir şeyi değiştirdiğinde, kalite düşerse CI kırılsın. Bu, yazılım testinin LLM dünyasındaki karşılığıdır ve donmuş sistemleri güvenle değiştirilebilir hale getirir.
Optimize edilmiş programı sabitleyin. Optimizer'ı her çalıştırdığınızda sonuç biraz değişebilir. Üretimde, optimize edilmiş programı (öğrenilen few-shot örnekleri ve talimatlarla birlikte) kaydedip sabitleyin; kontrolsüz yeniden optimizasyon yapmayın. Yeni optimizasyonu ayrı bir sürüm olarak değerlendirip onaylayarak yayına alın.
"Pratik tavsiye: DSPy programınızı bir mikroservis gibi düşünün. Girdisi, çıktısı, testi, sürümü ve izlemesi olsun. Bu disiplin kurulduğunda, model değişiklikleri korkulacak bir olay olmaktan çıkıp rutin bir güncellemeye dönüşür.
KVKK ve değerlendirme verisi: gözden kaçan risk
DSPy'ın kalbi değerlendirme verisidir ve bu veri çoğu zaman gerçek müşteri mesajlarından, çağrı kayıtlarından, destek taleplerinden gelir. İşte tam burada KVKK devreye girer ve çoğu ekip bunu atlar.
Değerlendirme ve optimizasyon setinizde kişisel veri (isim, telefon, adres, TC kimlik, e-posta) bulunuyorsa, bu verinin işlenmesi KVKK kapsamındadır. Üstelik bu veri çoğu zaman bir LLM sağlayıcısına, hatta yurt dışındaki bir modele gönderilir. Bu, hem veri işleme hem de yurt dışına aktarım açısından risk demektir.
Pratik önlemler: PII maskeleme. Değerlendirme setine koymadan önce kişisel verileri maskeleyin veya sahte verilerle değiştirin; "Ahmet Yılmaz, 0532..." yerine "[AD], [TELEFON]" gibi yer tutucular kullanın. Metriğiniz genellikle bu bilgilere ihtiyaç duymaz. Veri minimizasyonu. Değerlendirme için gereğinden fazla alan taşımayın. Yerel model seçeneği. Hassas görevlerde, veriyi dışarı göndermemek için yerelde çalışan açık ağırlıklı bir modeli değerlendirin; DSPy model-bağımsızdır, bu geçişi kolaylaştırır. Aydınlatma ve dayanak. Müşteri verisini bu amaçla işlemek için uygun hukuki dayanağı ve aydınlatma metnini danışmanınızla kurun.
Unutmayın: DSPy'ın metrik odaklı disiplini aslında KVKK ile dosttur. İyi tanımlanmış bir değerlendirme seti, aynı zamanda hangi verinin neden işlendiğinin de belgesidir. Uyumu baştan tasarıma katarsanız, hem daha iyi bir sisteme hem de denetime hazır bir sürece sahip olursunuz. Aynı disiplin EU AI Act açısından da işinize yarar: eğer LLM sisteminiz yüksek riskli bir kullanım alanında (örneğin işe alım, kredi değerlendirme, kamu hizmeti) çalışıyorsa, EU AI Act teknik dokümantasyon, şeffaflık ve insan gözetimi ister. DSPy'ın metrik odaklı değerlendirme kayıtları, program versiyonlaması ve CI çıktıları, tam da bu dokümantasyonun doğal bir parçası olur; yani "nasıl test ettik, hangi kalitede, hangi sürümle" sorularının cevabı elinizde hazır durur. AB pazarına dokunan bir uygulama geliştiriyorsanız, bu uyum altyapısını sonradan değil, DSPy pipeline'ınızı kurarken baştan tasarlayın.
DSPy'ın gerçekten parladığı yer: RAG ve çok adımlı pipeline'lar
Tek adımlık bir soru-cevapta DSPy'ın faydası kısmen görünür; asıl fark çok adımlı sistemlerde ortaya çıkar. Bugün kurumsal uygulamaların çoğu tek bir LLM çağrısı değildir. Tipik bir RAG (retrieval-augmented generation) hattı şöyle işler: kullanıcının sorusunu daha iyi bir arama sorgusuna dönüştür, ilgili belgeleri getir, getirilen belgelerle cevabı üret ve son olarak cevabın belgelerle tutarlı olup olmadığını doğrula. Bu dört adımın her biri ayrı bir prompt gerektirir ve elle yönetildiğinde kâbusa döner.
DSPy'da bu zinciri tek bir program olarak kurar ve bütünü birlikte optimize edersiniz. Basitleştirilmiş bir örnek:
class SorguYaz(dspy.Signature):
"""Kullanıcı sorusunu etkili bir arama sorgusuna dönüştür."""
soru: str = dspy.InputField()
sorgu: str = dspy.OutputField()
class CevapUret(dspy.Signature):
"""Getirilen belgelere dayanarak soruyu yanıtla."""
baglam: str = dspy.InputField()
soru: str = dspy.InputField()
cevap: str = dspy.OutputField()
class RAG(dspy.Module):
def __init__(self):
self.sorgu_yaz = dspy.ChainOfThought(SorguYaz)
self.cevap_uret = dspy.ChainOfThought(CevapUret)
def forward(self, soru):
sorgu = self.sorgu_yaz(soru=soru).sorgu
belgeler = dspy.Retrieve(k=3)(sorgu).passages
baglam = "\n".join(belgeler)
return self.cevap_uret(baglam=baglam, soru=soru)
Buradaki güzellik şu: Optimizer'ı bu RAG programına uyguladığınızda, hem sorgu yazma adımı hem de cevap üretme adımı aynı anda, uçtan uca metriğe göre iyileşir. Elle prompt'la bu neredeyse imkânsızdır; bir adımı düzeltirken diğerini bozarsınız. DSPy'ın bileşimsel (compositional) yapısı tam da bu yüzden çok adımlı sistemlerde oyunu değiştiriyor. Sahada gördüğüm en büyük kalite sıçramaları, tek bir prompt'u değil, bütün bir pipeline'ı optimize ettiğimizde geldi.
Alternatiflerle karşılaştırma: elle prompt, LangChain ve diğerleri
DSPy'ı doğru konumlandırmak için onu neyle karşılaştırdığınızı bilmek gerekir. Sık sorulan "LangChain yerine mi kullanacağım" sorusunun cevabı aslında hayır; ikisi farklı şeyler yapar. LangChain (ve benzeri çerçeveler) bileşenleri birbirine bağlamaya, orkestrasyona odaklanır — prompt'ların içeriğini yine siz yazarsınız. DSPy ise prompt'ların içeriğini optimize etmeye odaklanır. Aslında ikisini birlikte de kullanabilirsiniz.
Aşağıdaki tablo, üç yaklaşımı temel eksende karşılaştırıyor:
| Boyut | Elle prompt | Orkestrasyon çerçevesi | DSPy |
|---|---|---|---|
| Prompt içeriği | İnsan yazar | İnsan yazar | Otomatik optimize edilir |
| Metrik odaklı iyileştirme | Yok | Genelde yok | Merkezde |
| Model değişimine dayanıklılık | Düşük | Orta | Yüksek |
| Çok adımlı optimizasyon | Zor | Manuel | Uçtan uca |
| Öğrenme eğrisi | Düşük | Orta | Orta-yüksek |
| Değerlendirme verisi gereksinimi | Yok | Yok | Şart |
Bu tablodaki son satır kritik: DSPy'ın bedeli, değerlendirme verisi hazırlama zorunluluğudur. Ama bu bir kusur değil, aslında bir erdemdir; sizi kaliteyi ölçmeye zorlar. Ölçmediğiniz şeyi iyileştiremezsiniz.
Bir müşteri vakası: sayılarla DSPy geçişi
Somut bir örnek paylaşayım. Bir müşteride, gelen destek e-postalarını otomatik yönlendiren bir sınıflandırıcı vardı; elle yazılmış uzun bir prompt ile çalışıyordu ve doğruluğu bir değerlendirme setinde yaklaşık %78 seviyesindeydi. Yeni bir modele geçmek istediklerinde prompt'un doğruluğu %71'e düştü ve kimse nedenini çözemedi. Ekip haftalarca prompt'u elle kurcaladı, marjinal iyileşmeler elde etti ama tutarlı bir sonuç yakalayamadı.
Süreci DSPy'a taşıdık. Önce 150 örneklik, PII'dan arındırılmış bir değerlendirme seti hazırladık. Görevi basit bir sınıflandırma signature'ı ile modelledik. Metriği net tanımladık: doğru etikete düşme oranı, artı yanlış sınıflandırmanın maliyet ağırlığı (bir "acil" talebi "genel" olarak sınıflamak, tersinden daha pahalıydı). Sonra MIPROv2 ile optimize ettik.
Sonuç, aynı yeni modelde doğruluğun %71'den %86'ya çıkması oldu. Ama benim için asıl kazanım sayı değildi; ekibin artık model değiştirmekten korkmaması oldu. Bir sonraki model geldiğinde tek yaptıkları tek satırı değiştirip yeniden derlemek ve değerlendirme setinde sonucu görmek oldu. Haftalar süren korkulu bir süreç, yarım günlük rutin bir işleme dönüştü. DSPy'ın gerçek getirisi burada: kalite artışı güzel, ama asıl değer sürecin öngörülebilir ve güvenli hale gelmesi.
Öğrenme eğrisi ve ekip: DSPy'ı nasıl benimsetirsiniz
Dürüst olayım: DSPy'ın bir öğrenme eğrisi var. Elle prompt yazmaya alışmış bir ekip, ilk başta "niye bu kadar uğraşıyoruz, prompt'u yazsak bitecek" diye düşünür. Bu direnç doğaldır ve onu aşmanın yolu, küçük bir kazanımı erken göstermektir.
Benim önerdiğim benimsetme yaklaşımı şu. İlk olarak, DSPy'ı tüm sisteme değil, tek bir dertli göreve uygulayın; küçük bir zaferle başlayın. İkinci olarak, "önce/sonra" karşılaştırmasını aynı değerlendirme setinde, sayıyla gösterin — insanları ikna eden şey teori değil, kendi verilerindeki fark. Üçüncü olarak, metrik tanımlama işini bir ekip sporu yapın; çünkü iyi metrik, işi en iyi bilen kişinin (ürün sahibi, alan uzmanı) katkısını gerektirir; bu sadece veri biliminin işi değildir.
"Pratik tavsiye: DSPy'ı öğrenirken en çok zorlanılan nokta, "sihir"i optimizer'da aramaktır. Oysa değerin çoğu iyi bir signature ve iyi bir metrik tanımlamaktan gelir. Optimizer, iyi tanımlanmış bir problemi çözer; kötü tanımlanmış bir problemi kurtarmaz. Zamanınızın çoğunu bu iki tanıma ayırın.
Ekibinizin olgunluğu henüz Python ve değerlendirme disiplinine uygun değilse, aceleci olmayın. DSPy güçlü bir araç ama disiplin gerektirir. Önce tek bir görevde temiz bir değerlendirme kültürü kurun; DSPy o kültürün üzerine çok daha kolay oturur. Ben sahada, teknik hazır olmadan DSPy'a atlayıp yarım bırakan birkaç ekip gördüm; oysa aynı ekipler önce ölçme disiplinini kursalardı, geçiş çok daha sağlıklı olurdu.
İyi bir signature yazmanın incelikleri
Sahada gördüğüm kadarıyla ekiplerin en çok hafife aldığı iş, signature yazmak. "Girdi soru, çıktı cevap, oldu bitti" diye düşünürler. Oysa signature, DSPy'a niyetinizi anlattığınız yerdir ve ne kadar net olursa optimizer o kadar iyi çalışır. İyi bir signature'ın birkaç sırrı var.
Birincisi, alan açıklamaları (field descriptions). Her girdi ve çıktı alanına kısa ama net bir açıklama ekleyin. cevap: str = dspy.OutputField(desc="tek cümle, kaynak belirt") gibi bir açıklama, modele beklentinizi söyler ve optimizer'ın arama uzayını daraltır. İkincisi, docstring. Signature'ın docstring'i aslında görevin özüdür; "soruyu yanıtla" yerine "soruyu yalnızca verilen bağlama dayanarak, uydurmadan yanıtla" gibi görevin ruhunu yansıtan bir cümle yazın. Üçüncüsü, doğru granülerlik. Tek bir signature'a çok iş yüklemeyin; karmaşık görevi birkaç signature'a bölmek, hem optimizasyonu hem de hata ayıklamayı kolaylaştırır.
Bir diğer önemli nokta çıktı tipleri. DSPy 2.x, yapılandırılmış çıktıları (liste, sözlük, hatta Pydantic modelleri) destekliyor. Eğer çıktınızın belirli bir yapıda olması gerekiyorsa (örneğin bir JSON nesnesi), bunu signature'da tip olarak bildirin; böylece elle "lütfen JSON döndür" diye yalvarmak zorunda kalmazsınız. Tipli imzaların gücü tam da burada: yapı garantisini çerçeveye devredersiniz.
Değerlendirme setini kurmanın sanatı: az ama temiz
DSPy'ın kalbi metrikse, o metriğin çalıştığı zemin değerlendirme setidir. Ve burada en yaygın yanılgı, "ne kadar çok örnek o kadar iyi" sanmaktır. Gerçek şu: 50 temiz, dikkatle seçilmiş örnek, 5000 gürültülü örnekten iyidir. Kalite, nicelikten önce gelir.
İyi bir değerlendirme seti kurarken şunlara dikkat edin. Kapsayıcılık: setiniz gerçek dünyanın çeşitliliğini yansıtsın; sadece kolay örnekleri değil, zor ve sınır durumlarını da içersin. Çünkü optimizer setinizde ne varsa onu iyileştirir; kolay örneklerle beslerseniz, kolay örneklerde iyi ama zorlarda kötü bir sistem elde edersiniz. Etiket kalitesi: etiketleriniz tutarlı ve doğru olsun; çelişkili etiketler optimizer'ı şaşırtır. Ayrım: eğitim ve test setlerini ayırın; modeli gördüğü örneklerle değerlendirmek kendinizi kandırmaktır.
"Pratik tavsiye: Değerlendirme setinizi canlı tutun. Üretimde modelin yanıldığı gerçek örnekleri düzenli olarak toplayıp sete ekleyin. Böylece setiniz zamanla gerçek dünyanın zorluklarını daha iyi temsil eder ve her optimizasyon bir öncekinden daha isabetli olur. Bu, DSPy'ı statik bir araçtan sürekli öğrenen bir sisteme dönüştürür.
Türkçe görevlerde bu daha da kritik. Türkçenin zengin morfolojisi, argosu ve bölgesel farklılıkları nedeniyle, değerlendirme setinizin gerçek Türkçe kullanıcı verisinden gelmesi şart. İngilizce için hazırlanmış bir seti çevirip kullanmak, gerçek Türkçe kullanımın inceliklerini kaçırır. Kendi sahanızdan, kendi kullanıcılarınızdan toplanmış temiz bir Türkçe set, herhangi bir hazır çözümden daha değerlidir.
Optimizasyonun maliyeti: token bütçesini unutmayın
Sık atlanan bir konu: optimizasyonun kendisi de LLM çağrısı yapar ve para harcar. Özellikle MIPROv2 gibi Bayesçi arama yapan optimize ediciler, en iyi prompt'u ararken modeli defalarca çağırır. Bu yüzden optimizasyonu bir üretim çağrısı gibi değil, bir eğitim adımı gibi düşünün: seyrek, kontrollü ve bütçelenmiş. Geliştirme aşamasında auto="light" gibi hafif ayarlarla başlayın, ancak son üretim sürümü için daha kapsamlı bir arama yapın. Ayrıca optimizasyon sırasında daha ucuz bir modeli "öğretmen" olarak kullanıp, optimize edilmiş programı daha küçük ve ucuz bir modelde çalıştırmak yaygın bir kalıptır; bu, hem kaliteyi korur hem de üretim maliyetini düşürür. Sahada bütçeyi kontrol altında tutmanın anahtarı, optimizasyonu sık sık değil, anlamlı miktarda yeni değerlendirme verisi biriktikçe, planlı ve ölçülü biçimde çalıştırmaktır.
Nereden başlamalı: somut bir ilerleme planı
Bu yazıyı kapatırken elinizde uygulanabilir bir plan olsun istiyorum. DSPy'a geçişi üç aşamada düşünün.
İlk olarak, en çok acı çektiğiniz tek bir yapılandırılmış görevi seçin — tercihen bir sınıflandırma veya çıkarım görevi, çünkü bunlarda metrik tanımlamak en kolaydır. Bu görev için 50-200 etiketli örnekten oluşan küçük bir değerlendirme seti hazırlayın ve bu seti PII'dan arındırın.
İkinci olarak, görevi DSPy'da Predict veya ChainOfThought ile modelleyin, basit bir metrik tanımlayın ve BootstrapFewShot ile ilk optimizasyonu yapın. Sonucu elle yazdığınız mevcut prompt'la aynı değerlendirme setinde karşılaştırın. Aradaki farkı sayıyla görün; bu sayı ekibinizi ikna edecek olan şeydir.
Üçüncü olarak, işe yaradığını gördüğünüzde süreci kurumsallaştırın: DSPy programını git'e alın, CI'da değerlendirme çalıştırın, optimize edilmiş sürümü sabitleyin ve model değişikliklerini artık korkmadan yapın. Bir görevde bu döngüyü kurduğunuzda, diğer görevlere ölçeklemek çok daha hızlı olur.
Prompt mühendisliği bir sanat olarak başladı, ama olgunlaştıkça bir mühendislik disiplinine dönüşüyor. DSPy bu dönüşümün en somut aracı. Elle prompt yazmanın konforlu belirsizliğinden, ölçülebilir ve tekrarlanabilir bir sürece geçmek başta zahmetli görünür; ama bir kez o eşiği geçtiğinizde, geriye dönmek istemezsiniz.
Danismanlik Baglantilari
Bu yazıya en yakın consulting sayfaları
Bu içerikten sonraki mantıklı adım için en ilgili solution, role ve industry landing'lerini burada görebilirsin.
Kurumsal RAG Sistemleri Gelistirme
Sirket ici bilgiye kaynakli, guvenli ve denetlenebilir erisim saglayan uretim seviyesinde RAG mimarileri.
AI Agent ve Workflow Otomasyonu
Tek adimli chatbot'larin otesine gecen; arac, kural ve insan onayi ile ilerleyen AI destekli is akislarina gecis.
CTO'lar icin Kurumsal AI Mimari Danismanligi
PoC seviyesinde kalan AI girisimlerini guvenli, olceklenebilir ve production-ready mimarilere tasimak icin teknik liderlik danismanligi.