Bir LLM ile uygulama geliştirmek
Kısaca
- Bir LLM API’sine istek atmak, mesaj yapısını ve sistem komutunu anlamak
- Modelden doğrulanabilir JSON almak
- Araç çağırmanın (tool use) akışını kavramak
- Maliyet, gecikme ve bağlam penceresini tasarım kararı olarak görmek
Buraya kadar modelin içini gördük. Bundan sonra modeli bir bileşen olarak kullanacağız. Örnekler Anthropic’in Python SDK’sıyla yazıldı, ama aynı kavramlar diğer sağlayıcılarda da birebir var.
1. İlk çağrı
uv add anthropic
export ANTHROPIC_API_KEY="..." # anahtarı koda yazma, ortam değişkeninde tut
import anthropic
client = anthropic.Anthropic()
yanit = client.messages.create(
model="claude-sonnet-5-5",
max_tokens=500,
system="Kısa ve net cevap veren bir Türkçe asistansın.",
messages=[
{"role": "user", "content": "Gradyan inişi tek cümleyle anlat."},
],
)
print(yanit.content[0].text)
print(yanit.usage) # giriş ve çıkış token sayıları
Üç kavram:
- System: modelin rolünü ve kurallarını belirler. Kullanıcı mesajlarından önce gelir.
- Messages: konuşma geçmişi. Model önceki istekleri hatırlamaz (buna durumsuz denir). Sohbetin devam etmesi için önceki mesajları her istekte yeniden göndermen gerekir.
- Usage: her isteğin kaç token tuttuğu, yani maliyeti. Bunu her istekte kaydetmeyi alışkanlık hâline getir.
2. İyi bir istem yazmak
İstem (prompt) yazmak büyü değil, iyi bir iş tanımı yazmaktır:
- Bağlam ver: Kim için, ne amaçla?
- Görevi net söyle: “Özetle” yerine “3 maddede, her madde en fazla 15 kelime”.
- Örnek göster: Bir iki iyi örnek, uzun açıklamalardan çok daha etkili.
- Çıktı biçimini tanımla: Özellikle bir program okuyacaksa.
3. Yapılandırılmış çıktı
Modelin cevabını bir insan değil bir program okuyacaksa, düz metin kolayca bozulur. Bunun yerine modelden belli bir kalıba (şemaya) uyan JSON iste. JSON, programların kolayca okuyabildiği bir veri biçimidir. Gelen cevabı her zaman kontrol et:
import json
from pydantic import BaseModel, ValidationError
class Fatura(BaseModel):
firma: str
tarih: str # YYYY-AA-GG
toplam_tl: float
metin = "ABC Ltd. 12 Mart 2026 tarihli faturada toplam 1.250,40 TL yazıyor."
yanit = client.messages.create(
model="claude-sonnet-5-5",
max_tokens=300,
system=(
"Metinden fatura bilgisini çıkar. Yalnızca şu alanlara sahip geçerli bir JSON döndür: "
"firma (metin), tarih (YYYY-AA-GG), toplam_tl (sayı). Başka hiçbir şey yazma."
),
messages=[{"role": "user", "content": metin}],
)
try:
fatura = Fatura.model_validate(json.loads(yanit.content[0].text))
print(fatura)
except (json.JSONDecodeError, ValidationError) as hata:
print("Geçersiz çıktı, yeniden dene ya da insana devret:", hata)
Doğrulama başarısız olursa ne yapacağına önceden karar ver: tekrar dene, daha küçük bir görev ver ya da bir insana devret. Sağlayıcıların çoğu artık şemayı doğrudan zorlayan bir “yapılandırılmış çıktı” modu da sunuyor; varsa onu kullan, yine de doğrulamayı bırakma.
4. Araç çağırma
Model hesap yapamaz, saati bilmez, veritabanına bakamaz. Ama hangi aracı hangi argümanla çağırmak gerektiğine karar verebilir. Akış şöyle:
- Modele kullanabileceği araçları (ad, açıklama, parametre şeması) bildirirsin.
- Model bir aracı çağırmak istediğini söyler:
hava_durumu(sehir="İzmir"). - Sen o fonksiyonu çalıştırır, sonucu modele geri verirsin.
- Model sonucu kullanarak cevabını tamamlar.
araclar = [{
"name": "hava_durumu",
"description": "Bir şehrin güncel hava durumunu döndürür.",
"input_schema": {
"type": "object",
"properties": {"sehir": {"type": "string"}},
"required": ["sehir"],
},
}]
yanit = client.messages.create(
model="claude-sonnet-5-5", max_tokens=500, tools=araclar,
messages=[{"role": "user", "content": "İzmir’de bugün şemsiye lazım mı?"}],
)
for blok in yanit.content:
if blok.type == "tool_use":
print("Model şunu çağırmak istiyor:", blok.name, blok.input)
Önemli: aracı çalıştıran senin kodun. Model yalnızca öneride bulunur. Bu yüzden silme, para gönderme gibi geri dönüşü olmayan işlemlerde ek onay ve yetki kontrolü koymak senin sorumluluğun.
5. Tasarım kararları
| Karar | Soru |
|---|---|
| Model boyutu | Bu iş için en küçük yeterli model hangisi? Küçük model daha hızlı ve ucuz. |
| Bağlam | Gerçekten her şeyi göndermem gerekiyor mu? Gereksiz bağlam hem pahalı hem dikkat dağıtıcı. |
| Gecikme | Kullanıcı bekliyor mu? Akış (streaming) ile ilk kelimeyi hızlı göster. |
| Hata | Model saçmalarsa ya da API çökerse ne olacak? |
Kendini dene
1. Sohbet uygulamanda model bir önceki mesajı “unutuyor”. En olası neden?
2. Modelden JSON istedin ama bazen başına açıklama ekliyor. En sağlam yaklaşım?
3. Araç çağırmada aracı kim çalıştırır?
Daha derine inmek istersen