AI Agent Framework'leri — Derinlemesine Best Practices Rehberi (LangGraph, PydanticAI, LlamaIndex)

19 Mart 2026 · netologist · 26 dakika, 5535 kelime ·

LangGraph · PydanticAI · LlamaIndex (RAG)

Python ile production seviyesinde agentic sistemler inşa etmek isteyen senior/principal seviyesi geliştiriciler için referans doküman. Bu rehber, API sözdiziminden ziyade framework’ler değişse bile değerini koruyan mühendislik kavramlarına (state, dayanıklılık/durability, structured output, retrieval pipeline’ları) odaklanır.


İçindekiler

  1. LangGraph — Orkestrasyonun Omurgası
  2. PydanticAI — Agent Katmanı
  3. LlamaIndex — Bir Disiplin Olarak RAG
  4. Framework’ler Arası Mimari Pattern’ler
  5. Son Kontrol Listesi

1. LangGraph — Orkestrasyonun Omurgası

1.1 Neden LangGraph’e En Fazla Yatırımı Yapmalısın

Buradaki temel içgörü şu: framework değişebilir/atılabilir, ama kavramlar değişmez. LangGraph şu an için şunları öğrenmek adına iyi bir araç:

Temporal’a, AWS Step Functions’a, özel bir actor sistemine ya da gelecekteki başka bir framework’e geçsen bile bu sekiz kavram gerçek beceri olarak kalır. LangGraph’i sadece “LLM’i döngü içinde çağırma yöntemi” olarak değil, dayanıklı, stateful, dağıtık sistemler için bir öğretim aracı olarak ele al.

1.2 State Management

Zihinsel model: Graph’ın bir state machine (durum makinesi). Her node neredeyse saf bir fonksiyon: f(state) -> partial_state_update. Graph motoru bu güncellemeleri reducer’lar aracılığıyla birleştirir.

Best Practices

from typing import Annotated, TypedDict
from operator import add

class AgentState(TypedDict):
    messages: Annotated[list, add]      # sadece ekleme yapılan geçmiş
    retries: Annotated[int, add]        # retry sayısını biriktir
    plan: str | None                    # burada son-yazan-kazanır sorun değil
    scratch: dict                       # sadece dahili, kullanıcıya asla dönmez

Anti-Pattern’ler

1.3 Durable Execution (Dayanıklı Çalıştırma)

Zihinsel model: Uzun süre çalışan bir agent workflow’u, tam olarak bir veritabanı işleminin server yeniden başlatmasına dayanması gibi, process restart’larını, deploy’ları ve crash’leri atlatabilmeli.

Best Practices

Anti-Pattern’ler

1.4 Checkpointing

Zihinsel model: Bir checkpoint, state + graph içindeki konumun, dayanıklı bir depoya (Postgres, Redis, dev için SQLite) persist edilmiş bir anlık görüntüsüdür ve çalıştırmanın tam kaldığı yerden devam etmesini sağlar.

Best Practices

Design Pattern: Zaman-Yolculuğu (Time-Travel) Debugging

Checkpoint’ler sadece persist edilmiş state anlık görüntüleri olduğu için şunları yapabilirsin:

  1. Bir thread_id için herhangi bir geçmiş checkpoint’i yükle.
  2. Değiştirilmiş bir input ile o noktadan çalıştırmayı fork’la.
  3. Yeni izlenimi orijinaliyle karşılaştır.

Bu, tüm çok turlu konuşmayı sıfırdan tekrar çalıştırmadan “agent neden X yaptı” sorusunu debug etmek için paha biçilmez.

1.5 Retries (Yeniden Deneme)

Zihinsel model: Tüm hatalar eşit değildir. Bir network timeout’u, bir rate-limit hatası, bozuk bir LLM çıktısı ve gerçek bir iş mantığı hatası, her biri farklı bir retry stratejisi gerektirir.

Best Practices

def call_llm_with_repair(state):
    try:
        result = llm.invoke(state["messages"])
        validated = OutputSchema.model_validate_json(result.content)
        return {"result": validated, "retries": 0}
    except ValidationError as e:
        if state["retries"] >= MAX_RETRIES:
            return {"error": "max_retries_exceeded", "retries": state["retries"]}
        repair_prompt = f"Son çıktın doğrulamadan geçmedi: {e}. Düzelt ve sadece geçerli JSON döndür."
        return {"messages": [repair_prompt], "retries": state["retries"] + 1}

1.6 Branching (Dallanma)

Zihinsel model: Gerçek agent workflow’ları lineer pipeline’lar değildir — koşullu kenarlara, paralel fan-out’a ve birleşme noktalarına sahip graph’lardır.

Best Practices

Design Pattern: Supervisor Routing

Yaygın ve sağlam bir dallanma pattern’i: bir “supervisor” node, mevcut state/niyeti sınıflandırır ve birkaç uzman node/subgraph’tan birine yönlendirir, bunlar da kontrolü supervisor’a geri döndürür. Bu, routing mantığını dağınık ad-hoc koşullar yerine merkezi ve denetlenebilir tutar.

1.7 Human-in-the-Loop (HITL)

Zihinsel model: Bazı kararlar tam otomasyona bırakılamayacak kadar maliyetli, belirsiz ya da geri döndürülemez. HITL, UI katmanına sonradan eklenen bir şey değil, birinci sınıf bir interrupt mekanizmasıdır.

Best Practices

Anti-Pattern’ler

1.8 Multi-Agent Orchestration (Çoklu Agent Orkestrasyonu)

Zihinsel model: Birden çok uzmanlaşmış agent’ın (ya da subgraph’ın) işbirliği yapması, temelde bir dağıtık sistemler problemidir: mesaj geçişi, paylaşılan state, sahiplik sınırları ve hata izolasyonu.

Best Practices

Design Pattern: Sözleşme-Öncelikli (Contract-First) Alt-Agent’lar

Herhangi bir alt-agent’ın prompt’unu ya da mantığını yazmadan önce, onun arayüz sözleşmesini yaz: tam input şeması, tam output şeması ve başarısızlık modları. Her alt-agent’a bir API sözleşmesi olan bir mikroservis gibi davran — çoklu agent sistemlerini ölçekte gerçekten sürdürülebilir kılan şey budur.

1.9 Failure Recovery (Hata Sonrası Kurtarma)

Zihinsel model: Failure recovery, bir demo’yu production sisteminden ayıran şeydir. Node’ların, tool’ların ve modellerin başarısız OLACAĞINI varsay; sadece mutlu yol (happy path) için değil, zarif bozulma (graceful degradation) için tasarla.

Best Practices


2. PydanticAI — Agent Katmanı

2.1 Bu Kombinasyon Neden İşe Yarıyor

Zaten Python + Pydantic kullanıyorsan, değer PydanticAI’nin spesifik API’sinde değil — seni şunlar hakkında doğru düşünmeye zorlamasında:

Bunlar, herhangi bir tip’li, test edilebilir agent katmanı inşa ederken sahip olacağın aynı endişelerdir — PydanticAI bunlar için sadece iyi varsayılanlar ve koruma çitleri sağlar.

2.2 Tool Tasarımı

Zihinsel model: Bir tool, non-deterministik bir çağırana (LLM) verdiğin tip’li bir fonksiyon sözleşmesidir. Onu, güvenilmeyen, ara sıra kafası karışan bir istemci için tasarladığın bir public API gibi tasarla.

Best Practices

from pydantic import BaseModel, Field
from pydantic_ai import Agent, RunContext

class FlightSearchParams(BaseModel):
    origin: str = Field(description="IATA havalimanı kodu, örn. 'JFK'")
    destination: str = Field(description="IATA havalimanı kodu, örn. 'LAX'")
    date: str = Field(description="ISO 8601 tarih, örn. '2026-09-01'")
    max_results: int = Field(default=5, ge=1, le=20)

class Flight(BaseModel):
    flight_number: str
    price_usd: float
    departure_time: str

agent = Agent("openai:gpt-4o", deps_type=FlightAPI)

@agent.tool
def search_flights(ctx: RunContext[FlightAPI], params: FlightSearchParams) -> list[Flight]:
    """İki havalimanı arasında belirli bir tarihte mevcut uçuşları arar.
    Hiçbiri bulunamazsa boş liste döndürür. Geçerli, iyi biçimlendirilmiş
    bir arama için asla hata fırlatmaz — sadece bozuk IATA kodlarında hata verir."""
    return ctx.deps.search(params)

Anti-Pattern’ler

2.3 Structured Output

Zihinsel model: LLM’in nihai cevabına chat metni gibi değil, bir API yanıtı gibi davran — herhangi bir dış girdiyi doğruladığın gibi doğrula, çünkü aslında öyledir.

Best Practices

from typing import Literal
from pydantic import BaseModel, Field

class TicketTriage(BaseModel):
    category: Literal["billing", "technical", "account", "other"]
    priority: Literal["low", "medium", "high", "urgent"]
    summary: str = Field(description="Sorunun tek cümlelik özeti")
    needs_human_review: bool = Field(description="Belirsiz veya yüksek riskliyse True")
    confidence: float = Field(ge=0.0, le=1.0)

triage_agent = Agent("openai:gpt-4o", result_type=TicketTriage, retries=2)

2.4 Dependency Injection

Zihinsel model: Agent’ının davranışı koddur (deterministik), agent’ının muhakemesi LLM’dir (non-deterministik). Dependency injection, deterministik kısımları test edilebilir, değiştirilebilir ve gizli global state’ten arınmış tutmanın yoludur.

Best Practices

from dataclasses import dataclass

@dataclass
class AppDeps:
    db: DatabaseClient
    payments_api: PaymentsClient
    current_user_id: str

agent = Agent("openai:gpt-4o", deps_type=AppDeps)

@agent.tool
def get_account_balance(ctx: RunContext[AppDeps]) -> float:
    """Mevcut kullanıcının hesap bakiyesini döndürür."""
    return ctx.deps.db.get_balance(ctx.deps.current_user_id)

2.5 Validation (Doğrulama)

Zihinsel model: Doğrulama sadece “JSON parse oluyor mu” değildir — modelin ne döndürdüğünü düşündüğü ile sisteminin neye ihtiyacı olduğu arasındaki sessiz semantik kaymaya karşı birincil savunmandır.

Best Practices

2.6 Agent Sınırları

Zihinsel model: Bir “agent”, her şeye kadir sihirli bir aktör değildir — tam olarak bir mikroservis gibi, tanımlı bir yetki kapsamına sahip sınırlı bir bileşendir.

Best Practices

2.7 Context Management

Zihinsel model: Context window, kıt ve pahalı bir kaynaktır — içine ne koyduğuna, sonsuz bir taslak defteri gibi değil, bir fonksiyonun argümanlarına koyduğun şeye uyguladığın aynı disiplinle davran.

Best Practices

2.8 Testing

Zihinsel model: İki farklı şeyi test ediyorsun — deterministik kod (tool’lar, doğrulayıcılar, routing) ve non-deterministik davranış (LLM’in seçimleri) — ve bunlar farklı test stratejileri gerektirir.

Best Practices


3. LlamaIndex — Bir Disiplin Olarak RAG

3.1 RAG’ı Bir Kütüphane Değil, Bir Pipeline Olarak Öğrenmek Neden Önemli

LlamaIndex’e kalıcı bir bağımlılık olarak commit olmak zorunda değilsin. Gerçekten ihtiyacın olan şey, aşağıdaki pipeline aşamalarını derinlemesine anlamak — bunu yaptığında, LlamaIndex, LangChain, Haystack veya elle yazılmış bir RAG stack’i arasında geçiş yapmak önemsiz hale gelir, çünkü her yerde aynı yedi aşama vardır.

Document ingestion (Doküman alımı)
       ↓
Chunking (Parçalama)
       ↓
Embedding
       ↓
Index
       ↓
Retrieval (Getirme)
       ↓
Reranking (Yeniden sıralama)
       ↓
Context construction (Bağlam oluşturma)
       ↓
LLM

3.2 Document Ingestion (Doküman Alımı)

Zihinsel model: Çöp girer, çöp getirilir. Bu aşama olduğundan az değer görür ve gerçek dünya RAG kalitesinin çoğu burada kazanılır ya da kaybedilir.

Best Practices

3.3 Chunking (Parçalama)

Zihinsel model: Bir chunk, retrieval’ın atomik birimidir — boyutu ve sınırları, LLM’in sonunda göreceği bağlamı doğrudan belirler. Bu, muhtemelen RAG’daki en yüksek etkiye sahip tek ayar düğmesidir.

Best Practices

3.4 Embedding

Zihinsel model: Bir embedding modeli, sabit boyutlu bir vektöre kayıplı bir sıkıştırma fonksiyonudur — kalitesi tüm retrieval tavanını sınırlar; hiçbir downstream yeniden sıralama, kötü bir embedding’i tam olarak telafi edemez.

Best Practices

3.5 Index

Zihinsel model: Index, retrieval veri yapındır — buradaki trade-off alanı hız vs. recall vs. maliyet vs. güncelleme esnekliğidir ve farklı index tipleri çok farklı trade-off’lar yapar.

Best Practices

3.6 Retrieval (Getirme)

Zihinsel model: Retrieval bir arama-alaka düzeyi (search-relevance) problemidir ve buraya bir arama motoru mühendisinin uygulayacağı aynı titizliği uygulamalısın — bu “sadece .similarity_search() çağır ve devam et” değildir.

Best Practices

3.7 Reranking (Yeniden Sıralama)

Zihinsel model: İlk retrieval ölçekte recall için optimize eder (hızlı, yaklaşık, tüm corpus üzerinde); reranking küçük bir aday kümesinde hassasiyet için optimize eder (yavaş, kesin, sadece top-k üzerinde) — her birini iyi olduğu şey için kullan.

Best Practices

3.8 Context Construction (Bağlam Oluşturma)

Zihinsel model: Bu, alınan içeriğe uygulanan prompt mühendisliğidir — alınan chunk’ları LLM’in bağlamına nasıl bir araya getirdiğin, retrieval kalitesinin kendisinden bağımsız olarak cevap kalitesini ciddi şekilde etkiler.

Best Practices

3.9 LLM (Generation)

Zihinsel model: İçerik LLM’e ulaştığında, kalite tavanının çoğu zaten ingestion → chunking → embedding → retrieval → reranking → context construction tarafından belirlenmiştir. Generation adımı, kalan hataların genellikle yaratıldığı değil, açığa çıktığı yerdir.

Best Practices


4. Framework’ler Arası Mimari Pattern’ler

Bu üç öğrenme yolu, bir production sisteminde doğal olarak birleşir:

LangGraph (workflow, state, dayanıklılık, HITL)
   └── Node: "answer_question"
         └── PydanticAI Agent (tip'li tool'lar, structured output)
                └── Tool: search_knowledge_base()
                       └── RAG pipeline (ingest → chunk → embed → index →
                                          retrieve → rerank → context → LLM)

Genel Kapsamlı Best Practices


5. Son Kontrol Listesi

LangGraph

PydanticAI

LlamaIndex / RAG