agentData = [
{loop: "yerleşik (araç API'si)", k: 1, acc: 100.0, model: 2.0, tools: 1.0, tokens: 881, cap: 0.0},
{loop: "yerleşik (araç API'si)", k: 2, acc: 96.0, model: 2.0, tools: 2.0, tokens: 999, cap: 0.0},
{loop: "yerleşik (araç API'si)", k: 3, acc: 80.0, model: 2.0, tools: 3.0, tokens: 1112, cap: 0.0},
{loop: "yerleşik (araç API'si)", k: 4, acc: 68.0, model: 2.0, tools: 4.0, tokens: 1227, cap: 0.0},
{loop: "yerleşik (araç API'si)", k: 5, acc: 40.0, model: 2.0, tools: 5.0, tokens: 1338, cap: 0.0},
{loop: "metin protokolü", k: 1, acc: 40.0, model: 11.1, tools: 10.7, tokens: 3240, cap: 60.0},
{loop: "metin protokolü", k: 2, acc: 76.0, model: 6.5, tools: 5.7, tokens: 1815, cap: 24.0},
{loop: "metin protokolü", k: 3, acc: 52.0, model: 7.1, tools: 6.4, tokens: 2019, cap: 28.0},
{loop: "metin protokolü", k: 4, acc: 60.0, model: 5.3, tools: 4.3, tokens: 1322, cap: 0.0},
{loop: "metin protokolü", k: 5, acc: 28.0, model: 7.0, tools: 6.1, tokens: 1936, cap: 12.0}
]23 Ajan Anatomisi: Döngü, Durum ve Denetim
Öğrenme hedefleri. Bu bölümün sonunda:
- asgari ajan döngüsünü (agent loop) — model, araç çağrısı, gözlem, model — sıfırdan yazabilir ve her satırın ne işe yaradığını adlandırabilirsiniz;
- döngünün durumunun ne olduğunu ve bunun neden işin zor kısmı olduğunu söyleyebilirsiniz;
- bir görev daha çok adım gerektirdikçe ajanın güvenilirliğinin nasıl bozulduğunu bir hisse değil bir ölçüme dayanarak öngörebilirsiniz;
- bir görevin ne zaman ajan istediğine, ne zaman sabit bir hattın (pipeline) daha güvenli bir mühendislik tercihi olduğuna karar verebilirsiniz.
23.1 Döngü ve başka hiçbir şey
Bir ajan sihir değildir: bir ajan döngüsüdür — fonksiyonlara erişimi olan bir dil modelinin etrafındaki bir while döngüsü.
Ajan döngüsü (agent loop) — model bir eylem seçer, çalışma zamanı (runtime: modelin etrafında çağrıları yürüten ve sonuçları ekleyen kendi kodunuz) onu yürütür, sonuç transkripte (transcript: koşu boyunca biriken mesaj ve araç sonucu kaydı) eklenir ve model yeniden seçer. Model araç çağırmayı bıraktığında biter. ↩︎
Diğer her şey — planlama, bellek, orkestrasyon (orchestration: ajanların ve adımların koordinasyonu) — o döngünün etrafındaki mühendisliktir. İşte hiçbir şey çıkarılmadan tamamı:
def agent(question, tools, model, max_steps=10):
messages = [{"role": "system", "content": SYSTEM},
{"role": "user", "content": question}]
for step in range(max_steps): # 1. bütçe
reply = model.chat(messages, tools=tools) # 2. model karar verir
if not reply.tool_calls: # 3. çıkış
return reply.content
messages.append(reply.model_dump()) # 4. kararı hatırla
for call in reply.tool_calls: # 5. çalışma zamanı harekete geçer
try:
args = json.loads(call.function.arguments) # dict değil, JSON dizgisi
result = tools[call.function.name](**args)
except Exception as e:
result = f"ERROR: {e}" # 6. kusur bir gözlemdir
messages.append({"role": "tool",
"tool_call_id": call.id,
"content": str(result)})
raise StepLimitExceeded(question, messages) # 7. bitiremediAjan budur. def dâhil on dört ifade; sayın (Python dilbilgisinde try/except tek bir bileşik ifadedir, except ayrıca sayılmaz). Karşılaşacağınız framework’lerin (ajan geliştirmeyi kolaylaştıran yazılım çatılarının) altında yatan desen bu döngü. (Yorumlardaki numaralar aşağıdaki tartışma için etiketlerdir, ifade sırası değil.) model.chat şematik bir istemcidir; tools da burada iki işi birden görüyor: hem modele gönderilen şema listesinin hem de ad → fonksiyon sözlüğünün yerini tutuyor. Gerçek kodda ikisini ayırın (örneğin tool_schemas ve tool_impls). Framework’lerin eklediği şey çoğunlukla 1, 4 ve 7 numaralı satırlar hakkındaki görüşlerdir; bunlara, on dört ifadelik bir döngüde bulunmayan durum yönetimi, doğrulama, zamanlama ve kurtarma eklenir.
Oradaki üç ayrıntı süs değil. Birincisi argümanlar. OpenAI uyumlu bir uç noktada call.function.arguments bir JSON dizgisi olarak gelir; dolayısıyla **call.function.arguments TypeError fırlatır. Bu hata try bloğunun içinde oluştuğu için model, aslında çalışma zamanındaki bir kusurdan doğan hatayı kendi çağrısının suçuymuş gibi gösteren bir mesaj alır. Tersi tuzak da var: Ollama’nın yerleşik /api/chat uç noktası ve Anthropic’in Messages API’si argümanları zaten ayrıştırılmış bir nesne olarak verir; orada hatayı fırlatan json.loads olur. İstemcinizin hangisini döndürdüğüne bakın. İkincisi, paralel çağrıların sonuçlarını doğru çağrıyla eşleştirmeyi mümkün kılan şey tool_call_id’dir: tek turda beş sonuç geri gelir ve hangisinin hangi çağrıyı yanıtladığını yalnızca bu id söyler. Üçüncüsü, istisna messages’ı taşır, çünkü adım bütçesi dolduğunda ne yapmaya karar verirseniz verin, bunu ancak transkript raise’den sağ çıkarsa yapabilirsiniz.
Mesajların biçimini sağlayıcının protokolü belirler; biçimler ayrıntıda farklıdır, fikirde değil. Her şeyden önce modele araç listesi gönderilir: her araç için bir ad, bir açıklama ve argümanları için bir JSON Schema — Bölüm 18.4’ün kısıtladığı şemaların aynısı. Yukarıda kullanılan OpenAI tarzı biçimde asistan mesajı bir tool_calls listesi taşır ve her sonuç, eşleşen tool_call_id ile ayrı bir role: "tool" mesajı olarak geri gider. Anthropic’in biçiminde asistan mesajı tool_use blokları içerir (bir id, bir name ve bir input nesnesi), yanıtın stop_reason alanı "tool_use" olur ve sonuçlar, her biri eşleşen tool_use_id’yi taşıyan tool_result blokları olarak bir sonraki user mesajının içinde geri gider. Döngü ikisinde de aynıdır; yalnızca alan adları değişir.
Döngü ve kusurların ortaya çıktığı yerler
Karşılaşacağınız her framework, bu şemanın üç kenarına dair görüşler eklenmiş hâlidir: transkripte ne girer, döngünün ne zaman durmasına izin verilir ve çalışma zamanının neyi yürütmesine izin verilir.
Döngüdeki altı nokta ayrıca adlandırılmayı hak ediyor, çünkü her biri insanların çoğu zaman farkında olmadan verdiği bir karardır.
Model hiçbir şey yürütmez. Argüman üretir; onları çalıştırıp çalıştırmayacağına çalışma zamanınız karar verir. Güvenlik sınırının tamamı budur ve Bölüm 36, insanlar bunun tek sınır olduğunu unuttuklarında neler olduğunu anlatır.
messages durumdur ve yalnızca büyür. Başka bellek yoktur. Her gözlem eklenir, dolayısıyla bağlam her adımda uzar; bu da maliyetin adım sayısıyla doğrusaldan hızlı büyümesine yol açar ve bağlam sonunda bağlam penceresinin sınırına dayanır. On dört ifade bu durumu ele almıyor: pencere taştığında model.chat try’ın dışında hata fırlatır ve koşu, transkript kaydedilmeden çöker. Üretim sürümü o çağrıyı da sarar, istisnayı yeniden fırlatmadan önce messages’ı kalıcı olarak kaydeder ve taşmayı bir sıkıştırma (compaction) adımına devreder — Bölüm 25 tam oradan başlar.
3 numaralı satır sonlanma koşuludur ve bir model kararıdır. Döngü, model araç çağırmamayı seçtiğinde biter. Hiçbir şey görevin tamamlanıp tamamlanmadığını kontrol etmez. Klasik yazılım dünyasından gelen biri için bu mimarinin en şaşırtıcı özelliği budur: durma kuralı bir tahmindir. Üstelik bu koşul bitmiş bir cevaptan fazlasını yakalar. Çıktı token sınırında kesilmiş ya da bir içerik filtresine takılmış bir yanıtta da araç çağrısı yoktur; bu döngü o yarım parçayı cevapmış gibi döndürür. reply.content’e güvenmeden önce sağlayıcının bildirdiği durma nedenine (finish_reason ya da stop_reason) bakın.
6 numaralı satır bir istisnayı metne çevirir. Başarısız bir araç çağrısı bir çökme değil, modelin tepki verebileceği bir gözlemdir. İyi tepki verip vermediği Bölüm 24’ün konusudur ve büyük ölçüde o dizginin ne söylediğine bağlıdır. O except’in başka neyi yuttuğuna da dikkat edin: tools[call.function.name]’den gelen bir KeyError sizin hatanızdır ve model onu araç başarısız olmuş gibi alır. Güvenilir bir çalışma zamanı, gözlemi yazmadan önce araç kusurlarını düzeneğin (harness) — modelin etrafındaki kendi kodunuzun — kusurlarından ayırır.
Asıl önemli olan 7 numaralı satır. Bir adım bütçesi bir performans ayar düğmesi değil, döngünün kendi başına sonlanmayabileceğinin itirafıdır. Bütçe dolduğunda ne yapacağınız bir ürün kararıdır: yeniden denemek, aktarma (escalation: işi bir insana ya da daha güçlü bir modele devretmek) ya da o ana kadarki kısmi işi döndürmek. Bu karar bir framework’ün varsayılanına bırakılmamalı, bilerek verilmeli.
Adım bütçesi (step cap) — azami döngü yineleme sayısı. Bir ayar parametresi değil, döngünün çıkışının bir model kararı olduğunun ve hiç alınmayabileceğinin itirafı. ↩︎
Plan yoktur. Model bir eylem seçer, bir sonuç görür ve yeniden seçer. Planlamaya benzeyen her şey ya modelin kendi bağlamına bir plan yazıp sonra onu izlemesidir ya da kodunuzun dışarıdan yapı dayatmasıdır. İkisi de meşrudur; hiçbiri döngünün içinde değildir. Ayrımı koruyun: transkripte bir plan yazmak bağlam içi planlamadır ve modelin koşu boyunca tutarlı kalabildiği ölçüde işe yarar. Görevi, kodunuzun sonra yürüteceği adımlara önceden bölmek ise hiç planlama değildir — bu bir hattır ve Bölüm 23.4 bunun genellikle daha iyi bir ödünleşim (trade-off) olduğunu savunuyor.
23.1.1 Çıkışı yeniden bir koşula çevirmenin üç yolu
Çıkışın tahmin olarak kalması şart değil. Üç ucuz hamle, en az müdahaleciden en çoğuna doğru sıralanmış olarak, döngüye kontrol edilebilir bir koşulu geri koyuyor.
Bitirmeyi bir araç yapın. Şemadaki bir submit_answer(answer), “bitirdim”i çalışma zamanının tanıyabileceği bir çağrıya dönüştürür; böylece döngü bir yokluk üzerine değil gözlemlenebilir bir olay üzerine sonlanır. Çıkışın gerçekten bir koşul olması için düz metin bir yanıtın çıkış sayılmaması gerekir: API izin veriyorsa her turda bir araç çağrısını zorunlu kılın (OpenAI’nin API’sinde tool_choice: "required", Anthropic’inkinde {"type": "any"}). Bitirme aracı, Bölüm 23.3’te ölçülen metin protokolünün sorununu da doğrudan çözer: orada cevap komutu CEVAP, arama komutu ARA ile yarışıyor; ikisi aynı tür şey olduğunda bu yarış biter.
Tekrarı saptayın. Bir çağrı transkriptte zaten bulunan biriyle bayt bazında aynıysa döngü muhtemelen ilerlemeyi bırakmıştır. Bunun gerçek bir istisnası var: bir işin durumunu yoklamak, ajanın az önce yazdığı bir dosyayı yeniden okumak ya da değişen veriyi yeniden sorgulamak meşru tekrarlardır. Tekrarın zaten amaç olduğu araçları muaf tutun, kontrolü geri kalanlara uygulayın. Aynı sonucu yeniden döndürmek yerine tekrarı bildiren bir gözlem döndürün — bölümün aşağıda ölçülen en kötü kusuru da adım bütçesi dolana kadar tekrarlanan aynı çağrıdır ve tek satırlık bir kayıt tutma onu yakalar.
Tek bir bütçeye değil üçüne sınır koyun. Adım sayısı, wall-clock süresi (gerçekte geçen süre, saniye cinsinden) ve token sayısı farklı biçimlerde tükenir: bir koşu on adımın altında kalıp yine de bir dakika ya da elli bin token harcayabilir. Her biri dolduğunda ne olacağı önceden tanımlanmalıdır; yukarıdaki on dört ifade ise yalnızca birincisini sınırlıyor.
Bu döngüyü kullandığınız dilde, iki gerçek araçla bir kez kendiniz yazın. Bir öğleden sonra sürer ve framework belgelerini okuma biçiminizi kalıcı olarak değiştirir — sonradan karşılaştığınız her soyutlama bu on dört ifadenin tanınabilir bir sarmalayıcısıdır ve ne yaptığını değil ne eklediğini sorabilirsiniz.
Neye bakacağız. Önce döngünün durumunun gerçekte ne olduğu — yalnızca büyüyen bir transkript — ve doğrudan bundan çıkan üç sonuç; “yeniden dene”nin burada sıradan yazılımdakinden neden çok daha pahalı bir öneri olduğu da buna dâhil. Sonra görevler daha çok adım gerektirdikçe döngünün ne kadar ilerlediğini ölçeceğiz; sürpriz, araç kullanımı kusursuz kalırken doğruluğun çökmesi. Sonra aynı döngüyü elle yazılmış bir metin protokolüyle karşılaştıracağız; o protokol en zor görevde değil, en kolay görevde en kötü sonucu veriyor. Son olarak da hepsinden önce verilmesi gereken karar: bu görev gerçekten bir döngü istiyor mu?
23.2 Durum bir transkripttir ve asıl problem budur
Bu ajanın durumunun ne olduğunu sorarsanız cevap rahatsız edicidir: mesaj listesi, o kadar. Çalışma belleği yoktur, değişken bağlamaları yoktur, modelin adresleyebileceği bir karalama alanı yoktur. Ajanın yedinci adımda bildiği her şey, altıncı adıma kadar transkripte girmiş ve orada kalmış olan şeydir.
Bu, asgari döngünün bir özelliği; ajanlar hakkında bir yasa değil. Sonraki bölümlerden üçü bu sınırlamayı aşmanın farklı yollarını ele alıyor: Bölüm 25 durumu ajanın geri okuduğu dosyalara taşıyor, Bölüm 26 ajana koşudan daha uzun yaşayan bir depo veriyor ve Bölüm 28 alt görevleri kendi transkriptleri olan çalışanlara devrediyor. Aşağıdaki üç sonucu varsayılan olarak elinize geçen şey ve o bölümlerin var olma sebebi diye okuyun.
Akıl yürüten modellerde (Bölüm 10) transkripte bir şey daha girer: düşünce içeriği. Sağlayıcılar bunu farklı taşır. Anthropic’in genişletilmiş düşünme (extended thinking) modu, bir araç turunda son asistan mesajının thinking bloklarının değiştirilmeden geri gönderilmesini ister; Ollama ise düşünceyi content’ten ayrı bir thinking alanında döndürür ve yalnızca content’i transkripte yazan bir döngü onu fark etmeden atar. Mesajı transkripte eklemeden önce istemcinizin hangi alanları döndürdüğüne bakın.
Bu durumdan doğrudan üç sonuç çıkıyor; pratikte ters giden şeylerin çoğunu bunlar açıklıyor.
Maliyet, araç çağrısı sayısıyla değil model çağrısı sayısıyla büyür. Her model çağrısı bütün transkripti yeniden gönderir, dolayısıyla gerçekten sıralı n adımlık bir koşu kabaca ilk n bağlam uzunluğunun toplamına mal olur — doğrusal değil karesel. İşin tesellisi, Bölüm 23.3’te ölçüldüğü gibi, aynı anda birkaç araç çağrısı üreten bir modelin pek çok adımı bire indirmesidir; bu bölümün ölçümünde ajanın maliyeti üzerindeki en büyük kaldıraç da bu çıkıyor.
Hiçbir şey unutulmaz, hatalar dâhil. Yanlış bir araç çağrısı ve hata mesajı koşunun geri kalanı boyunca bağlamda kalır; model de sonraki her adımda çıktısını onlara koşullu olarak üretmeyi sürdürür. Yanlış giden bir ajanın çoğu zaman aynı yönde yanlış gitmeyi sürdürmesinin nedeni budur — daha önceki kafa karışıklığının izleri artık akıl yürütürken dayandığı malzemenin bir parçasıdır.
Varsayılan olarak transkript geri alınamaz. Sıradan yazılımda başarısız bir adımı temiz bir durumdan yeniden denerdiniz. Burada kusur durumun içindedir ve bu döngü her mesajı saklar. Geri almayı kurabilirsiniz — bir adımdan önce mesaj listesinin anlık görüntüsünü alıp gerekirse listeyi o noktaya geri kırpmak ucuzdur ve genellikle yapılmalıdır. Hiçbir anlık görüntünün geri almadığı şey yan etkilerdir: giden e-posta, silinen kayıt, geçen ödeme. İkisini kafanızda ayrı tutun, çünkü yalnızca biri sizin denetiminizde; “yeniden dene”nin bir ajan için bir HTTP isteğine göre çok daha pahalı bir öneri olmasının nedeni de budur.
Karesel terimi hafifleten tek bir şey var ve başka bir şeyi eniyilemeden önce bunu bilmekte yarar var. Bir ajan döngüsündeki her istek, bir önceki isteğin tamamıyla, hiç değişmeden başlar — prompt önbellekleme (prompt caching) tam da bu desen için tasarlandı: bugünkü fiyat listelerinde önbellekten okuma çoğu zaman taze okumanın kabaca onda birine mal olur. Kesin indirim sağlayıcıya ve modele göre değişir, bazı sağlayıcılar önbelleğe yazmak için ek ücret alır ve bir önbellek kaydı varsayılan olarak birkaç dakika kullanılmayınca silinir. Karesel terim kaybolmuyor; sabiti küçülüyor, en fazla bir büyüklük mertebesi kadar. Bunun rahatsız edici bir sonucu da var: bir transkripti sıkıştırmak ön eki yeniden yazar ve önbelleği geçersiz kılar. Bölüm 25’in sıkıştırması bu yüzden bedava değil; ayrıntılı mekanizma Bölüm 31’de.
Bölüm 25’in ayrı bir bölüm olmasının nedeni de budur. Transkriptin durumun kendisi olduğunu gördüğünüzde, ona ne gireceğine — ve neyin özetleneceğine, atılacağına ya da hiç eklenmeyeceğine — karar vermek bir temizlik işi olmaktan çıkıp asıl tasarım faaliyeti olur.
23.2.1 Denetim: sonra ne olacağına kim karar veriyor?
Transkript ajanın ne bildiğini belirler. Sonraki eylemi kimin seçeceğini ise belirlemez; bu ayrı bir eksendir ve bu eksen boyunca bir yelpaze uzanır. O yelpazede bilerek bir nokta seçmek, mühendisliğin büyük kısmıdır.
| sonraki eylemi kim seçer | ne zaman doğrudur | |
|---|---|---|
| Sabit hat | siz, tasarım anında | adımlar biliniyor ve değişmiyor. En ucuz, en hızlı ve test edilebilir |
| Yönlendirici (router) | model, bir kez, küçük bir kümeden | birkaç bilinen yol var ve hangisinin izleneceğine girdi karar veriyor |
| Kısıtlı döngü | model, her adımda, adım bütçeli kısıtlı bir araç kümesinden | yol değişiyor ama olası yollar sınırlı |
| Açık döngü | model, her adımda, geniş araçlarla | gerçekten açık uçlu görevler. En yetenekli ve en öngörülemez |
| Onay kapılı döngü | model, her adımda; ama belirlenen araçlar yürütülmeden önce bir insanın onayını bekler | eylem geri alınamaz: para hareket eder, veri silinir, mesaj gider |
Onay kapısı prompt’a (istem) değil çalışma zamanına aittir: bir model izin istememeye ikna edilebilir, aracın üzerindeki bir requires_approval bayrağı edilemez. O kapının nereye konacağı ve karşı tarafta kimin olduğu Bölüm 37’nin konusu.
Son satır özerklikte bir basamak daha yukarısı değil — onay kapısı her döngüye eklenebilir — o yüzden ölçeği ilk dört satır olarak okuyun. Adını koymak gereken hata, işe açık döngüyle başlamaktır. Açık bir döngü kurulacak en etkileyici şeydir ve neredeyse hiçbir zaman problemin ihtiyaç duyduğu şey değildir; ve bir demoda çalıştığı için bedeli ancak sonradan, kimsenin hata ayıklayamadığı bir sistem biçiminde ortaya çıkar.
En üstten başlayın ve yalnızca bir ölçüm sizi zorladığında aşağı inin.
23.3 Döngü ne kadar ilerliyor?
Yukarıdakilerin hepsi mimari. Bir uygulayıcının asıl sorusu şu: bu ne kadar güvenilir? Cevap ölçülebilir bir şeye bağlı: görevin kaç adım gerektirdiğine.
Kurulum diğer her şeyi sabit tutuyor. Uydurma projelerden oluşan bir veritabanına — ZRG-14 gibi kodlar, hiçbir modelin tahmin edemeyeceği bütçeler — yalnızca tek bir araçla erişilebiliyor. Her soru k arama ve bir toplama gerektiriyor; k 1’den 5’e kadar. Her k değerinde yirmi beş görev, sıcaklık 0, tam eşleşmeli puanlama. Aynı model üzerinde iki döngü: sağlayıcının yapılandırılmış araç çağırma API’sini kullanan yerleşik döngü ve modelin ARA(ZRG-14, butce) yazıp çalışma zamanının onu ayrıştırdığı, elle yazılmış bir metin protokolü. Aşağıdaki çıktıda birincisi native, ikincisi text diye geçiyor; sütunlar sırasıyla arama sayısı (lookups), doğruluk, %95 güven aralığı, görev başına model çağrısı ve araç çağrısı, ideal çağrı sayısı, adım bütçesine çarpan koşuların oranı (hit cap) ve görev başına token.
Bütçeye takılan bir koşu dışlanmıyor, yanlış sayılıyor — bunu belirtmek gerekiyor, çünkü metin protokolünün hikâyesinin çoğu bu.
qwen3.5:9b, 25 tasks per step count, step cap 14
95% intervals are Wilson on n = 25
loop lookups accuracy 95% CI model calls tool calls ideal hit cap tokens
native 1 100.0% [86.7, 100.0] 2.0 1.0 1 0.0% 881
native 2 96.0% [80.5, 99.3] 2.0 2.0 2 0.0% 999
native 3 80.0% [60.9, 91.1] 2.0 3.0 3 0.0% 1,112
native 4 68.0% [48.4, 82.8] 2.0 4.0 4 0.0% 1,227
native 5 40.0% [23.4, 59.3] 2.0 5.0 5 0.0% 1,338
text 1 40.0% [23.4, 59.3] 11.1 10.7 1 60.0% 3,240
text 2 76.0% [56.6, 88.5] 6.5 5.7 2 24.0% 1,815
text 3 52.0% [33.5, 70.0] 7.1 6.4 3 28.0% 2,019
text 4 60.0% [40.7, 76.6] 5.3 4.3 4 0.0% 1,322
text 5 28.0% [14.3, 47.6] 7.0 6.1 5 12.0% 1,936
Hücre başına yirmi beş görev küçük bir örneklem ve Wilson aralıkları bunu söylüyor: beş aramada %40, [23, 59]; üç aramada %80, [61, 91]. Bu ölçümün desteklediği şey yön — bir arama ile beş arama birbirinden uzak (Fisher kesin testi, p = 3 × 10⁻⁶) — aradaki eğrinin tam şekli değil. Komşu adım sayılarının hiçbir çifti kendi başına ayrışmıyor; en yakını p = 0,088 ile 4’e karşı 5. Ara noktaları tek tek kesin değerler olarak değil, genel bir eğilimin parçaları olarak okuyun.
23.3.1 Araç çağrıları kusursuz, cevaplar değil
native (yerleşik) satırlarını dikkatle okuyun, çünkü ilginç sütun doğruluk değil.
Araç kullanımı her adım sayısında kusursuz. k arama gerektiren bir görev için tam olarak k çağrı, sıfır bozuk çağrı, adım bütçesine çarpan sıfır koşu. Model her zaman doğru şeyi istiyor. Buna rağmen doğruluk aynı aralıkta %100’den %40’a düşüyor.
Bozulan şey döngünün kendisi değil; döngünün topladığı bilgiler üzerinde yapılan akıl yürütme. Ajan beş doğru sayıyı getiriyor ve sonra onları yanlış topluyor.
Bunu iyice sindirmekte yarar var, çünkü hata ayıklarken nereye bakacağınızı değiştiriyor. Bir ajan bozulduğunda ilk içgüdü araç çağrılarını incelemektir — oysa burada araç çağrıları hiçbir zaman sorun değildi. Sorun, biriken gözlemleri bir araya getirip toplamaktaydı.
İki rakip açıklamayı ciddiye almak gerekiyor; ikisi farklı sonuçlara varıyor. Birincisi bağlam uzunluğu. Kesilme olası değil: yerleşik döngüde görev başına ortalama token en fazla 1.338, yani pencerenin epey içinde; Bölüm 25.2 de aynı modeli benzer bir görevde 11.048 token’a kadar koşuyor ve doğruluk %88,3 ile %100 arasında kalıyor. Bu, pencerenin dolmasını olası bir suçlu olmaktan çıkarıyor. Biriken gözlemlerin etkisini ise dışlamıyor — modelin topladıklarını nasıl kullandığı, bunların biçimi, aralarına ne girdiği. Bu, yerin bitmesinden farklı bir şeydir ve bu deney tasarımı onu ayıramıyor.
İkinci açıklama bu tasarımla elenemiyor; o yüzden açıkça yazmak gerekiyor. k iki şeyi birden kontrol ediyor: döngünün taşıması gereken gözlem sayısını ve tek bir ileri geçişte (forward pass) toplanması gereken sayı adedini. Düşüşün bir kısmı ajanlıktan değil aritmetik genişlikten, yani aynı anda toplanan sayı adedinden kaynaklanıyor olabilir. İkisini ayırt edecek kontrol deneyi ucuz ama koşulmadı: aynı 25 görev, beş sayı doğrudan prompt’a yapıştırılmış ve hiç araç yok. O deney yapılana kadar eğriyi “güvenilirlik, sonda birleştirilmesi gereken bilgi miktarı arttıkça düşüyor” diye okuyun; ajanlıkla ilgili okumayı ise bir bulgu değil, bir yorum sayın.
Eğrinin gösterdiği şey ise adım başına sabit bir aşınma değil. Her arama birbirinden bağımsız olarak aynı \(p\) olasılığıyla başarılı olsaydı, k arama gerektiren bir görev \(p^k\) olasılığıyla başarılı olurdu. İki ile beş arama için \(p^k\) = ölçülen doğruluk denklemini çözünce \(p\) = 0,980, 0,928, 0,908 ve 0,833 çıkıyor — sabit değil, düşüyor — ve adım başına sabit 0,90’lık bir başarı, beş aramada ölçülen %40 yerine \(0{,}9^5 \approx\) %59 öngörürdü. Adım başına yük ağırlaşıyor; aynı sonuca başka bir yönden varıyoruz. Görev uzunluğu arttıkça başarının düşmesini büyük ölçekte ölçen dış çalışma Kwa vd. (2025): modellerin başarısını, görevin bir insana ne kadar sürdüğüne göre izliyor. Yao vd. (2024) ise güvenilirliğin farklı bir boyutunu, aynı görevin tekrarlı denemelerindeki tutarlılığı ölçüyor: pass^k, bir ajanın aynı görevdeki k bağımsız denemenin hepsinde başarılı olma olasılığıdır (buradaki k deneme sayısıdır, arama sayısı değil). 2024’te denedikleri en iyi fonksiyon çağırma ajanı (gpt-4o) görevlerin yarısından azında başarılı oldu ve perakende alanında pass^8 değeri %25’in altında kaldı.
23.3.2 Paralel araç çağırma döngüyü iki tura indiriyor
Aynı tablo ikinci bir sürpriz barındırıyor ve bu iyi haber. model calls sütunu her adım sayısında 2,0, çünkü model paralel araç çağırma kullanıyor.
Paralel araç çağırma (parallel tool calling) — bir modelin tek bir turda birkaç araç çağrısı üretmesi. Pek çok döngü yinelemesini bire indirir; çağrılar birbirinden bağımsızsa bu, onu bir ajanın maliyeti üzerindeki en büyük kaldıraçlardan biri yapar. ↩︎
Beş arama yapmak için beş tur harcamıyor; beş isteği tek turda üretiyor, beş sonucu okuyor ve cevaplıyor. Yani görev ne kadar iş gerektirirse gerektirsin döngü tam olarak iki kez çalışıyor.
Adın gizlediği bir ayrım var: paralel olan çağrılar, on dört ifadedeki yürütme değil. Yukarıdaki döngü onları bir for içinde sırayla koşturuyor; dolayısıyla batchleme (çağrıları tek turda toplu gönderme) token faturasını ve gidiş-dönüş sayısını azaltıyor, araçların içinde geçen wall-clock süresini değil. Yürütmeyi de paralel yapmak — çağrılar üzerinde bir asyncio.gather — ayrı bir değişiklik; araçlarınız sözlük aramaları değil ağ çağrıları olduğunda asıl önemli olan da bu.
Bunun maliyette büyük bir sonucu var. Beş kat iş 1,52 kat token’a mal oluyor — 881’den 1.338’e — çünkü pahalı olan şey transkripti yeniden göndermek ve transkript yalnızca iki kez gönderiliyor. Gerçekten sıralı bir döngü o bedeli her adımda öder; metin protokolünün yaptığı da budur: k = 5’te 3,5 kat model çağrısı ve k = 1’de 3,7 kata kadar token.
Bu aynı zamanda deneyin sınırı. Beş arama bağımsız olduğu için model onları batchleyebiliyor — dolayısıyla ölçülen şey sıralı planlama değil, yük altında toplama. İkinci adımı birinci sonuca bağlı olan bir görev gerçek bir döngüyü zorunlu kılar; orada daha kötü sayılar ve karesel bir maliyet eğrisi beklenir. Bu sayılardan herhangi birine farklı yapıda bir görevde güvenmeden önce o deneyi koşmakta yarar var.
23.3.3 Yapılandırılmış API yalnızca bir kolaylık değil
O tablodaki iki döngü de aynı modeli aynı görevlerde çalıştırdı; yalnızca protokol farklıydı. Yani ikinci blok, genellikle zevke göre karara bağlanan bir soruya temiz bir cevap veriyor: sağlayıcının araç çağırma API’si size iyi yazılmış bir prompt’un veremeyeceği bir şey kazandırıyor mu?
Metin protokolü bilerek ReAct’in (Yao, Zhao, vd. 2023) Action/Observation biçimini izliyor, ama Thought adımı olmadan. ReAct’te (“reason + act”, akıl yürüt + eyle) model düz metin olarak önce bir Thought (kısa bir akıl yürütme), sonra bir Action (bir araç adı ve argümanları) yazar; bir ayrıştırıcı eylemi çıkarır, çalışma zamanı onu çalıştırır ve sonuç bir Observation (gözlem) satırı olarak geri döner; ardından döngü yinelenir. 2022’de alternatif yoktu — hiçbir sağlayıcı tipli bir araç şeması sunmuyordu — ve katkı, akıl yürütmeyi eylemle iç içe geçirmenin akıl yürütmeden yalnızca eylemeyi yendiğini ve düşünce zinciriyle birleştirildiğinde soru cevaplamada en iyi sonuçları verdiğini göstermekti. Yani aşağıda söylenen “ReAct kötüdür” değil; tipli taşıma katmanı (typed transport) geldikten sonra neler eklendiği — üstelik yalnızca tek bir küçük modelde. Başta söylediğimiz gibi bu protokolde Thought: adımı yok; yani bu, ReAct’in taşıma biçimi, ama karalama defteri (scratchpad) olmadan. Dolayısıyla aşağıdaki sonuç ReAct’in kendisine genellenemez.
Yerleşik döngü her adım sayısında önde — 60, 20, 28, 8 ve 12 doğruluk puanıyla — üstelik ortalamada model çağrılarının kabaca üçte birini kullanarak (adım sayısına göre beşte bir ile beşte iki arası). Ama bu farklardan yalnızca birincisi 25 görevle yapılan bir anlamlılık testini geçiyor: 25/25’e karşı 10/25, Fisher kesin testi p = 3 × 10⁻⁶; dört aramadaki 8 puanlık fark ise 17 doğruya karşı 15 (p = 0,77) ve hiçbir anlam taşımıyor. Metin protokolünün kendi eğrisi — 40, 76, 52, 60, 28 — monoton bile değil. Tek başına şansın açıklayabileceğinden fazla değişiyor (beş hücre üzerinde bir χ² testi p ≈ 0,009 veriyor), ama düzenli bir düşüş olarak değil: en düşük noktaları tek arama (koşuların çoğunun hiç durmadığı yer) ile beş arama. Toplamların gizleyemediği iki bulgu ise akılda tutulmalı: yerleşik döngü model çağrılarının kabaca üçte birini kullandı ve her koşuda kendiliğinden durdu. İkisinin de nedeni doğruluk oranlarında değil transkriptlerde görünüyor.
İşte en kolay görevde, tek aramada bir metin protokolü koşusu:
SORU: BRS-26 projesinin bütçesi kaçtır?
step 0: ARA(BRS-26, butce) -> 3168 ← cevap zaten elinde
step 1: ARA(BRS-26, personel) -> 7
step 2: ARA(BRS-26, sure) -> 8
step 3: ARA(BRS-26, butce) -> 3168
step 4: ARA(BRS-26, butce) -> 3168
... adım bütçesine kadar tekrarlıyor
Cevabı 0. adımda aldı ve hiç durmadı. Tek aramalık görevlerin yüzde altmışı adım bütçesine çarptı — en kolay koşulun sonlanma davranışı en kötüsüydü ve protokol tek arama gerektiren bir görev için ortalama 10,7 araç çağrısı yaptı.
Bunu doğruluk sütununun yanında okuyun; bir özdeşlik ortaya çıkıyor. Bir ve iki aramada metin protokolünün doğruluğu tam olarak 100 eksi bütçeye çarpma oranı: 40 + 60 ve 76 + 24. Durmayı başaran her koşu doğruydu. Protokol orada daha kötü akıl yürütmüyordu; bittiğini söylemeyi beceremiyordu. Yani tek aramadaki 60 puanlık fark bir doğruluk sonucu değil bir sonlanma sonucu — ki bu, çıkışın döngünün kırılgan parçası olduğuna dair bu bölümdeki en temiz kanıt. Üç aramadan itibaren özdeşlik bozuluyor (52 + 28, 60 + 0, 28 + 12) ve bütçenin yanında gerçek akıl yürütme hataları da beliriyor.
Bu, Bölüm 23.1’in üçüncü noktasının ölçülmüş hâli. Çıkış bir model kararıdır ve yerleşik API’de “araç çağırmayı bırak ve cevapla”, araç çağırmaktan yapısal olarak farklı bir eylemdir.
Bir metin protokolünde değildir. CEVAP(...), ARA(...) ile yarışan bir dizgiden ibarettir — ve transkript üç ARA satırı içerdiğinde en olası sonraki satır bir dördüncüsüdür. Döngünün kendi geçmişi, döngüden çıkmanın aleyhine işler.
Durmak neden bir protokolde kolay, diğerinde zor
Bu iki panel arasında modelle ilgili hiçbir şey değişmedi — yalnızca durma kararının nasıl ifade edildiği. Solda farklı bir alan; sağda transkriptte zaten bulunan dizgilerle yarışan bir dizgi ve transkript kazanıyor.
NotBu deneyin ilk sürümü modeli değil benim prompt’umu ölçtü
Metin protokolü ilk koşuda her adım sayısında %0,0 aldı; hiçbir adım ayrıştırılamadı ve her görev bütçeye çarptı. Bu, şüphe uyandıracak kadar eksiksiz bir başarısızlık; değerlendirme düzeneğindeki bir hata genellikle tam da böyle görünür.
Hata benimdi. Protokolün imzasını ARA(proje, alan) diye yazmıştım ve bunları yer tutucu olarak kastediyordum. Model onları birebir etiket olarak okudu ve ARA(proje, ZRG-14) üretti; regex’im de bunu haklı olarak reddetti. Tek bir somut örnek eklemek — ornek: ARA(ZRG-14, butce) — sorunu çözdü.
Ders “daha iyi prompt yazın” değil. Ders şu: elle yazılmış bir protokol, bir çağırma kuralını düzyazıyla ve belirsizliğe yer bırakmadan tanımlamanızı gerektirir; tipli bir şema ise bunu size bedavaya verir. O %0, metin yaklaşımının gerçek bir bedeliydi; yalnızca ölçmeye çalıştığım bedel değildi ve onu bir model sonucu olarak yayımlamak yanlış olurdu.
Düzeltmeden sonra bile bir sınır kalıyor. Bu tek bir protokol prompt’u ve ilk sürüm, sonucun sözcüklere ne kadar duyarlı olduğunu açıkça gösterdi. “Cevap zaten elindeyse hemen CEVAP yaz” kadar küçük bir talimat ya da CEVAP üzerine bir durdurma dizisi (stop sequence), sonlanma farkının çoğunu kapatabilirdi; bunu sınayan bir ablasyon deneyi koşulmadı. Tipli bir şemanın verdiği şey daha iyi bir prompt değil — o değişkenin deneyden çıkarılmasıdır.
23.4 Ajan mı hat mı?
En önemli karar yukarıdakilerin hepsinden önce verilir: bu görev gerçekten bir ajan istiyor mu?
Bir ajan size tek bir şey kazandırır — adımların sırası, önceki adımların bulduğuna bağlı olabilir. Bu gerçekten değerlidir ve kazandırdığı tek şeydir. Ajan faydaları listesindeki diğer her şey, sabit noktalarda bir model çağıran bir hattan da elde edilebilir.
Yani soru “bu görev karmaşık mı” değil, “denetim akışı veriye bağlı mı”. Ölçüt karmaşıklık değil, dallanma.
| görev | ne kurulur |
|---|---|
| Bir belgeden alanları çıkar, sonra doğrula | Hat. Adımlar hiç değişmiyor |
| Bir destek talebini sınıflandır, sonra yönlendir | Yönlendirici. Bir model kararı, sonra sabit yollar |
| Bir bilgi tabanından cevapla | Hat — eriş, sonra üret. Bölüm 20 bir hattır, ajan değil |
| Cevapla, ama bazen ilk arama yetmiyor | Kısıtlı döngü. Dallanma gerçek ama olası yollar az |
| Bir müşteri siparişinin neden başarısız olduğunu beş sistemi tarayarak bul | Ajan. İkinci olarak neye bakacağınız gerçekten ilk bulduğunuza bağlı |
Bölüm 23.3’teki ölçüm bu ölçütü somut kanıtla destekliyor. O görev için sabit bir hat — proje kodlarını ayrıştır, her birini ara, topla — bütün riski tek bir yere, ayrıştırmaya taşır. Kodlar bir kez çıkarıldıktan sonra aramalar ve toplama her adım sayısında kesindir, çağrı başına hiçbir şeye mal olmaz ve mikrosaniyeler sürer; ajanın doğruluğu ise beş aramada %40’a düşüyor. Ödünleşim en açık hâliyle bu ve ne olmadığına dikkat edin: “model yok” değil ve “regex her zaman modeli yener” hiç değil. Model, beş sıralı iş yerine sınırlı tek bir iş yapıyor. Adımlar biliniyorsa onları yazmak, bir modelden her seferinde yeniden keşfetmesini istemeyi açık ara yener.
Anthropic (2024) aynı savı üretimdeki deneyime dayanarak kuruyor ve daha açık sözlü biçimde söylüyor: karmaşıklığı ancak sonuçları gösterilebilir biçimde iyileştirdiğinde ekleyin. O yazının sözcük dağarcığıyla her yerde karşılaşacaksınız, bu yüzden bu bölümünkiyle eşleyin: workflow (iş akışı) dediği şey — model çağrılarının ve araçların önceden tanımlı kod yolları üzerinden düzenlenmesi — yukarıdaki hatlar ve yönlendiricilerdir; ajan sözcüğünü ise modelin kendi adımlarını kendisinin yönettiği sistemlere ayırır.
23.4.1 Kusurlar da farklı türdendir
Bozulan bir hat bir satır numarasında istisna fırlatır. Bozulan bir ajan ise beklemediğiniz bir şey yapmış olmasına rağmen makul görünen bir cevap döndürür; bunu da ancak transkriptten öğrenirsiniz.
Bölüm 23.2’deki özerklik düzeylerini bir olgunluk merdiveni olarak değil, bir mühendislik tercihi olarak ciddiye almanın nedeni bu farktır. Önceden sıralayamadığınız girdilerle başa çıkabilmek karşılığında hata ayıklanabilirlikten vazgeçiyorsunuz — ve o girdileri sıralayabiliyorsanız, bu vazgeçişin karşılığında hiçbir şey almamış olursunuz.
Bu argümanın fazla ileri giden bir sürümü var — “sadece bir hat yazın” — ve ajanların gerçekten iyi olduğu görevler için yanlıştır. Doğru konum şudur: insanların ajan olarak kurduğu şeylerin çoğu fazladan adımları olan hatlardır, ve geriye kalan görevler gerçekten bir ajan döngüsünü hak eder. Yukarıdaki ölçüt, hangisiyle karşı karşıya olduğunuzu anlamanın yoludur.
23.5 Sezgi kontrolleri
Her birini açmadan önce cevaplayın. İkisi bu bölümün savunduğu tanımlar; diğer dördünü bölüm tartışmayla değil ölçümle çözdü.
Not1. Bir ajan nedir, tek cümlede?
Fonksiyon çağırabilen bir modelin etrafındaki bir while döngüsü. Model argüman üretir ve çalışma zamanınız onları yürütür; döngü, model hiçbir şey çağırmamayı seçtiğinde biter. Diğer her şey — planlama, bellek, orkestrasyon — o on dört ifadenin etrafındaki mühendisliktir; bunu bilmek, framework belgelerini okunur kılan şeydir.
Not2. Ajanınız beş aramalı bir görevde vakaların %60’ında yanlış cevap veriyor. Nereye bakarsınız?
Muhtemelen araç çağrılarına değil. Burada ölçüldü: araç kullanımı kusursuz kaldı — tam olarak doğru sayıda çağrı, hiçbiri bozuk değil, hiçbiri bütçeye çarpmadı — doğruluk ise %100’den %40’a düştü. Kusur, geleni toplamaktaydı. Genellemeden önce görevin yapısına dikkat edin: beş arama birbirinden bağımsız, dolayısıyla model onları iki model çağrısına sığdırdı ve hiçbir zaman beş ardışık adım koşturmadı. Çöken şey, yük altında sonuçları bir araya getirmekti; birbirine bağlı beş kararlık bir zincir değil. Bir şemayı yeniden yazmadan önce toplanan gözlemler üzerindeki akıl yürütmeyi kontrol edin ve yapabiliyorsanız görevi parçalara bölün: aynı anda akılda tutulacak şeyi azaltmak, gerçekten işe yarayan çözümdür.
Not3. Bir ajanın durumu nedir?
Asgari döngüde transkript ve başka hiçbir şey — çalışma belleği yok, değişken bağlaması yok. Üç şey buradan çıkar: maliyet model çağrısı sayısıyla büyür, çünkü her biri her şeyi yeniden gönderir; hiçbir şey unutulmaz, hatalar dâhil — kafası karışmış bir ajanın aynı yönde karışık kalma eğiliminin nedeni budur; ve siz bir mekanizma kurmadıkça transkript geri alınamaz; geri alsanız bile dış etkiler geri alınmaz — onlar, varsa, kendi işlem (transaction) ya da telafi mekanizmalarına ihtiyaç duyar. Sonra bu kısmın geri kalanının ne eklediğini söyleyin: dış dosyalar, bir bellek deposu ve kendi transkriptleri olan alt ajanlar — hepsi tek bir mesaj listesinin içinde yaşamamanın yolları.
Not4. Yapılandırılmış araç çağırma API’si gerçekten yardımcı mı, yoksa süs mü?
Yardımcı; üstelik kolaylıktan çok daha fazlası. Aynı model ve görevde yerleşik API, elle yazılmış bir metin protokolünü her adım sayısında yendi — 60 doğruluk puanına kadar, gerçi 25 görevde istatistiksel olarak net olan yalnızca bu en büyük fark — üstelik model çağrılarının kabaca üçte birini kullanarak. Farkı yaratan mekanizma sonlanma: yapılandırılmış API’de “araç çağırmak yerine cevapla” farklı türde bir eylemken, bir metin protokolünde cevap komutu araç komutuyla yarışır ve transkriptin kendi geçmişi başka bir araç çağrısından yana ağırlık koyar.
Not5. Beş araç çağrısı beş model çağrısı demek, değil mi?
Model onları batchlemiyorsa öyle. Burada ölçüldü: yerleşik döngü 1’den 5’e her adım sayısında 2,0 model çağrısı kullandı, çünkü bütün aramaları tek turda üretti. Beş kat işin yalnızca 1,52 kat token’a mal olmasının nedeni budur. İkisini ayrı sayın: araç çağrıları ajanın ne yaptığını, model çağrıları neye mal olduğunu söyler.
Not6. Ne zaman ajan kurmamalısınız?
Denetim akışı veriye bağlı değilken. Ölçüt zorluk değil dallanmadır: adımları yazabiliyorsanız yazın. Bu bölümün görevi için sabit bir hattın her adım sayısında yanlış verecek bir kararı yoktur, çağrı başına hiçbir şeye mal olmaz ve mikrosaniyeler sürer; karşısındaki ajanın doğruluğu ise beş aramada %40’a düşüyor. (Hattın da hataları olabilir — sonuçta koddur — ve başka her kod gibi test ister; olmayan şey, sonraki adımı seçen bir modeldir.) Döngüye ancak ikinci adımda yapacağınız şey gerçekten ilk adımda bulduğunuza bağlıysa başvurun.
23.6 Mülakat soruları
Kaynak konusunda — Bölüm 2’deki çekincenin aynısı. Bu sorular, kitabın kullandığı iki güvenilir açık kaynakta tekrar tekrar geçiyor; bunlara bu bölümün ölçümleriyle cevaplanabilir hâle gelen sorular eklendi.
23.6.1 Mekanizmayı anlayıp anlamadığınızı sınayanlar
S: Bir ajan araç çağırdığında ne olduğunu anlatın.
Model çıktısı olarak yapılandırılmış bir çağrı — bir ad ve argümanlar — üretir. Hiçbir şey yürütmez. Çalışma zamanınız onu doğrular ve çalıştırır, sonucu ya da hatayı bir gözlem olarak mesaj listesine geri ekler. Sonra bütün transkript modele geri gider. Gerçekten bir ajan kurmuş olduğunuzu gösteren iki sonucu da ekleyin: çalışma zamanı tek güvenlik sınırıdır ve asgari döngüde transkript tek durumdur.
S: Bir ajan bittiğine nasıl karar verir?
Denetlenebilir bir anlamda karar vermez — döngü, model araç çağrısı üretmediğinde biter; dolayısıyla durma kuralı bir koşul değil bir tahmindir. Bir adım bütçesinin isteğe bağlı olmamasının ve yapılandırılmış API’nin “araç çağır” ile “içerik üret” arasındaki ayrımının önemli olmasının nedeni budur: bu bölümdeki ölçümde, ikisinin yarıştığı bir metin protokolü, cevabı çoktan getirmiş olduğu hâlde tek adımlık görevlerin %60’ında duramadı.
S: Görevler uzadıkça bir ajan neden pahalılaşır?
Çünkü her model çağrısı bütün transkripti yeniden gönderir, dolayısıyla n adımlık sıralı bir koşu kabaca büyüyen n bağlamın toplamına mal olur. Sorulmasa da eklenmesi gereken incelik, bunun modelin araç çağrılarını batchleyip batchlemediğine bağlı olmasıdır: bu bölümün ölçümünde yerleşik döngü görev boyutu ne olursa olsun iki model çağrısı kullandı ve beş kat iş 1,52 kat token’a mal oldu — sıralı metin döngüsü ise aynı beş aramalık görev için 3,5 katı kadar model çağrısı yaptı.
23.6.2 Gerçekten bir ajanı yayına alıp almadığınızı sınayanlar
S: Ajan mı yoksa hat mı kuracağınıza nasıl karar verirsiniz?
Görevin zor olup olmadığına değil, denetim akışının veriye bağlı olup olmadığına bakarak. Adımlar biliniyor ve değişmiyorsa onları yazın — sabit ve sınanmış bir hat, bir sonraki adıma karar vermeyi modelin elinden alır, ucuzdur ve bir satır numarasında hata verir. Yine de hattın girdilerinin, hesaplarının ve dış etkilerinin doğrulanması gerekir; kod da sessizce yanlış olabilir. Döngüye ancak ikinci olarak neye bakacağınız gerçekten ilk bulduğunuza bağlıysa başvurun. Sonra bunun size neye mal olacağını söyleyin: bozulan bir ajan, beklenmedik bir şey yapmış olmasına rağmen makul görünen bir cevap döndürür; bu da bir istisnadan çok daha kötü bir hata ayıklama konumudur.
S: Ajanınız testte çalışıyor ve üretimde sonsuza kadar dönüyor. Ne yaparsınız?
Önce kuram üretmek yerine bütçeye çarpan koşuların transkriptlerine bakın — kusur genellikle üç satırda görünür. İki örüntüden birini bekleyin. Ya sonucu zaten elinde olan bir çağrıyı tekrarlıyordur — bu bir sonlanma sorunudur ve “bitti” eyleminin nasıl ifade edildiğine işaret eder — ya da sürekli başarısız olan bir şeyi yeniden deniyordur; bu da aracın döndürdüğü hata mesajına işaret eder. Sonra döngüye düzgün sınırlar koyun: bir adım bütçesi, bir wall-clock süresi bütçesi ve bir token bütçesi; her biri dolduğunda ne olacağı da tanımlanmış olarak.
23.7 2026 alet çantası
Bu bölümdeki her şey aşağıdaki sürümlerle yerel makinede ve — dikkat çekici biçimde — hiçbir ajan framework’ü kullanılmadan çalıştı.
| kütüphane | kullanılan sürüm | burada ne işe yarıyor |
|---|---|---|
ollama |
0.24.0 | /api/chat üzerinde araç çağırmayla qwen3.5:9b sunmak |
numpy |
2.5.2 | uydurma veritabanı ve puanlama |
Yukarıda kullanılmayan ama bilinmesi gerekenler:
| kütüphane | güncel sürüm | ne zaman kullanılır |
|---|---|---|
langgraph |
1.2.11 | denetim akışı bir while döngüsü olarak değil, bir diyagram olarak çizilmeyi hak ettiğinde |
openai-agents |
0.22.0 | handoff’lar (konuşmayı başka bir ajana devretme) ve korkuluklar (guardrails) yerleşik gelen, küçük ve okunabilir bir uygulama |
smolagents |
1.26.0 | yalnızca import etmek için değil, kodunu okumak için de ideal bir framework |
pydantic-ai |
2.35.3 | yığınınız zaten Pydantic ise tipli araçlar ve doğrulanmış çıktılar |
llama-index |
0.14.24 | erişim altyapısı hazır bağlanmış, kendi verinizle çalışan ajanlar |
crewai / autogen-agentchat |
1.15.18 / 0.7.5 | çok ajanlı orkestrasyon (Bölüm 28); tek bir ajan düzgün çalışana kadar ertelemekte yarar var |
23.8 Lab: döngüyü kurun, sonra bozun
Bir sonraki framework belgesini okumadan önce bu döngüyü kurun; alıştırmanın amacı, o belgelerin anlattıklarını eşleyebileceğiniz somut bir şeyi elinizde tutmaktır.
23.8.1 Adım 1 — on dört ifadeyi kendiniz yazın
Framework yok. İki gerçek araç, bir model, bir adım bütçesi. İki araç gerektiren bir soruyu uçtan uca cevaplayabildiğinde iş bitmiş demektir.
23.8.2 Adım 2 — her adımda transkripti yazdırın
Bir kayıt satırı değil — gerçek mesaj listesi. Büyümesini izleyin. Durumun soyut olmayı bıraktığı an budur. Üretimde bunun karşılığı olan iz kaydı ve izleme Bölüm 34’ün konusu.
23.8.3 Adım 3 — bozulmayı ölçün
1, 2, 3, 4 ve 5 araç çağrısı gerektiren, cevaplarını tam kontrol edebileceğiniz görevler kurun. Her birinden yirmi beş tane. Doğruluğu adım sayısına karşı çizin ve modelinizin nerede çöktüğünü bulun. Ajanları daha sistemli değerlendirmenin yolları Bölüm 30’da.
23.8.4 Adım 4 — model çağrılarını araç çağrılarından ayrı sayın
Bunlar farklı sayılardır ve yalnızca biri faturanızı öngörür. Eşitlerse modeliniz batchlemiyordur ve maliyet eğriniz dik olanıdır.
23.8.5 Adım 5 — bir aracı bozun
Bir araçtan bir hata dizgisi döndürün. Döngü toparlanıyor mu, vazgeçiyor mu, yoksa bir değer mi uyduruyor? Sonra hata mesajını değiştirin ve davranışın değişip değişmediğine bakın — bu, Bölüm 24’ün bütün konusunun on dakikalık ön izlemesidir.
23.8.6 Adım 6 — adım bütçesini kaldırın
Modelin tamamlayamayacağı bir görevde çalıştırın ve ne olduğunu izleyin. Bütçeyi geri koyun. Onu bir daha asla bir ayar parametresi olarak görmezsiniz.
23.8.7 Teslim edilecekler
Doğruluk–adım sayısı eğrisi; yan yana model çağrısı ve araç çağrısı sayıları; başarısız bir koşunun transkripti; ve hangi adım sayısının ötesinde bu ajana gözetimsiz güvenmeyeceğinizi söyleyen tek bir cümle.
23.9 Alıştırmalar
- On dört ifade. Döngüyü elinizdeki iki araçla sıfırdan yazın. Framework kullanmayın. Süre tutun; bir öğleden sonra sürer.
- Bozulma eğrinizi bulun. Cevapları kontrol edilebilir, 1’den 6’ya araç çağrısı gerektiren görevler kurun ve doğruluğu adım sayısına karşı çizin. Doğruluğun ürününüzün ihtiyaç duyduğu eşiğin altına düştüğü noktayı işaretleyin.
- Sayaçları ayırın. Gerçek bir iş yükünde model çağrılarını ve araç çağrılarını ayrı ölçün. Oranı hesaplayın. 1’e yakınsa sıralı maliyet eğrisini ödüyorsunuz.
- Batchlemeyi kapatın. Ajanınızı tur başına bir araç çağrısı yapmaya zorlayın ve maliyeti yeniden ölçün. Aradaki fark, paralel araç çağırmanın size para olarak ne kazandırdığıdır.
- Sonlanma testi. Ajanınıza tek çağrıda bitirebileceği bir görev verin ve ne sıklıkla hemen durduğunu sayın. Bu bölümün metin protokolü, mümkün olan en kolay görevde bu testte vakaların %60’ında başarısız oldu.
- Hat kontrolü. Şu anda ajanla çözdüğünüz bir görev için sabit hattı yazın. Doğruluğu, maliyeti ve gecikmeyi karşılaştırın. Ajanın yerini hak edip etmediğini açıkça raporlayın.
- Durumu bozun. Bir koşunun ortasında transkripte yanlış bir gözlem ekleyin ve ajanın toparlanıp toparlanmadığına bakın. Sonra Bölüm 23.2’den yola çıkarak neden genellikle toparlanmadığını açıklayın.
- Önce şemalar, sonra karar. İyi bildiğiniz, elle yürüttüğünüz üç adımlık bir iş akışı alın. Bir ajanın ihtiyaç duyacağı araç şemalarını yazın, sonra ajanın buna değip değmediğini tartışın — şemalar genellikle cevabı apaçık yapar.
23.10 Daha derine
Bunlardan önce: döngüyü kendiniz, iki gerçek araçla ve framework kullanmadan yazın. Aşağıdaki her şey sonrasında farklı okunur.
| kaynak | ne olduğu |
|---|---|
| Building effective agents — Anthropic | bu konudaki en iyi kısa yazı; merkezî argümanı bu bölümünkiyle aynı, ama üretim deneyimine dayanarak savunuluyor |
| Agents — Chip Huyen | planlama, araçlar ve kusur biçimlerinin uzun ve iyi düzenlenmiş bir ele alınışı |
| LLM Powered Autonomous Agents — Lilian Weng | bugün kullanılan terimlerin çoğunu yaygınlaştıran, derleme niteliğinde derinlemesine bir yazı |
smolagents |
bir öğleden sonrada okunacak kadar küçük; bu da onu bir framework’ün ne yaptığını öğrenmek için en iyi framework yapıyor |
langgraph |
açık bir durum makinesi olarak döngü — denetim akışını çizilebilir bir şeye dönüştürdüğü için yararlı |
pydantic-ai |
tipli araçlar ve tipli sonuçlar; doğrulama sınırı açıkça görünür |
openai-agents |
döngünün, handoff’ların ve korkulukların asgari bir referans uygulaması |
| konu | kaynak |
|---|---|
| eylemle iç içe geçmiş akıl yürütme | Yao, Zhao, vd. (2023) |
| modelin fonksiyon çağırmayı öğrenmesi | Schick vd. (2023) |
| kendini düzeltme ve neyi düzeltmediği | Madaan vd. (2023); Huang vd. (2024) |
| eylemler üzerinde değil, akıl yürütme üzerinde arama | Yao, Yu, vd. (2023) |
| döngü içinde kendini düzeltme | Shinn vd. (2023) |
| tekrarlı denemelerde güvenilirliğin ne kadar düştüğü | Yao vd. (2024) |
| aynı bozulma, görev süresi ufku (time horizon) olarak ölçülmüş | Kwa vd. (2025) |
| ajanın kendi bellek problemi | Packer vd. (2023) |
23.11 Akılda kalması gerekenler
- Asgari ajan on dört ifadedir. Araçları olan bir modelin etrafındaki bir while döngüsü. Model argüman üretir ve onları asla yürütmez, dolayısıyla çalışma zamanı tek güvenlik sınırıdır. Döngü, model araç çağırmamayı seçtiğinde biter. Bu asgari döngüde transkript tek durumdur; sonraki bölümler durumu dosyalara, bir bellek deposuna ve alt ajanlara taşıyor.
- Çıkış bir koşul değil bir tahmindir. Hiçbir şey görevin bitip bitmediğini kontrol etmez; adım bütçesinin bir ayar parametresi değil mimari bir bileşen olmasının nedeni budur.
- Bu deneyde doğruluk arama sayısıyla düştü. Bir aramadan beşe %100 → %96 → %80 → %68 → %40; sıcaklık 0’da ve cevabı kesin olarak bilinen bir görevde — hücre başına n = 25, yani %40’ın aralığı [23, 59] ve sağlam olan şey eğrinin şekli değil yönü. Aramalar iki model çağrısında batchlendi, yani bu beş ardışık karar değil; görev uzunluğuyla bozulmayı büyük ölçekte Kwa vd. (2025) ölçüyor; Yao vd.’nin (2024)
pass^kölçüsü ise tekrarlı denemelerdeki tutarlılığa bakar. - Bozulan şey döngü değildi. Araç kullanımı her adım sayısında kusursuzdu — tam olarak doğru çağrılar, bozuk yok, bütçeye çarpan yok — doğruluk ise 60 puan düştü. Kusur, toplanan gözlemleri bir araya getirme aşamasında; dolayısıyla önce orada hata ayıklayın.
- Model çağrılarını araç çağrılarından ayrı sayın. Paralel araç çağırma bu döngüyü her adım sayısında 2,0 model çağrısına indirdi, dolayısıyla beş kat iş 1,52 kat token’a mal oldu. Sıralı bir döngü bedeli her adımda öder: beş aramada metin protokolü aynı iş için 3,5 kat model çağrısı kullandı.
- Yapılandırılmış araç API’si süs değildir. Her adım sayısında öndeydi, 60 doğruluk puanına kadar — gerçi 25 görevde yalnızca tek aramalık fark bir anlamlılık testini geçiyor — ve her koşuda kendiliğinden durdu; bunun başlıca nedeni “dur ve cevapla”yı “araç çağır”dan yapısal olarak farklı bir eylem hâline getirmesi.
- Sonlanma kusuru en kolay görevde en kötüydü. Metin döngüsü tek aramalık görevlerin %60’ında adım bütçesine çarptı; üstelik cevabı 0. adımda getirmiş olduğu hâlde, bütçe bitene kadar çağrı yapmayı sürdürerek.
- Ajanı zorluğa göre değil dallanmaya göre seçin. Adımlar biliniyorsa onları yazın: sabit ve sınanmış bir hat, sonraki adımı seçmeyi modelin elinden alır, ucuzdur ve bir satır numarasında bozulur — gerçi girdilerinin ve çıktılarının yine de doğrulanması gerekir. Bozulan bir ajan ise hata vermek yerine makul görünen bir şey döndürür.