Agent’ın context window’u dolduğunda model performansı düşer. Search bu doluşun en büyük tek tetikleyicisi. Bütçeyi sayısal düşünmeden agent davranışını anlamak mümkün değil.
AI agent için kod arama yazısında “search bir alt bütçedir, varsayılan üst sınır context window’un %15’i” demiştim. Bu yazıda formülün nereden geldiğini, farklı boyuttaki context window’lar için nasıl ölçeklendiğini ve bütçe aşımı sinyallerini nasıl yakalayacağını sayısal olarak açıyorum.
Context Window Bir Bütçe, Search Alt Bütçe
Modelin context window’u sabit bir kaynak. AI/LLM ekosisteminde kapasiteler sürekli genişliyor (bugünün yaygın değerleri yarın küçük kalabilir, milyonluk pencereler yolda), ama her tool call, her dosya okuması, her reasoning turu bu kaynaktan harcar. Mutlak rakam ne olursa olsun bütçe disiplini değişmiyor; değişen sadece her alt bütçenin ölçeklendiği taban.
ARCS adlı 2025 sonu çalışması bu gerçeği bir mimari prensibe çevirdi: agentic retrieval budgeted synthesize-execute-repair döngüsünde çalışır, accuracy ve cost trade-off’u açıkça optimize edilmelidir.1
Pratik karşılığı şu: context window’u beş alt bütçeye böl, her birinin sınırını oran olarak bil.
Kendi ajanlı iş akışlarımda ve ARCS prensibinden türettiğim tipik dağıtım:
| Alt bütçe | Tipik pay | Ne kapsar |
|---|---|---|
| System + project context | %30 | CLAUDE.md, .cursorrules, system prompt, file tree, project memory |
| Conversation history | %25 | Önceki user-assistant turn’leri, agent’ın kendi notları |
| Search + tool results | %15 | rg/ast-grep/repo-map/Read output’ları, MCP tool dönüşleri |
| Reasoning headroom | %20 | Modelin düşünmek için ihtiyaç duyduğu boş alan |
| Reserve | %10 | Beklenmeyen tool call, error recovery, compaction tetiklenmesin diye |
Örnek olarak orta-üst seviye bir context window (yazının yazıldığı tarihte yaygın bir referans noktası) için sayısal karşılığı:
Total 200,000 token (örnek referans)
System + project 60,000 token
History 50,000 token
Search results 30,000 token <-- bu yazının konusu
Reasoning headroom 40,000 token
Reserve 20,000 token
%15 sabit bir doğa yasası değil, tipik orta-üst aralıktaki context window’lar (~100-200k) için başlangıç heuristic’i. Uç boyutlarda framework olduğu gibi uygulanmaz çünkü üç sebep oranı bozar:
- Sabit maliyetler ölçeklenmiyor. Tek bir
Readçağrısı typical case’de ~750 token civarında bir source dosyası getirir, ama dağılım uzun kuyruklu: bu projedeki ölçümde median 740, p75 1516, p95 5911, p99 19,213, max ~52k token. Yani “tipik” Read 1k’nın altında, ama dosyaların ~%6’sı 5k’yı geçiyor. Context window 32k de olsa 1M de olsa bu sabit maliyet değişmez: 32k’da %15 sadece 4.8k token demek; iki orta-büyük Read bütçeyi bitirir. 1M’de %15 = 150k token; tipik bir görev için bunun yarısı bile israftır. - Task ihtiyacı context boyutuna bağlı değil. Bir bug fix N dosya search + M dosya read gerektirir; context window büyüdü diye bu ihtiyaç orantılı büyümez.
- Uçlarda strateji değişir, sadece ratio değişmez. Küçük window’da “ratio’yu artır” değil “stratejiyi sıkılaştır” gerek (semantic’i kapat, surgical lexical’a çevir). Büyük window’da ratio değil “absolute ceiling” düşünülür.
Üç katmanlı doğru çerçeve:
| Pratik kural | Tipik aralık | Açıklama |
|---|---|---|
| Başlangıç oranı %15 | 100-200k window | Tipik IDE entegrasyonları için sağlıklı default |
| Absolute floor ~4k token | < 50k window | En az 1 sağlıklı search + 2 file read garantilensin; ratio buna ulaşmıyorsa strateji komple değişir |
| Absolute ceiling ~50k token | > 500k window | Ratio bunun üstüne çıkıyorsa rakam düşürülür; gereksiz alan reasoning’e veya history’ye kayar |
Bu çerçevede %15 bir başlangıç noktası, kemikleşmiş kural değil. Window büyüdükçe oran düşer (mutlak tavan devreye girer), küçüldükçe oran ya yükselir ya da strateji komple değişir. Asıl prensip: search ne kadar lazımsa o kadar, fazlası bütçe israfı, azı görev başarısızlığı.
Dağıtım katı değil, agent türüne göre kaydırılabilir. Multi-step refactor görevinde history payı %40’a çıkabilir, tek seferlik soru-cevap görevinde %10’a düşebilir. Ama “search için %15-20 aralığı” tipik kod arama görevlerinde reasoning + history için yeterli alan bırakan ampirik bir başlangıç.
Ölçüm: Hangi Flag Gerçekten Tasarruf Ediyor?
Spoke için ceaksan-v4.0 codebase’inde (298 dosya) üç tip sorgu çalıştırıldı: nadir symbol (validateTurnstileToken, ~6 hit), orta sıklıkta identifier (newsletterCluster, ~306 hit), patolojik vaka (import, ~1547 hit). rg default baseline alındığında varyantların token oranı:
| Varyant | Symbol (~6 hit) | Concept (~306 hit) | High-freq (~1547 hit) |
|---|---|---|---|
rg (baseline) | 1.00× (111 tok) | 1.00× (9k tok) | 1.00× (47k tok) |
rg --vimgrep | 1.22× | 1.15× | 1.15× |
rg -C 2 | 3.81× | 5.67× | 2.75× |
rg -m 5 | 1.00× | 1.00× | 0.81× |
rg | head -50 | 1.00× | 0.17× | 0.02× |
rg -l (dosyalar) | 0.18× | 0.76× | 0.16× |
İki ana çıkarım:
- Baskın lever flag değil,
\| head -Nveya-lile output kesme. High-freq sorgudarg \| head -50baseline’ı 40× ucuzlatıyor (47k → 1.2k tok). Hiçbir flag bu kadar kuvvetli değil. --vimgrepucuz değil, daha pahalı (her sorguda %15-22 daha yüksek). Parseable tek satırlık format = daha az token değil; satır başına ek metadata var. Compact output istiyorsanrg --no-heading -nveya pipe toheadtercih et.-C 2inflation match yoğunluğuna bağlı: seyrek sorguda 3.8×, yoğun sorguda 2.75× ile 5.67× arasında. Sabit “3-5×” oranı yerine “match yoğunluğu × context faktörü” düşün.
ast-grep ayrı bir tool sınıfı, token alternatifi değil. Aynı corpus’ta export const $N pattern’i için ast-grep default 11.9k token, --json=compact ise 24.9k token döndürdü; karşılaştırılabilir rg -C 2 2.4k. ast-grep tasarruf aracı değil, regex’in yapamadığı structural ayrım aracı (fonksiyon deklarasyonu vs çağrı, typed const vs untyped, JSX bileşeni vs HTML element). Bu ayrımı yapacak başka yol yoksa pahalılığa katlanırsın; yoksa rg + filtre yeterli.
Üç Farklı Tier için Sayısal Walkthrough
Tier A: Geniş context window (referans 200k+ aralığı)
Total context window 200,000 token (örnek)
Search budget (%15) 30,000 token
Tek tool result hedef 1,000 token (yaklaşık 30 sonuç satırı)
Tek turn'de max tool call 30
Tipik bir görev: “find all middleware functions and refactor to use the new auth pattern”. Bu görev kabaca 8-12 turn alır.
- Turn 1:
rg "middleware"→ 12 dosya, ~150 token - Turn 2:
ast-grepile gerçek middleware’leri filtrele → 3 fonksiyon, ~400 token - Turn 3-5: 3 dosyayı Read et → 3 × 800 token = 2400 token
- Turn 6-8: refactor, write back, verify → minimal search
Toplam search harcaması: ~3000 token. Bütçenin yüzde 10’u. Sağlıklı.
Karşı örnek (kötü pattern): Aynı görev için agent doğrudan semantic search çağırır → 200 sonuç döner, 8000 token. Sonra hangisinin gerçek middleware olduğuna karar vermek için her dosyayı Read eder → 12 × 1200 token = 14,400 token. Toplam search harcaması: 22,400 token. Bütçenin %75’i. Reasoning headroom kalmadı, compaction tetiklendi, context kaybı başladı.
İki yaklaşım arası fark: 7 kat. Aynı görev, aynı model, sadece search policy farkı.
Tier B: Orta context window (referans 100-200k aralığı, çoğu IDE entegrasyonu bu sınıfta)
Total context window 128,000 token (örnek)
Search budget (%15) 19,200 token
Tek tool result hedef 750 token (yaklaşık 20 sonuç satırı)
Tek turn'de max tool call 25
Daha küçük window, daha sıkı disiplin. Built-in semantic search’ler genelde top-K vector hit + her hit için snippet döndürür; K=10 ve snippet=100 token gibi tipik bir konfigürasyonda bir çağrı kolayca birkaç bin token bulabilir. Spesifik rakamı IDE versiyonuna ve embedding chunk boyutuna bağlı, ama büyüklük sırası agent’ın bütçeyi planlaması için yeterli sinyal: iki üst üste semantic call orta tier window’da search bütçesinin yarısını yiyebilir.
Pratik öneri: IDE settings’te semantic search’ü disable et veya Manual moda al, ripgrep’i default yap. Cursor için ilgili setting yeni versiyonlarda Settings → Models → Search altında bulunuyor (versiyona göre yer değişebilir).
Tier C: Küçük context window (referans 32k ve altı)
Total context window 32,000 token (örnek)
Search budget (%15) 4,800 token
Tek tool result hedef 200 token (yaklaşık 5-7 sonuç satırı)
Tek turn'de max tool call 15
Küçük window’da agresif sıkıştırma şart. Semantic search neredeyse sığmaz. Lexical + structural’a sıkı sıkıya bağlı kal:
# Tier C için tipik search invocation
rg -C 1 -m 10 --vimgrep "pattern" --type ts # max 10 match, 1 satır context
ast-grep --json --no-color 'pattern' | head -20 # max 20 match
-m 10 ve head -20 flag’leri kritik. Bunlar olmadan tek bir search call bütçeyi tüketir.
Bütçe Aşımı Sinyalleri
Üç kırmızı bayrak:
1. Tek tool result search bütçesinin %15-20’sini geçiyor
Tek bir search çağrısı veya Read kendi başına search bütçesinin %15-20’sini tüketiyorsa agent yanlış sorgu yapıyor. Tier A’da bu ~5000 token, Tier C’de ~800 token’a denk düşer. Müdahale:
// Wrapper pseudo-code
function searchWrapper(query, backend, searchBudget) {
const result = backend.exec(query);
const tokens = estimateTokens(result);
const cap = Math.floor(searchBudget * 0.2); // tool result cap = budget'ın %20'si
if (tokens > cap) {
return summarize(result, {
maxTokens: Math.floor(cap * 0.3),
strategy: "first-N-files",
});
}
return result;
}
2. Aynı dosyanın 3+ kez okunması
Agent aynı dosyayı tekrar tekrar Read ediyorsa caching layer eksik. Bu hem bütçe israfı hem de LLM’lerin davranışsal bozulma modları yazısında belirttiğim context rot’a doğrudan davetiye. Çözüm:
- Skill veya MCP wrapper’da session-level file content cache tut
- Aynı
file:linearalığı tekrar istendiğinde cache’den dön - Cache key:
sha256(file_path + line_range + mtime)
Pratik gözlemimde tipik refactor task’larında %30-40 civarında search token tasarrufu sağlıyor, ama bu oran cache hit rate’e bağlı değişiyor; çünkü agent doğal olarak referansta aldığı dosyaları tekrar açar.
3. Context window doluluk %70 üstü
Kendi heuristiğim olarak %70’i erken uyarı eşiği alıyorum; resmi bir threshold değil. Bu noktada hâlâ reasoning için yeterli alan var ama hızla azalıyor. Müdahale stratejisi:
- Eski tool result’larını temizle (Anthropic’in tool result clearing pattern’i)
- Conversation history’yi özetle (otomatik compaction’a bırakma, sen kontrol et)
- Aktif task’ı bitir, sonra yeni session başlat
%85 üstüne çıktıysa compaction tetiklenmek üzere. Bu noktada hassas detayları kaybetmemek için manuel notes-to-self yaz (Anthropic’in context management rehberinden uyarladığım structured note-taking pattern’i).
CLAUDE.md / .cursorrules Snippet’leri
CLAUDE.md (Claude Code için)
## Search and Tool Budget
- Total search budget per task: ~15% of available context window
- Single tool result cap: ~20% of search budget (scope down if exceeded)
- File read cap: keep proportional to context window; use line range when possible
- Start with rg, escalate to ast-grep only for structural patterns regex cannot express
- For high-frequency queries, always cap output with `| head -50` (dominant cost lever)
- Use `rg -l` for discovery, then targeted `rg` or Read on the shortlist
- Avoid `--vimgrep` (measurably more tokens than default); avoid `-C N` unless context truly needed
## Budget overflow recovery
When a tool result exceeds the cap:
1. Summarize to top-3 files
2. Re-query with narrower scope (--type ts, path filter)
3. Do not feed the full result back to next turn
.cursorrules (Cursor için)
Search budget per task: 15% of available context window.
Disable IDE semantic search default. Use ripgrep first, ast-grep for structure.
Tool result cap: 20% of search budget. If exceeded, summarize before returning.
File read: use line range when known; avoid reading full large files.
Never re-read the same file twice in a session without cache check.
Generic MCP wrapper (token-aware backend)
import tiktoken
class BudgetAwareSearch:
def __init__(self, context_window: int, search_ratio: float = 0.15):
self.budget = int(context_window * search_ratio)
self.tool_result_cap = int(self.budget * 0.2)
self.used = 0
self.encoder = tiktoken.get_encoding("cl100k_base")
self.file_cache = {}
def search(self, query: str) -> str:
if self.used >= self.budget * 0.8:
return "[budget warning: 80% of search budget used, summarize and stop]"
cache_key = self._cache_key(query)
if cache_key in self.file_cache:
return self.file_cache[cache_key]
raw_result = self._run_backend(query)
tokens = len(self.encoder.encode(raw_result))
if tokens > self.tool_result_cap:
result = self._summarize(raw_result, int(self.tool_result_cap * 0.3))
else:
result = raw_result
self.used += len(self.encoder.encode(result))
self.file_cache[cache_key] = result
return result
Bu sınıf production-grade değil, prensip taşıyıcı. Asıl noktası: backend wrapper’ı her zaman budget-aware olmalı, raw call’ı agent’a doğrudan açmamalı. Constructor’da context_window parametresi geçilmesi de kritik; rakam hardcode değil, runtime’da hangi modelle çalıştığına göre değişir.
Bir Hafta Sonra Ne Ölç?
Üç metrik takip et:
- Average tokens per search task: task tipine göre ortalama. Pratik bir başlangıç hedefi olarak kendime %80 koyuyorum; benchmark değil
- Tool call count per resolved task: düşük sayı iyi (etkili), aşırı düşük (5’in altı) kötü (yetersiz keşif). Kendi ajanlı refactor görevlerimde sağlıklı aralık 8-15 tool call oldu; görev karmaşıklığına bağlı değişir
- Compaction tetiklenme oranı: task başına compaction sayısı 0 hedef. 1+ varsa budget discipline başarısız, müdahale gerek
Bu metrikler için Anthropic Claude Code admin dashboard, Cursor’ın usage tab’ı veya kendi MCP wrapper logging’i kullanılabilir. Üçü de olmasa da basit bir günlük not yeterli: “bugün 10 task’ta kaç tanesi compaction tetikledi?”
Sıradaki Adım
Bu cluster’ın üçüncü yazısı Compaction uyumlu arama çıktısı: pratik bir playbook yazıldığında tool result sıkıştırma kalıplarını kod örnekleriyle açacak. Cluster’ın dördüncü yazısı LLM-free SpecAgent: AST tabanlı forecasting ise bu bütçenin daha verimli kullanılmasının ileri tekniğini, yani agent’ın bir sonraki sorgusunu önceden cache’lemeyi anlatacak.
Bu yazının pratik karşılığı: 4 cluster yazısının uzun versiyonu, akademik literatür özetleri, ölçüm notebook'u, hazır policy snippet'leri ve karar ağacı şablonu. ceaksan.com Premium tier kapsamında.
Premium'a KatılFootnotes
- ARCS. Agentic Retrieval-Augmented Code Synthesis with Iterative Refinement. arXiv:2504.20434. “Budgeted synthesize-execute-repair loop targeting predictable accuracy-latency trade-offs under fixed iteration and retrieval budgets.” https://arxiv.org/html/2504.20434 ↩
- 01 Context window sabit bir bütçedir. Search bu bütçenin alt bütçesi, varsayılan %15 üst sınır.
- 02 Tipik dağıtım: %30 system+project, %25 history, %15 search, %20 reasoning headroom, %10 reserve. Agent türüne göre kaydırılabilir.
- 03 Tek tool result search bütçesinin %15-20'sini geçiyorsa kırmızı bayrak. Truncate veya scope daralt.
- 04 %15 ratio başlangıç heuristic'i, sabit doğa yasası değil. Küçük window'da absolute floor, büyük window'da absolute ceiling devreye girer.
- 05 Aynı dosyayı 3+ kez okumak = caching layer eksikliği. Skill'inde dedup ve session cache şart.
+ Token bütçesini gerçekten manuel saymalı mıyım?
Hayır. Her tool çağrısında manuel sayım imkansız. Bunun yerine tool result'larını üst sınıra göre kes (rg için en güçlü lever pipe ile | head -50; gerekirse -C N ekle ama maliyeti 2-6 kat şişirir), backend output'unu post-process ile sıkıştır, agent'a hatırlatıcı prompt koy: 'Each tool call must stay under N tokens'.
+ %15 search budget kuralı nereden geliyor?
Ampirik bir kural. ARCS paper'ı explicit budget allocation prensibini akademik olarak savunuyor, Anthropic context engineering blog'u compaction default'larında %15-20 aralığını öneriyor. Pratikte bu oran tipik kod arama görevlerinde reasoning + history için yeterli alan bırakıyor.
+ Küçük context window'lı modellerle bu kural geçerli mi?
Geçerli ama daha agresif. Küçük window'da %15 search budget mutlak rakam olarak çok küçülür, bu da tek bir semantic search çağrısının bütçeyi tüketmesi anlamına gelir. Bu tier'da lexical + structural'a sıkı sıkıya bağlı kal, semantic'i son çare yap.
+ Context auto-compaction varsa bütçe takip etmeye gerek var mı?
Var. Auto-compaction bir kurtarma mekanizması, fix değil. Compaction olduğunda detay kaybedersin, agent'ın doğru sonuca ulaşma olasılığı düşer. Budget discipline compaction'a hiç ihtiyaç duymamak için.
+ Bütçe aşımı olduğunda agent ne yapmalı?
Üç adım: önce mevcut sonuçlardan özet çıkar (10 dosya yerine top 3), sonra eski tool result'ları context'ten temizle (Anthropic'in tool result clearing pattern'i), son çare olarak yeni bir agent turn'üne devret. Her durumda raw dump etmeyi bırak.