ज़िशान अली खान द्वारा अंग्रेजी में लिखा गया; यह एक मशीन अनुवाद है। AI किसी भी भाषा से तेज़ चलता है, इसलिए कुछ तकनीकी शब्द जानबूझकर अंग्रेजी में रहते हैं, और बिंदीदार अंडरलाइन वाले शब्द होवर या टैप करने पर मूल दिखाते हैं। मूल पढ़ें →
AG-UI: इंटरफ़ेस को स्ट्रीम करना, सिर्फ़ जवाब नहीं
एजेंट-यूज़र इंटरैक्शन प्रोटोकॉल के लिए एक फ़ील्ड गाइड, और क्या होता है जब एक प्रोसेस इंजन स्ट्रीम को चलाता है
10 जुलाई 2026 · 18 min · रॉ .md
मैं अपने कामकाजी सप्ताह बड़े वित्तीय संस्थानों में बिताता हूँ, जहाँ मैं उन टीमों को “AI एजेंट” का डेमो देते हुए देखता हूँ जो, जाँच करने पर, सिस्टम प्रॉम्प्ट वाले चैट बॉक्स होते हैं। इंटरफ़ेस एक टेक्स्ट स्ट्रीम है। उपयोगकर्ता टोकन देखता है। एजेंट वापस टोकन देखता है। और कुछ नहीं होता। और फिर ऑपरेशंस पक्ष से कोई वह सवाल पूछता है जो डेमो को खत्म कर देता है: “अनुमोदन कहाँ होता है?”
क्योंकि असली काम बातचीत नहीं है। एक वेल्थ ऑनबोर्डिंग फ़्लो “अपने बारे में बताओ” नहीं है। यह पहचान सत्यापन है, फिर जोखिम मूल्यांकन, फिर एक रूटिंग निर्णय, फिर उन मामलों के लिए एक सलाहकार समीक्षा जिन्हें इसकी आवश्यकता है, फिर खाता खोलना। प्रत्येक चरण में स्थिति, आउटपुट और एक निर्णय होता है। जिस क्षण एक एजेंट जोखिम स्कोर की गणना करता है, उपयोगकर्ता स्कोर का वर्णन करने वाला एक वाक्य नहीं चाहता। वे गेज चाहते हैं। जब यह आवंटन का प्रस्ताव करता है, तो वे डोनट चार्ट चाहते हैं जिस पर वे क्लिक कर सकें, न कि एक पैराग्राफ जो उसका अनुमान लगाता हो।
यह मार्गदर्शिका AG-UI के बारे में है, वह प्रोटोकॉल जो इस अंतर को भरता है: एक एजेंटिक बैकएंड और उपयोगकर्ता-सामने वाले फ्रंटएंड के बीच एक टाइप्ड इवेंट स्ट्रीम। मैंने इसके लिए एक पूर्ण संदर्भ कार्यान्वयन (AURUM, एक काल्पनिक निजी-बैंक ऑनबोर्डिंग डेमो, सार्वजनिक रेपो अंत में लिंक किया गया है) बनाया है, जिसमें चैट लूप के बजाय एक प्रोसेस इंजन ऑर्केस्ट्रेटर के रूप में है। वह आर्किटेक्चरल पसंद प्रोटोकॉल से ही ज़्यादा महत्वपूर्ण निकली, और इस मार्गदर्शिका का दूसरा भाग इसी बारे में है कि ऐसा क्यों है। यहाँ के पैटर्न फ़्रेमवर्क-अज्ञेयवादी हैं। मैंने Camunda 8 का उपयोग किया क्योंकि मैं इसे अच्छी तरह जानता हूँ; बाहरी स्थिति के बारे में मेरे सभी दावे Temporal, चेकपॉइंटर के साथ LangGraph, या आपके द्वारा स्वयं लिखी गई स्टेट मशीन पर समान रूप से लागू होते हैं।
समस्या: टोकन एक इंटरफ़ेस नहीं हैं
स्ट्रीमिंग टोकन ने विलंबता की समस्या को हल किया, इंटरफ़ेस की समस्या को नहीं। टोकन स्ट्रीमिंग एक धीमे मॉडल को प्रतिक्रियाशील महसूस कराती है। यह काम के वास्तविक स्वरूप के लिए कुछ नहीं करती।
विचार करें कि एक चैट-नेटिव एजेंट आपको क्या नहीं दिखा सकता है:
- एक प्रक्रिया के माध्यम से प्रगति। “6 में से चरण 3” एक UI अवधारणा है। एक टोकन स्ट्रीम में कोई चरण नहीं होते, केवल और टोकन होते हैं।
- एक टूल कॉल एक फर्स्ट-क्लास ऑब्जेक्ट के रूप में। एजेंट ने
verifyIdentityको कॉल किया और{status: "verified", method: "document+biometric"}वापस मिला। यह हरे चेक वाला एक कार्ड है, न कि एक वाक्य जिसे मॉडल दोहराता है (और कभी-कभी गलत दोहराता है)। - एक विराम। एक इंसान को इसे अनुमोदित करने की आवश्यकता है। एक चैट लूप में, “एक इंसान का इंतजार” का मतलब है कि अनुरोध या तो खुला रखा गया है या खो गया है। दोनों में से कोई भी वास्तविक विराम नहीं है।
- संरचित स्थिति। ऑनबोर्डिंग रिकॉर्ड में 40 फ़ील्ड हैं जिनकी एजेंट और UI दोनों को परवाह है। हर मोड़ पर इसे गद्य में क्रमबद्ध करना दोनों दिशाओं में हानिपूर्ण है।
मैंने जिन भी टीमों को इस दीवार से टकराते देखा है, वे इसे एक ही तरीके से हल करती हैं: वे अपने बैकएंड और अपने फ्रंटएंड के बीच एक निजी इवेंट शब्दावली का आविष्कार करती हैं। type फ़ील्ड के साथ एक JSON ब्लब, React में एक स्विच स्टेटमेंट। यह काम करता है, और फिर यह कठोर हो जाता है। इवेंट्स अनडॉक्यूमेंटेड होते हैं, फ्रंटएंड और बैकएंड में विचलन होता है, और दूसरे क्लाइंट (मोबाइल ऐप, ऑप्स डैशबोर्ड) को बोली को रिवर्स-इंजीनियर करना पड़ता है।
AG-UI वह निजी शब्दावली है, मानकीकृत। यही पूरी बात है, और यह पर्याप्त है।
AG-UI क्या है
AG-UI (एजेंट-यूज़र इंटरैक्शन प्रोटोकॉल) एक खुला, इवेंट-आधारित प्रोटोकॉल है जो मानकीकृत करता है कि एक एजेंटिक बैकएंड उपयोगकर्ता-सामने वाले एप्लिकेशन से कैसे बात करता है। यह CopilotKit से निकला है, जिसे LangGraph और CrewAI के साथ साझेदारी में विकसित किया गया था, और अब GitHub पर ag-ui-protocol संगठन के तहत खुला है। एजेंट पक्ष एक स्ट्रीम पर टाइप्ड इवेंट्स उत्सर्जित करता है। ऐप पक्ष प्रत्येक इवेंट को रेंडर करता है। उपयोगकर्ता इनपुट संरचित संदेशों के रूप में वापस प्रवाहित होता है। यही पूरा मॉडल है।
| तथ्य | विवरण |
|---|---|
| उत्पत्ति | CopilotKit, LangGraph और CrewAI के साथ; ag-ui-protocol के तहत ओपन-सोर्स किया गया |
| स्वरूप | एजेंट-से-ऐप एक-दिशात्मक इवेंट स्ट्रीम, साथ ही ऐप-से-एजेंट एक संरचित इनपुट चैनल |
| मुख्य इवेंट शब्दावली | मूल विनिर्देश में पाँच श्रेणियों में ~16 इवेंट प्रकार: रन लाइफ़साइकिल, टेक्स्ट संदेश, टूल कॉल, स्टेट मैनेजमेंट, और विशेष (RAW, CUSTOM)। वर्तमान विनिर्देश सुविधा चंक इवेंट्स और रीज़निंग इवेंट्स के साथ उससे आगे बढ़ गया है |
| स्टेट मॉडल | साझा टाइप्ड स्टोर: पूर्ण स्थिति के लिए STATE_SNAPSHOT, RFC 6902 JSON पैच अंतर के लिए STATE_DELTA |
| ट्रांसपोर्ट | ट्रांसपोर्ट-अज्ञेयवादी। सर्वर-सेंट इवेंट्स (SSE) डिफ़ॉल्ट और संदर्भ ट्रांसपोर्ट है; प्लेन HTTP और WebSockets भी काम करते हैं |
| ह्यूमन-इन-द-लूप | फर्स्ट-क्लास: स्थिति खोए बिना रन के बीच में रोकें, अनुमोदित करें, संपादित करें, पुनः प्रयास करें |
| यह क्या मानकीकृत करता है | इवेंट प्रकार, उनके पेलोड आकार, ऑर्डरिंग सिमेंटिक्स, और स्टेट-सिंक तंत्र |
| यह क्या खुला छोड़ता है | आप कुछ भी कैसे रेंडर करते हैं, जनरेटिव UI के लिए कंपोनेंट स्कीमा, प्रमाणीकरण, प्राधिकरण, दृढ़ता |
| एकीकरण | 16+ फ़्रेमवर्क बाइंडिंग: LangGraph, CrewAI, Microsoft Agent Framework, Google ADK, AWS Strands, Pydantic AI, LlamaIndex, और अन्य |
डिज़ाइन शर्त ‘ढीला प्रारूप मिलान’ है: AG-UI एजेंट स्थिति और UI इरादे के प्रवाह को मानकीकृत करता है, न कि पिक्सेल को। एक TOOL_CALL_START इवेंट आपके फ्रंटएंड को गोल कोनों वाले कार्ड में एक स्पिनर रेंडर करने के लिए नहीं कहता है। यह आपके फ्रंटएंड को बताता है कि एक टूल कॉल शुरू हुई, एक नाम और एक ID के साथ, और बाकी आपकी समस्या है। यह सही निर्णय है। रेंडरिंग लेयर को ही मानकीकृत करने का हर प्रयास जो मैंने देखा है, वह अपनी खुद की कंपोनेंट लाइब्रेरी के बोझ तले दब जाता है।
प्रोटोकॉल स्टैक में इसकी स्थिति कहाँ है
एजेंटिक प्रोटोकॉल परिदृश्य ने खुद को, लगभग अठारह महीनों में, प्रतिपक्ष द्वारा चार परतों में व्यवस्थित कर लिया। मुझे यह एकमात्र फ़्रेमिंग लगती है जो संक्षिप्त रूपों को याद रखने योग्य बनाती है:
| प्रोटोकॉल | एजेंट को… से जोड़ता है | उत्पत्ति | एक-पंक्ति का काम |
|---|---|---|---|
| MCP | उपकरण और संदर्भ | Anthropic | एजेंट को हाथ दें: सिस्टम और डेटा तक मानकीकृत पहुँच |
| A2A | अन्य एजेंट | एजेंटों को विक्रेताओं और रनटाइम में प्रतिनिधिमंडल और समन्वय करने दें | |
| AG-UI | इंसान | CopilotKit | अंतिम मील: एजेंट गतिविधि को कुछ ऐसा बनाएं जिसे एक व्यक्ति देख और क्लिक कर सके |
| AP2 | पैसा | Google + भुगतान भागीदार | एजेंट-शुरू किए गए भुगतानों के लिए क्रिप्टोग्राफिक रूप से जवाबदेह मैंडेट |
एक उत्पादन प्रणाली अक्सर इनमें से तीन का एक साथ उपयोग करती है, और तेजी से सभी चार का। AURUM में, एजेंट ऑर्केस्ट्रेशन लेयर के माध्यम से अपने उपकरणों तक पहुँचता है (Camunda का AI एजेंट कनेक्टर टूल ब्रोकरेज की MCP भूमिका निभाता है), और उपयोगकर्ता जो कुछ भी देखता है वह AG-UI पर चलता है। मैं अन्य परतों को A2A फ़ील्ड गाइड और AP2 फ़ील्ड गाइड में गहराई से कवर करता हूँ; यह दस्तावेज़ मानव परत पर रहता है।
परतें वास्तव में ऑर्थोगोनल हैं। AG-UI के बारे में कुछ भी यह नहीं मानता कि इसके नीचे MCP है, और A2A के बारे में कुछ भी यह नहीं मानता कि AG-UI सतह मौजूद है। वह ऑर्थोगोनैलिटी ही कारण है कि आप उन्हें स्वतंत्र रूप से अपना सकते हैं, जो कि उद्यमों के भीतर वास्तविक रूप से कैसे अपनाया जाता है: प्रति बजट चक्र एक प्रोटोकॉल।
इवेंट की संरचना
AG-UI इवेंट्स type डिस्क्रिमिनेटर के साथ फ्लैट JSON ऑब्जेक्ट्स हैं। पाँच श्रेणियाँ काम करती हैं।
रन लाइफ़साइकिल
RUN_STARTED, RUN_FINISHED, RUN_ERROR, साथ ही एक रन के अंदर नामित चरणों के लिए STEP_STARTED / STEP_FINISHED। ये वे इवेंट्स हैं जिन पर आपका प्रगति UI निर्भर करता है। एक रन में threadId और runId होता है; चरणों में stepName होता है। AURUM में, ऑपरेटर कंसोल अनिवार्य रूप से लाइफ़साइकिल इवेंट्स के लिए एक रेंडरर है: प्रत्येक BPMN गतिविधि एक चरण से मैप करती है, इसलिए कच्ची वायर एक प्रोसेस लॉग की तरह पढ़ती है क्योंकि यह वही है।
टेक्स्ट स्ट्रीमिंग
प्रति संदेश तीन इवेंट, messageId द्वारा सहसंबद्ध:
{ "type": "TEXT_MESSAGE_START", "messageId": "msg_042", "role": "assistant" }
{ "type": "TEXT_MESSAGE_CONTENT", "messageId": "msg_042", "delta": "Your risk profile " }
{ "type": "TEXT_MESSAGE_CONTENT", "messageId": "msg_042", "delta": "suggests a balanced allocation." }
{ "type": "TEXT_MESSAGE_END", "messageId": "msg_042" }
‘बस स्ट्रिंग स्ट्रीम करें’ के बगल में स्टार्ट/कंटेंट/एंड ट्रिपल नौकरशाही जैसा लगता है, लेकिन स्पष्ट सीमाएँ ही क्लाइंट को कई समवर्ती संदेशों को इंटरलीव करने और निश्चित रूप से यह जानने देती हैं कि एक संदेश कब पूरा हो गया है बजाय इसके कि वह रुका हुआ है।
टूल कॉल
TOOL_CALL_START (नाम और ID), TOOL_CALL_ARGS (स्ट्रीम किए गए तर्क डेल्टा), TOOL_CALL_END, और TOOL_CALL_RESULT। यह वह श्रेणी है जो एक एजेंट UI को एक चैट UI से अलग करती है। फ्रंटएंड कॉल को उसके अपने लाइफ़साइकिल के साथ एक ऑब्जेक्ट के रूप में रेंडर कर सकता है: लंबित, चल रहा, हल किया गया, तर्कों और परिणामों के साथ निरीक्षण योग्य। AURUM में, parseApplicationForm → {fieldsParsed: 12} ग्राहक दृश्य में एक पूर्ण चरण चिप के रूप में और ऑपरेटर दृश्य में एक कच्चे इवेंट के रूप में रेंडर होता है। एक ही इवेंट, दो रेंडरिंग।
स्टेट सिंक्रोनाइज़ेशन
STATE_SNAPSHOT पूरे साझा स्टेट ऑब्जेक्ट को वहन करता है। STATE_DELTA एक RFC 6902 JSON पैच ऐरे वहन करता है:
{ "type": "STATE_DELTA", "delta": [
{ "op": "replace", "path": "/application/riskScore", "value": 72 },
{ "op": "add", "path": "/application/flags/-", "value": "PEP_SCREEN_REQUIRED" }
] }
कनेक्ट होने पर स्नैपशॉट, स्ट्रीमिंग के दौरान डेल्टा। यह पैटर्न UI स्थिति पर लागू इवेंट-सोर्सिंग है, और यह वह हिस्सा है जिसे अधिकांश घरेलू बोलियाँ हर बदलाव पर पूरी स्थिति भेजकर और यह सोचकर गलत करती हैं कि स्ट्रीम जितनी होनी चाहिए उससे 40 गुना बड़ी क्यों है।
जनरेटिव UI
यहाँ विनिर्देश जानबूझकर रायहीन है: जनरेटिव UI कंपोनेंट्स के रूप में रेंडर किए गए टूल-कॉल इवेंट्स पर, या CUSTOM इवेंट्स पर चलता है। मेरी डेमो बोली इसे स्पष्ट रूप से नाम देती है, जिसे विनिर्देश एक कस्टम इवेंट के रूप में वर्गीकृत करेगा:
{ "type": "GENERATIVE_UI", "pid": "2251799813737463", "ts": 1719849302144,
"component": "PortfolioAllocationChart",
"props": { "equities": 60, "fixedIncome": 30, "alternatives": 10 } }
फ्रंटएंड component नामों को वास्तविक React कंपोनेंट्स (IdentityResultCard, PortfolioAllocationChart, ProjectedGrowthChart, AccountOpenedCard) से मैप करने वाली एक रजिस्ट्री रखता है। अज्ञात कंपोनेंट नाम? कच्चे प्रॉप्स के साथ एक फ़ॉलबैक कार्ड रेंडर करें। उस एक रक्षात्मक निर्णय ने विकास के दौरान डेमो को दो बार बचाया, और यह एक ऐसी बोली के बीच का अंतर है जो खराब होती है और एक जो सफेद स्क्रीन दिखाती है।
ऑर्डरिंग नियम सरल और भार-वहन करने वाले हैं: आगमन क्रम में इवेंट्स को प्रोसेस करें, और एक ID (messageId, toolCallId) साझा करने वाले इवेंट्स को एक तार्किक स्ट्रीम के रूप में मानें। क्लाइंट में बाकी सब कुछ उन दो नियमों से आता है।
वह पैटर्न जो मैंने सिद्ध किया: प्रोसेस-ऑर्केस्ट्रेटेड जनरेटिव UI
यह वह हिस्सा है जिसकी मुझे सबसे ज़्यादा परवाह है, क्योंकि यह वह हिस्सा है जो प्रोटोकॉल डॉक्स आपको नहीं बता सकते।
AG-UI वायर को मानकीकृत करता है। यह इस बारे में कुछ नहीं कहता कि वायर के पीछे की स्थिति का मालिक कौन है। हर CopilotKit-शैली के क्विकस्टार्ट में, उत्तर एजेंट लूप ही होता है: एक चैट रनटाइम बातचीत को रखता है, मॉडल को कॉल करता है, इवेंट्स उत्सर्जित करता है। यह तब तक काम करता है जब तक प्रक्रिया क्रैश नहीं हो जाती, या किसी इंसान को निर्णय लेने में तीन दिन नहीं लगते, या कोई ऑडिटर यह नहीं पूछता कि 14 मार्च को क्या हुआ था।
AURUM में मैंने इसे उलट दिया। ऑर्केस्ट्रेटर एक प्रोसेस इंजन (Camunda 8, BPMN) है, और AG-UI स्ट्रीम प्रोसेस स्थिति का एक प्रक्षेपण है। बैकएंड एक SSE हब के साथ एक Node BFF है; Zeebe वर्कर्स और एक टास्क पोलर इंजन इवेंट्स को AG-UI इवेंट्स में अनुवादित करते हैं। एजेंट (Camunda का AI एजेंट कनेक्टर एक एड-हॉक सब-प्रोसेस चला रहा है, जिसमें Bedrock पर Claude और Gemini स्वैपेबल मॉडल के रूप में हैं) प्रति मोड़ 13 विषम उपकरणों में से चुनता है: सर्विस टास्क, एक FEEL स्क्रिप्ट, लाइव FX दरों के लिए एक HTTP कनेक्टर, एक मानव हैंड-ऑफ। प्रवाह इंटेक, पहचान, जोखिम, रूटिंग के लिए एक DMN निर्णय तालिका, फिर या तो सीधे खाता खोलना या एक सलाहकार समीक्षा है।
जब ऑर्केस्ट्रेटर स्थिति का मालिक होता है, तो UI स्ट्रीम को तीन गुण विरासत में मिलते हैं जो चैट-नेटिव आर्किटेक्चर में नहीं हो सकते:
पुनः शुरू करने योग्य। यदि BFF या एजेंट प्रवाह के बीच में क्रैश हो जाता है, तो प्रोसेस इंस्टेंस अभी भी इंजन में उसी गतिविधि पर बैठा रहता है जहाँ वह पहुँचा था। बैकएंड को पुनरारंभ करें, प्रोसेस वेरिएबल्स से STATE_SNAPSHOT को फिर से चलाएं, और स्ट्रीम जारी रहती है। स्थिति इंजन में रहती है, LLM के संदर्भ विंडो में नहीं और Node प्रोसेस के हीप में नहीं।
रोका जा सकने वाला। DMN तालिका $1.5M से ऊपर के मामलों को एक मानव उपयोगकर्ता कार्य पर रूट करती है। उस क्षण प्रोसेस टोकन रुक जाता है। “एजेंट लूप में पोल करता है” नहीं, “हम एक लंबी टाइमआउट के साथ एक HTTP अनुरोध खुला रखते हैं” नहीं। टोकन एक मिनट या एक महीने के लिए, स्थायी रूप से पार्क किया जाता है। AG-UI स्ट्रीम USER_TASK इवेंट उत्सर्जित करती है, ग्राहक एक ईमानदार “आपका सलाहकार इसकी समीक्षा कर रहा है” कार्ड देखता है, सलाहकार अपनी कतार में एक अनुमोदन कार्ड देखता है। जब सलाहकार निर्णय लेता है, तो टोकन चलता है और स्ट्रीम फिर से शुरू होती है। ह्यूमन-इन-द-लूप ऑर्केस्ट्रेटर का एक फर्स्ट-क्लास कंस्ट्रक्ट है, न कि चैट लूप पर लगाया गया एक हैक। महत्वपूर्ण रूप से, AI ने प्रतीक्षा करने का निर्णय नहीं लिया। प्रक्रिया ने किया। आप नहीं चाहते कि “अनुपालन समीक्षा के लिए रोकें” एक ऐसा व्यवहार हो जिसके लिए आप प्रॉम्प्ट करें।
ऑडिट करने योग्य। प्रत्येक स्थिति संक्रमण, प्रत्येक टूल इनवोकेशन, प्रत्येक रूटिंग निर्णय को इंजन द्वारा निष्पादन के एक साइड इफेक्ट के रूप में रिकॉर्ड किया जाता है। Camunda में वह ऑडिट ट्रेल ऑपरेट में शून्य कस्टम लॉगिंग कोड के साथ दिखाई देता है। जब ऑडिटर पूछता है कि जेम्स रोड्रिगेज का आवेदन मैन्युअल समीक्षा में क्यों गया और सारा चेन का क्यों नहीं, तो उत्तर हिट-पॉलिसी सिमेंटिक्स और एक टाइमस्टैम्प्ड टोकन हिस्ट्री के साथ एक DMN तालिका है, न कि मॉडल ट्रांसक्रिप्ट्स के माध्यम से एक grep।
समीक्षा टिप्पणी: यदि आपकी ऑडिट कहानी एक डेवलपर द्वारा हर टूल कॉल के बगल में एक लॉग लाइन जोड़ने की याद रखने पर निर्भर करती है, तो आपके पास एक ऑडिट कहानी नहीं है। आपके पास एक डायरी है।
इनमें से कुछ भी Camunda-विशिष्ट नहीं है। यह गुण स्थिति को किसी ऐसी टिकाऊ चीज़ में बाहरीकृत करने से आता है जो मॉडल संदर्भ और वेब टियर नहीं है। Temporal आपको इवेंट-सोर्स्ड वर्कफ़्लो हिस्ट्रीज़ के माध्यम से वही पुनः शुरू करने की क्षमता देता है। LangGraph आपको चेकपॉइंटर के माध्यम से एक कमजोर लेकिन वास्तविक संस्करण देता है। आपके द्वारा स्वयं लिखी गई एक Postgres-समर्थित स्टेट मशीन योग्य है। डिज़ाइन नियम है: AG-UI स्ट्रीम टिकाऊ स्थिति पर एक दृश्य होना चाहिए, कभी भी रिकॉर्ड की प्रणाली नहीं। इसे सही करें और वायर पर प्रोटोकॉल का चुनाव लगभग आकस्मिक है। इसे गलत करें और कोई प्रोटोकॉल आपको नहीं बचाएगा।
एक स्ट्रीम, कई सतहें
इवेंट स्ट्रीम टाइप्ड और सिमेंटिक है, इसलिए इसके बारे में कुछ भी एक रीडर को नहीं मानता है। AURUM एक ही वायर से तीन पर्सोना चलाता है:
| सतह | मार्ग | यह स्ट्रीम से क्या रेंडर करता है |
|---|---|---|
| ग्राहक | #/customer |
कंसीयर्ज टेक्स्ट, एक-एक करके स्ट्रीम होने वाले जनरेटिव कार्ड, ईमानदार “समीक्षा की प्रतीक्षा” स्थितियाँ |
| सलाहकार | #/advisor |
अनुमोदन कतार: USER_TASK इवेंट्स कार्रवाई योग्य कार्ड बन जाते हैं; निर्णय प्रक्रिया में वापस प्रवाहित होते हैं |
| ऑपरेटर | #/operator/{pid} |
कच्चा इवेंट लॉग, अनरेंडर्ड: प्रत्येक लाइफ़साइकिल इवेंट, टूल कॉल, और स्टेट डेल्टा जैसे ही वह आता है |
ऑपरेटर दृश्य ‘मेरी बात पर विश्वास न करें’ दृश्य के रूप में मौजूद है। इसे एक ग्राहक सत्र के बगल में खोलें और आप वास्तविक समय में कच्ची वायर को पॉलिश किए गए UI का उत्पादन करते हुए देखते हैं। ग्राहक डेमो में यह किसी भी आर्किटेक्चर स्लाइड से ज़्यादा प्रभावशाली होता है, क्योंकि यह साबित करता है कि कार्ड कोरियोग्राफ किया गया फ्रंटएंड थिएटर नहीं हैं। वे उन्हीं इवेंट्स के रेंडरिंग हैं जिन्हें ऑप्स कंसोल कच्चा दिखाता है।
गहरा बिंदु: अधिकांश उद्यमों में, ग्राहक UI, बैक-ऑफिस कतार, और ऑप्स डैशबोर्ड तीन टीमें, तीन कोडबेस, और तीन एकीकरण परियोजनाएँ हैं। एक टाइप्ड इवेंट स्ट्रीम उसे तीन रेंडरर्स के साथ एक कॉन्ट्रैक्ट में समेट देती है। सलाहकार डेस्क दृश्य (#/desk, #/pipeline) शब्दावली मौजूद होने के बाद लगभग मुफ्त में आ गए, और ‘लगभग मुफ्त में’ एक ऐसा वाक्यांश नहीं है जिसका मैं लापरवाही से उपयोग करता हूं।
कार्यान्वयन की ईमानदारी: ~150 लाइनें आपको क्या देती हैं
AURUM फ्रंटएंड में कोई एजेंट फ़्रेमवर्क नहीं है। कोई CopilotKit नहीं, कोई ChatKit नहीं। AG-UI क्लाइंट एक छोटा EventSource रैपर और एक useAGUI React हुक है, कुल लगभग 150 लाइनें। मैंने यह जानबूझकर किया, यह पता लगाने के लिए कि एक क्लाइंट को वास्तव में क्या चाहिए। यहाँ ईमानदार लेखा-जोखा है।
~150 लाइनें वास्तव में क्या संभालती हैं: प्रति प्रोसेस इंस्टेंस SSE कनेक्शन खोलना, प्रत्येक इवेंट को पार्स करना, type पर React स्थिति में भेजना (टेक्स्ट डेल्टा जोड़ना, ID द्वारा टूल कॉल को अप्सर्ट करना, एक जनरेटिव कार्ड पुश करना, उपयोगकर्ता-कार्य फ़्लैग सेट करना), और EventSource के अंतर्निहित ऑटो-रीकनेक्ट पर निर्भर रहना। यह वास्तव में वह सब है जिसकी एक डेमो क्लाइंट को आवश्यकता होती है, और यही कारण है कि मैं टीमों को बताता हूँ कि AG-UI अपनाने की क्लाइंट-साइड लागत कम है। एजेंट UX का महंगा हिस्सा बैकएंड सिमेंटिक्स है, न कि सॉकेट हैंडलिंग।
वे क्या नहीं संभालते, और मैं उत्पादन के लिए क्या मजबूत करूँगा:
- निरंतरता के साथ पुनः कनेक्शन।
EventSourceपुनः कनेक्ट होता है, लेकिन मेरा सर्वरLast-Event-IDलागू नहीं करता है, इसलिए डिस्कनेक्ट के दौरान उत्सर्जित इवेंट्स बस चले जाते हैं। समाधान मानक है: मोनोटोनिक इवेंट IDs असाइन करें, एक छोटा रीप्ले बफर रखें (या इंजन से फिर से प्राप्त करें, जो रिकॉर्ड की वास्तविक प्रणाली है), और पुनः कनेक्ट होने पर क्लाइंट की अंतिम ID से फिर से चलाएं। जब बफर पुराना हो जाता है तो एक नएSTATE_SNAPSHOTपर वापस लौटना बाकी को कवर करता है। - बैकप्रेशर। SSE में कोई नहीं है। एक धीमा क्लाइंट का मतलब है कि सर्वर बफर करता है। एक डेमो ब्राउज़र के साथ यह अदृश्य है; हजारों समवर्ती स्ट्रीम के साथ यह एक मेमोरी समस्या है। उत्पादन के उत्तर: ओवरफ़्लो पर स्नैपशॉट-और-रीसेट के साथ प्रति-कनेक्शन कतार कैप, या स्टेट डेल्टा को समेकित करना (JSON पैच कंपोज करता है, इसलिए N डेल्टा एक में ढह सकते हैं)।
- स्रोतों में ऑर्डरिंग। एक SSE कनेक्शन के भीतर, ऑर्डरिंग की गारंटी है। लेकिन मेरा BFF कई वर्कर्स और एक टास्क पोलर से इवेंट्स को फैन करता है। लगभग एक साथ उत्सर्जित होने वाले दो वर्कर्स एक ऐसे क्रम में इंटरलीव कर सकते हैं जो इंजन ऑर्डर से भिन्न होता है। डेमो इसे अनदेखा करता है; उत्पादन को सॉकेट पर लिखने से पहले इंजन-साइड ऑर्डरिंग (प्रोसेस इंस्टेंस से स्थिति या टाइमस्टैम्प) का उपयोग करके हब पर अनुक्रमित करना चाहिए।
- आइडम्पोटेंट रेंडरिंग। रीप्ले प्लस एट-लीस्ट-वन्स डिलीवरी का मतलब डुप्लिकेट है।
messageId/toolCallIdद्वारा अप्सर्ट करना आपको अधिकांश रास्ते तक ले जाता है; मेरा जनरेटिव कार्ड हैंडलर जोड़ता है, इसलिए एक रीप्ले किया गयाGENERATIVE_UIइवेंट दो बार रेंडर होता है। कार्ड्स को भी स्थिर IDs की आवश्यकता होती है। - स्ट्रीम प्रमाणीकरण। डेमो के पर्सोना हैश रूट्स हैं। SSE एंडपॉइंट पर कोई प्रमाणीकरण नहीं है। उत्पादन को प्रोसेस इंस्टेंस और पर्सोना से बंधे एक अल्पकालिक टोकन की आवश्यकता होती है, जिसे सदस्यता के समय जांचा जाता है, और पुनः कनेक्ट होने पर फिर से जांचा जाता है।
डेमो के बारे में एक और ईमानदारी की बात: यह बिना किसी API कुंजी के चलता है। ANTHROPIC_API_KEY के बिना, एजेंट वर्कर्स एक नियतात्मक स्क्रिप्टेड परिदृश्य (‘शैडो मोड’) को फिर से चलाते हैं, इसलिए पूरा AG-UI स्ट्रीम, ह्यूमन-इन-द-लूप विराम, और इंजन कोरियोग्राफी सभी काम करते हैं इससे पहले कि आप टोकन पर एक पैसा खर्च करें। मैंने इसे डेमो विश्वसनीयता के लिए बनाया था, लेकिन इसने एक टेस्ट हार्नेस के रूप में अपनी जगह बनाई: पूरी इवेंट पाइपलाइन को शून्य मॉडल भिन्नता के साथ अभ्यास किया जाता है, जो कि CI में आप बिल्कुल यही चाहते हैं। यदि आप इस खंड से एक विचार अपनाते हैं, तो उसे अपनाएं।
समीक्षा टिप्पणी: एक स्क्रिप्टेड ‘शैडो मोड’ एक कमतर डेमो नहीं है। यह आपके इवेंट कॉन्ट्रैक्ट के लिए एक फिक्स्चर है, और यह किसी भी प्रॉम्प्ट मूल्यांकन से ज़्यादा फ्रंटएंड रिग्रेशन को पकड़ेगा।
AG-UI क्या हल नहीं करता
प्रोटोकॉल अपनी सीमाओं के बारे में स्पष्ट होकर विश्वास अर्जित करते हैं। तीन अंतराल जो आप स्वयं संभालेंगे:
UI में दिखाए गए कार्यों का प्राधिकरण। AG-UI एक अनुमोदन कार्ड एक सलाहकार को स्ट्रीम कर सकता है। इस पर उसकी कोई राय नहीं है कि उस सलाहकार को अनुमोदित करने की अनुमति है या नहीं। इवेंट एक रेंडरिंग निर्देश है, न कि अनुमति अनुदान, और एक फ्रंटएंड जो “कार्ड दिखाई दिया” को प्राधिकरण के रूप में मानता है, उसमें एक IDOR-आकार का छेद है। जाँच वहीं होनी चाहिए जहाँ कार्रवाई निष्पादित होती है। AURUM में वह इंजन है: उपयोगकर्ता कार्य पूर्णता API यह लागू करता है कि इसे कौन पूरा कर सकता है, और UI उस तथ्य पर सिर्फ एक सुंदर चेहरा है। जहाँ भी आपके कार्य निष्पादित होते हैं, वहीं लागू करें, और हर आने वाले “उपयोगकर्ता ने X का निर्णय लिया” संदेश को अविश्वसनीय इनपुट के रूप में मानें।
जनरेटिव कंपोनेंट्स का स्कीमा शासन। बैकएंड एमिटर्स और फ्रंटएंड रजिस्ट्री के बीच component + props कॉन्ट्रैक्ट आपकी अनुशासन के जितना ही मजबूत है। AG-UI में कुछ भी यह मान्य नहीं करता कि पिछले सप्ताह के रीफैक्टर के बाद PortfolioAllocationChart अभी भी alternatives स्वीकार करता है। आपको वही चाहिए जो आपको किसी भी API के लिए चाहिए होगा: साझा स्कीमा परिभाषाएँ (मैं zod या JSON स्कीमा का उपयोग करूँगा, उत्सर्जित होने पर और रेंडर होने पर मान्य), अज्ञात कंपोनेंट्स के लिए एक फ़ॉलबैक रेंडरर, और कंपोनेंट प्रॉप्स को एक संस्करणित सार्वजनिक API के रूप में मानना, क्योंकि वे वही हैं।
डिप्लॉयमेंट में इवेंट्स का वर्जनिंग। स्ट्रीम लंबी अवधि की होती हैं; डिप्लॉयमेंट नहीं होते। एक रोलिंग डिप्लॉय के दौरान, कल के इवेंट आकारों के खिलाफ बनाया गया एक क्लाइंट आज के इवेंट प्राप्त कर सकता है, और पिछले सप्ताह शुरू किया गया एक प्रोसेस इंस्टेंस एक रीडिज़ाइन किए गए फ्रंटएंड में स्ट्रीमिंग फिर से शुरू कर सकता है। विनिर्देश आपको RAW और CUSTOM एस्केप हैच देता है लेकिन कोई वर्जनिंग कहानी नहीं। न्यूनतम व्यवहार्य उत्तर: इवेंट पेलोड में केवल योगात्मक परिवर्तन, आपके कस्टम इवेंट्स में एक संस्करण फ़ील्ड, और ब्रेकिंग परिवर्तनों से पहले लंबी अवधि की स्ट्रीम को निकालने की एक नीति। प्रोसेस-ऑर्केस्ट्रेटेड सेटअप इसे ज़्यादा महसूस करते हैं, कम नहीं, क्योंकि एक पार्क किया गया उपयोगकर्ता कार्य खुशी-खुशी छह डिप्लॉयमेंट के माध्यम से प्रतीक्षा कर सकता है।
मैं एक नरम चौथा जोड़ूँगा: AG-UI आपके एजेंट को अच्छा नहीं बनाता। एक खराब प्रक्रिया की एक टाइप्ड स्ट्रीम एक अच्छी तरह से स्वरूपित खराब प्रक्रिया है। प्रोटोकॉल ने मेरी समस्या को ‘मैं फ्रंटएंड को संरचना कैसे प्राप्त करूँ’ से ‘इस वर्कफ़्लो को वास्तव में किस संरचना की आवश्यकता है’ में बदल दिया, जो सही समस्या है, लेकिन यह अभी भी काम है।
एक-पैराग्राफ संस्करण
AG-UI एक एजेंटिक बैकएंड और उपयोगकर्ता-सामने वाले फ्रंटएंड के बीच एक खुला, टाइप्ड इवेंट प्रोटोकॉल है: रन लाइफ़साइकिल, स्ट्रीम किया गया टेक्स्ट, परिणामों के साथ टूल कॉल, JSON पैच स्टेट डेल्टा, और जनरेटिव UI कंपोनेंट्स के लिए एक खुला लेन, आमतौर पर SSE पर। यह स्टैक की एजेंट-से-मानव परत पर कब्जा करता है, MCP (उपकरण), A2A (अन्य एजेंट), और AP2 (भुगतान) के साथ, और एक सक्षम क्लाइंट छोटा होता है (मेरा लगभग 150 लाइनें है, कोई फ़्रेमवर्क नहीं)। प्रोटोकॉल वायर को मानकीकृत करता है और जानबूझकर रेंडरिंग, प्राधिकरण, या स्कीमा शासन को नहीं, इसलिए वे आपका काम बने रहते हैं। सबसे अधिक लाभ वाला निर्णय वायर पर बिल्कुल नहीं है: स्ट्रीम को टिकाऊ, बाहरीकृत स्थिति (एक प्रोसेस इंजन, Temporal, एक चेकपॉइंटेड ग्राफ) का एक प्रक्षेपण बनाएं, और UI क्रैश के बाद फिर से शुरू करने योग्य हो जाता है, मानव अनुमोदन के लिए एक फर्स्ट-क्लास कंस्ट्रक्ट के रूप में रोका जा सकने वाला, और निष्पादन के एक साइड इफेक्ट के रूप में ऑडिट करने योग्य। मैंने AURUM के साथ पैटर्न को सिद्ध किया, एक काल्पनिक निजी-बैंक ऑनबोर्डिंग प्रवाह जहाँ एक इवेंट स्ट्रीम एक ग्राहक दृश्य, एक सलाहकार अनुमोदन कतार, और एक कच्चे ऑपरेटर कंसोल को फ़ीड करती है, और जहाँ $1.5M अनुमोदन विराम एक पार्क किया गया प्रोसेस टोकन है, न कि एक प्रॉम्प्ट।
संदर्भ
- AG-UI प्रोटोकॉल दस्तावेज़: https://docs.ag-ui.com
- GitHub पर AG-UI प्रोटोकॉल: https://github.com/ag-ui-protocol/ag-ui
- AURUM डेमो रेपो (चलाने योग्य, शैडो मोड को किसी API कुंजी की आवश्यकता नहीं है): https://github.com/letmereviewyourcode/camunda-agui-wealth-demo
- LinkedIn पर EP02 डेमो वीडियो और चर्चा: https://www.linkedin.com/posts/zishanalikhan_agenticai-agui-camunda-ugcPost-7480344185674313728-ffd8
- इस श्रृंखला में साथी मार्गदर्शिकाएँ: A2A फ़ील्ड गाइड · AP2 फ़ील्ड गाइड
- RFC 6902 (JSON पैच),
STATE_DELTAके पीछे का तंत्र: https://datatracker.ietf.org/doc/html/rfc6902
एक न्यूज़लेटर आ रहा है। तब तक, नए गाइड और एपिसोड पहले LinkedIn पर और RSS फ़ीड में प्रकाशित होंगे।