Omnilude बनाने के लिए, मैं ऐसा backend बना रहा हूँ
यह लेख किसी एक feature का परिचय नहीं है। यह इस बात को व्यवस्थित करके बताने की कोशिश है कि Omnilude नाम का प्रोजेक्ट किस तरह की संरचना पर बन रहा है, और मैं backend को इस तरह क्यों संगठित कर रहा हूँ।
मैं अभी जो काम कर रहा हूँ, वह दो दिशाओं में एक साथ फैला हुआ है। पहली दिशा coding agents की सीमाओं को परखने की है। मैं लगातार देख रहा हूँ कि केवल vibe coding और stream of consciousness के करीब निर्देशों के सहारे implementation कहाँ तक जा सकती है, और क्या यह तरीका सचमुच production level development तक पहुँच सकता है। दूसरी दिशा यह है कि यह प्रयोग सिर्फ प्रयोग बनकर खत्म न हो, बल्कि अंततः एक वास्तविक service में बदल जाए। उस service के केंद्र में Omnilude है, और मैं इस संरचना के ऊपर सबसे पहले उस तरह के game development के माध्यम से इस प्रयोग को आगे बढ़ाना चाहता हूँ जिसे मैं पहले से बनाना चाहता था।
इसी वजह से यह लेख implementation showcase से अधिक structure introduction के करीब है। लेकिन मैं इसे केवल services की सूची बनाकर समझाना नहीं चाहता था। यह backend कई modules में बँटा हुआ है, फिर भी मैं इसे जिस तरह देखता हूँ वह थोड़ा अलग है। मैं पूरी चीज़ को एक product backend की तरह देखता हूँ। Authentication, AI execution, content management, realtime connections, file storage और event streams सब एक ही लक्ष्य की ओर बँधे हुए हैं।
यह लेख लंबा और थोड़ा कठिन लग सकता है, फिर भी मैं इसे जितना हो सके उतना ठोस तरीके से समझाने की कोशिश करूँगा।
Omnilude किस तरह का प्रोजेक्ट बनना चाहता है
मेरे लिए Omnilude एक साथ दो अर्थ रखता है।
पहला अर्थ है experimentation। आज के समय में मुझे नहीं लगता कि developers के लिए सिर्फ कोई नया tool आज़मा लेना काफी है। जो लोग AI को अच्छी तरह इस्तेमाल कर पाते हैं और जो नहीं कर पाते, उनके बीच का अंतर आगे और बढ़ सकता है। और मेरा मानना है कि यह अंतर केवल implementation speed में नहीं, बल्कि problem definition, structure design और verification में और बड़ा होगा। मैं इस बदलाव को सिर्फ बाहर से देखना नहीं चाहता था। मैं इसे एक वास्तविक product बनाते हुए अपने शरीर से पार करना चाहता था।
दूसरा अर्थ एक बहुत ठोस product goal है। मैं लंबे समय से games बनाना चाहता था। लेकिन अब मैं उस लक्ष्य तक सिर्फ पुराने तरीके से नहीं पहुँचना चाहता। मैं AI-powered creation tools, content generation pipelines, operable backend और realtime experience को एक ही flow में जोड़कर आगे बढ़ना चाहता हूँ। Omnilude उसी दिशा पर रखा गया प्रोजेक्ट है।
दूसरे शब्दों में, यह प्रोजेक्ट एक ओर AI को जितना हो सके उतना आक्रामक तरीके से इस्तेमाल करने वाला AI agent experiment है, और दूसरी ओर ऐसा product development project है जिसे अंततः एक shippable service में बदलना ही है।
कई services, लेकिन मेरी नज़र में एक product backend
जब मैं यह लेख लिख रहा हूँ, उस समय Omnilude backend अभी भी एक single monolithic service है। फिर भी मैं इस monolith को सिर्फ एक बड़े server की तरह नहीं देखता। मैं इसे ऐसी संरचना की तरह देखता हूँ जिसमें कई responsibility boundaries पहले से मौजूद हैं। इस लेख में आने वाले auth-service, ai-service, blog-service, game-service, storage-service, backbone-service, mmorpg-service, और shared foundation common(jspring) मेरे लिए आज की deployment units से ज़्यादा इस system को समझने और बढ़ाने का एक lens हैं। इस लेख में मैं इस internal shared layer को सुविधा के लिए common कहूँगा।
इसलिए जब मैं कहता हूँ कि कई services होने के बावजूद मैं इसे एक product backend की तरह देखता हूँ, तो उसका मतलब वर्तमान structure को बढ़ा-चढ़ाकर पेश करना नहीं है। उल्टा, यह उस नज़रिये के करीब है जिसमें अभी एक साथ जुड़े हुए system के भीतर कौन-सी responsibilities पहले से अलग हैं, और आगे वे किस दिशा में और स्पष्ट हो सकती हैं, यह समझाया जाता है। महत्वपूर्ण चीज़ services की संख्या नहीं, बल्कि यह है कि हर responsibility साझा rules के ऊपर एक ही product की ओर बँधी हुई है या नहीं।
मैं आज के Omnilude को केवल एक विशाल server के रूप में नहीं, बल्कि ऐसे product backend के रूप में देखता हूँ जिसमें एक ही system के भीतर कई boundaries साथ मौजूद हैं। बाद में ये boundaries repository और deployment units में कैसे बदलती हैं, उस प्रक्रिया को मैं अलग post में लिखना चाहता हूँ। इस लेख में मैं अभी के monolithic structure के भीतर पहले से मौजूद responsibility split को आज के शब्दों में खोलकर दिखाना चाहता हूँ।
नीचे का diagram current non-legacy backend का एक overview है, जिसे एक product backend की तरह फिर से समूहित करके दिखाया गया है।
इस diagram में मेरे लिए तीन बातें सबसे महत्वपूर्ण हैं।
पहली, common पूरे system की बुनियाद बनाता है। हर service स्वतंत्र रूप से मौजूद है, लेकिन authentication rules, internal HTTP calls, event publishing, storage handling और distributed jobs की processing shared foundation के ऊपर दोहराई जाती है। इसलिए structure बिखरता नहीं है।
दूसरी, product domains और operational infrastructure अलग हैं। auth, ai, game, mmorpg और blog product capabilities को दर्शाते हैं, जबकि storage और backbone उस shared operational foundation को संभालते हैं जिसकी product features को वास्तव में चलने के लिए जरूरत होती है।
तीसरी, यही separation structure को AI-friendly भी बनाता है। Coding agents किसी बहुत बड़े codebase को बिना साफ context के अच्छे से handle नहीं करते। लेकिन जब roles अलग हों और rules साफ हों, तब वे कहीं ज़्यादा स्थिर तरीके से काम करते हैं। मैंने यह structure सिर्फ इंसानों के लिए maintainability बढ़ाने के लिए नहीं बनाया, बल्कि AI को भी बेहतर working environment देने के लिए बनाया है।
इस structure के केंद्र में common है
इस project को समझाते समय सबसे पहले common की बात करनी पड़ती है, क्योंकि आखिरकार यही वजह है कि पूरा backend एक product की तरह चलता है।
common केवल utilities का collection नहीं है। मैं इसे internal platform SDK के ज़्यादा करीब मानता हूँ। अगर services के बीच connections को देखें, तो बहुत-सी चीज़ें पहले से common के भीतर standardize हो चुकी हैं।
common-coreJWT, shared exceptions और basic utilities जैसी सबसे निचली foundation देता है।common-webinternal HTTP client और shared web-layer conventions देता है।common-dataJPA, QueryDSL और shared data access foundation को जोड़ता है।common-messagingevent publishing path को एकसमान करता है।common-cloudstorage commit flow और access URL जैसी file-handling integrations को standardize करता है।common-dtedistributed jobs, workflows और Job Event flow उपलब्ध कराता है।
यह layer मेरे लिए इसलिए महत्वपूर्ण है क्योंकि AI-first development में असली सवाल सिर्फ इतना नहीं होता कि code कितनी तेजी से लिखा जा सकता है। असली सवाल यह होता है कि system में repeatable patterns कितने हैं। अगर हर नए feature के साथ किसी इंसान या agent को पूरी तरह नया structure समझना पड़े, तो productivity बहुत जल्दी टूट जाती है। इसके उलट, shared foundation मजबूत हो तो responsibilities को छोटे units में बाँटा जा सकता है और review points भी ज़्यादा स्पष्ट हो जाते हैं।
उदाहरण के लिए, जब game-service AI capabilities को call करता है, तो वह सीधे किसी external model से नहीं जुड़ता। वह internal रूप से ai-service को call करता है। File storage भी इस तरह व्यवस्थित है कि हर service अपने-अपने तरीके से S3 को handle नहीं करती, बल्कि storage-service के रास्ते जाती है। Events भी ज़रूरत पड़ने पर backbone-service से होकर बहते हैं। इसी consistency की वजह से मैं AI को ज़्यादा precise instructions दे पाता हूँ और results को तेज़ी से verify कर पाता हूँ।
Developers के लिए भी यह structure महत्वपूर्ण है। Services भले कई दिखें, लेकिन वे वास्तव में एक ही language, framework, rules और internal platform share करती हैं। इसलिए सोचने की unit पूरी तरह टूटती नहीं है। मुझे लगता है कि यह Omnilude की सबसे बड़ी strengths में से एक है।
Product domain इस तरह क्यों बाँटा गया है
अब मैं थोड़ा और ठोस तरीके से बताना चाहता हूँ कि हर service क्या role निभाती है। सिर्फ names गिनाने से ज़्यादा महत्वपूर्ण यह समझना है कि उन्हें इस तरह क्यों अलग किया गया है।
auth-service: trust की शुरुआत
auth-service login, accounts, devices, permissions, credits और activity logs को संभालता है। ऊपर से यह एक familiar auth server जैसा दिख सकता है, लेकिन मैं इसे सिर्फ login API की तरह नहीं देखता। यह service पूरे product की trust boundary को संभालती है।
User कौन है, उसके पास कौन-सा session है, उसके permissions क्या हैं, और उसका credit या usage history क्या है, इसकी शुरुआत ज़्यादातर यहीं से होती है। अगर बाकी services को तेज़ी से experiment करना है और नई capabilities जोड़नी हैं, तो इस foundational trust layer को और ज़्यादा conservative और explicit होना पड़ता है।
दिलचस्प बात यह है कि यह service पूरी तरह isolated नहीं है। Startup के समय यह backbone-service और platform settings के साथ sync होती है, और मिलकर backend की shared JWT conventions बनाती है। दूसरे शब्दों में, authentication एक स्वतंत्र feature भी है और पूरे system की connection language भी।
ai-service: AI execution का hub
ai-service इस project की सबसे प्रतीकात्मक service है। LLM calls, multi-agent workflows, media generation, product agents, roleplay flows और कई system-level AI APIs यहीं इकट्ठा होते हैं।
महत्वपूर्ण बात यह है कि यह service सिर्फ external model APIs का proxy नहीं है। मैं इसे AI execution hub की तरह देखता हूँ। यह वही central layer है जो तय करती है कि कौन-सा model call होगा, कौन-सा workflow चलेगा, कौन-से events emit होंगे, outputs कहाँ store होंगे और progress बाहर कैसे stream होगी।
मुझे लगता है कि समय के साथ यह structure और महत्वपूर्ण होती जाएगी। जो projects AI को आक्रामक तरीके से इस्तेमाल करते हैं, उनमें अगर external model calls हर जगह फैल जाएँ तो control बहुत जल्दी मुश्किल हो जाता है। Cost, error handling, prompt conventions, execution logs, output storage और provider switching strategy सबको साथ रखें, तो AI को एक जगह से orchestrate करना बेहतर होता है। ai-service वही भूमिका निभाता है।
game-service: वह domain जिसे मैं सबसे पहले वास्तविक बनाना चाहता हूँ
game-service इस project का core product domain है। Scenarios, story quizzes, game sessions, shared game metadata और asset studio features सब यहाँ इकट्ठा होते हैं।
यह service क्यों महत्वपूर्ण है, इसका कारण सीधा है। Omnilude से मैं जो पहली चीज़ वास्तव में launch करना चाहता हूँ, वह अंततः इसी क्षेत्र से जुड़ती है। इसलिए यह service केवल passive data store नहीं है, बल्कि ऐसा domain है जो AI के साथ सबसे अधिक interaction करता है। Scenario creation, asset generation, session creation और play flow operation सब यहीं केंद्रित हैं।
खासतौर पर यह महत्वपूर्ण है कि game-service सीधे ai-service से जुड़ा हुआ है। Content generation, review, support tasks, asset production और कुछ automation flows अनिवार्य रूप से AI के कारण तेज़ होने वाले हैं। मैंने इस connection को छिपाने की बजाय structure में ही स्पष्ट रूप से दिखाना बेहतर समझा।
mmorpg-service: realtime runtime को मैं अलग axis की तरह देखता हूँ
mmorpg-service game area के भीतर है, लेकिन इसकी प्रकृति काफी अलग है। यह service केवल HTTP-based management APIs ही नहीं देती, बल्कि एक अलग gateway port पर realtime WebSocket runtime भी चलाती है।
अगर कोई पूछे कि मैंने इसे बाकी के साथ क्यों नहीं मिला दिया, तो जवाब साफ है। CRUD-centric content APIs और realtime game servers की failure modes, performance requirements और state management patterns एकदम अलग होते हैं। मुझे लगता है कि इन्हें एक ही thinking unit की तरह नहीं संभालना चाहिए।
Authentication model भी दिलचस्प है। Realtime connection के समय mmorpg-service के भीतर का gateway, auth-service द्वारा जारी JWT convention को locally validate करता है। वह हर interaction पर auth service को HTTP से दोबारा call नहीं करता। इससे साफ दिखता है कि realtime systems को regular business APIs से कहाँ अलग होना चाहिए।
blog-service: project की external memory
blog-service बाकी services की तुलना में कम complex लग सकता है, लेकिन मेरे लिए इसकी जगह महत्वपूर्ण है। यह service केवल blog चलाने के लिए CMS नहीं है। यह वह path है जिसके ज़रिए मैं बाहर की दुनिया में यह जमा करता हूँ कि मैं क्या बना रहा हूँ, कौन-से निर्णय ले रहा हूँ और कौन-से experiments कर रहा हूँ।
अगर Omnilude केवल अंदर चलने वाला project नहीं है, तो उसकी structure, experiments और trial and error को बाहर से भी समझाया जा सकना चाहिए। blog-service उसी record को संभालता है। Posts, comments, translations, SEO और static asset links यहीं इकट्ठा होते हैं, क्योंकि product को external communication layer की भी जरूरत होती है।
Operational infrastructure को अलग क्यों रखा गया है
किसी service को केवल product features के सहारे operate नहीं किया जा सकता। Results को store करने, files का lifecycle manage करने, progress stream करने, events को move करने, long-running jobs को track करने और realtime connections को बनाए रखने वाली layers भी चाहिए होती हैं।
Omnilude में यह जिम्मेदारी मुख्य रूप से storage-service और backbone-service निभाते हैं।
storage-service: files का असली lifecycle यहीं संभाला जाता है
कई projects में file storage को बाद में जोड़ी जाने वाली capability की तरह लिया जाता है। लेकिन वास्तविक product operation में file uploads, temporary states, commit और cancel flows, access URLs, thumbnail URLs और static object metadata सब महत्वपूर्ण होते हैं। File बस upload करके खत्म नहीं होती। उसका एक lifecycle होता है।
इसीलिए मैंने storage-service को अलग रखा। चाहे वह blog image हो, AI-generated result हो या game asset, मैंने कोशिश की कि जितना हो सके सब इसी रास्ते से गुजरे। इससे file handle करने वाली कोई भी service shared rules के ऊपर काम कर सकती है। और बाद में अगर access policy या storage strategy बदलती है, तो impact radius को सीमित रखना भी आसान होता है।
backbone-service: operations और asynchrony का केंद्र
backbone-service अपने नाम की तरह system की backbone के बहुत करीब है। Event hub, SSE, WebSocket, platform settings और DTE Job event flows सब यहीं इकट्ठा होते हैं।
यह service खास तौर पर इसलिए महत्वपूर्ण है क्योंकि यह AI execution के साथ बहुत अच्छी तरह जुड़ती है। मैं जो कई capabilities बना रहा हूँ, वे एक simple synchronous API call पर खत्म नहीं होतीं। जब user कोई काम शुरू करता है, तो intermediate progress चाहिए, completion event चाहिए, और कभी-कभी realtime connection या notification भी चाहिए। अगर हर domain service इन समस्याओं को अलग-अलग हल करने लगे, तो structure बहुत जल्दी messy हो जाती है।
इसीलिए मैंने asynchronous delivery और operational realtime layer को backbone में समेटा। HTTP -> backbone -> Kafka/RabbitMQ जैसी default event path और DTE progress को SSE से बाहर भेजने वाला approach मुझे ज़्यादा manageable लगता है।
नीचे का flow यह सरल करके दिखाता है कि AI generation job वास्तव में कैसे आगे बढ़ती है।
मुझे यह structure इसलिए पसंद है क्योंकि responsibilities साफ बँटी हुई हैं। Generation ai-service के पास है, result storage storage-service के पास है, और progress की external delivery backbone-service के पास है। यह separation validation को भी अधिक स्पष्ट बनाती है।
Data stores और messaging layer का उपयोग मैं इस तरह करता हूँ
अगर इस structure को और गहराई से देखना है, तो storage और messaging layer को भी साथ देखना होगा। Omnilude का current non-legacy backend infrastructure को बिना सोचे-समझे mix नहीं करता। हर layer की भूमिका काफी स्पष्ट है।
- PostgreSQL लगभग हर service के लिए default durable store है।
auth,ai,blog,game,storage,backboneऔरmmorpgसब इस axis को share करते हैं। - Redis simple cache से ज़्यादा Pub/Sub और session-like event delivery के लिए इस्तेमाल होता है। यह कई services में फैला है, लेकिन इसका purpose काफी strategic है।
- Cassandra अभी
auth-serviceऔरbackbone-serviceके activity logs और event writes के ज़्यादा करीब है। Boundaries रखी गई हैं ताकि हर service बिना वजह इससे न जुड़ जाए। - Kafka और RabbitMQ व्यवहार में
backbone-serviceके केंद्र में हैं। हर service को सीधे message broker से जोड़ने के बजाय events पहले backbone को भेजे जाते हैं, और backbone उन्हें messaging layer तक propagate करता है। - S3 को
storage-serviceसीधे handle करता है, और बाकी services जहाँ तक संभव हो, उसी के रास्ते जाती हैं। File-handling rules को एक जगह रखने के लिए यह एक जानबूझकर किया गया choice है।
शुरुआत में यह थोड़ा indirect लग सकता है। लेकिन मुझे लगता है कि लंबी अवधि में यही separation कहीं अधिक महत्वपूर्ण है। अगर feature services खुद storage और messaging दोनों संभालने लगें, तो responsibility boundaries जल्दी धुंधली हो जाती हैं। इसके उलट, जब infrastructure access को gateway-style services के जरिए व्यवस्थित किया जाता है, तब policy changes और failure points दोनों को संभालना आसान हो जाता है।
AI के साथ काम करते समय भी यह structure फायदेमंद है। जब मैं किसी agent को कोई feature देता हूँ, तो अगर यह साफ हो कि वह feature कहाँ तक directly handle करेगा और कहाँ shared paths का उपयोग करेगा, तो result कहीं अधिक stable आता है।
Authenticated requests और realtime connections अलग रास्तों से क्यों जाते हैं
Omnilude को और ठोस तरीके से समझने के लिए synchronous requests और realtime connections को अलग-अलग देखना बेहतर है।
ज़्यादातर सामान्य content queries और management operations उस flow का पालन करते हैं जिसमें user पहले auth-service के माध्यम से login करता है और फिर domain APIs को call करता है। इस flow में मुख्य बात shared JWT conventions और permission model का बना रहना है। क्योंकि blog-service, game-service और ai-service इस common convention को share करते हैं, इसलिए services के अलग होने पर भी user को अपेक्षाकृत consistent experience मिलता है।
लेकिन realtime connections की requirements अलग होती हैं। खास तौर पर mmorpg-service अलग gateway port :9088/ws का उपयोग करता है। User के पास पहले से auth-service द्वारा जारी token होता है, और gateway उसे locally validate करता है। यह structure इसलिए है ताकि हर बार auth service तक round trip किए बिना session जल्दी बन सके।
नीचे का flow यही अंतर दिखाता है।
यह अंतर दिखने से अधिक महत्वपूर्ण है। इस structure के जरिए मैं यह साफ दिखाना चाहता था कि सामान्य business APIs, long-running AI jobs और realtime game sessions के center of gravity अलग-अलग होते हैं। सब कुछ एक ही pattern में डाल देना सरल लग सकता है, लेकिन वास्तविक operation में यह अक्सर समस्याएँ बढ़ा देता है।
यह structure AI-first development से कैसे जुड़ती है
यहाँ तक पहुँचने पर एक स्वाभाविक सवाल उठता है। आखिर इस तरह की structure का AI को अच्छी तरह इस्तेमाल करने से क्या संबंध है?
मुझे लगता है यह सवाल बहुत महत्वपूर्ण है। आज भी बहुत-से developers AI को सिर्फ code लिख देने वाले tool की तरह देखते हैं। लेकिन मेरा मानना है कि productivity में असली छलांग तब नहीं आती जब हम बस ज़्यादा code generate करने लगते हैं। वह तब आती है जब system खुद ऐसी structure हासिल करने लगता है जिसे AI आसानी से समझ सके।
उदाहरण के लिए:
- Blurry roles वाले एक बड़े service की तुलना में clear responsibilities वाले service set को prompts में बाँटना आसान होता है।
commonजैसी internal platform वाली codebase agents को बिना shared conventions वाली codebase की तुलना में कहीं ज़्यादा stable context देती है।- अगर file handling, event handling, AI execution और realtime connections अलग हों, तो यह trace करना आसान हो जाता है कि समस्या किस boundary पर हुई।
- अंत में इंसानों को किन points पर review करना है, यह भी कहीं ज़्यादा स्पष्ट हो जाता है।
अंततः AI-first development का मतलब हर जगह AI चिपकाना नहीं है। यह system को इस तरह व्यवस्थित करने के ज़्यादा करीब है कि AI अधिक consistency के साथ काम कर सके। Omnilude बनाते हुए मैं ठीक इसी बिंदु को test कर रहा हूँ।
इस नज़रिये से मुझे लगता है कि developers को इस समय केवल नए models की खबरों की नहीं, training की जरूरत है। सिर्फ बेहतर prompts लिखने की training नहीं, बल्कि बेहतर structures बनाने, बेहतर standards के साथ review करने और ऐसे contexts design करने की training जिनमें AI सचमुच काम कर सके। मेरा मानना है कि यह project अंततः उसी training का परिणाम होना चाहिए।
मंज़िल अब भी Omnilude launch करना है
एक वजह है कि मैं नहीं चाहता था कि यह लेख सिर्फ architecture पर आकर रुक जाए। यह structure समझाने के लिए नहीं बनाई गई। यह structure कुछ ऐसा बनाने के लिए बनाई गई है जिसे वास्तव में launch किया जाएगा।
मैं अभी AI-powered creation tools बना रहा हूँ और उनके ऊपर एक game platform implement कर रहा हूँ। यह backend इस तरह design की जा रही है कि ये दोनों flows एक जगह मिलें। AI content production को आगे धकेलती है, game domain उसे product experience में बदलता है, और operational infrastructure पूरे system को एक वास्तविक service level तक उठाती है।
मैं अब भी एक अच्छी तरह बना हुआ game launch करना चाहता हूँ। और मैं खुद यह देखना चाहता हूँ कि क्या यह प्रक्रिया सिर्फ instinct और passion से नहीं, बल्कि बेहतर structure, तेज़ experimentation और अधिक accurate verification के सहारे भी संभव हो सकती है। Omnilude मेरे लिए वह project है जहाँ यह सारी अपेक्षाएँ एक साथ जमा होती हैं।
इसीलिए यह blog सिर्फ architecture की बात नहीं करेगा। मैं लगातार यह दर्ज करना चाहता हूँ कि कौन-से features सचमुच जुड़ रहे हैं, AI वास्तव में कहाँ तक चीज़ों को आगे धकेल रही है, इंसानों को कहाँ judgment देना पड़ता है, और क्या यह structure सच में एक shippable product तक पहुँच सकती है।
अभी मैं backend structure का परिचय दे रहा हूँ, लेकिन मेरे मन में एक सवाल इससे भी ज़्यादा महत्वपूर्ण है। क्या यह तरीका सचमुच आखिर तक जा सकता है?
मैं इसका जवाब केवल शब्दों से नहीं देना चाहता। मैं इसे Omnilude को सचमुच बनाकर साबित करना चाहता हूँ।