"Durum yönetimi ve akış kontrolü daha düzenli hale gelir" beklentisiyle LangGraph’ı benimsedik, ama kod aksine daha karmaşıklaştı.
Bir framework kullanmaya başladıktan sonra bile yapının kötüleşebileceğini bizzat deneyimleyip derlediğim notların paylaşımıdır.
İncelediğimizde durum şöyleydi:
- Grafikte yalnızca tek bir node vardı. current_step → END yapısı olduğu için koşullu edge ya da dallanma yoktu; graph.invoke() doğrudan bir fonksiyonu çağırmakla aynı şeydi. Step geçişine grafiğin dışındaki servis kodu karar veriyordu.
- Aynı durum iki yerde saklanıyordu. LangGraph MemorySaver (in-memory) ile kendi PostgreSQL Checkpointer’ımız aynı oturumu çift şekilde kaydedip geri yüklediği için tutarsızlıklar oluşuyordu.
- Yaklaşık 8.700 satırlık 3 LangGraph çalıştırma kodunda (Executor) tekrar vardı. Asıl temel mantık "LLM çağrısı + prompt birleştirme" kadardı; geri kalanların çoğu durum yönetimi, koşullu dallanma ve edge-case yamalarıydı.
Yüzeyde sorun, framework’ün gerçek işlevlerini (koşullu edge’ler, yerleşik checkpointer, Human-in-the-Loop) kullanmayıp onu yalnızca bir kabuk gibi benimsememizdi; ancak daha derine inince asıl nedenin başka olduğu ortaya çıktı.
- Büyük ölçüde vibe coding ile geliştirilmişti; fakat üretim sürecinde iç kodu ya da tasarım ilkelerini derinlemesine incelemeden, her seferinde yalnızca gereksinimleri ve niyeti toparlayıp uygulamaya devam eden bir yöntem izlenmişti.
- Sorun vibe coding’in kendisi değil, doğrulama olmadan ilerlemekti. Bu yaklaşım sadece gözün önündeki işlevi optimize eder; tüm yapının sorumluluk sınırlarını korumaz. Çift checkpoint alma da, dağılmış durum da, yinelenen mantık da tamamen kısmi optimizasyonların birikimiydi.
- Tasarımcı yok değildi; asıl neden, framework’ün neyin sorumluluğunu üstlenmek üzere tasarlandığını yeterince anlamadan onun üzerinde yalnızca talimat vermiş olmaktı.
Bu yüzden durup düşündük ve şöyle geri çevirdik:
- Bağımsız topoloji + thread_id izolasyonu ile oturumları ayırma
- State’te yalnızca metadata bırakıp gövdeyi Store’a taşıma
- regex parsing yerine yerel tool_use kullanma
- Test edilebilirlik için node’ları ayırma
- Framework’ü doğru anlama ve kullanma yapısına ihtiyaç duyan kişinin aslında ben olduğumu fark etme
Bu, "nasıl kullanılır" değil, "nasıl yanlış kullandık" üzerine bir kayıt/paylaşımdır.
2 yorum
LangChain ve LangGraph kullanılan her durumun AI SDK ile değiştirilebileceği gibi görünüyor.
Evet, öyle. Katılıyorum. SDK bağımlılığı oluşacak olsa da öğrenme eğrisi yüksek olduğu için bence bu daha iyi olabilir.