Blog
Mert Özen'in yazılım geliştirme, backend, frontend ve DevOps üzerine blog yazıları.
Semantic Kernel'den Microsoft Agent Framework'e: Tarihçe, Destek Durumu ve Eski Kodu Taşımak
Semantic Kernel kritik hata ve güvenlik düzeltmesi almaya devam ediyor, ama yeni özellikler Microsoft Agent Framework'e gidiyor; resmi taahhüt MAF GA'den (3 Nisan 2026) sonra en az bir yıl. Tarihçeyi NuGet ve GitHub tarihleriyle kuruyor, eski bir SK agent'ını yerel modelle çalıştırıp MAF'a taşıyor ve eşleme tablosunu çıkarıyoruz.
ASP.NET Core'da Agent Host Etmek: AddAIAgent, OpenAI Uyumlu Endpoint, AG-UI ve A2A
Bir agent'ı AddAIAgent ile DI'a kaydedip MapOpenAIChatCompletions, MapAGUIServer ve MapA2AJsonRpc ile üç protocol'den açarsın; agent bir kez yazılır, adapter'lar yalnız biçimi çevirir. Gerçek çağrılarla çoklu choice dönen OpenAI cevabını, reasoning'i tarayıcıya taşıyan AG-UI akışını, A2A agent card'ını ve claim tabanlı session izolasyonuyla rate limiting'i görüyoruz.
Agent Framework'te Middleware, Context Provider ve Session Saklama
Agent Framework'te kart numarası gibi girdileri agent run middleware'i, başkasının siparişine erişimi function invocation middleware'i, kullanıcı tercihini de session'a yazan bir context provider yönetir; session JSON olarak saklanıp geri yüklenir. Gerçek koşuda memory'nin çalıştığını, modelin yine de yazar uydurduğunu ve reasoning'in session'ı nasıl şişirdiğini görüyoruz.
Microsoft Agent Framework'e Giriş: IChatClient'tan AIAgent'a
AsAIAgent, bir IChatClient'ı ChatClientAgent'a çevirir; agent talimatı, function invocation'ı ve AgentSession ile sohbet geçmişini üstlenir ama modeli akıllandırmaz. Aynı Bookstore asistanını önce düz IChatClient, sonra agent olarak yazıp RunAsync, RunStreamingAsync ve AgentResponse'u gerçek çıktılarla karşılaştırıyoruz.
IChatClient Kullanan Kodu Test Etmek: Fake Client, Deterministik Testler ve Microsoft.Extensions.AI.Evaluation
IChatClient kullanan kodun doğruluğunu fake bir client'la, modelsiz ve milisaniyeler içinde test edersin; modelin cevap kalitesini ise Microsoft.Extensions.AI.Evaluation ile, ayrı çalışan ve cache'lenen evaluation'larla ölçersin. Gerçek koşularda judge timeout'larını, 800 token'a takılan reasoning'i, eski cevap dönen cache'i ve prompt hatasını yakalayan Relevance skorunu görüyoruz.
Microsoft.Extensions.VectorData: Vector Store Abstraction'ı ile İlk Collection
Microsoft.Extensions.VectorData, kaydı attribute'larla tanımlayıp aynı kodla bellek içi store'dan PostgreSQL + pgvector'a geçmeni sağlar; embedding'i store'a verdiğin generator üretir. Gerçek çıktılarla filtreli aramayı, ScoreThreshold'u, distance function'ın skorun anlamını nasıl tersine çevirdiğini ve InMemory'nin yakalamadığı boyut hatasını görüyoruz.
LLM Çağrılarını Gözlemlemek: UseOpenTelemetry, GenAI Semantic Conventions ve Aspire Dashboard
LLM çağrılarını gözlemlemek için UseOpenTelemetry'yi UseFunctionInvocation'ın içine koyar, AddSource ile aynı source adını dinler ve trace'i Aspire Dashboard'da okursun. Gerçek bir trace'te iki dakikalık gecikmenin modelden değil Ollama kuyruğundan geldiğini buluyor, EnableSensitiveData'nın e-postayı nasıl telemetry'ye taşıdığını görüyoruz.
LLM Maliyetini Kontrol Etmek: DistributedCachingChatClient, Rate Limiting ve Token Kullanımı
LLM maliyetini üç katmanda kontrol ediyoruz: Redis'li DistributedCachingChatClient tekrar eden soruyu sıfır token'la cevaplar, kullanıcı başına rate limiting kötüye kullanımı sınırlar, UsageDetails ile tutulan günlük token bütçesi de asıl harcamayı. Cache key'inin içeriğini, kayıtların varsayılan olarak süresiz yazıldığını ve token muhasebesinin neden cache'in içinde durması gerektiğini gerçek çıktılarla gösteriyoruz.
Tool Calling'i Production'a Taşımak: FunctionInvokingChatClient Ayarları, DI'dan Servis ve Onay Akışı
Production'da tool'un kimin adına çalıştığı modelin argümanından değil oturumdan gelir, geri alınamaz işlemler ApprovalRequiredAIFunction ile kullanıcı onayı bekler. Scoped servis kullanan OrderTools class'ı, FunctionInvokingChatClient ayarları, tool hatası ile kullanıcı hatasının ayrımı ve iki HTTP isteğiyle yürüyen onay akışını gerçek koşularla gösteriyoruz.
Sohbet Geçmişini Saklamak: Stateless API, ConversationId, EF Core ve Chat Reducer'lar
Stateless bir provider'da sohbet geçmişini senin kodun tutar: ChatMessage'ları tool call ve tool result content'leriyle birlikte AIJsonUtilities ile JSON'a çevirip EF Core'da kullanıcı ve conversation bazında saklıyoruz. Sahiplik kontrolünü sorguya koyuyor, ConversationId ile stateful provider'ları da destekliyor ve MessageCountingChatReducer ile SummarizingChatReducer'ın gerçek çıktılarını karşılaştırıyoruz.
ASP.NET Core'da LLM Streaming: Minimal API, IAsyncEnumerable ve Server-Sent Events
LLM cevabını tarayıcıya akıtmanın güvenilir yolu .NET 10'un TypedResults.ServerSentEvents'i: delta, thinking, tool, usage, done ve error event'leri, sessiz bekleyişte heartbeat ve modele kadar taşınan CancellationToken. Düz IAsyncEnumerable'ın sınırlarını, kullanıcı sekmeyi kapatınca modelin gerçekten durduğunu ve token'ı vermeyi unutan endpoint'in 1024 token'ı boşa harcadığını gerçek ölçümlerle gösteriyoruz.
ASP.NET Core'a IChatClient Bağlamak: AddChatClient, Keyed Client'lar, Options ve Secret'lar
IChatClient'ı ASP.NET Core'a AddKeyedChatClient ile singleton olarak kaydediyor, "fast" ve "smart" iki model için keyed client, provider ve model seçimi için açılışta doğrulanan options kullanıyoruz. Standard resilience handler'ın 10 sn/30 sn varsayılanlarının LLM çağrısını üç kez baştan ürettirip 500'le bitirdiğini gerçek log'la gösteriyor, timeout ve retry'ı LLM'e göre ayarlıyoruz.