AI Kod Ajanları İçin MCP Sunucularında Context Şişmesini Önleyen 5 Tool-Use Pattern’i
Blog'a Dön

AI Kod Ajanları İçin MCP Sunucularında Context Şişmesini Önleyen 5 Tool-Use Pattern’i

Buğra Şıkel

AI Kod Ajanları İçin MCP Sunucularında Context Şişmesini Önleyen 5 Tool-Use Pattern'i

Giriş

Model Context Protocol (MCP) tabanlı AI kod ajanları (Claude, Cursor, Aider vb.) ile production ortamında çalışırken karşılaşılan en kritik darboğaz, kontrolsüz context büyümesidir. Ajan, read_directory veya fetch_database_schema gibi bir aracı (tool) çağırdığında dönen 400 KB’lık bir JSON veya 15.000 satırlık bir log dosyası, LLM’in 128k/200k token sınırını anında domine eder. Bu durumun sonuçları nettir: TTFT (Time to First Token) değerinin 1.2 saniyeden 24 saniyeye fırlaması, “Lost in the Middle” (ortadaki bilginin kaybolması) sendromu nedeniyle ajanın halüsinasyon görmesi ve API işlem başına maliyetin $0.05 bandından $3+ bandına çıkması.

Büyük dil modellerine (LLM) dış dünyayı açan MCP sunucularını tasarlarken, araçları (tools) basit birer RPC (Remote Procedure Call) endpoint’i olarak düşünmek mimari bir hatadır. Ajanlar, bağlamı filtreleme konusunda doğuştan yetersizdir; onlara verilen veriyi ham haliyle tüketirler. 2024 son çeyreğinde 1.2 milyon satırlık bir mikroservis ekosisteminde devreye aldığımız MCP altyapısında, context boyutunu optimize etmeden önce p99 tool yanıt süremiz 18 saniyeydi. Aşağıda detaylandırılan pattern’leri uyguladıktan sonra token tüketiminde %84 düşüş sağlarken, p99 latency değerini 1.4 saniyeye indirmeyi başardık.

İçindekiler

  • Multi-Step Drill Down (Keşiften Detaya Pattern’i)
  • AST-Aware Semantic Truncation (Semantik Budama Pattern’i)
  • Paginated Resource Yielding (Cursor Tabanlı Akış Pattern’i)
  • Strict Schema Projection (Seçici Alan Projeksiyonu Pattern’i)
  • Stateful Context Caching (Durum Korumalı Ön Bellek Pattern’i)

Multi-Step Drill Down (Keşiften Detaya Pattern’i)

Problem

Ajanın bir modüldeki belirli bir iş mantığını anlaması gerektiğinde, tüm dosyayı okuması (read_file) ciddi bir token israfıdır. 3000 satırlık bir PaymentProcessor.ts dosyasını okumak yaklaşık 25.000 token tüketir, oysa ajanın sadece 15 satırlık refundTransaction metoduna ihtiyacı vardır.

Çözüm

Dosya okuma işlemini iki aşamalı bir hiyerarşiye bölmek: Önce sadece sembollerin (class, interface, metod adları ve imzaları) listelendiği bir keşif aracı (list_symbols), ardından sadece istenen sembolün içeriğini getiren bir detay aracı (read_symbol) sunmak.

Çalışan Kod / Konfigürasyon

// MCP Tool Definition using @modelcontextprotocol/sdk
server.tool(
  "list_file_symbols",
  "Returns only the signatures of functions and classes in a file to save context window.",
  {
    filePath: z.string().describe("Absolute path to the file")
  },
  async ({ filePath }) => {
    // Implementation uses an AST parser to extract signatures
    const symbols = await extractSignatures(filePath);
    return {
      content: [{ type: "text", text: JSON.stringify(symbols, null, 2) }]
    };
  }
);

server.tool(
  "read_specific_symbol",
  "Reads the exact implementation body of a specified function or class.",
  {
    filePath: z.string(),
    symbolName: z.string()
  },
  async ({ filePath, symbolName }) => {
    const body = await extractSymbolBody(filePath, symbolName);
    return {
      content: [{ type: "text", text: body }]
    };
  }
);

Ne Zaman Uygulanır?

Büyük monolitik kod tabanlarında, 500 satırdan uzun dosyaların ağırlıkta olduğu projelerde ve ajanın kod analizi (code review, refactoring) görevlerinde. RTT (Round Trip Time) maliyeti, token maliyetinden düşük olduğunda.

Ne Zaman Uygulanmaz?

Dosyaların genelde 50-100 satır arası olduğu mikro mimarilerde. Bu durumda fazladan atılan LLM isteği (RTT), toplam gecikmeyi (latency) artırır ve gereksiz overhead yaratır.

AST-Aware Semantic Truncation (Semantik Budama Pattern’i)

Problem

Ajanlardan çok uzun metinleri işlemek için sadece satır numaralarıyla (startLine, endLine) sınırlandırılmış tool’lar kullanmaları istendiğinde, LLM genellikle satır numaralarını yanlış tahmin eder. RegEx tabanlı kesme işlemleri ise süslü parantezlerin ({}) kopmasına neden olarak ajanın derlenemeyen kod bağlamı üzerinden halüsinasyon üretmesine yol açar.

Çözüm

MCP sunucusu içinde Tree-sitter gibi bir AST (Abstract Syntax Tree) ayrıştırıcısı kullanarak, döndürülen kodu semantik olarak bütün tutmak. Ajan bir fonksiyonu istediğinde, sunucu sadece o fonksiyonu, bağlı olduğu import’ları ve sınıfın iskeletini döndürür; diğer tüm metodları /* ... 450 lines truncated ... */ şeklinde budar.

Ne Zaman Uygulanır?

Derleme bütünlüğünün (compilability) kritik olduğu görevlerde. Ajanın dönen kod bloğuna doğrudan yama (patch) veya diff uygulayacağı senaryolarda.

Ne Zaman Uygulanmaz?

Düz metin, Markdown veya JSON gibi hiyerarşik AST yapısı olmayan, sadece satır bazlı veya döküman bazlı verilerde.

Paginated Resource Yielding (Cursor Tabanlı Akış Pattern’i)

Problem

query_database veya fetch_application_logs gibi araçlar, dış sistemlerden dönen sonucun boyutunu önceden bilemez. “Son 24 saatin hata logları” sorgusu, sisteme 80.000 satırlık log döndürebilir. Node.js tabanlı bir MCP sunucusu bu veriyi string’e çevirip stdout üzerinden ajana iletmeye çalıştığında OOM (Out of Memory) crash’leri yaşanır.

Çözüm

Tool parametrelerine zorunlu bir cursor ve katı bir limit (maksimum satır/bayt) eklemek. Ajan, verinin devamı olduğunu tool’un döndürdüğü hasMore: true ve nextCursor alanlarından anlayıp otonom olarak tekrar istek atar.

Çalışan Kod / Konfigürasyon

server.tool(
  "query_audit_logs",
  "Fetches system audit logs with mandatory pagination. Max 100 records per call.",
  {
    severity: z.enum(["ERROR", "WARN", "INFO"]),
    limit: z.number().min(1).max(100).default(50),
    cursor: z.string().optional().describe("Pagination cursor from previous call")
  },
  async ({ severity, limit, cursor }) => {
    const dbResult = await db.logs.find({ severity })
                            .limit(limit + 1)
                            .cursor(cursor);
    
    const hasMore = dbResult.length > limit;
    const records = hasMore ? dbResult.slice(0, limit) : dbResult;
    const nextCursor = hasMore ? records[records.length - 1].id : null;

    return {
      content: [{
        type: "text",
        text: JSON.stringify({ records, nextCursor, hasMore })
      }]
    };
  }
);

Ne Zaman Uygulanır?

Veritabanı sorgularında, Elasticsearch/Kibana log aramalarında ve boyutu dinamik olan dış API entegrasyonlarında. Özellikle LLM’in “Samanlıkta İğne Arama” (Needle in a Haystack) yeteneğinin 64k token sonrasında %32 oranında düştüğü bilinen senaryolarda.

Ne Zaman Uygulanmaz?

Kritik bir root-cause analysis (kök neden analizi) anında ajanın zaman serisindeki anomalileri korele etmesi gerekiyorsa, veriyi parçalamak bağlamı koparabilir. Bu durumda pagination yerine özetleme (map-reduce) pattern’i tercih edilmelidir.

Strict Schema Projection (Seçici Alan Projeksiyonu Pattern’i)

Problem

Geliştiriciler genellikle mevcut REST API’lerini doğrudan MCP aracı olarak sararlar (wrap ederler). Ajan get_user_profile aracını çağırdığında sadece kullanıcının rolüne (role: "admin") bakacakken, yanıtın içinde kullanıcının 2 MB’lık base64 avatarı, son 50 giriş logu ve yüzlerce alakasız timestamp döner. Bu durum ajanın dikkat mekanizmasını (attention mechanism) bozar.

Çözüm

GraphQL mantığını MCP tool’larına taşımak. Ajan, aracı çağırırken sadece ihtiyacı olan alanların listesini bir array olarak (fields: ["id", "role"]) sunucuya iletmek zorundadır. Sunucu, yanıtı bu şemaya göre filtreler (projection).

Ne Zaman Uygulanır?

Büyük JSON objeleri döndüren NoSQL veritabanı sorgularında veya enterprise sistemlerin (Salesforce, SAP vb.) şişkin API yanıtlarını ajana sunarken.

Ne Zaman Uygulanmaz?

Ajanın şemayı önceden bilmediği “keşif” (discovery) aşamalarında. Bu durumda ajanın hangi alanları isteyeceğini bilmesi imkansızdır.

Stateful Context Caching (Durum Korumalı Ön Bellek Pattern’i)

Problem

Anthropic (Claude) Prompt Caching gibi özellikler, token maliyetlerini %90 oranında düşürebilir (örn: $15 yerine $1.50). Ancak caching mekanizmasının çalışması için context’in bayt seviyesinde (byte-for-byte) aynı kalması gerekir. Eğer bir MCP tool’u, dönen metnin içine dinamik olarak "generated_at": "2023-10-12T14:32:01Z" gibi her saniye değişen bir alan eklerse, cache hit oranı %0’a düşer ve her seferinde cold-start token maliyeti ödenir.

Çözüm

MCP sunucusundan dönen metinlerden izlenebilirlik (traceability) için kullanılan tüm dinamik değişkenleri (timestamp, rastgele request ID’ler, anlık CPU metrikleri) izole etmek. Aracı tamamen deterministik hale getirmek.

“Production’da karşılaştığımız en sinsi token maliyeti artışı, log analiz tool’umuzun her satırın sonuna dinamik bir query execution süresi (ms) eklemesiydi. Bu milisaniye farklılıkları Claude’un önbelleğini geçersiz kılıyordu. Değerleri yuvarlayarak statik hale getirdiğimizde maliyetler anında normale döndü.”

Pratik Öneriler / Production Notları

  • Tool Fallback Stratejisi: Eğer bir MCP tool’u sınırları aşan bir veri döndüreceğini fark ederse, HTTP 500 fırlatmak yerine ajana semantik bir hata döndürmelidir: {"error": "Result is 15MB. Please use the 'search_logs' tool with a specific 'keyword' parameter instead of fetching all."}. Ajanlar bu hata mesajlarını okuyup stratejilerini değiştirebilirler.
  • Monitoring ve Metrikler: Prometheus veya Datadog üzerinde mutlaka mcp_tool_token_yield_bytes ve mcp_tool_execution_duration_ms metriklerini takip edin. 100 KB’ı sürekli aşan tool’lar alarm üretmelidir.
  • System Prompt Yönlendirmesi: Ajanın bu spesifik tool’ları kullanma yeteneğini artırmak için global system prompt’a şu yönergeyi ekleyin: “Büyük dosyaları incelerken doğrudan okuma yapmak yerine daima list_symbols ve read_symbol hiyerarşisini kullan.”

Sık Sorulan Sorular

Neden sadece 200k’lık büyük context pencerelerine güvenmiyoruz?

Çünkü context boyutu büyüdükçe LLM’in “Attention” (dikkat) dağılımı zayıflar. 150k token’lık bir context içinde, ajanın spesifik bir satırdaki hatayı bulma olasılığı (recall), 10k’lık izole bir context’e göre %40 daha düşüktür. Ayrıca RTT gecikmesi kullanıcı deneyimini yok eder.

Ajanı Pagination (sayfalandırma) kullanmaya nasıl zorlayabilirim?

Tool şemasındaki limit parametresine katı bir maksimum değer (örn. JSON Schema’da maximum: 100) vererek. Eğer ajan daha fazlasını isterse, MCP sunucusu validation hatası fırlatır ve ajan kendi hatasını düzeltip döngüyü limit dahilinde baştan kurar.

Bu pattern’ler ajanın API istek sayısını artırıp daha çok beklemesine neden olmaz mı?

Kısa vadede evet, ağ üzerinden geçen HTTP request sayısı artar (1 devasa istek yerine 4 küçük istek). Ancak LLM tarafında 100k token işlemek (Time to First Token) 15-20 saniye sürerken, 4 adet 2k token’lık paralel/sıralı istek toplamda 3-4 saniyede tamamlanır. Toplam işlem süresinde (TTC – Time to Completion) her zaman küçük ve spesifik context kazanır.

Sonuç

AI kod ajanları için MCP sunucuları geliştirirken, araçları pasif birer veri aktarım borusu olarak değil, proaktif birer context koruyucu (context guardian) olarak tasarlamanız gerekir. Keşiften detaya inen hiyerarşik yapıları kurmak, AST farkındalığı ile semantik bütünlüğü korumak ve otonom pagination stratejileri uygulamak, ajanınızın hem hızını hem de doğruluk oranını dramatik şekilde artıracaktır.

Aksiyon Adımı: Mevcut MCP sunucunuzdaki en çok kullanılan 3 tool’un payload boyutlarını analiz edin. Eğer herhangi bir aracın medyan yanıt boyutu 50.000 karakteri aşıyorsa, o aracı derhal Strict Schema Projection veya Multi-Step Drill Down pattern’i ile refactor edin.

Bunları da beğenebilirsiniz

jQuery ile Hızlı Filtreleme Yapımı (Türkçe Karakter Uyumlu)
20 Ekim 2022

jQuery ile Hızlı Filtreleme Yapımı (Türkçe Karakter Uyumlu)

Merhabalar, bu içeriğimizde Javascript dilinin kuşkusuz en önemli kütüphanelerinden biri olan jQuery ile çok hızlı çalışan ve Türkçe karakterle tamamen uyumlu bir filtreleme sistemi yapacağız….

Devamını Oku
vLLM ile LLM Sunumunda Mühendislerin Düştüğü 5 PagedAttention ve VRAM Tuzağı
5 Haziran 2026

vLLM ile LLM Sunumunda Mühendislerin Düştüğü 5 PagedAttention ve VRAM Tuzağı

Production ortamında vLLM kullanan mühendislerin PagedAttention, KV Cache ve VRAM yönetiminde yaptığı 5 kritik konfigürasyon hatası, tespiti ve çözümleri.

Devamını Oku
Pulumi Automation API ile PR Bazlı İzole Test Altyapıları: State Yönetimi ve Maliyet Optimizasyonu
11 Mayıs 2026

Pulumi Automation API ile PR Bazlı İzole Test Altyapıları: State Yönetimi ve Maliyet Optimizasyonu

CI/CD pipeline’larında her Pull Request için Pulumi Automation API kullanarak izole altyapılar kurma teknikleri, S3 backend locking çözümleri ve %68 maliyet tasarrufu sağlayan yaşam döngüsü stratejileri.

Devamını Oku
AI Asistan