21 जुलाई 2026

एक प्लगइन की पाँच प्रतियाँ: एक अव्यवस्थित डिप्लॉयमेंट मुझे क्या बताने की कोशिश कर रहा था

एक प्लगइन की पाँच प्रतियाँ: एक अव्यवस्थित डिप्लॉयमेंट मुझे क्या बताने की कोशिश कर रहा था

पिछले हफ्ते मैं एक छोटी बग ढूँढने निकला और उसी सॉफ़्टवेयर की पाँच प्रतियाँ मिलीं।

सॉफ़्टवेयर hermes-memory-pgvector है, एक ओपन-सोर्स प्लगइन जिसे मैं मेंटेन करता हूँ। यह AI एजेंटों के एक बेड़े को PostgreSQL और pgvector पर साझा, टिकाऊ मेमोरी देता है — ताकि एक एजेंट जो सीखता है, उसे बाकी याद रख सकें। इसे PyPI पर प्रकाशित किया गया है। आप इसे pip के साथ इंस्टॉल कर सकते हैं।

और फिर भी मेरे अपने सर्वर पर यह एक git checkout से चल रहा था, जो किसी दूसरे प्रोजेक्ट के source tree के भीतर छिपा हुआ था — और साफ़-सफ़ाई की एक सामान्य कार्रवाई से मिट जाने से बस एक कदम दूर था। मेरे infrastructure repo में भी एक vendored copy थी जिसका कोई इस्तेमाल नहीं कर रहा था, एक stale build directory थी, एक package cache था, और कुछ ही मिनट पहले बनाया गया एक hand-made symlink था, बस पूरे arrangement को ढहने से रोकने के लिए।

ऐसा सेटअप वही होता है जो आप छह महीने बाद अपने ही आप से विरासत में पाते हैं और जिसका औचित्य तुरंत नहीं बता पाते।

क्यों pip install पर्याप्त नहीं था

असल में यही हिस्सा पूरे mess को समझाता है।

Host framework memory plugins को directories स्कैन करके खोजता है। वह अपने bundled plugins folder के अंदर, और एक user plugins folder के अंदर, __init__.py वाली ऐसी subdirectory ढूँढता है जिसमें सही class का उल्लेख हो। यही पूरी discovery mechanism है। वह कभी installed Python packages को inspect नहीं करता, और कोई entry-point registration भी नहीं है।

तो pip install ने मेरे plugin को मशीन पर सही तरीके से, बिल्कुल सही environment में, डाल तो दिया — लेकिन framework उसे देख ही नहीं सका। पूरी तरह installed. पूरी तरह invisible.

ऐसी स्थिति में साफ़ विकल्प यही लगता है कि एक copy वहाँ रख दी जाए जहाँ scanner देखेगा। deployment repo में folder copy कर दो। उसे framework के साथ-साथ checkout कर लो। उसे symlink कर दो। इनमें से हर एक अपने-आप में एक उचित local decision है, और मिलकर यही वजह बनते हैं कि पाँच copies बन जाती हैं और कोई ऐसा deployment नहीं बचता जिसे समझाया जा सके।

समाधान: scanner से लड़ना बंद करो

इस हफ्ते मैंने जो release ship किया, उसमें एक command जोड़ी गई है, जिसे install करने के बाद एक बार चलाना होता है:

pip install hermes-memory-pgvector
hermes-pgvector install

वह दूसरी command उस folder में एक छोटा shim लिखती है जिसे scanner पढ़ता है — कुछ पंक्तियाँ, जिनका एकमात्र काम असली, pip-installed package को import करना है। Scanner को एक directory मिल जाती है और वह संतुष्ट हो जाता है। Python import को सही ढंग से installed library तक resolve कर देता है।

वह एक ही indirection पाँच copies को एक में समेट देती है। Upgrades का मतलब हो जाता है एक pip upgrade और एक restart। Roll back करने का मतलब हो जाता है पिछले version को pin करना। कुछ भी vendored नहीं है, कुछ भी checked out नहीं है, कुछ भी drift नहीं करता, और किसी और के repository में routine housekeeping अब मेरी memory layer को साथ ले जाकर नुकसान नहीं पहुँचा सकती।

इससे और क्या निकला

Deployment को consolidate करने का मतलब था code को ठीक से दोबारा पढ़ना, और उसी में कई असली bugs सामने आए, जिनका नाम लेना ज़रूरी था:

एक substring search जो वास्तव में substring search नहीं थी। Stored memory को edit करते समय आपका text database में SQL LIKE से match किया जाता था, जहाँ % एक wildcard है। "revenue grew 15% YoY" वाली memory असंबंधित rows से match हो सकती थी — और उन्हें modify भी कर सकती थी। Backslashes के साथ उल्टा problem था: एक Windows file path quietly कुछ भी match नहीं करता था।

एक queue जो काम गिरा देती थी, जबकि दावा करती थी कि finish हो गई है। Background writer writes स्वीकार करता था, और फिर shutdown पर, अगर वह busy होता, तो logs में एक शब्द बोले बिना queue में बची हुई हर चीज़ को छोड़ देता था।

एक भ्रामक error। Plugin को ऐसे embedding model की ओर point करें जिसका output size गलत हो, तो आपको किसी unrelated fallback से 404 मिलता था, बजाय इसके कि "expected 768 dimensions, got 1024."

इनमें से कोई भी exotic नहीं था। ये सब ऐसी चीज़ें थीं जिन्हें ध्यान से पढ़ने पर पकड़ा जा सकता था, और एक passing test suite नहीं पकड़ पाता था।

वह सबक जो मैं बार-बार सीखता हूँ

जब deployment mess हो, तो वह mess आमतौर पर design के बारे में कुछ सच बता रहा होता है।

पाँच copies लापरवाही नहीं थीं। हर एक एक तर्कसंगत workaround थी। वे एक symptom थीं, और मूल समस्या यह थी कि मेरा package उसी तरह discover नहीं किया जा सकता था जैसा उसे install किया जाना था। Workarounds को एक-एक करके ठीक करने से बस एक ज्यादा सुथरा mess बनता। Discovery gap को ठीक करने से workarounds की ज़रूरत ही खत्म हो गई।

अगर आप ऐसी चीज़ maintain करते हैं जिसे लोग एक तरीके से install करते हैं और दूसरे तरीके से deploy, तो उस gap को बंद करना काबिल-ए-ग़ौर है। वह शायद आपको कुछ बताने की कोशिश कर रहा है।


hermes-memory-pgvector BSD-3 licensed है, और GitHub तथा PyPI पर उपलब्ध है।