दो नंबरों ने मुझे इस बेंचमार्क पर वापस भेजा। codebase-memory-mcp, जो MCP पर परोसा जाने वाला tree-sitter आधारित कोड ग्राफ़ है, उसका README 99% कम टोकन का वादा करता है। मेरे अपने पिछले रन के मुताबिक़ cbm-lean, जो मैंने उसके चारों ओर लिखा एक पतला रैपर है, कोडिंग एजेंट को haiku पर सादे grep से 26% और sonnet पर 18% सस्ता बनाता था। पहला नंबर मैं कभी दोहरा नहीं सका, और दूसरा मेरे सेटअप की एक ख़ामी से आया था। यह सार्वजनिक रिपॉज़िटरी पर दोबारा किया गया रन है, जिसमें वह ख़ामी ठीक कर दी गई है।
सेटअप
हर सवाल तीन विकल्पों में चलाया गया:
- cbm-lean, साथ में सिस्टम प्रॉम्प्ट में एक रूटिंग नियम: संरचना वाले सवाल ग्राफ़ के पास जाते हैं, सटीक स्ट्रिंग वाले Grep के पास;
- कच्चा codebase-memory-mcp सर्वर, साथ में वही नियम;
- सिर्फ़ Read, Grep और Glob।
हर रिपॉज़िटरी को बारह सवाल मिले। छह संरचना वाले हैं: किसी फ़ंक्शन को कौन बुलाता है, वह क्या बुलाता है, किसी HTTP एंडपॉइंट से डेटाबेस में लिखने तक की कॉल चेन, मॉड्यूल की बनावट। छह सटीक हैं: कोई कॉन्फ़िग मान, कोई एनवायरनमेंट वेरिएबल कहाँ पढ़ा जाता है, कोई एरर संदेश, वह लाइन जहाँ कोई क्लास परिभाषित है। हर सवाल के साथ उन सबस्ट्रिंग की सूची है जो सही जवाब में होनी चाहिए, और मैंने हर एक को हाथ से कोड के सामने जाँचा।
रिपॉज़िटरी में तीन छोटी हैं (FastAPI फ़ुल-स्टैक टेम्पलेट, ltx-2-mlx और avoid-ai-writing, 1.6k से 5k ग्राफ़ नोड) और dub, 25k नोड वाली एक Next.js मोनोरिपो। Haiku 4.5 सब पर चला और sonnet 5 dub पर: 252 रन, API क़ीमतों पर $14.69।
लागत tokenEquiv के रूप में मापी गई: इनपुट टोकन, जमा 1.25 × कैश राइट, जमा 0.1 × कैश रीड। प्रॉम्प्ट कैशिंग चालू होने पर कच्चा बिल किया गया इनपुट भ्रामक होता है, क्योंकि जो विकल्प संयोग से गर्म कैश पर चलता है, वह ऐसे कारणों से सस्ता दिखता है जिनका उस विकल्प से कोई लेना-देना नहीं।
नतीजे
प्रति रन मध्यिका tokenEquiv, कोष्ठक में सही जवाबों की संख्या:
| परिस्थिति | रन | cbm-lean | कच्चा ग्राफ़ | grep |
|---|---|---|---|---|
| छोटी रिपॉज़िटरी, haiku 4.5 | 108 | 30,321 (28/36) | 43,846 (32/36) | 31,159 (33/36) |
| dub, haiku 4.5 | 72 | 18,791 (22/24) | 20,687 (22/24) | 14,955 (20/24) |
| dub, sonnet 5 | 72 | 17,227 (22/24) | 23,085 (22/24) | 13,348 (22/24) |
तीन नतीजे टिकते हैं:
- टोकन पर ग्राफ़ कभी नहीं जीता। grep के मुक़ाबले छोटी रिपॉज़िटरी पर (p = 0.13) और haiku के साथ dub पर (p = 0.18) कोई मापने लायक़ फ़र्क़ नहीं था, और sonnet के साथ dub पर grep 12 में से 11 सवालों पर सस्ता था (p = 0.034), उतनी ही सटीकता के साथ, हर विकल्प में 24 में से 22।
- रैपर ने हर परिस्थिति में कच्चे सर्वर को हराया (p ≤ 0.021)। कच्चा सर्वर हर सर्च हिट पर लगभग 1.3 KB लौटाता है, जिसमें ज़्यादातर आइडेंटिफ़ायर डंप और हैश वेक्टर होते हैं, और cbm-lean एक हिट को लगभग 250 बाइट तक छाँट देता है।
- ग्राफ़ की एकमात्र साफ़ जीत बड़ी रिपॉज़िटरी पर छोटे मॉडल की सटीकता थी। Haiku ने dub पर संरचना वाले सवालों का सही जवाब ग्राफ़ के साथ 12 में से 12 बार और grep के साथ 12 में से 8 बार दिया, 23.5k के मुक़ाबले 16.0k टोकन की मध्यिका पर।
p मान हर सवाल की मध्यिकाओं पर Wilcoxon signed-rank टेस्ट से आते हैं।
हर विकल्प कहाँ ग़लत हुआ
- ग्राफ़ से मिले लाइन नंबर। किसी एरर संदेश की लाइन पूछे जाने पर ग्राफ़ वाले विकल्प ने जवाब ग्राफ़ के आउटपुट से पढ़ा और login.py:33 बताया; raise लाइन 34 पर है, और 33 उसके ऊपर वाला if है। उसने एक ऐसी क्लास के लिए config.py:74 बताया जिसे ग्राफ़ खुद लाइन 15 से 88 पर रखता है, और लाइन 59 पर परिभाषित एक क्लास के लिए client.ts:129। रूटिंग नियम ने उससे सटीक सवालों के लिए grep करने को कहा था, और haiku ने हमेशा उसका पालन नहीं किया।
- एक जैसे नाम। FastAPI टेम्पलेट में create_user नाम के दो हैंडलर हैं। एडमिन एंडपॉइंट के बारे में पूछे जाने पर दोनों ग्राफ़ वाले विकल्पों ने 6 में से 5 रन में बिना ऑथेंटिकेशन वाले हैंडलर को ट्रेस किया। Grep ने हर बार सुपरयूज़र जाँच के पीछे वाला हैंडलर ढूँढा।
- जल्दी रुक जाना। dub पर grep वाले haiku ने कॉल चेन के आख़िर में डेटाबेस में असली लिखाई को दो बार छोड़ दिया।
- मेरी अपनी जाँच। हर विकल्प में, sonnet के हर रन ने dub की आर्किटेक्चर वाले जवाब में packages/tinybird को छोड़ दिया। उस फ़ोल्डर में Tinybird की डेटा फ़ाइलें हैं और कोई package.json नहीं है, इसलिए कहा जा सकता है कि मॉडल सही थे और मेरी जाँच नहीं। sonnet की सभी छह चूकें इसी एक सवाल पर हैं, और इसे हटाने से कोई तुलना नहीं बदलती।
ग्राफ़ जोड़ देना उसका इस्तेमाल करना नहीं है
सबसे काम का नतीजा मुख्य रन से नहीं, पायलट से आया। Claude Code 2.1.283 डिफ़ॉल्ट रूप से MCP टूल के स्कीमा को एक ToolSearch चरण के पीछे टाल देता है: मॉडल को टूल के नाम दिखते हैं, और कुछ भी बुलाने से पहले उसे स्कीमा लाने पड़ते हैं। हेडलेस haiku ने ऐसा नहीं किया। छह पायलट रन में, रूटिंग नियम के साथ या बिना, ग्राफ़ एक बार भी नहीं बुलाया गया। छोटी रिपॉज़िटरी के बारह सवालों पर:
| सेटअप | ग्राफ़ बुलाया | सही | मध्यिका tokenEquiv |
|---|---|---|---|
| डिफ़ॉल्ट लोडिंग, नियम के साथ | 12 में से 2 | 12 में से 11 | 41,008 |
| स्कीमा लोड, बिना नियम | 12 में से 4 | 12 में से 9 | 62,008 |
| स्कीमा लोड, नियम के साथ | 36 में से 22 | 36 में से 28 | 30,321 |
स्कीमा लोड होने पर (ENABLE_TOOL_SEARCH=false), कॉल करने वालों वाला वही सवाल तीन टर्न में दो ग्राफ़ कॉल से होकर गया। बिना नियम के जुड़ा ग्राफ़ सबसे महँगा सेटअप था: हर सत्र स्कीमा की क़ीमत चुकाता है, और मॉडल ज़्यादातर उन्हें बिना इस्तेमाल के छोड़ देता है।
अगर आप कोई MCP सर्वर जारी करते हैं और उसे डिफ़ॉल्ट सेटिंग में टेस्ट करते हैं, तो पहले देखिए कि मॉडल उसे बुलाता भी है या नहीं।
पहले वाला नंबर ग़लत क्यों था
पहला बेंचमार्क मेरे प्रोजेक्ट फ़ोल्डर के अंदर चला था। उसकी CLAUDE.md ने एजेंट से संरचना वाले सवालों के लिए ग्राफ़ इस्तेमाल करने को कहा था, और Claude Code पैरेंट डायरेक्टरी से भी CLAUDE.md फ़ाइलें लोड करता है, इसलिए वह निर्देश हर विकल्प तक पहुँचा, उस विकल्प तक भी जिसमें ग्राफ़ था ही नहीं। नियंत्रण समूह को ट्रीटमेंट समूह के निर्देश मिल गए थे, यानी तुलना ने टूल जितना ही नियम को भी मापा।
दोबारा रन में रिपॉज़िटरी किसी भी ऐसे ट्री के बाहर रखी गई हैं जिसके ऊपर CLAUDE.md हो, यूज़र सेटिंग और हुक छोड़ दिए
गए हैं (--setting-sources project), और नियम सिर्फ़ उन विकल्पों को दिया गया है जिनके पास ग्राफ़ है। बाक़ी हर
नियंत्रण ने किसी पिछले दौर के एक ग़लत निष्कर्ष को ठीक किया। Bash और Agent हर विकल्प में मना हैं, क्योंकि सीमित
Bash अनुमतियाँ पाइप वाले कमांड से मेल नहीं खातीं, और सबएजेंट टोकन ख़र्च करते हुए भी टर्न छिपा लेते हैं। विकल्पों
का क्रम हर दोहराव के बीच बदलता है, इसलिए कोई विकल्प हमेशा गर्म कैश पर नहीं चलता। जो रन किसी ऐसे टूल को बुलाता
है जो उसके विकल्प का नहीं है, उसे हटा दिया जाता है। और जवाबों की जाँच होती है, क्योंकि ग़लत जवाब पर बचाए गए टोकन
बचत नहीं हैं।
ग्राफ़ को एजेंट से जोड़ रही टीम से मैं क्या कहूँगा
- 25k नोड तक की रिपॉज़िटरी पर Claude मॉडल के साथ कोड ग्राफ़ से टोकन बचत की उम्मीद न करें। पहले अपने सवालों पर मापें।
- फिर भी जोड़ें, तो उसका आउटपुट छाँटें, उसके स्कीमा लोड करें और एजेंट को एक रूटिंग नियम दें। आख़िरी दो के बिना वह हर प्रॉम्प्ट में बेकार बोझ है।
- मॉडल जो लाइन नंबर ग्राफ़ के नतीजों से पढ़ता है, उन पर भरोसा न करें, उन्हें grep से जाँचें।
- ग्राफ़ तब अपनी जगह कमाता है जब कोई छोटा मॉडल किसी बड़े कोडबेस पर संरचना वाले सवालों का जवाब देता है: आर्किटेक्चर और कॉल चेन।
सीमाएँ
दो मॉडल, 25k नोड तक की चार रिपॉज़िटरी, दो या तीन दोहराव, हर एक में बारह सवाल। कोई Opus नहीं, कोई लंबा इंटरैक्टिव सत्र नहीं, 25k नोड से आगे कुछ नहीं। मध्यिकाएँ इसलिए दी गई हैं क्योंकि एक ही सवाल के दोहराए गए रन में बहुत अंतर था।
दोहराएँ
सब कुछ code-graph-vs-grep में है: पिन किए गए कमिट के साथ सवाल, बेंचमार्क ड्राइवर, हर जवाब के साथ कच्चे रन, और खुद cbm-lean।
bash bench/setup.sh
node bench/run.mjs --reps 3
python3 bench/stats.py results/*.json