भविष्य को आकार देने वाली तकनीक पर गहन लेख।

एजेंटिक कोडिंग CLI के अंदर: लूप, Context, Permissions

एजेंटिक कोडिंग CLI असल में कैसे काम करता है? tool-call लूप, context मैनेजमेंट, permission मॉडल और client/server डिज़ाइन पर एक व्यावहारिक नज़र।

गियर, पाइप और वॉल्व की परतों से घिरा एक छोटा चमकता केंद्र, जो harness बनाम मॉडल को दिखाता है।
एजेंटिक कोडिंग CLI में मॉडल एक छोटा सा केंद्र है; उसके चारों ओर का harness ही असली मशीन का ज़्यादातर हिस्सा है।

मॉडल तो आसान हिस्सा है। कम से कम दावा तो यही है — और पिछले कुछ सालों में डज़नों agentic coding CLI को आते, फोर्क होते और लड़खड़ाते देखने के बाद मुझे लगता है कि यह सच है: agentic coding CLI की सफलता या असफलता उसके harness पर निर्भर करती है, मॉडल पर नहीं। OpenCode 2.0 की रिलीज़ — एक ओपन-सोर्स, टर्मिनल-आधारित coding agent जो इस हफ़्ते खूब चर्चा में रहा — इसे खुलकर कहने का अच्छा बहाना है। उस रिलीज़ की दिलचस्प बातें नए model integrations नहीं हैं। वे हैं client/server विभाजन, hot-reload होने वाले plugins, background में चल सकने वाले tasks, और दोबारा बनाया गया agent loop। यानी प्लंबिंग। यही प्लंबिंग असली प्रोडक्ट है।

मैं पूर्व ML इंजीनियर हूँ, इसलिए यह निष्कर्ष मुझे चुभा। मैं चाहता था कि मॉडल की क्वालिटी ही फ़र्क पैदा करे। लेकिन जब मैं देखता हूँ कि मैं इन टूल्स को क्यों रखता हूँ या क्यों छोड़ देता हूँ, तो जवाब कभी यह नहीं होता कि “मॉडल पहले से ज़्यादा समझदार हो गया।” जवाब होता है “टूल ने हर कमांड के लिए मेरी मंज़ूरी माँगना बंद कर दिया”, या “अब यह restart के बिना मेरा config reload कर देता है”, या “मैं रिमोट मशीन पर चल रहे session में GUI जोड़ सकता हूँ।” आइए उन तीन subsystems को खोलकर देखें जो तय करते हैं कि coding agent काम का है या नहीं: tool-call loop, context management और permission model। फिर मैं बताऊँगा कि contrarian दावा कहाँ टूटता है।

Tool-Call Loop एक Distributed System है

मार्केटिंग हटा दें, तो हर coding agent एक ही प्रोग्राम है: prompt और tools की सूची के साथ मॉडल को कॉल करो, या तो text मिले या tool call, tool चलाओ, नतीजा जोड़ो, दोहराओ। यह लूप सुनने में मामूली लगता है। है नहीं, और जो टूल्स इसे मामूली मानते हैं, वे असली इस्तेमाल के पाँच मिनट में ही अटपटे लगने लगते हैं।

सोचिए लूप को असल में क्या-क्या सँभालना पड़ता है। Tool executions फेल होते हैं — compiler error देता है, test suite अटक जाता है, फ़ाइल उस path पर है ही नहीं क्योंकि मॉडल ने उसे गढ़ लिया था। मॉडल tool arguments के लिए गलत JSON भेज देता है। एक tool call चालीस सेकंड लेता है और user बीच में Escape दबा देता है। एक turn में दो tool calls आते हैं और अगर एक फेल हो जाए तो दूसरा नहीं चलना चाहिए। Context window काम के बीच भर जाती है और कुछ न कुछ छोड़ना पड़ता है। इनमें से हर एक concurrency और failure की समस्या है, intelligence की नहीं। मैं पहले भी कह चुका हूँ कि LLM agents असल में distributed systems ही हैं, और coding CLI इसका सबसे साफ़ उदाहरण है: एक अविश्वसनीय, nondeterministic रिमोट component (मॉडल) स्थानीय effectful components (shell, filesystem, LSP) से तालमेल बिठाता है, और लूप उनके बीच का consensus protocol है।

इसीलिए यह अहम है कि OpenCode 2.0 ने अपना लूप Effect के इर्द-गिर्द दोबारा बनाया बताया जाता है, जो structured concurrency और typed errors के लिए एक TypeScript framework है। यह चुनाव संकेत देता है कि टीम ने लूप को “fetch वाला एक while loop” मानना बंद कर दिया और उसे वैसा समझना शुरू किया जैसा वह असल में है: explicit error channels वाले interruptible, composable और retryable effects का एक सिस्टम। जब agent loop में असली cancellation semantics हों, तो “user ने Escape दबाया” एक पहली-श्रेणी की घटना बन जाती है, न कि बिगड़ी हुई state। जब tool results typed हों, तो आप मॉडल के output को execute करने से पहले validate कर सकते हैं, जो constrained decoding जैसी तकनीकों के साथ अच्छी तरह मेल खाता है, जहाँ आप मॉडल के output space को सीमित कर देते हैं ताकि गलत tool calls पकड़े जाने के बजाय असंभव हो जाएँ।

Client/Server वह फ़ीचर है जिसका कोई मार्केटिंग नहीं करता

कोडिंग CLI का सबसे अहम डिज़ाइन फ़ैसला यह है कि agent एक process है या एक service। सीधा डिज़ाइन — एक process, एक terminal, terminal बंद तो session खत्म — ज़्यादातर टूल्स ने ऐसे ही शुरू किया, और यह एक सीमा है। OpenCode का client/server मॉडल (जहाँ एक लंबे समय तक चलने वाला server sessions का मालिक होता है और कितने भी clients — TUI, desktop app, web UI — उससे जुड़ सकते हैं) वह सीमा हटा देता है। व्यवहार में इसका मतलब है: terminal बंद होने पर भी आपका session बचा रहता है, आप agent को रिमोट dev box पर चला सकते हैं और अपने laptop पर native app से चला सकते हैं, और कई interfaces एक ही session को देख सकते हैं।

अगर आपने कभी VM पर SSH से agent चलाया है और reconnect होने पर session बिगड़ गया है, तो आप जानते हैं कि यह कोई सुविधा भर नहीं है। यही खिलौने और infrastructure के बीच का फ़र्क है। लंबे समय तक चलने वाले agents उसी श्रेणी में आते हैं जिसमें builds और test suites आते हैं: ऐसी चीज़ें जिन्हें आप शुरू करते हैं, छोड़कर चले जाते हैं, और बाद में देखते हैं। OpenCode 2.0 के background में चल सकने वाले tasks उसी दिशा में आगे बढ़ते हैं — agent एक सिंक्रोनस बातचीत से बदलकर chat interface वाला job runner बन जाता है।

अब caveat, क्योंकि मैं यह राय लगातार रखता हूँ: server architecture का मतलब स्थायी daemon नहीं है। कई commenters ने शक के साथ नोट किया कि हर agent harness अचानक आपकी मशीन पर एक persistent background process चाहने लगा है। यह सहज शक सही है। मैं पहले लिख चुका हूँ कि CLI tools को डिफ़ॉल्ट रूप से background daemons इंस्टॉल नहीं करने चाहिए, और मैं उस पर कायम हूँ। एक साफ़ बीच का रास्ता है: server ज़रूरत पड़ने पर शुरू करें, project directory तक सीमित रखें, और आखिरी client के disconnect होने पर बंद कर दें। इससे session की स्थिरता और कई clients का जुड़ना मिलता है, और आपकी मशीन पर हमेशा चलने वाला process नहीं होता जो घर फ़ोन करता रहे। OpenCode का config को server की working directory की बजाय session के फ़ोल्डर से लोड करना — 2.0 का एक और बदलाव — बताता है कि वे समझते हैं कि server को project के पीछे चलना चाहिए, न कि उल्टा।

Context Management में ही क्वालिटी रहती है

किसी भी practitioner से पूछिए कि एक घंटे के काम के बाद agent “बेवकूफ़” क्यों हो गया, तो जवाब लगभग कभी मॉडल का regression नहीं होता। जवाब होता है context rot। Window पुराने tool output, बेकार रास्तों और चालीस turns पहले प्रासंगिक रही फ़ाइलों के पूरे text से भर जाती है। अब मॉडल एक भूसे के ढेर में फैसले ले रहा होता है, और nominal token limit तक पहुँचने से बहुत पहले needle-recall गिरने लगता है।

अच्छा harness context को एक pipe नहीं, बल्कि allocation policy वाला बजट मानता है। ठोस रूप से इसके कई हिस्से मिलकर काम करते हैं:

  • Retrieval के escape hatch के साथ tool output truncation। पाँच हज़ार लाइन का test log context में सिर्फ़ उसकी असफल चालीस लाइनों के साथ आना चाहिए, और इस नोट के साथ कि पूरा log एक path पर है जिसे मॉडल दोबारा पढ़ सकता है। क्या ज़रूरी है यह harness तय करता है; कब और ज़्यादा चाहिए, यह मॉडल तय करता है।
  • Sub-sessions और sub-agents। “जाकर देखो इस repo में auth कैसे काम करता है और वापस रिपोर्ट करो” को एक अलग context में चलना चाहिए जो पूरा exploration transcript नहीं, बल्कि एक digest लौटाए। OpenCode 2.0 का बेहतर sub-session communication ठीक यही विचार है।
  • ऐसी compaction जो intent बचाए। Window भरने पर बातचीत का सार बनाना पड़ता है। जो harness भोलेपन से summarize करता है, वह शोर के साथ user की शर्तें भी खो देता है (“billing module को मत छूना”)। अच्छी compaction फ़ैसलों और शर्तों को शब्दशः रखती है और सिर्फ़ narrative को संक्षिप्त करती है।
  • Config और skills को code नहीं, context की तरह देखें। Project-level निर्देश, plugin-defined tools और skill files सब window का हिस्सा खाते हैं। इन्हें hot-reload करना — 2.0 का एक और सुधार — मायने रखता है, क्योंकि restart किए बिना session का context बदलना ही agent के व्यवहार को खुद iterate करने का तरीका है।

इनमें से कुछ भी मॉडल की बुद्धि नहीं है। फिर भी इन्हीं से तय होता है कि मॉडल कितना बुद्धिमान दिखता है। एक frontier model, जिसकी context policy ढीली हो, बीस मिनट से लंबे किसी भी काम पर एक सस्ते मॉडल से हार जाएगा, जिसके पीछे अनुशासित harness हो।

एक काँच की फ़नल, जो दस्तावेज़ों की धाराओं को रोशनी की पतली किरण में संकुचित करती है, context compression का प्रतीक।
Context management विवेक वाली compression है: सब कुछ अंदर जाता है, बाहर सिर्फ़ ज़रूरी निकलता है।

Permission Models: वह उबाऊ फ़ीचर जो adoption तय करता है

HN चर्चा का एक सवाल, जिसे मैं इस क्षेत्र का सबसे अहम product सवाल मानता हूँ: क्या “हर कमांड की मंज़ूरी दो” और “yolo mode” के बीच कुछ है? पूरी तरह auto-approval सचमुच खतरनाक है — shell access वाला coding agent एक turn में rm -rf, git push --force चला सकता है और आपके environment variables बाहर भेज सकता है। पूरी तरह manual approval सचमुच बेकार है — घंटे में अस्सी कमांड की मंज़ूरी देने का मतलब है आप agent की निगरानी नहीं कर रहे, बल्कि धीमे इंसानी keyboard interrupt बन गए हैं। जो टूल बीच का रास्ता सही पकड़ता है, वही व्यावहारिक लोगों को जीतता है।

बीच का रास्ता एक graded permission model है, और उसका डिज़ाइन स्पेस लोगों की सोच से ज़्यादा समझा जा चुका है:

  • Read-only बनाम write बनाम execute। Reads लगभग मुफ़्त हैं; writes project tree तक सीमित होने चाहिए; execution ही वह जगह है जहाँ policy सबसे ज़्यादा मायने रखती है।
  • Argument-aware allowlists। git status अपने-आप मंज़ूर होता है; git push पूछता है। भोले टूल्स binary के नाम से मिलान करते हैं; अच्छे टूल्स verb और flags से, क्योंकि npm test और npm publish एक ही binary हैं पर उनके नुकसान की सीमा बिल्कुल अलग है।
  • Session-scoped grants। “इस session में यह कमांड हमेशा मंज़ूर करो” अपने आप में सबसे ज़्यादा मूल्य वाला permission फ़ीचर है। यह सत्तर prompts को एक में बदल देता है।
  • अपरिवर्तनीय चीज़ों के लिए containment। Network access, project directory के बाहर की कोई भी चीज़ और credentials को छूने वाली हर चीज़ structurally सीमित होनी चाहिए, सिर्फ़ prompt से पूछकर नहीं।

आख़िरी बिंदु वह हिस्सा है जिसमें ज़्यादातर harness कम निवेश करते हैं, क्योंकि prompt लगाना आसान है और containment कठिन। पर prompt एक ऐसा सवाल है जिसका सही जवाब मॉडल उम्मीद करता है कि आप शुक्रवार शाम 6 बजे सही देंगे। Agent के process tree को sandbox करना — सीमित network, सीमित filesystem mounts — किसी भी मॉडल या user के कुछ भी करने के बावजूद पूरी तरह की failure classes को असंभव बना देता है। मैंने इस trade-off का विस्तार से हिस्सा AI agents के लिए containment बनाम monitoring में लिखा है; मेरा छोटा सार यह है कि prompts monitoring हैं, sandboxing containment है, और अपरिवर्तनीय चीज़ों के लिए आपको containment चाहिए। CLI की दुनिया धीरे-धीरे यह सीख रही है। जो सबसे तेज़ी से सीखेंगे, वही वह भरोसा कमाएँगे जिससे user बोरिंग 90% के लिए auto-approval सच में चालू कर सकें।

Extensibility और Self-Hosted Model की समस्या

2.0 की चर्चा से दो छोटे सबक ध्यान देने लायक हैं। पहला: “सब कुछ plugin है” जीत रहा है। User इन harnesses के ऊपर skills, config editors और workflow hooks बना रहे हैं, और वह harness जो plugins को पहली-श्रेणी का बनाता है — hot-reload होने वाले, sessions देख सकने वाले, व्यवहार बदल सकने वाले — समुदाय की मेहनत को जोड़ता है, उससे लड़ता नहीं। संकेत कि OpenCode इसे गंभीरता से लेता है: उनका अपना GitHub app bug reports को पुनः पेश करके और निष्कर्ष टिप्पणी में लिखकर triage करता है, यानी agent से agent का रखरखाव कराया जा रहा है। उपयोगकर्ताओं ने जिस “self-awareness” की तारीफ़ की, वह एक plugin-architecture का नतीजा है, मॉडल का नहीं।

दूसरा: model-agnostic होना लगता है उससे कठिन है, और यह एक context-format की समस्या है। एक user ने एक बढ़िया local model आज़माया जो bash में कमांड जारी करने के लिए trained था, जबकि harness ज़िद में JavaScript-जैसे tool calls की उम्मीद कर रहा था, और दोनों आपस में काम ही नहीं कर पाए। हर agent harness में यही छिपा हुआ coupling है: tool-call format, system prompt की मान्यताएँ और मॉडल का training distribution, तीनों को एक लाइन में होना पड़ता है। जो harness एक model family की परंपराएँ हार्डकोड करता है, वह model-agnostic नहीं, बहुत से बहुत model-tolerant है। अगर local models coding agents के लिए मायने रखेंगे — और लागत व privacy के कारणों से उन्हें रखना चाहिए — तो harnesses को सिर्फ़ pluggable API endpoints नहीं, pluggable tool-call dialects चाहिए।

जहाँ contrarian दावा टूटता है

मैंने कहा था कि मॉडल आसान हिस्सा है। अब किनारों को मानने का समय है। यह दावा harness के design — loops, context, permissions — पर लागू होता है, पर कुछ जगहों पर मॉडल सच में bottleneck है। Tool-use की विश्वसनीयता खुद मॉडल में trained होती है; जो मॉडल लगातार valid function calls नहीं दे सकता, वह हर harness को टूटा हुआ दिखाता है, और Effect-आधारित structured concurrency उस मॉडल को ठीक नहीं कर सकती जो अपने ही schema से बहस करता हो। लंबी horizon पर multi-step planning अभी भी मॉडल tiers को ऐसे अलग करती है जो एक ही session में महसूस हो जाती है। और harness-बनाम-मॉडल वाले ढाँचे की एक उम्र है: जैसे-जैसे मॉडल agentic व्यवहार को training में समा रहे हैं (native tool use, native long-horizon planning), क्षमताएँ harness से weights की ओर खिसक रही हैं, और आज का चतुर harness फ़ीचर कल की बेकार मेहनत बन सकता है। Harness बनाने वाली टीमों को मान लेना चाहिए कि वे उस scaffolding को बना रही हैं जिसे मॉडल आखिरकार अप्रासंगिक कर देंगे — और ईमानदारी से कहूँ तो यह plugin ecosystems वाले open-source harnesses के पक्ष में तर्क है, क्योंकि वे अस्थायी क्षमता अंतर पर नहीं, समुदाय के सहारे टिकते हैं।

एक UX की न्यूनतम सीमा भी है, जिसे कोई architecture माफ़ नहीं करती। कुछ user OpenCode 2.0 आज़माकर भी उसे अटपटा मानते हैं; कुछ धीमे startup और लगातार बढ़ते dead chat history database की शिकायत करते हैं। ये गहरी समस्याएँ नहीं हैं, पर यही वे चीज़ें हैं जिनकी वजह से लोग पहले दस मिनट में टूल छोड़ देते हैं, इससे पहले कि agent loop की खूबसूरती दिखने का मौका मिले। पॉलिश भी एक फ़ीचर है, और ओपन-सोर्स प्रोजेक्ट इसी पर सबसे ज़्यादा कम निवेश करते हैं।

मॉडल कोड लिखता है, पर harness तय करता है कि आप उस पर इतना भरोसा करें कि उसे काम करने दें।

तो इस श्रेणी को बदलते देखने वाले के नाते मेरी व्यावहारिक सलाह: अपना coding agent वैसे चुनिए जैसे आप database चुनते हैं, न कि benchmark के विजेता मॉडल की तरह। लूप की failure handling, context policy, permission की बारीकी, और यह देखिए कि क्या session आपके terminal बंद होने के बाद बचा रहता है। यही हिस्से अगले मॉडल release के बाद भी मायने रखेंगे, जब वह सबको फिर से बराबर समझदार बना देगा।