46 रिपॉजिटरीज़ में एक नॉलेज ग्राफ बनाना

मैं airCloset का CTO, रयान हूँ।

मैंने code-graph बनाने में तीन महीने बिताए। यह एक सिंगल नॉलेज ग्राफ है जो कई सेवाओं (services) में फैली 46 रिपॉजिटरीज़ को एक साथ जोड़ता है।

बहुत से लोगों को लगता है कि आप अपना सारा कोड बस एक AI को दे सकते हैं और सवाल पूछ सकते हैं। यह दो कारणों से विफल हो जाता है:

  • कॉन्टेक्स्ट विंडोज़ (Context windows): आप 46 रिपॉजिटरीज़ के वर्षों के कोड को एक प्रॉम्प्ट में नहीं समा सकते।
  • मतिभ्रम (Hallucination): जब AI संबंधों का अनुमान लगाने की कोशिश करता है, तो वह गलतियाँ करता है। वह कनेक्शन मिस कर देता है।

इसे हल करने के लिए, मैंने 'सोर्स ऑफ ट्रुथ' (source of truth) बनाने के लिए स्टैटिक एनालिसिस (static analysis) का उपयोग किया।

चुनौती: सीमाओं को पार करना

एक बड़ा कोडबेस काफी जटिल (messy) होता है। एक API को पाँच अलग-अलग रिपॉजिटरीज़ द्वारा कॉल किया जा सकता है। एक डेटाबेस टेबल का उपयोग तीन अलग-अलग सेवाओं द्वारा किया जा सकता है।

यदि आप केवल एक रिपॉजिटरी को देखते हैं, तो आप पूरी तस्वीर नहीं देख पाते। यह खतरनाक है। यदि आप कोड बदलते हैं और वास्तविक 'ब्लास्ट रेडियस' (blast radius) नहीं देख पाते, तो आप सिस्टम को खराब कर सकते हैं।

मेरा तरीका कोड को सिंटैक्स ट्रीज़ (syntax trees) में पार्स करने के लिए tree-sitter का उपयोग करता है। लेकिन tree-sitter अकेले रिपॉजिटरी की सीमाओं के पार नहीं देख सकता।

मैंने इसे हल करने के लिए 'बाउंड्री नोड्स' (boundary nodes) बनाए।

यह कैसे काम करता है:

  • हम tree-sitter का उपयोग करके एक रिपॉजिटरी के भीतर संबंधों को निकालते हैं।
  • हम टाइप्स और वेरिएबल्स को हल करने के लिए TypeScript Compiler API का उपयोग करते हैं।
  • हम उन डायनेमिक मामलों को संभालने के लिए Gemini का उपयोग करते हैं जिन्हें टूल्स मिस कर देते हैं।

AI से अनुमान लगाने के लिए कहने के बजाय, हम उसे तथ्य (facts) देते हैं। हम उसे बताते हैं: "इस API को Repo X से भी कॉल किया जाता है।" यह मतिभ्रम (hallucinations) को रोकता है।

कठिन हिस्सा: फ्रेमवर्क ज़ू (Framework Zoo)

असली लड़ाई इन सीमाओं को निकालने की थी। हर फ्रेमवर्क सीमाओं को अलग तरह से लिखता है।

एक टीम NestJS decorators का उपयोग करती है। दूसरी Express routes का उपयोग करती है। कोई और raw jQuery का उपयोग करता है। प्रत्येक कोड में एक अलग संरचना बनाता है।

इसे काम करने लायक बनाने के लिए, हमें इनके लिए कस्टम पार्सर बनाने पड़े:

  • NestJS और TypeORM
  • Express और Fastify
  • AngularJS और Redux
  • विभिन्न path-alias स्कीम्स

हमें 99% सटीकता का लक्ष्य रखना था। यदि हमारी कनेक्शन दर केवल 90% है, तो AI 10% कनेक्शन मिस कर देता है। एक प्रोडक्शन सिस्टम में, वह 10% ही वह जगह है जहाँ बग्स छिपे होते हैं।

अब हम रोज़ाना चेक करते हैं। यदि हमारी कनेक्शन दर 5% से अधिक गिरती है, तो हमें अलर्ट मिलता है। यह तब पकड़ लेता है जब नए कोड पैटर्न हमारे पार्सर्स को तोड़ देते हैं।

वर्तमान सीमाएँ

ग्राफ एकदम सही नहीं है।

  • सर्च करना कठिन है। अक्सर अपनी खोज शुरू करने के लिए आपको एक फंक्शन का नाम जानने की आवश्यकता होती है।
  • नोड एक्सप्लोजन (Node explosion)। एक पाथ का अनुसरण करने से हजारों छोटे, बेकार हेल्पर फंक्शन शामिल हो सकते हैं।
  • मेंटेनेंस। हर बार जब हमारे स्टैक में कोई नया फ्रेमवर्क आता है, तो हमें एक नया पार्सर लिखना पड़ता है।

यह भाग 1 है। भाग 2 में, मैं उस service-product-graph (SPG) लेयर के बारे में चर्चा करूँगा जिसे मैंने इन कमियों को दूर करने के लिए बनाया है।

Source: https://dev.to/ryantsuji/building-one-knowledge-graph-across-46-repositories-with-static-analysis-part-1-egm

Optional learning community: https://t.me/GyaanSetuAi