Mert Özen Her Satırda Daha İleri
Yapay Zeka LLM Temelleri — #20

LLM API'lerinin Evrimi: Completions'tan Tool Calling, Structured Outputs ve MCP'ye

Mert Özen 6 Kas 2026 7 dk 8 görüntülenme
LLM API'lerinin Evrimi: Completions'tan Tool Calling, Structured Outputs ve MCP'ye

Metni sürdüren ilk API'den chat biçimine, function calling'den JSON mode ve structured outputs'a, reasoning parametrelerinden Model Context Protocol'e ve agent'lara kadar LLM API'lerinin doğrulanmış tarihlerle evrimi. Her adımın serideki hangi örneğe karşılık geldiğini görüyor ve serinin sonunda sıradaki yapay zeka serilerine köprü kuruyoruz.

Sürüm notu: Bu yazı LLM API'lerinin 2020'den bu yazının yazıldığı Kasım 2026'ya kadar olan evrimini anlatır. Tarihler sağlayıcıların kendi duyurularından, changelog'larından ve sürüm notlarından doğrulanmıştır.

Önce Tahmin Et

Bookstore asistanından bir kitap için {"title": ..., "genre": ..., "year": ...} biçiminde JSON istiyorsun. Elinde üç yol var: prompt'a "yalnız JSON döndür" yazmak, JSON mode'u açmak ya da bir JSON schema vermek. Hangisi geçerli bir JSON garanti eder? Hangisi o JSON'un senin şemana uyduğunu garanti eder?

Cevap: prompt hiçbirini garanti etmez, JSON mode yalnız geçerli JSON'u, şemayla kısıtlanmış structured output ise şemaya uygunluğu da hedefler. Bu üç yol aynı anda icat edilmedi; üç yıla yayılan bir evrimin durakları. Serinin son yazısında modellerden API'lere geçiyor ve bir geliştiricinin LLM'le konuşma biçiminin nasıl değiştiğine bakıyoruz.

Başlangıç: Metni Sürdüren API

OpenAI ilk API'sini 11 Haziran 2020'de açtı. Arkasındaki model GPT-3'tü ve 18. yazıda gördüğümüz gibi bu model bir metni sürdürmek için eğitilmişti. API de buna uygun, son derece sade bir sözleşme sunuyordu: bir prompt gönderirsin, model onun devamını yazar. Talimat vermek, örnek göstermek, çıktı biçimini tarif etmek; hepsi tek bir metnin içinde, "devamı şöyle gelmeli" diye kurgulanırdı.

Bu biçim bugün de yaşıyor. Ollama'nın /api/generate endpoint'i bir prompt alır, OpenAI uyumlu tarafta da /v1/completions var. Serinin ilk yazılarında kullandığımız num_predict (max tokens) ve stop sequence'ler de bu dönemin mirası: model metni sürdürürken nerede duracağını sen söylemek zorundaydın.

1 Mart 2023: Chat Biçimi

ChatGPT'nin başarısından üç ay sonra, 1 Mart 2023'te OpenAI "Introducing ChatGPT and Whisper APIs" yazısıyla gpt-3.5-turbo modelini API'ye açtı. Fiyat 1.000 token başına 0,002 dolardı; duyuruya göre önceki GPT-3.5 modellerinden on kat ucuz. Ama kalıcı değişiklik fiyat değil biçimdi. İstek artık tek bir metin değil, rolleri olan bir mesaj listesiydi: system, user, assistant.

5. yazıda bu rolleri kullandık; 18. yazıda da modelin önüne yine tek bir metin olarak dizildiklerini gördük. Peki neden ayrı alanlar? Çünkü ayrımı API seviyesinde yapmak, şablonu sağlayıcıya bırakır. Sen role: "system" yazarsın, o rolü modele özel işaretlere (gemma3'te <start_of_turn>) çevirmek sağlayıcının işidir. Bu, sağlayıcı değiştirmeyi de kolaylaştırdı. 17. yazıda Ollama'yı OpenAI SDK'sıyla çağırabilmemizin sebebi, chat biçiminin fiilî bir ortak dil hâline gelmesi.

13 Haziran 2023: Function Calling

Bir sonraki adım, modelin yalnız metin değil, bir eylem önerisi üretebilmesiydi. OpenAI 13 Haziran 2023'te "Function calling and other API updates" yazısıyla functions ve function_call parametrelerini gpt-4-0613 ve gpt-3.5-turbo-0613 modelleriyle duyurdu. Fikir 11. yazıda kurduğumuz akışın ta kendisi: fonksiyonlarını JSON schema ile tarif edersin, model gerekirse metin yerine bir çağrı isteği döndürür, çağrıyı sen çalıştırıp sonucu geri gönderirsin. Model hiçbir zaman kodu kendisi çalıştırmaz.

Bu yetenek kısa sürede sağlayıcılar arasında yayıldı. 6 Kasım 2023'teki DevDay'de OpenAI tek cevapta birden fazla çağrı isteyebilen paralel function calling'i ekledi. Anthropic 30 Mayıs 2024'te Claude 3 ailesinde tool use'u genel kullanıma açtı. Ollama 25 Temmuz 2024'te v0.3.0 ile tool desteği getirdi, 28 Mayıs 2025'te de tool çağrılarını streaming ile göndermeye başladı. Bugün bu alan çoğu API'de tools adıyla anılıyor ve serideki örneklerde de öyle kullandık.

JSON Mode'dan Structured Outputs'a

Function calling, modelin JSON üretmesine dayanıyordu; ama modelin her zaman geçerli JSON üreteceğinin garantisi yoktu. İlk çözüm 6 Kasım 2023'te DevDay'de geldi: response_format ile açılan JSON mode. Bu mod çıktının geçerli bir JSON olmasını sağlıyor ama hangi alanların, hangi tiplerde olacağını garanti etmiyordu. Açılıştaki sorunun ikinci yarısı tam bu boşluk.

Boşluk 6 Ağustos 2024'te "Introducing Structured Outputs in the API" yazısıyla kapandı. Artık response_format içinde bir json_schema verebiliyor, tool tanımlarında strict: true ile şemaya kesin uyum isteyebiliyordun. OpenAI'ın kendi şema testinde gpt-4o-2024-08-06 bu özellikle yüzde 100 başarı aldı; karşılaştırmadaki gpt-4-0613 yüzde 40'ın altında kalmıştı. Ollama da 2024 Aralık başındaki v0.5.0 ile format alanına JSON schema kabul etmeye başladı; 10. yazıda gemma3:4b ile kullandığımız özellik bu. Yine de 10. yazıda konuştuğumuz kural geçerli: şemaya uyan bir JSON, doğru bir JSON demek değil. Doğrulamayı kendi kodunda yap.

Reasoning Parametreleri

19. yazıdaki reasoning modelleri API'ye yeni bir ayar getirdi: modelin ne kadar düşüneceği. OpenAI 17 Aralık 2024'te o1'i API'ye açarken changelog'a reasoning_effort parametresini ekledi. Ollama 2025 Mayıs sonundaki v0.9.0 ile think parametresini getirdi; bu parametre true/false ya da "low", "medium", "high" gibi bir seviye alıyor ve düşünme metnini cevaptan ayrı, thinking alanında döndürüyor. Ollama'nın OpenAI uyumlu endpoint'i de reasoning_effort değerini kabul ediyor. Microsoft.Extensions.AI tarafında ChatOptions içinde bir Reasoning property'si var.

Burada yine bir soyutlama meselesi görüyorsun. Düşünme ayarı her sağlayıcıda farklı adla ve farklı ayrıntıyla geliyor. 17. yazıdaki kural geçerli: ortak bir interface'in arkasında dur, sağlayıcıya özel ayarı tek bir yerde topla.

Model Context Protocol

Function calling modelin araç çağırmasını mümkün kıldı, ama her uygulama her aracı kendisi tanımlamak zorundaydı. Bookstore asistanına sipariş veritabanını, kargo firmasının API'sini ve şirketin dokümanlarını bağlamak istediğinde, her biri için ayrı tool tanımı ve ayrı entegrasyon kodu yazıyordun. Başka bir uygulama aynı kaynaklara bağlanmak istese aynı işi bir daha yapacaktı.

Anthropic 25 Kasım 2024'te "Introducing the Model Context Protocol" yazısıyla bu soruna açık bir standart önerdi. MCP'de araçları ve veri kaynaklarını bir MCP server sunar; LLM uygulaması da bir MCP client olarak bu server'a bağlanır ve sunulan araçları modele tool olarak tanıtır. USB gibi düşün: her cihaz için ayrı kablo yerine ortak bir fiş. Sipariş veritabanı için bir kez MCP server yazarsın, MCP konuşan her uygulama onu kullanabilir. Altta yatan mekanizma yine 11. yazıdaki tool calling; MCP onun üstüne bir dağıtım ve paylaşım katmanı ekliyor.

Sunucuda Durum ve Agent'lar

Serinin başından beri tekrar ettiğimiz bir gerçek var: chat API'leri stateless, geçmişi her istekte sen gönderirsin. Sağlayıcılar bu yükü sunucuya almayı da denedi. OpenAI 6 Kasım 2023'te sohbeti ve araçları sunucuda tutan Assistants API'yi beta olarak duyurdu; 11 Mart 2025'te ise "New tools for building agents" yazısıyla Responses API'yi ve Agents SDK'yı tanıttı. Ollama'nın OpenAI uyumlu tarafında da /v1/responses var, ama Ollama dokümanına göre yalnız stateless biçimde.

"Agent" kelimesi bu dönemde her yerde. Ama 11. ve 12. yazılarda kurduğumuz şeye bakarsan, bir agent'ın iskeleti çok sade: bir model, bir araç listesi ve model araç istemeyi bırakana kadar dönen bir döngü. Microsoft.Extensions.AI'daki UseFunctionInvocation bu döngüyü senin yerine çalıştırıyordu. Agent framework'leri bu iskeletin üstüne plan yapma, bellek, birden fazla agent'ı koordine etme ve gözlemlenebilirlik gibi katmanlar ekliyor. İskeleti bildiğin sürece hangi framework'ü kullandığın ikinci planda kalır.

Sık Düşülen Tuzaklar

Birincisi, JSON mode'u şema garantisi sanmak. JSON mode geçerli JSON verir, senin alanlarını değil. Şema gerekiyorsa schema ile kısıtlanmış structured output kullan ve sonucu yine kodunda doğrula.

İkincisi, eski parametre adlarıyla yazılmış örnekleri körü körüne kopyalamak. 2023 ortasındaki functions/function_call biçimi ile bugünkü tools biçimi aynı değil. Bir blog yazısından ya da eski bir cevaptan kod alırken tarihine ve sağlayıcının güncel API referansına bak.

Üçüncüsü, MCP'yi güvenlik çözümü sanmak. MCP araçları bağlamayı kolaylaştırır; bir aracın neye erişebileceğini, hangi işlemin kullanıcı onayı gerektirdiğini sınırlamak hâlâ senin işin. 12. yazıdaki yetki sınırlama ve argüman doğrulama kuralları MCP server'larına da aynen uygulanır ve Web Güvenliği serisindeki prompt injection konusu burada daha da önem kazanır.

Dördüncüsü, sunucuda tutulan durumu bedava sanmak. Sohbeti sağlayıcı tutsa bile geçmiş, modelin bağlamına girdiği sürece token'dır ve faturaya yansır. Stateful bir API kullanırken de 16. yazıdaki maliyet hesabını yap.

Küçük Bir Deneme

★☆☆ Aynı soruyu Ollama'ya üç yoldan sor: /api/generate ile prompt olarak, /api/chat ile messages olarak ve /v1/chat/completions ile OpenAI biçiminde. Üç cevabın JSON yapısını yan yana koy; metin, token sayıları ve bitiş sebebi hangi alanlarda?

★★☆ Açılıştaki üç yolu gemma3:4b ile dene: yalnız prompt'la, format: "json" ile ve format alanında bir JSON schema ile. Her birini on farklı seed ile çalıştır; kaç cevap JSON.parse'tan geçti, kaçı şemana uydu?

★★★ qwen3:4b ile aynı aracı iki API'den tanımla: Ollama'nın /api/chat endpoint'inde ve /v1/chat/completions üzerinden OpenAI biçiminde. Dönen tool_calls içindeki arguments alanının tipi iki API'de aynı mı? Sağlayıcıdan bağımsız kod yazarken bu fark nereye saklanmalı?

Böylece LLM Temelleri serisinin sonuna geldik. Token'dan context window'a, sampling'den structured output'a, tool calling'den RAG'e kadar kemik yapıyı yerel modellerle çalıştırarak kurduk, sonra bu yapının nereden geldiğine ve API'lerin nasıl evrildiğine baktık. Alan hızla değişiyor; seri yeni gelişmeler oldukça güncellenmeye devam edecek. Sıradaki yapay zeka serilerinde bu temelin üstüne çıkacağız: .NET ile yapay zeka uygulamaları, RAG'i vektör veritabanlarıyla ayrıntılı kurmak, agent'lar ve MCP server yazmak, ve LLM güvenliği. Hepsinde aynı yaklaşımı sürdüreceğiz: önce kavram, sonra gerçekten çalışan kod.