नमस्ते। मैं Spanlens बना रहा हूँ, जो LLM कॉल लॉगिंग, लागत ट्रैकिंग और एजेंट trace को एक ही जगह पर दिखाने वाला एक ओपन सोर्स observability प्लेटफ़ॉर्म है。

इसे बनाने की वजह

जब मैं अपने निजी side project में LLM इस्तेमाल कर रहा था, तो दो चीज़ें बार-बार खटक रही थीं।

एक थी लागत ट्रैकिंग।
GPT-आधारित browser extension बनाते समय, महीने के अंत में OpenAI का बिल पाकर मैं पहली बार सच में चौंक गया था। मैं कॉलेज का छात्र हूँ, इसलिए रकम बहुत बड़ी नहीं थी, लेकिन कुल खर्च तो दिख रहा था—यह नहीं दिख रहा था कि किस feature पर कितना खर्च हुआ, या कौन-सा model औसतन कितने token इस्तेमाल कर रहा है। इसलिए हर बार मुझे code में console.log डालना पड़ता था, CSV export करके Excel में जोड़ना पड़ता था, और model के हिसाब से unit price लगाकर अनुमान निकालना पड़ता था।

दूसरी थी एजेंट debugging।
यह मैंने Spanlens में LangGraph integration जोड़ते समय खुद अनुभव किया। जब कई LLM कॉल मिले हुए एक trace को पूरा होने में 30 सेकंड लगे, तो

  • समय किस node में गया
  • उसी tool को दो बार क्यों बुलाया गया
  • LangGraph state किस बिंदु पर बदला
    इन सबको समझने के लिए logs फैलाकर हाथ से trace करना पड़ता था।

मैं इन दोनों समस्याओं को कम करना चाहता था, इसलिए Spanlens बनाया।

मुख्य फीचर

  1. baseURL की एक-पंक्ति integration

अगर आप OpenAI/Anthropic/Gemini SDK के baseURL को https://api.spanlens.io/proxy/openai/v1 जैसे URL में बदल दें, तो request, response, token और लागत अपने-आप रिकॉर्ड हो जाते हैं। response वैसा ही passthrough रहता है, इसलिए streaming, tool calling, JSON mode—सब कुछ मूल SDK की तरह ही काम करता है।

अगर agent की तरह wrap-आधारित तरीका चाहिए, तो SDK के जरिए trace_id, span_id inject किए जा सकते हैं, ताकि parent-child relation भी साथ में रिकॉर्ड हो सके।

  1. एजेंट trace + LangGraph topology view

trace को सिर्फ समय-क्रम timeline में नहीं, बल्कि वास्तविक graph node के ऊपर overlay करके भी देखा जा सकता है। अगर agent LangGraph से बना है, तो एक ही स्क्रीन पर दिखता है कि समय किस node में गया और कौन-सा edge सबसे ज़्यादा बार चला।

  1. Critical Path का automatic analysis

trace के अंदर latency सबसे ज़्यादा लेने वाली call chain अपने-आप highlight हो जाती है। हमारा लक्ष्य यह था कि “यह trace धीमा क्यों था?” का जवाब ढूँढने के लिए कम click करने पड़ें।

  1. Prompts A/B सांख्यिकीय तुलना

एक ही prompt के दो version को latency, लागत और token उपयोग के आधार पर compare किया जा सकता है। यह सिर्फ average का अंतर नहीं दिखाता, बल्कि Welch t-test लागू करके sample variance सहित अंतर दिखाता है। इसे इसलिए जोड़ा कि आप सिर्फ “average थोड़ा कम है” न कहें, बल्कि “यह अंतर statistically meaningful है” भी कह सकें।

  1. Self-hosting

इसे Docker image के रूप में अपने server पर चलाया जा सकता है। SaaS version वाला वही code public repository में उपलब्ध है। पूरा code MIT license के तहत है।

इसे कैसे बनाया गया

फिलहाल pipeline लगभग इस तरह काम करती है।

  • Proxy request को Hono से receive किया जाता है, फिर Authorization header और X-Spanlens-* metadata को अलग किया जाता है, और provider key को AES-256-GCM से decrypt करके call से ठीक पहले केवल memory में इस्तेमाल किया जाता है।
  • Streaming response में body.tee() के जरिए original stream तुरंत client को लौटा दी जाती है, और उसकी copy को background parser token और लागत की गणना के लिए इस्तेमाल करता है।
  • Logs को ClickHouse में asynchronously insert किया जाता है। अगर INSERT fail हो जाए, तो Supabase fallback queue में सुरक्षित रखा जाता है और cron बाद में retry करता है। यानी यह fire-and-forget है, लेकिन डेटा लॉस से बचने की कोशिश की गई है।
  • Model pricing DB table में रखी जाती है और 5-मिनट TTL stale-while-revalidate caching के साथ cache की जाती है। Fallback pricing cold start के लिए safety net का काम करती है।

शुरुआत में यह सिर्फ एक simple proxy था, लेकिन इस्तेमाल करते-करते समझ आया कि raw logs से ज़्यादा महत्वपूर्ण normalized trace है। “यह trace धीमा क्यों था?” का जवाब पाने के लिए सिर्फ call order नहीं, बल्कि parent-child relation, parallel calls और Critical Path भी चाहिए। वहीं से LangGraph topology view और automatic Critical Path जैसे फीचर आए।

Stack है Next.js 14, Hono, Supabase Postgres, ClickHouse, और सब कुछ TypeScript pnpm monorepo में है।

जिन बातों पर अभी सोच रहा हूँ

  • मैं self-hosting को एक-पंक्ति docker run जितना आसान बनाना चाहता हूँ, लेकिन इसके लिए Supabase Postgres को भी साथ में चलाना होगा। अभी managed Supabase को मानकर docker-compose में web, server, ClickHouse—ये 3 container हैं। अब सोच रहा हूँ कि Supabase के लिए भी self-hosting option बनाना बेहतर होगा, या managed setup को ही आधार बनाए रखना चाहिए।

  • Prompts A/B comparison में Welch t-test calculation तो शामिल है, लेकिन यह तय नहीं कर पाया हूँ कि p-value सीधे दिखाना उपयोगी होगा या सिर्फ निष्कर्ष badge (significant / not significant) दिखाना बेहतर होगा। छोटे sample size (n<30) पर warning कैसे दिखानी चाहिए, इस पर भी सोच रहा हूँ।

  • LangGraph topology view में node, edge और Critical Path दिखाए जाते हैं, लेकिन state channel में बदलाव बहुत noisy थे, इसलिए उन्हें जानबूझकर बाहर रखा है। असली debugging में state changes को track करना ज़्यादा ज़रूरी है या मौजूदा स्तर पर्याप्त है—इस पर आपकी राय जानना चाहूँगा।

यह एक ऐसा project है जो मेरी अपनी असुविधा से शुरू हुआ और जिसे मैं लगातार निखार रहा हूँ।

[ Spanlens ]
वेब: https://www.spanlens.io
GitHub: https://github.com/spanlens/Spanlens
Self-hosting guide: https://www.spanlens.io/docs/self-host

Dashboard UX, trace visualization, proxy integration, self-hosting experience—किसी भी दृष्टिकोण से feedback देंगे तो मैं सच में आभारी रहूँगा। खासकर अगर OpenAI/Anthropic/Gemini के अलावा कोई और provider है जिसे आप support में देखना चाहते हैं, तो कृपया comment में बताइए।

वेबसाइट पर demo version उपलब्ध है, कृपया ज़रूर देखें।
फिलहाल UI अंग्रेज़ी में है, और हिंदी समर्थन भी जल्द जोड़ा जाएगा।

अभी कोई टिप्पणी नहीं है.

अभी कोई टिप्पणी नहीं है.