- स्वायत्त coding agents के मूल्यांकन अब तक मुख्यतः fixed codebase में task success rate देखते रहे हैं, लेकिन यह अध्ययन अलग से मापता है कि code की cleanliness exploration और modification cost को बदलती है या नहीं
- architecture, dependencies और external behavior समान रखते हुए, केवल SonarQube rule violations और cognitive complexity में अंतर वाले 6 minimal-pair repositories और hidden tests पर आधारित 33 tasks बनाए गए
- Claude Code और Claude Sonnet 4.6 के साथ हर task को repository pair के दोनों पक्षों पर 10-10 बार चलाकर कुल 660 experiments किए गए; agent को यह पता नहीं था कि वह किस तरह के code पर काम कर रहा है
- code cleanliness ने pass rate नहीं बदला, लेकिन साफ code में token-equivalent metrics 7~8% घटे और file revisits 34% कम हुए
- model या prompt ही नहीं, codebase की हालत भी agent की computation cost और exploration efficiency को प्रभावित करने वाला एक व्यावहारिक variable बनी रहती है
शोध प्रश्न और समस्या सेटअप
- स्वायत्त coding agents तेजी से फैल रहे हैं
- 2026 में 128,018 GitHub projects के सर्वे में, पहले practical agent के release के एक साल से भी कम समय बाद 22~29% projects में agent activity के निशान मिले
- agent execution cost भी कम नहीं है
- SWE-bench Verified में एक single task frontier LLM के आधार पर औसतन लगभग 4 million tokens इस्तेमाल करता है
- कुल usage में input tokens का हिस्सा सबसे बड़ा होता है
- मौजूदा evaluations SWE-bench जैसे benchmarks में task हल हुआ या नहीं पर केंद्रित रहे हैं, और हाल के studies pass rate के साथ resource usage भी मापने लगे हैं
- आम तुलना का तरीका codebase को fixed रखकर agent या scaffolding बदलना था
- यह अध्ययन उल्टा agent और tasks को fixed रखकर केवल codebase cleanliness बदलकर तुलना करता है
code cleanliness और minimal-pair निर्माण
- code cleanliness को maintainable code से जुड़ी खूबियों के समूह के रूप में लिया गया
- पढ़ने में आसान होना
- कम cognitive complexity
- अच्छी तरह अलग किए गए helpers
- स्पष्ट names
- कम dead code, duplicate logic और accidental coupling
- अध्ययन code cleanliness की कोई सख्त formal definition तय नहीं करता, बल्कि SonarQube static analysis rule violations की संख्या को loosely proxy metric के रूप में इस्तेमाल करता है
- इस्तेमाल किया गया tool SonarQube Cloud Enterprise Edition है
- rule set “default quality gate” है
- minimal-pair repositories में केवल internal cleanliness अलग है, और नीचे की शर्तें समान रखी गईं
- वही language और framework
- वही dependencies
- वही tests या equivalent test coverage
- वही external behavior
- behavior equivalence का मतलब समान input पर externally observable output और state transitions का समान होना माना गया
- वास्तविक verification समान test suite को समान coverage के साथ pass करने, या refactoring जैसी externally unobservable changes को adjust करने वाले paired tests pass करने के रूप में किया गया
minimal-pair generation pipeline: Slopify और Vibeclean
- minimal pairs दोनों दिशाओं में बनाए गए
- clean repository को ज्यादा messy बनाने वाला Slopify
- messy repository को साफ करने वाला Vibeclean
-
Slopify
- clean codebase को ऐसे version में बदलता है जैसे वह code review या linting के बिना grow हुआ हो
- लक्ष्य जानबूझकर broken code बनाना नहीं, बल्कि static analysis न होने पर उसकी alternative-history version बनाना है
- तीन stages अलग-अलग नए agents द्वारा किए गए
- Build: repository build करना, tests pass करवाना, फिर commands को
build instructions.mdमें pin करना - Explore: repository scan करना और cleanup target directories के लिए
summary.mdलिखना - Transform: चुनी गई directory में SonarQube rule violations introduce करना, और हर pass के बाद tests फिर से चलाकर broken changes reject करना
- Build: repository build करना, tests pass करवाना, फिर commands को
- helper inlining, path-wise logic duplication, dead code जोड़ना, कुछ modules को single file में merge करना आदि से cognitive complexity बढ़ाई गई
-
Vibeclean
- स्वाभाविक रूप से rule violations अधिक वाले codebase को external behavior बनाए रखते हुए साफ करता है
- agent की task list analyzer द्वारा पकड़ी गई issues की list होती है, और हर issue code range से जुड़ी होती है
- modification scope analyzer द्वारा दिखाए गए issues तक सीमित रहता है; पूरा redesign लक्ष्य नहीं है
- यह दो stages में काम करता है
- Build: build और test commands verify करना और
build instructions.mdमें pin करना - Clean: module-wise analyzer rule violations को mechanically साफ करना, और module processing के बाद tests से behavior equivalence verify करना
- Build: build और test commands verify करना और
- duplicated string literals हटाना, commented-out code delete करना, legacy collection idioms बदलना, dead branches हटाना आदि करता है
- जब analyzer ने सचमुच बड़ी structures को flag किया, तो 200+ line dispatch switch को named helpers में बदला गया, या 2,800-line class से persistence helper extract किया गया
- हालांकि extraction complexity को हटाने के बजाय उसे ज्यादा methods में redistribute कर सकता है, और कुछ सबसे बड़े विशाल structures
wontfixके रूप में बचे रहे
benchmark repositories और task design
- benchmark Harbor framework v0.4.0 पर बनाया गया
- कुल 6 minimal-pair repositories इस्तेमाल किए गए
- 3 Java-focused, 3 Python-focused
- कुछ repositories में अन्य languages का थोड़ा code भी शामिल है
- 3 public open-source repositories और 3 private SonarSource codebases शामिल हैं
- private pairs evaluation target LLM के public repositories से train हो चुके होने की संभावना के खिलाफ memorization prevention का काम करते हैं
- हर repository के clean side और messy side के मुख्य numbers ये हैं
sonar-sca*: issues 94 / 2,825, issue density 0.73 / 20.66, cognitive complexity density 30.6 / 56.5sonar-caas-poc*: issues 16 / 855, issue density 0.61 / 27.16, cognitive complexity density 179.8 / 218.9sonarcloud-codedatalake*: issues 199 / 1,319, issue density 4.36 / 34.39, cognitive complexity density 34.0 / 216.5commons-bcel: issues 694 / 2,711, issue density 12.60 / 49.46, cognitive complexity density 102.8 / 108.3genie: issues 152 / 1,262, issue density 1.28 / 10.81, cognitive complexity density 22.2 / 23.5ckan: issues 1,006 / 3,632, issue density 7.54 / 27.50, cognitive complexity density 69.3 / 76.5
- task design ने तीन rules follow किए
- hotspot traversal: pair के दोनों sides में उन code areas से task गुजरें जहां issue density और cognitive complexity का अंतर बड़ा है
- externally observable description: केवल input-output और example scenarios दिए गए; file, function या internal structure names नहीं दिए गए
- public surface tests: hidden tests application द्वारा callers को दिए जाने वाले interfaces—CLI, HTTP routes, library/API आदि—के जरिए चलाए गए
- task creation agents और humans ने मिलकर किया
- एक agent ने clean variant और messy variant की तुलना करके difference map बनाया
- दूसरे agent ने task outline और testability लिखी
- human ने उनमें से plausible और interesting outlines चुनकर edit और curate किए
- तीसरे agent ने actual instructions, hidden public-surface tests और internal reference implementation बनाए
- reference implementation को दोनों repositories में hidden tests pass करने थे
- pre-fix repository को hidden tests pass नहीं करने चाहिए थे
- दो iterations के बाद भी conditions पूरी न करने वाले tasks को human ने rewrite या remove किया
- अंतिम task count 33 है और ये तीन tracks में बंटे हैं
- 13 cognitive hotspot tasks: single method या single class के high-density complexity area से गुजरते हैं
- 14 multi-module tasks: दो या अधिक modules के पार changes की जरूरत होती है
- 6 calibration tasks: दोनों sides एक ही area में simple tasks करते हैं ताकि cleanliness से असंबंधित variation की जांच हो सके
experiment setup और metrics
- सभी experiments default tool set का इस्तेमाल करने वाले Claude Code से किए गए
- reported numbers Claude Sonnet 4.6 runs से आए हैं
- Claude Haiku 4.5 को भी उसी task set पर scan किया गया, लेकिन pass rate बहुत कम था, इसलिए footprint differences साफ पढ़ना कठिन था और उसे main results से बाहर रखा गया
- agent ने केवल task description पढ़ा
- code cleanliness पर कोई extra priming नहीं दी गई
- उसे नहीं पता था कि वह minimal pair के किस side पर काम कर रहा है
- हर task को pair के दोनों sides पर 10-10 बार चलाया गया
- कुल experiments 33 × 2 × 10 = 660 हैं
- हर run containerized sandbox में किया गया
- CPU, memory, storage और wall-clock time limited थे
- public package registries तक access उपलब्ध था
- base image में repository-specific toolchain, build cache और services शामिल थे
- pair के भीतर केवल
/appपर mounted source tree अलग था
- record किए गए metrics 10 थे
- pass rate: final state में hidden tests pass होने का ratio
- input tokens: सभी turns में model द्वारा पढ़े गए tokens की संख्या; इनमें file contents और पिछली conversation retransmission का बड़ा हिस्सा होता है
- output tokens: model और sub-agents के पूरे outputs, जिनमें prose, code, reasoning traces और tool calls शामिल हैं
- reasoning character count: Anthropic API reasoning tokens को अलग से expose नहीं करता, इसलिए reasoning content blocks के plain-text characters गिने गए
- conversation turns: agent-tool exchanges की कुल संख्या
- turns before first edit: पहली file modification से पहले लगे turns
- characters before first edit: उसी interval में conversation characters की संख्या
- files read: run के दौरान खोली गई unique files की संख्या
- file revisits: पहले पढ़ी और modify की गई file को फिर से पढ़ने की संख्या
- modified lines: final patch द्वारा बदली गई source lines की संख्या
- file revisits
read → edit → possible other work → read againजैसे flow में दिखते हैं- study इसे broad exploration के बजाय previous edit को लेकर uncertainty signal के रूप में interpret करता है
- agent footprint metrics एक ही task को fixed temperature पर repeat करने पर भी काफी बदल सकते हैं, इसलिए outlier filter लागू किया गया
- हर
(task, side)combination के भीतर 10 repetitions के median से 50% से ज्यादा दूर runs को average से पहले हटाया गया - व्यवहार में कुल runs के 9.7% हटाए गए
- हर
- dataset-level numbers 33 tasks पर micro-averaged हैं
- हर metric के लिए task-wise clean side average और messy side average जोड़कर ratio difference निकाला गया
- pass rate को exception के रूप में clean side और messy side के absolute percentage-point difference से report किया गया
results: success rate से ज्यादा exploration cost पर असर
- code cleanliness ने agent के pass rate में meaningful change नहीं किया
- ज्यादा साफ code में token-equivalent metrics 7~8% कम हुए
- file revisits 34% कम हुए, जिससे दिखता है कि clean code उसी task में भी वापस जाकर फिर से पढ़ने की cost घटा सकता है
- इसलिए code cleanliness को model selection, harness और prompts के साथ agent execution cost को प्रभावित करने वाली एक अलग axis माना जा सकता है
1 टिप्पणियां
Hacker News टिप्पणियां
शोध के लिए दिलचस्प सवाल है, लेकिन प्रयोग के डिजाइन को लेकर मैं काफी संशय में हूं
प्रयोग में Opus 4.6 से “quality-degraded” या “cleaned-up” codebase synthesize करके सापेक्ष तुलना में इस्तेमाल किया गया
इससे भी खराब बात यह है कि उन्होंने यह control नहीं किया कि application के tests टूटे या नहीं
“पास रेट हर task के लिए हमारे लिखे hidden tests के आधार पर agent की final state को score करता है। यह नहीं जांचता कि agent ने repository में पहले से मौजूद unrelated tests तोड़े या नहीं, और भले ही clean और messy दोनों तरफ के solutions hidden tests पास कर लें, unscored tests में फर्क हो सकता है”
अगर final output की quality control नहीं की जाती, तो token consumption पर निष्कर्ष लगभग अर्थहीन लगते हैं
fair तुलना के लिए हर pair के दोनों projects पर चलने वाला tests का एक single suite लिखना चाहिए
इसका मतलब यह नहीं कि study अच्छी है, लेकिन test pass होना agent की effectiveness से जरूरी नहीं जुड़ा हो, इसलिए ऐसा निर्णय समझ में आता है
यह बस इतना दिखाता है कि functionality में ठीक दिखने वाली स्थिति में भी काम पूरा करने में ज्यादा token cost लगती है
AI fatigue बहुत पहले ही उबाऊ हो चुका था, अब तो बस तकलीफदेह हद तक पहुंच गया है
मेरे अनुभव में, जब codebase में dead code, duplicate code, unreachable alternate paths, leaky abstractions, और अधपके design patterns भरे हों, बनाम जब data flow साफ हो और encapsulation व structure clean हों, तो agent performance में काफी बड़ा फर्क दिखता है
खराब code में सभी frontier models को कई rounds के code review, quality checks और fixes से गुजरना पड़ा, जबकि अच्छे code में मैंने देखा कि 1–2 attempts में ही सही हो गया
LLM से ऐसे items check करने वाली scripts चलवाई जा सकती हैं, और वही scripts pre-commit hook के रूप में enforce भी की जा सकती हैं
जिन भी codebases पर मैं काम करता हूं, उनमें ऐसी settings सख्ती से डालना agentic coding में सबसे ज्यादा असरदार रहा
मैं जो कई linters इस्तेमाल करता हूं, उन पर ज्यादा detail में लिखा post यहां है: https://www.balajeerc.info/Use-Deterministic-Guardrails-for-...
मेरे हिसाब से agent भी एक बड़े messy codebase की तुलना में clean codebase में बेहतर ही करेगा
ठीक वैसे ही जैसे अच्छी तरह बनी specs और documentation access मिलने पर वह बेहतर करता है
एक point के बाद वे भयानक patterns मुझ पर भी चिपकने लगते हैं
यहां सवाल का जवाब देने की कोशिश करता हुआ एक paper है, और anecdotal testimony सिर्फ reader को bias देती है, समस्या पर objectively निष्कर्ष निकालने में कोई value नहीं जोड़ती
सबसे उपयोगी discussion यह होगी कि सब paper पढ़ें और methodology या results की आलोचना करें
फिर भी जो लोग complain करते हैं कि LLM उतना अच्छा नहीं है, वे आम तौर पर messy codebase वाले type लगते हैं
Python के लिए मैंने जो तरीका कारगर देखा, वह इस तरह refactoring का निर्देश देना है
“Python code को और Pythonic तरीके से refactor करो। उदाहरण के लिए classes और singletons कम करो, खासकर अगर speed improvement हो। Python code को benchmark performance regression के बिना popular open-source Python package code से expected code organization standards जरूर follow करने चाहिए”
Rust code के लिए मैंने इसका यह variant इस्तेमाल किया
“
/srcमें Rust codebase कई 1,000+ line files में bloated हो गया है। benchmark performance regression के बिना popular open-source Rust code से expected code organization standards के अनुरूप Rust codebase को refactor करो”ऐसे prompts से लगता है कि a) code logically reorganize होता है और b) filenames related code location के semantic hints देते हैं, इसलिए agent performance भी बेहतर होती है
5,000-line की bloated file में agent को related code खोजने के लिए कई chunks पढ़ने पड़ते हैं, जो inefficient है
benchmark performance भी आम तौर पर refactoring के बाद बेहतर हो जाती है; खासकर compiled Rust में यह शायद संयोग हो, लेकिन complain करने की बात नहीं
मूल रूप से agentic coding tools code delete करने में हिचकिचाते हैं। delete करने को कहने पर भी ऐसा होता है; वे पुराना code छोड़ने या उसे आगे भी call हो सकने लायक बनाए रखने के लिए complexity जोड़ने की पूरी कोशिश करते हैं
अगर आप सिर्फ prototyping कर रहे हों तो यह सच में annoying है, और आखिर में बहुत सारा dead code जमा हो जाता है, जो बाद में features जोड़ने पर confusion पैदा करता है
यह जान लेने के बाद बस legacy हटाने को कह देना होता है
codebase clean रखने से AI सही काम करने के लिए प्रेरित होता है। tests ज्यादा हों तो नया feature बनाते समय वह और tests जोड़ता है, documentation हो तो अलग से कहे बिना update करता है
जैसे-जैसे code harnesses बेहतर होंगे, ये चीजें और built-in होती जाएंगी, और कम prompt experience वाले लोगों के लिए भी ठीक results पाना आसान होगा
आम तौर पर पहले उससे review कराकर review items की list बनवाता हूं, फिर हर item साथ देखकर मैं yes/no decide करता हूं या extra fixes suggest करता हूं
खासकर अगर पूरे system के लिए careful end-to-end tests नहीं हैं
वैसे भी code style rules मैंने पहले से CLAUDE.md में डाल रखे हैं
“गंदे repository को साफ करने वाली agent pipeline” वाला approach भयानक लगता है, और अपने-आप में पूरे research को खारिज करने के लिए काफी है
लगता है इस काम में minimal pairs का आधा हिस्सा उसी तरह बनाया गया था
जिन निष्कर्षों में यह मानना पड़े कि AI ने “साफ” किया हुआ repository सच में अच्छे codebase का प्रतिनिधित्व करता है, उन पर मैं बिल्कुल भरोसा नहीं करूंगा
यहां “cleanliness” का मतलब agent से बस बेहतर code लिखने को कहना नहीं था
हमने 50–100 static analyzer rule violations की सूची और code lines की संख्या दी, और इन्हें हटाने को कहा
फिर हमने जांचा कि rule violations ठीक हुए या नहीं
LLM से code rewrite कराकर ऐसे violations हटाना काफी accepted practice है
Sonar का मौजूदा one-shot LLM-based approach [1] एक साल से ज्यादा समय से production में है, और हालिया agentic approach [2] भी यही काम काफी अच्छे से करता है
[1] https://www.sonarsource.com/solutions/ai/ai-codefix/
[2] https://www.sonarsource.com/products/sonarqube/remediation-a...
मेरे हिसाब से इसका असर पड़ना तो तय है
कोई भी model असल codebase पूरा context में नहीं रख सकता, और इंसान की तरह code को scan करना पड़ता है
तरीका वही है: search करना और files पढ़ना
अगर file expected जगह पर है, और उसका नाम ऐसा है जिसे model या इंसान पहले search करेगा, तो पहली कोशिश में मिल जाएगी; वरना deep search और कई attempts लगेंगे
सभी paths देखे, जिन areas पर काम हो चुका है उन्हें ignore करे, और अगले path पर बढ़ जाए
यह developer के काम करने के तरीके से काफी मिलता-जुलता है
NJIT में चल रहे मिलते-जुलते काम में भी हमने ऐसे ही results देखे हैं। हम इसे contextual quality contagion कहते हैं
यहां दिलचस्प हिस्सा industry में आम real-world स्थितियां हैं: mixed quality वाले codebase, ऐसे codebase जहां legacy code patterns और नए “अच्छे” patterns मिले हुए हैं और agent conventions को लेकर confuse हो जाता है
minimal pair design असल में इसकी strengths में से एक है, क्योंकि यह repositories की तुलना करने के बजाय structure, dependencies, tests जैसे दूसरे factors से cleanliness को अलग करने की कोशिश करता है
हालांकि LLM-generated “messified” code का इस्तेमाल थोड़ा questionable है, क्योंकि यह mechanical या human-guided तरीका नहीं है
सबसे बड़ी आलोचना, जैसा कि दूसरों ने सही बताया, यह है कि पूरा test suite verify नहीं किया गया। “behavioral equivalence” का दावा tests और coverage जितना ही valid होता है
यह hypothesis दो वजहों से convincing है। 1) LLM codebase में जो देखता है उसकी नकल करता है, इसलिए garbage in, garbage out के लिहाज से बात बनती है 2) पिछले 1–2 साल में इन models का इस्तेमाल करते हुए कई engineers ने intuitively जो महसूस किया है, उससे यह मेल खाता है
greenfield लगभग हमेशा किसी busy codebase में शामिल होने से आसान होता है, और mess जटिल integrations और legacy-purpose systems को maintain करने जैसी चीजों से पैदा होती है
भले ही agent अपने छोड़े हुए stubs और WET code से निपटना सीख जाए, क्या हम सच में ऐसा codebase चाहते हैं जहां इंसान समझ ही न पाए कि असल में क्या हो रहा है?
इसलिए निजी तौर पर मैं चाहता हूं कि कम से कम code क्या कर रहा है, यह code के जरिए बताया जाए
अगर दो छोटे functions में कुछ logic ऐसा हो जिसे shared helper में निकाला जा सकता है, तब भी human programmer कभी-कभी ऐसा नहीं करता, क्योंकि वह जानता है कि वह abstraction messy होगी और दोनों में से किसी एक को थोड़ा बदलना भी उसे तोड़ देगा
इसे quantify करके देखना दिलचस्प है
clean structure इंसानों और agents दोनों का cognitive load कम करता दिखता है, और इसलिए naming और modularization उम्मीद से ज्यादा important लगते हैं
इसे quantify करना मुश्किल है, लेकिन सभी code quality metrics आखिरकार यही capture करने की कोशिश करते हैं
उस criterion से देखें तो, अगर इस्तेमाल किया गया code quality metric reasonable है, तो conclusion ज्यादा surprising नहीं है
अगर coding agent context में quality metric अच्छा है, तो expected result यही होगा
बहुत सारे tokens code navigation में खर्च होते हैं। code ढूंढना या call sites को follow करना, ताकि task करने लायक पर्याप्त context बन सके
agent को किसी तरह का LSP access दिया जाए, और monorepo हो तो AGENTS.md जैसी file से hierarchical guidance मिले, तो navigation में लगने वाले token usage को काफी घटाया जा सकता है
लेकिन बिखरे हुए codebase में हर task solve करने के लिए आखिर किसी-न-किसी रूप में navigation जरूरी होगा
और यह navigation सिर्फ token usage नहीं है। हर step पर LLM latency, prefill, decoding, output से agent parsing, tool call, tool response, और फिर वापस LLM तक round-trip delay दोहराया जाता है
कुछ चीजें parallel हो सकती हैं, लेकिन व्यवहार में ज्यादातर sequential होती हैं, इसलिए task काफी slow हो जाता है
agents को efficiently इस्तेमाल करने के लिए locality और structure key हैं। context window हमेशा limited होती है, और उसके भीतर attention भी consistent नहीं होती
मेरे अनुभव में जो भी चीज engineers को प्रभावित करती है, वह agents को भी प्रभावित करती है
अच्छे abstractions, सही size के methods, अच्छे names, principled service-internal और inter-service structure, unit tests—ये सब इसमें आते हैं
ये चीजें ऐतिहासिक रूप से engineer के काम का हिस्सा रही हैं, ताकि दूसरे लोग code में आसानी से contribute कर सकें
अब ये सिर्फ दूसरे लोगों ही नहीं, बल्कि दूसरे agents के लिए भी code में contribute करना आसान बनाती हैं