1 puan yazan jhs6312 6 시간 전 | Henüz yorum yok. | WhatsApp'ta paylaş

Merhaba. LLM çağrı loglama, maliyet takibi ve ajan trace’lerini tek bir yerde görmeyi sağlayan açık kaynak bir gözlemlenebilirlik platformu olan Spanlens’i geliştiriyorum.

Yapma nedeni

Kişisel yan projelerde LLM kullanırken iki şey sürekli gözüme battı.

Bunlardan biri maliyet takibiydi.
GPT tabanlı bir tarayıcı eklentisi geliştirirken ay sonunda OpenAI faturasını alıp ilk kez şaşırmam her şeyin başlangıcı oldu. Üniversite öğrencisi olduğum için çok büyük bir tutar değildi ama toplam görünse de hangi özellikten ne kadar maliyet çıktığına ya da hangi modelin ortalama ne kadar token kullandığına dair ayrı bir görünürlük yoktu. Bu yüzden her seferinde koda console.log ekliyor, CSV olarak dışa aktarıp Excel’de topluyor ve model bazlı birim fiyatları çarparak tahmini maliyet çıkarma işini tekrar ediyordum.

Diğeriyse ajan debug süreciydi.
Spanlens’e LangGraph entegrasyonu eklerken bizzat yaşadığım bir durumdu: birden fazla LLM çağrısının karıştığı tek bir trace 30 saniye sürdüğünde

  • zamanın hangi node’da harcandığını
  • aynı aracın neden iki kez çağrıldığını
  • LangGraph state’inin hangi noktada değiştiğini
    görmek için logları açıp elle takip etmek zorunda kalıyordum.

Bu iki sorunu azaltmak istediğim için Spanlens’i yaptım.

Başlıca özellikler

  1. Tek satırlık baseURL entegrasyonu

OpenAI/Anthropic/Gemini SDK’lerinin baseURL değerini https://api.spanlens.io/proxy/openai/v1 gibi bir adrese çevirmeniz yeterli; istekler, yanıtlar, token’lar ve maliyetler otomatik olarak kaydedilir. Yanıtlar doğrudan passthrough olduğu için streaming, tool calling ve JSON mode davranışı da orijinaliyle aynı kalır.

Ajan gibi wrap yaklaşımı gerektiren durumlarda ise SDK üzerinden trace_id, span_id enjekte edilerek parent-child ilişkilerinin de birlikte kaydedilmesini sağladım.

  1. Ajan trace’i + LangGraph topology view

Trace’leri sadece zaman sıralı bir timeline üzerinde değil, gerçek grafik node’larının üstüne bindirilmiş şekilde de gösterir. Eğer ajanınız LangGraph ile yazıldıysa, zamanın hangi node’da harcandığını ve hangi edge’in en sık çalıştığını tek ekranda görebilirsiniz.

  1. Otomatik Critical Path analizi

Bir trace içinde latency’yi en çok yiyen çağrı zinciri otomatik olarak işaretlenir. “Bu trace neden yavaştı?” sorusunun cevabına ulaşmak için gereken tıklama sayısını azaltmaya çalıştım.

  1. Prompts A/B istatistiksel karşılaştırması

Aynı prompt’un iki sürümünü latency, maliyet ve token kullanımı açısından karşılaştırır. Sadece ortalama farkı değil, Welch t-test uygulayarak örneklem varyansını da dikkate alan farkı gösterir. Bunu “ortalama biraz daha düşükmüş” demek yerine “anlamlı bir fark var” diyebilmek için ekledim.

  1. Self-hosting

Docker image ile kendi sunucunuza kurabilirsiniz. SaaS sürümüyle aynı kod, public repository’de aynen yer alıyor. Tüm kod MIT lisanslı.

Nasıl uyguladım

Şu anki pipeline kabaca şöyle çalışıyor.

  • Proxy istekleri Hono ile alınıyor; Authorization header’ı ile X-Spanlens-* metadata’sı ayrıştırılıyor, provider key AES-256-GCM ile çözüldükten sonra yalnızca çağrıdan hemen önce bellekte kullanılıyor.
  • Streaming yanıtlarında body.tee() ile orijinal stream istemciye anında döndürülüyor, kopyası ise arka planda parser tarafından işlenerek token ve maliyet hesaplanıyor.
  • Loglar ClickHouse’a asenkron şekilde yazılıyor. INSERT başarısız olursa Supabase fallback queue içinde tutuluyor ve cron tarafından yeniden deneniyor; yani yapı fire-and-forget olsa da veri kaybını önlemeye çalıştım.
  • Model fiyatları DB tablosunda tutuluyor ve 5 dakikalık TTL stale-while-revalidate ile cache’leniyor. Fallback fiyatı cold start için güvenlik ağı görevi görüyor.

Başta basit bir proxy olarak başlamıştı ama gerçek kullanımda önemli olanın raw loglar değil, normalize edilmiş trace’ler olduğunu gördüm. “Bu trace neden yavaştı?” sorusunun cevabı için sadece çağrı sırası değil; parent-child ilişkileri, paralel çağrılar ve Critical Path de gerekiyor. LangGraph topology view ve otomatik Critical Path gibi özellikler de buradan çıktı.

Kullandığım stack: Next.js 14, Hono, Supabase Postgres, ClickHouse; hepsi TypeScript pnpm monorepo içinde.

Hâlâ düşündüğüm noktalar

  • Self-hosting’i tek satırlık bir docker run komutuna indirmek istiyorum ama bunun için Supabase Postgres’i de birlikte ayağa kaldırmak gerekiyor. Şu anda managed Supabase varsayımıyla docker-compose içinde web, server, ClickHouse olmak üzere 3 container var. Supabase için de self-hosting seçeneği eklemek mi daha doğru olur, yoksa managed varsayımını korumak mı, emin değilim.

  • Prompts A/B karşılaştırmasında Welch t-test hesabı mevcut ama p-value’yu doğrudan göstermek mi daha faydalı olur, yoksa sadece sonuç rozeti (anlamlı/anlamlı değil) göstermek mi daha iyi, karar veremedim. Küçük örneklemlerde (n<30) uyarının nasıl verilmesi gerektiğini de düşünüyorum.

  • LangGraph topology view içinde node, edge ve Critical Path görselleştiriliyor ama state channel değişimleri çok fazla gürültü oluşturduğu için bilinçli olarak dışarıda bıraktım. Gerçek debug sürecinde state değişimlerini takip etmek daha mı gerekli, yoksa mevcut seviye yeterli mi, buna dair görüş duymak isterim.

Bizzat yaşadığım bir rahatsızlıktan yola çıkarak başlayıp düzenli olarak geliştirdiğim bir proje.

[ Spanlens ]
Web: https://www.spanlens.io
GitHub: https://github.com/spanlens/Spanlens
Self-hosting rehberi: https://www.spanlens.io/docs/self-host

Dashboard UX’i, trace görselleştirmesi, proxy entegrasyon yöntemi, self-hosting deneyimi; kısacası hangi açıdan olursa olsun geri bildirim verirseniz gerçekten çok sevinirim. Özellikle OpenAI/Anthropic/Gemini dışında desteklenmesini istediğiniz bir provider varsa lütfen yorumlarda belirtin.

Web sitesinde bir demo sürüm de var; ilginizi bekliyorum.
Şu anda arayüz İngilizce, Türkçe desteği de yakında eklenecek.

Henüz yorum yok.

Henüz yorum yok.