Tüm Yazılar
KategoriAI
Okuma Süresi
28 dk okuma
Yayın Tarihi
...
Kelime Sayısı
2.273kelime

Kahveni hazırla - bu içerikli bir makale!

LLM agent'larının çalışma prensibi: ReAct, Plan-and-Execute, Reflexion pattern'leri, function calling spec'leri, LangGraph vs AutoGen vs CrewAI karşılaştırması ve gerçek production örneği.

Agentic AI: Tool Use, Planner Loops ve Production Agent Mimarisi

# Agentic AI: Tool Use, Planner Loops ve Production Agent Mimarisi

"Yapay zeka bir şeyi çözebilir" ile "yapay zeka bir şeyi yapabilir" arasındaki fark — işte bu fark agentic AI'ı tanımlıyor. 2023'te bir araştırma konsepti olan LLM agent'ları, 2026'da ciddi production sistemlerinde çalışıyor: müşteri destek süreçlerini otomasyon altına alıyor, kod tabanlarında bug fix yapıyor, veri pipeline'larını yönetiyor. Ama bu güç beraberinde karmaşıklık getiriyor. Bir agent nasıl tasarlanır? Hangi framework seçilir? Hata durumlarını nasıl idare edersin? Latency ve maliyet nasıl optimize edilir? Bu yazı, teoriden production gerçekliğine uzanan tam bir rehber.

💡 Pro Tip: Agent mimarisi tasarlarken önce "en az agent gerekli" prensibiyle başla. Tek bir akıllı prompt ile çözülebilen her şeyi agent'a taşıma — karmaşıklık ve hata yüzeyini artırır.

İçindekiler


LLM Agent Nedir? Temel Bileşenler

Klasik LLM: soru → cevap. Tek adım, tek yön.

LLM Agent: hedef → plan → araç kullan → gözlemle → plan güncelle → araç kullan → ... → sonuç. Çok adımlı, döngüsel, kendi kendini yönlendiren.

Bir agent'ın 4 temel bileşeni var:

typescript
1interface AgentArchitecture {
2 // 1. LLM — "beyin": karar veren, planlayan, akıl yürüten
3 brain: LLMClient;
4 
5 // 2. Tools — "eller": dünyayla etkileşim araçları
6 tools: Map;
7 
8 // 3. Memory — "hafıza": kısa ve uzun vadeli bilgi depolama
9 memory: {
10 shortTerm: ConversationHistory; // mevcut görev bağlamı
11 longTerm: VectorMemory; // kalıcı bilgi deposu
12 };
13 
14 // 4. Planning — "koordinatör": hangi araç, ne zaman, hangi sırada
15 planner: PlanningStrategy;
16}
17 
18interface Tool {
19 name: string;
20 description: string; // LLM bu açıklamayı okuyarak aracı seçiyor
21 parameters: JSONSchema;
22 execute: (params: unknown) => Promise;
23}

Tool Use ve Function Calling Spec'leri

Her major AI sağlayıcısının function calling spec'i var. Format farklı ama konsept aynı: modele "şu araçlar mevcut" diyorsun, model cevap yerine araç çağrısı dönebiliyor.

OpenAI Function Calling

python
1import openai
2import json
3 
4client = openai.OpenAI()
5 
6tools = [
7 {
8 "type": "function",
9 "function": {
10 "name": "search_database",
11 "description": "Ürün veritabanında arama yap. Fiyat, stok ve ürün detayları döner.",
12 "parameters": {
13 "type": "object",
14 "properties": {
15 "query": {
16 "type": "string",
17 "description": "Arama sorgusu"
18 },
19 "category": {
20 "type": "string",
21 "enum": ["elektronik", "giyim", "gıda"],
22 "description": "Ürün kategorisi (opsiyonel)"
23 },
24 "max_price": {
25 "type": "number",
26 "description": "Maksimum fiyat (TL)"
27 }
28 },
29 "required": ["query"]
30 }
31 }
32 }
33]
34 
35response = client.chat.completions.create(
36 model="gpt-4.7",
37 messages=[
38 {"role": "user", "content": "1000 TL altında en iyi kablosuz kulaklıkları göster"}
39 ],
40 tools=tools,
41 tool_choice="auto"
42)
43 
44message = response.choices[0].message
45if message.tool_calls:
46 for call in message.tool_calls:
47 fn_name = call.function.name
48 fn_args = json.loads(call.function.arguments)
49 result = execute_tool(fn_name, fn_args)

Anthropic Tool Use

python
1import anthropic
2 
3client = anthropic.Anthropic()
4 
5tools = [
6 {
7 "name": "get_weather",
8 "description": "Belirtilen şehir için güncel hava durumu bilgisi al",
9 "input_schema": {
10 "type": "object",
11 "properties": {
12 "city": {
13 "type": "string",
14 "description": "Şehir adı"
15 },
16 "unit": {
17 "type": "string",
18 "enum": ["celsius", "fahrenheit"],
19 "default": "celsius"
20 }
21 },
22 "required": ["city"]
23 }
24 }
25]
26 
27response = client.messages.create(
28 model="claude-opus-4-7",
29 max_tokens=1024,
30 tools=tools,
31 messages=[
32 {"role": "user", "content": "İstanbul'da bugün hava nasıl?"}
33 ]
34)
35 
36for block in response.content:
37 if block.type == "tool_use":
38 result = execute_tool(block.name, block.input)
39 # Sonucu modele geri gönder
40 continue_response = client.messages.create(
41 model="claude-opus-4-7",
42 max_tokens=1024,
43 tools=tools,
44 messages=[
45 {"role": "user", "content": "İstanbul'da bugün hava nasıl?"},
46 {"role": "assistant", "content": response.content},
47 {"role": "user", "content": [
48 {"type": "tool_result", "tool_use_id": block.id, "content": str(result)}
49 ]}
50 ]
51 )

Paralel Tool Çağrısı

2026'da hem OpenAI hem de Anthropic paralel tool çağrısını destekliyor:

typescript
1async function executeParallelTools(
2 toolCalls: ToolCall[],
3 tools: Map
4): Promise {
5 // Paralel çalıştır — latency düşer
6 return Promise.all(
7 toolCalls.map(async (call) => {
8 const tool = tools.get(call.name);
9 if (!tool) throw new Error(`Tool not found: ${call.name}`);
10 
11 try {
12 const result = await tool.execute(call.params);
13 return { id: call.id, success: true, result };
14 } catch (error) {
15 return { id: call.id, success: false, error: String(error) };
16 }
17 })
18 );
19}

Temel Agent Pattern'leri

Plan-and-Execute

Önce bir plan üret, sonra adım adım uygula. Planı en başta yapmak, sonradan değiştirmekten daha verimli.

python
1class PlanAndExecuteAgent:
2 def __init__(self, llm, tools):
3 self.llm = llm
4 self.tools = tools
5 
6 async def run(self, task: str) -> str:
7 # 1. Görev analizi ve plan üretimi
8 plan = await self.create_plan(task)
9 
10 results = []
11 for step in plan['steps']:
12 result = await self.execute_step(step, results)
13 results.append(result)
14 
15 # Gerekirse planı güncelle
16 if result.get('needs_replan'):
17 plan = await self.replan(task, plan, results)
18 
19 return await self.synthesize(task, results)
20 
21 async def create_plan(self, task: str) -> dict:
22 prompt = f"""Görevi alt adımlara böl. Her adım bağımsız çalıştırılabilmeli.
23 
24GÖREV: {task}
25MEVCUT ARAÇLAR: {list(self.tools.keys())}
26 
27JSON döndür:
28{{"steps": [{{"id": 1, "description": "...", "tool": "...", "depends_on": []}}]}}"""
29 response = await self.llm.complete(prompt)
30 return json.loads(response)

Reflexion Pattern

Shinn et al. 2023'ten. Model görev başarısız olunca hatayı analiz eder ve "refleksiyon" üretir. Bu refleksiyon sonraki denemeye eklenir.

python
1class ReflexionAgent:
2 def __init__(self, llm, tools, max_trials: int = 3):
3 self.llm = llm
4 self.tools = tools
5 self.max_trials = max_trials
6 
7 async def run(self, task: str) -> str:
8 reflections: list[str] = []
9 
10 for trial in range(self.max_trials):
11 result = await self.attempt(task, reflections)
12 
13 if result['success']:
14 return result['output']
15 
16 reflection = await self.reflect(task, result)
17 reflections.append(reflection)
18 
19 raise RuntimeError(f"Görev {self.max_trials} denemede çözülemedi")
20 
21 async def reflect(self, task: str, result: dict) -> str:
22 prompt = f"""Görev başarısız oldu. Neyi yanlış yaptın?
23 
24GÖREV: {task}
25ALINAN HATA: {result.get('error')}
26YAPILAN EYLEMLER: {result.get('actions')}
27 
28Kısa, spesifik analiz yaz (max 100 kelime):"""
29 return await self.llm.complete(prompt)

Memory Yönetimi: Kısa ve Uzun Vadeli

Kısa Vadeli Bellek

Mevcut konuşma/görev geçmişi. Token limitleri nedeniyle yönetim gerektirir.

typescript
1class ConversationMemory {
2 private messages: Message[] = [];
3 private readonly maxTokens: number;
4 
5 constructor(maxTokens = 8000) {
6 this.maxTokens = maxTokens;
7 }
8 
9 add(message: Message): void {
10 this.messages.push(message);
11 this.enforceLimit();
12 }
13 
14 private async enforceLimit(): Promise {
15 const currentTokens = this.estimateTokenCount();
16 
17 if (currentTokens > this.maxTokens * 0.8) {
18 // Eski mesajları özetle — son 4'ü koru
19 const toSummarize = this.messages.slice(0, -4);
20 const summary = await this.summarize(toSummarize);
21 
22 this.messages = [
23 { role: 'system', content: `Önceki konuşma özeti: ${summary}` },
24 ...this.messages.slice(-4)
25 ];
26 }
27 }
28 
29 private estimateTokenCount(): number {
30 return this.messages.reduce((total, m) => total + m.content.length / 4, 0);
31 }
32}

Uzun Vadeli Bellek (Semantic Memory)

python
1class SemanticMemory:
2 def __init__(self, vector_db, embedder):
3 self.db = vector_db
4 self.embedder = embedder
5 
6 async def store(self, key: str, content: str, metadata: dict = {}):
7 embedding = await self.embedder.embed(content)
8 await self.db.upsert({
9 "id": key,
10 "vector": embedding,
11 "metadata": {"content": content, **metadata}
12 })
13 
14 async def recall(self, query: str, k: int = 5) -> list[str]:
15 query_vec = await self.embedder.embed(query)
16 results = await self.db.search(query_vec, k)
17 return [r.metadata["content"] for r in results]
18 
19 async def build_context_block(self, query: str) -> str:
20 memories = await self.recall(query)
21 if not memories:
22 return ""
23 lines = "
24".join(f"- {m}" for m in memories)
25 return f"
26 
27İlgili geçmiş bilgi:
28{lines}"

Framework Karşılaştırması: LangGraph, AutoGen, CrewAI

LangGraph

LangChain ekibinin geliştirdiği, state machine tabanlı agent framework. DAG yapısında agent akışları modelleniyor.

Güçlü yönleri:

  • Karmaşık, dallanmalı iş akışları
  • Durumun açıkça modellenmesi
  • LangSmith ile built-in observability

Zayıf yönleri:

  • LangChain bağımlılığı, öğrenme eğrisi yüksek
  • Basit kullanım için fazla karmaşık

AutoGen (Microsoft)

Multi-agent konuşmalar için tasarlandı. Agent'lar birbirleriyle sohbet ediyor.

python
1import autogen
2 
3config_list = [{"model": "gpt-4.7", "api_key": "YOUR_KEY"}]
4 
5planner = autogen.AssistantAgent(
6 name="Planner",
7 system_message="Görevleri alt adımlara böl ve koordine et.",
8 llm_config={"config_list": config_list}
9)
10 
11coder = autogen.AssistantAgent(
12 name="Coder",
13 system_message="Python kodu yaz ve çalıştır.",
14 llm_config={"config_list": config_list}
15)
16 
17critic = autogen.AssistantAgent(
18 name="Critic",
19 system_message="Kodu gözden geçir, hata ve iyileştirme öner.",
20 llm_config={"config_list": config_list}
21)
22 
23user_proxy = autogen.UserProxyAgent(
24 name="UserProxy",
25 human_input_mode="NEVER",
26 code_execution_config={"work_dir": "coding"}
27)
28 
29group_chat = autogen.GroupChat(
30 agents=[planner, coder, critic, user_proxy],
31 messages=[],
32 max_round=10
33)
34manager = autogen.GroupChatManager(groupchat=group_chat, llm_config={"config_list": config_list})

CrewAI

Role-based multi-agent framework. Her agent bir "rol" üstleniyor. Öğrenme eğrisi düşük, ama production stability henüz beta seviyesinde.

Özellik
LangGraph
AutoGen
CrewAI
Öğrenme eğrisi
Yüksek
Orta
Düşük
Karmaşık iş akışları
Excellent
İyi
Orta
Multi-agent kolay
Orta
Excellent
Excellent
Production stability
İyi
Beta
Beta
Observability
Excellent
Orta
Sınırlı

Multi-Agent Koordinasyonu

Orchestrator-Worker Pattern

typescript
1class MultiAgentOrchestrator {
2 private workers = new Map();
3 
4 register(role: string, agent: WorkerAgent): void {
5 this.workers.set(role, agent);
6 }
7 
8 async executeTask(task: ComplexTask): Promise {
9 const subTasks = await this.decompose(task);
10 
11 // Bağımsız görevleri paralel çalıştır
12 const results = new Map();
13 const groups = this.groupByDependency(subTasks);
14 
15 for (const group of groups) {
16 const groupResults = await Promise.all(
17 group.map((st) => {
18 const worker = this.workers.get(st.requiredRole);
19 if (!worker) throw new Error(`No worker for role: ${st.requiredRole}`);
20 return worker.execute(st, results);
21 })
22 );
23 groupResults.forEach((r, i) => results.set(group[i].id, r));
24 }
25 
26 return this.synthesize(task, results);
27 }
28}

Error Recovery ve Güvenilirlik

Hata Kategorileri ve Stratejiler

typescript
1const enum AgentErrorType {
2 ToolTimeout = 'TOOL_TIMEOUT',
3 ToolRateLimit = 'TOOL_RATE_LIMIT',
4 ContextOverflow = 'LLM_CONTEXT_OVERFLOW',
5 ToolExecutionError = 'TOOL_EXECUTION_ERROR',
6 PlanningFailure = 'PLANNING_FAILURE',
7 MaxIterations = 'MAX_ITERATIONS_EXCEEDED',
8}
9 
10interface RetryStrategy {
11 retry: boolean;
12 maxRetries?: number;
13 backoffMs?: number;
14 exponential?: boolean;
15 action?: 'COMPRESS_CONTEXT' | 'REPLAN';
16 escalate?: boolean;
17}
18 
19const ERROR_STRATEGIES: Record = {
20 [AgentErrorType.ToolTimeout]: { retry: true, maxRetries: 3, backoffMs: 1000, exponential: true },
21 [AgentErrorType.ToolRateLimit]: { retry: true, maxRetries: 5, backoffMs: 5000, exponential: true },
22 [AgentErrorType.ContextOverflow]: { retry: true, maxRetries: 1, action: 'COMPRESS_CONTEXT', backoffMs: 0 },
23 [AgentErrorType.PlanningFailure]: { retry: true, maxRetries: 2, action: 'REPLAN', backoffMs: 0 },
24 [AgentErrorType.MaxIterations]: { retry: false, escalate: true },
25 [AgentErrorType.ToolExecutionError]: { retry: true, maxRetries: 2, backoffMs: 500, exponential: false },
26};

Circuit Breaker Pattern

python
1import time
2 
3class CircuitBreaker:
4 def __init__(self, failure_threshold: int = 5, recovery_timeout: int = 60):
5 self.failure_threshold = failure_threshold
6 self.recovery_timeout = recovery_timeout
7 self.failure_count = 0
8 self.last_failure_time: float | None = None
9 self.state = "CLOSED" # CLOSED, OPEN, HALF_OPEN
10 
11 async def call(self, func, *args, **kwargs):
12 if self.state == "OPEN":
13 elapsed = time.time() - (self.last_failure_time or 0)
14 if elapsed > self.recovery_timeout:
15 self.state = "HALF_OPEN"
16 else:
17 raise RuntimeError("Circuit breaker OPEN — araç geçici olarak devre dışı")
18 
19 try:
20 result = await func(*args, **kwargs)
21 self._on_success()
22 return result
23 except Exception as exc:
24 self._on_failure()
25 raise
26 
27 def _on_success(self):
28 self.failure_count = 0
29 self.state = "CLOSED"
30 
31 def _on_failure(self):
32 self.failure_count += 1
33 self.last_failure_time = time.time()
34 if self.failure_count >= self.failure_threshold:
35 self.state = "OPEN"

Observability ve Debugging

Agent'ları debug etmek klasik uygulamalardan çok daha karmaşık. Çok adımlı, dallanabilir, araç çağrıları olan sistemlerde sorun tespiti zordur.

Temel Tracing

python
1import structlog
2import time
3 
4logger = structlog.get_logger()
5 
6class ObservableAgent:
7 async def execute_step(self, step: dict) -> dict:
8 step_id = step['id']
9 step_type = step['type']
10 
11 logger.info("agent_step_start", step_id=step_id, step_type=step_type)
12 start_time = time.time()
13 
14 try:
15 result = await self._run_step(step)
16 duration_ms = (time.time() - start_time) * 1000
17 
18 logger.info(
19 "agent_step_complete",
20 step_id=step_id,
21 duration_ms=round(duration_ms, 1),
22 success=True
23 )
24 return result
25 
26 except Exception as exc:
27 logger.error(
28 "agent_step_failed",
29 step_id=step_id,
30 error=str(exc),
31 duration_ms=round((time.time() - start_time) * 1000, 1)
32 )
33 raise

Gerçek Production Örneği: Müşteri Destek Agent'ı

Bir e-ticaret şirketinin tier-1 müşteri destek sürecini ele alalım. Günde ~2000 bilet, %70'i şu konularda: sipariş durumu, iade talebi, ürün bilgisi.

Mimari

typescript
1const customerSupportAgent = {
2 model: "claude-opus-4-7",
3 maxIterations: 8,
4 
5 tools: [
6 {
7 name: "get_order_status",
8 description: "Müşterinin sipariş durumunu ve kargo bilgisini döner",
9 parameters: {
10 order_id: { type: "string", required: true },
11 customer_email: { type: "string", required: false }
12 }
13 },
14 {
15 name: "initiate_return",
16 description: "İade talebi başlatır ve iade talimatları döner",
17 parameters: {
18 order_id: { type: "string", required: true },
19 reason: {
20 type: "string",
21 enum: ["defective", "wrong_item", "not_as_described", "change_of_mind"]
22 }
23 }
24 },
25 {
26 name: "search_product_info",
27 description: "Ürün özellikleri, stok durumu ve fiyat bilgisi",
28 parameters: {
29 query: { type: "string", required: true }
30 }
31 },
32 {
33 name: "escalate_to_human",
34 description: "Karmaşık veya hassas durumları insan temsilciye aktar",
35 parameters: {
36 reason: { type: "string" },
37 priority: { type: "string", enum: ["low", "medium", "high", "urgent"] },
38 summary: { type: "string" }
39 }
40 }
41 ],
42 
43 systemPrompt: `Sen [Şirket] müşteri destek asistanısın.
44Nazik, çözüm odaklı ve verimli ol.
45Müşteri bilgilerini doğrulamadan hassas işlem yapma.
46Çözüm bulamazsan insan temsilciye eskalasyon yap.`
47};

3 Aylık Production Sonuçları

Metrik
Agent
Önceki (Manuel)
İyileşme
Ortalama çözüm süresi
2.3 dakika
18 dakika
7.8x hız
İlk temas çözüm oranı
%74
%58
+16 puan
Müşteri memnuniyeti
4.1/5
3.8/5
+8%
Eskalasyon oranı
%26
%42
-38%
Maliyet/bilet
$0.38
$3.20
8.4x tasarruf

ALTIN İPUCU

Bu yazının en değerli bilgisi

Bu ipucu, yazının en önemli çıkarımını içeriyor.

Easter Egg

Gizli bir bilgi buldun!

Bu bölümde gizli bir bilgi var. Keşfetmek ister misin?

Okuyucu Ödülü

Agent geliştirmeye başlarken harcayabileceğin en değerli zaman: **LangSmith veya Arize Phoenix ile ilk 50 çağrını trace et ve incele.** Deneyimler gösteriyor ki uygulayıcıların %90'ı "agent karmaşık planlama yaptı" sandığı şeyin aslında tek bir tool çağrısıyla çözülebilecek bir görev olduğunu fark ediyor. Bu analiz, mimarini basitleştirmene ve maliyeti dramatik ölçüde düşürmene yardımcı olur.

Sonuç

Agentic AI 2026'da olgunluktan üretime geçiş döneminde. Araçlar hazır, pattern'ler test edilmiş, maliyet makul hale geldi. Ama başarılı production sistemleri mutlaka şu özelliklere sahip:

  1. Minimal karmaşıklık: Agent'ı yalnızca gerekli olduğunda kullan
  2. Kapsamlı observability: Her adımı logla, trace et
  3. Sağlam hata yönetimi: Circuit breaker, retry, eskalasyon
  4. Açık state tracking: Modelin "aklında" bir şey tutmasını bekleme

Paralel multi-agent sistemler için Claude Multi-Agent Teams yazısına, MCP ile araç entegrasyonu için MCP Protocol yazısına bakabilirsin.

Etiketler

#AI#Agent#Tool Use#Function Calling#Planner#Production#2026
Muhittin Çamdalı

Muhittin Çamdalı

Senior iOS Developer

12+ yıllık deneyime sahip iOS Developer. Swift, SwiftUI ve modern iOS mimarileri konusunda uzman. Apple platformlarında performanslı ve kullanıcı dostu uygulamalar geliştiriyorum.

iOS Geliştirme Haberleri

Haftalık Swift tips, SwiftUI tricks ve iOS best practices. Spam yok, sadece değerli içerik.

Gizliliğinize saygı duyuyoruz. İstediğiniz zaman abonelikten çıkabilirsiniz.

Paylaş

Bunu da begenebilirsiniz