सामग्री पर जाएँ
cd /blog

मल्टी-मोडल फ़्यूज़न सर्च: हर क्वेरी के लिए सही रिट्रीवर चुनना

[खोज][आर्किटेक्चर]

> "parseConfig कहां परिभाषित है" जैसी क्वेरी को "auth कैसे काम करता है" से अलग तरह की सर्च चाहिए। Maguyva इंटेंट को वर्गीकृत करता है, उसके हिसाब से चार रिट्रीवल मोडैलिटी को वेट देता है, और नतीजों को वेटेड Reciprocal Rank Fusion से जोड़ता है।

सर्च क्वेरी कोई एक चीज़ नहीं होती।

parseConfig कहां परिभाषित है” को एक सटीक सिंबल चाहिए — एक सटीक लोकेशन, तेज़ी से। “authentication कैसे काम करता है” को अर्थ चाहिए — संबंधित कोड का वह फैलाव जो किसी अवधारणा को समझाता है। “अगर मैं यह फ़ंक्शन बदलूं तो क्या टूटता है” को डिपेंडेंसी ग्राफ चाहिए। “स्ट्रिंग ECONNREFUSED खोजें” को एक लिटरल मैच चाहिए, कुछ भी चतुराई भरा नहीं।

grep लिटरल मैच के लिए बेहतरीन है और कुछ रेफ़रेंस खोजों के लिए उपयोगी है, लेकिन यह कोई डिपेंडेंसी ग्राफ नहीं है और यह अर्थ नहीं समझता। एम्बेडिंग सिमेंटिक पक्ष को कवर करती हैं, लेकिन ये सटीक स्ट्रिंग और इम्पैक्ट विश्लेषण के लिए ग़लत टूल हैं। ज़्यादातर कोड सर्च टूल एक इंजन चुनते हैं और हर क्वेरी को उसी चुनाव के साथ जीने पर मजबूर करते हैं। Maguyva नहीं चुनता। यह पता लगाता है कि आपने किस तरह का सवाल पूछा, फिर उस सवाल के हक़दार अनुपात में चार रिट्रीवर को मिलाता है।

चार मोडैलिटी

अंदरखाने, कोड खोजने के चार स्वतंत्र तरीक़े हैं:

  • semantic — Voyage बाइनरी एम्बेडिंग पर वेक्टर सर्च; अर्थ के आधार पर कोड खोजता है।
  • text — ट्राइग्राम मैचिंग; लिटरल, एरर स्ट्रिंग, सटीक आइडेंटिफ़ायर खोजता है।
  • structural — AST क्वेरी; परिभाषाएं, सिग्नेचर, और भाषा निर्माण खोजता है।
  • ग्राफ़ — डिपेंडेंसी ग्राफ; कॉलर, कैली, और ब्लास्ट रेडियस खोजता है।

हर एक अलग तरह के सवाल पर मज़बूत है। तरक़ीब यह तय करने में है कि आपके सामने वाली क्वेरी के लिए किस पर कितना भरोसा किया जाए।

इंटेंट क्लासिफ़िकेशन

किसी भी रिट्रीवल के चलने से पहले, एक हल्का क्लासिफ़ायर क्वेरी को छह इंटेंट में से एक में, एक कॉन्फ़िडेंस स्कोर के साथ छांटता है। यह जानबूझकर सस्ता है — क्रमबद्ध हेयुरिस्टिक्स, पहला मैच जीतता है — क्योंकि यह हॉट पथ पर चलता है और सिर्फ़ एक-दो मिलीसेकंड जोड़ता है:

  • def , class , func , import … से शुरू होता है → find_definition (कॉन्फ़िडेंस 0.95)
  • “who calls”, “usages of”, “references to” → find_references (0.90)
  • “impact”, “blast radius”, “what depends on” → impact_analysis (0.90)
  • कोई कोटेड "string" या traceback जैसा कोई एरर टोकन → exact_match (0.85–0.90)
  • एक CamelCase या snake_case आइडेंटिफ़ायर → find_definition (0.60–0.80)
  • “how”, “why”, “explain”, “architecture” → understand_code (0.75)
  • कुछ भी मैच नहीं होता → understand_code, कम कॉन्फ़िडेंस (0.40)

हर इंटेंट चार मोडैलिटी में एक वेट प्रोफ़ाइल रखता है। ये असली आंकड़े हैं:

मंशा semantic text structural (AST) ग्राफ़
find_definition 0.2 0.1 0.6 0.1
find_references 0.1 0.2 0.2 0.5
understand_code 0.5 0.2 0.2 0.1
find_similar 0.4 0.3 0.2 0.1
impact_analysis 0.1 0.1 0.1 0.7
exact_match 0.0 0.9 0.1 0.0

तो “parseConfig कहां परिभाषित है” ज़ोरदार तरीक़े से AST (0.6) पर झुकता है। “auth कैसे काम करता है” सिमेंटिक वेक्टर (0.5) पर झुकता है। “इस पर क्या निर्भर करता है” लगभग पूरी तरह ग्राफ़ (0.7) है। “ECONNREFUSED खोजें” लगभग पूरी तरह ट्राइग्राम (0.9) है, एम्बेडिंग मॉडल पूरी तरह बंद के साथ — क्योंकि सिमेंटिक समानता किसी सटीक स्ट्रिंग के लिए ठीक ग़लत टूल है।

तेज़ पथ, और फ़्यूज़्ड पथ

जब क्लासिफ़ायर आश्वस्त हो — स्कोर ≥ 0.85 — और क्वेरी सामान्य हो, तो Maguyva फ़्यूज़न को पूरी तरह छोड़ देता है और सीधे एकल प्रभावी मोडैलिटी की ओर रूट करता है। “X कहां परिभाषित है” को चार रिट्रीवर की ज़रूरत नहीं; इसे अभी AST इंडेक्स चाहिए। वह डायरेक्ट पथ fusion_strategy: "direct" के रूप में वापस रिपोर्ट किया जाता है।

जो कुछ भी अस्पष्ट है वह फ़्यूज़न से गुज़रता है। चारों (या डिफ़ॉल्ट प्रीसेट पर तीनों) मोडैलिटी समानांतर में चलती हैं, हर एक अपनी ख़ुद की रैंक्ड लिस्ट लौटाती है, और हम उन्हें मिलाते हैं।

वेटेड Reciprocal Rank Fusion

विषम रिट्रीवर को मिलाना सुनने से कहीं ज़्यादा मुश्किल है: 0.82 का कोसाइन सिमिलैरिटी और 137 का ट्राइग्राम स्कोर और 0.004 की ग्राफ सेंट्रैलिटी एक ही पैमाने पर नहीं हैं, तो आप उन्हें बस जोड़ नहीं सकते। Reciprocal Rank Fusion कच्चे स्कोर को फेंककर और सिर्फ़ हर इंजन द्वारा दी गई रैंक को रखकर इस समस्या को टाल देता है। किसी एक मोडैलिटी से किसी नतीजे का योगदान यह है:

contribution = weight × 1 / (k + rank + 1)

जहां rank उस मोडैलिटी की लिस्ट में उसकी पोज़िशन है और k एक स्मूदिंग कॉन्स्टेंट है। ऐसे किसी भी नतीजे के लिए, जिसे एक से ज़्यादा इंजन ने खोजा हो, योगदान मोडैलिटी में जोड़े जाते हैं — रिट्रीवर के बीच सहमति स्वाभाविक रूप से ऊपर तैर आती है। हम डिफ़ॉल्ट प्रीसेट पर k = 40 और thorough पर 60 इस्तेमाल करते हैं (quick सिर्फ़-सिमेंटिक चलता है, तो वहां फ़्यूज़न कभी शुरू नहीं होता)। मूल RRF काम सामान्य-प्रयोजन रिट्रीवल के लिए k = 60 पर पहुंचा था; हम थोड़ा तीखा डिफ़ॉल्ट रखते हैं, जो मोडैलिटी के बीच टॉप-रैंक्ड सहमति को थोड़ा ज़्यादा वेट देता है — और हम इसे हाथ से ट्यून करने की सलाह नहीं देते।

इसके ऊपर, नतीजे एक ग्राफ-इम्पॉर्टेंस बूस्ट लेकर चलते हैं। एक हब — एक ऐसा फ़ंक्शन जिस पर पूरा कोडबेस निर्भर करता है — को उसी टेक्स्चुअल रेलेवेंस पर भी किसी अस्पष्ट लीफ़ से आगे निकलना चाहिए, तो हम हर योगदान को इससे गुणा करते हैं:

boost = min(1 + 0.3 × ln(1 + centrality), 1.5)

सेंट्रैलिटी पाइपलाइन के प्री-कंप्यूटेड PageRank/डिग्री मेट्रिक्स से आती है, और बूस्ट को 1.5× पर क्लैम्प किया गया है ताकि कोई लोकप्रिय फ़ंक्शन किसी ज़्यादा प्रासंगिक अस्पष्ट फ़ंक्शन को पूरी तरह दबा न सके। आख़िर में हम vendor, build, और archive पथों से आने वाले नतीजों को डिमोट करते हैं, और प्रति फ़ाइल सबसे अच्छे चंक तक डिड्यूप करते हैं।

अब भी क्या अधूरा है

इंटेंट क्लासिफ़ायर रेगेक्स का एक ढेर है, कोई लर्न्ड मॉडल नहीं। यह क्वेरी के आम आकारों को अच्छी तरह कवर करता है — जिस डिसीज़न ने इसे शुरू किया उसने ज़ीरो-रिज़ल्ट रेट को लगभग 15% से घटकर 5% से नीचे आते दर्ज किया — लेकिन यह हेयुरिस्टिक है, और एक सचमुच अस्पष्ट क्वेरी understand_code और एक सिमेंटिक-झुकाव वाले मिश्रण में गिर जाती है। यह एक सुरक्षित डिफ़ॉल्ट है, कोई चतुर डिफ़ॉल्ट नहीं। हमने इसे किसी ट्रेंड क्लासिफ़ायर से नहीं बदला क्योंकि सस्ता वर्ज़न तेज़ और काफ़ी अच्छा है, और क्योंकि एक ग़लत-लेकिन-आश्वस्त क्लासिफ़ायर एक ईमानदार फ़ॉलबैक से बदतर है। वेट ख़ुद हाथ से चुने गए प्रायर हैं, किसी क्लिक डेटा से लर्न नहीं किए गए जिसे हम इकट्ठा नहीं करते।

सवाल पूछें, टूल नहीं

किसी एजेंट को यह जानने की ज़रूरत नहीं होनी चाहिए कि grep, एम्बेडिंग, या कॉल ग्राफ में से किसका सहारा लें — उसे अपना सवाल सीधे शब्दों में पूछना चाहिए और सही जवाब पाना चाहिए। मल्टी-मोडल फ़्यूज़न ही है जो find_symbol, सिमेंटिक सर्च, और डिपेंडेंसी विश्लेषण को एक क्वेरी सरफ़ेस के पीछे बिठाता है: सिस्टम सवाल के आकार को पढ़ता है और चुपचाप उसके लिए सही रिट्रीवर जोड़ देता है। जो मॉडल एम्बेडिंग को स्कोर करता है वह मायने रखता है, लेकिन यह जानना भी मायने रखता है कि उन्हें कब इस्तेमाल न करें। हर क्वेरी के लिए सही टूल चुनना अपने आप में एक तरह की क्वालिटी है, और हम इसे कॉलर पर थोपने के बजाय ख़ुद संभालना पसंद करते हैं।

// you bring the question. it brings the tools.

जुड़ी हुई रीडिंग

Maguyva की बिल्ड लॉग से और लेख

हमने कोड सर्च को voyage-4-large में क्यों अपग्रेड किया_

हमने अपनी कोड एम्बेडिंग को voyage-4-large पर शिफ़्ट किया — जो फ़िलहाल पब्लिक RTEB कोड रिट्रीवल लीडरबोर्ड में शीर्ष पर है। ईमानदार वर्ज़न: वह ट्रेड-ऑफ़ जो हम करते हैं, हम वास्तव में क्या इंडेक्स करते हैं, और हम प्रीमियम एम्बेडिंग के लिए भुगतान क्यों करते हैं।

[एम्बेडिंग][खोज][आर्किटेक्चर]

भाषा आवर्ती स्व-सुधार: लगभग 280 भाषाओं में कोड इंटेलिजेंस को अनथक मेहनत से निखारना_

हम लगभग 280 भाषाओं के लिए कोड इंटेलिजेंस सपोर्ट करते हैं। कोई इंसान इसका हाथ से ऑडिट नहीं कर सकता। इसलिए हमने एक भाषा आवर्ती स्व-सुधार लूप बनाया — स्पॉट-चेक, LLM-as-judge, एक चीज़ ठीक करो, दोबारा वैलिडेट करो — और इसे आइसोलेटेड एजेंट्स के एक फ़्लीट के साथ तब तक चलाते हैं जब तक एक्सट्रैक्शन वास्तव में सही न हो जाए, सिर्फ़ ग्रीन न हो।

[आर्किटेक्चर][भाषाएँ][एजेंट्स]

एजेंट ऑब्ज़र्वेबिलिटी: Hooks, Alloy, और Grafana_

हमने Claude Code और Codex को OpenTelemetry और Alloy के साथ एक ही Grafana स्टैक में जोड़ा, फिर एजेंट व्यवहार की समस्याओं को उनके स्रोत पर खोजने और ठीक करने के लिए ट्रेस और लॉग का उपयोग किया।

[ऑब्ज़र्वेबिलिटी][Grafana][OpenTelemetry][आर्किटेक्चर]