मैंने एक एजेंट को एक ही दोपहर में एक अनजान पेमेंट सर्विस में चार बार खुद को शामिल करते देखा। वही सर्विस, चार नए सत्र, चार बार उसने webhook हैंडलर को शुरू से ट्रेस किया, फिर से पता लगाया कि एक dedupe कुंजी की वजह से रीट्राई idempotent हैं, और फिर से यह निष्कर्ष निकाला कि तीन फंक्शन्स पर लगा legacy_ उपसर्ग मतलब "मत छुओ"। हर सत्र में उसने अच्छा काम किया। हर सत्र में संदर्भ विंडो बंद होते ही उसने वह काम फेंक दिया।
एजेंट के पास एक नक्शा था। वह कोडबेस में सर्च कर के कुछ भी ढूँढ सकता था। जो उसके पास नहीं था वह थी याददाश्त। तो वह बार-बार वही निष्कर्ष दोबारा बनाता रहा जो पहले बना चुका था, क्योंकि नक्शा आपको बताता है कि चीज़ें कहाँ हैं — यह नहीं बताता कि पिछले मंगलवार आपने उनके बारे में क्या तय किया था।
यह पोस्ट इसी अंतर के बारे में है। सिमेंटिक कोड सर्च और स्थायी मेमोरी एक ही समस्या के दो आधे हिस्से हल करते हैं, और ज़्यादातर लोग ठीक एक ही चलाते हैं। यहाँ बताया है कि आपको दोनों क्यों चाहिए, और इन्हें कैसे जोड़ें।
दो तरह की विफलताएँ, एक गायब आधा हिस्सा
एजेंट को मेमोरी के बिना सर्च दीजिए और आपको "दोपहर में चार बार" वाला चक्र मिलता है। वह webhook हैंडलर तुरंत ढूँढ लेता है, लेकिन उस हैंडलर का मतलब — वह ऐसा क्यों बना है, क्या बदलना सुरक्षित है, कौन-सा रास्ता legacy है — कहीं टिकाऊ रूप में नहीं रहता। हर सत्र उसे दोबारा निकालता है। एजेंट सक्षम है और भुलक्कड़ है।
एजेंट को सर्च के बिना मेमोरी दीजिए और आपको उल्टी विफलता मिलती है, जो ज़्यादा चुपचाप और ज़्यादा बुरी है। उसे निष्कर्ष याद रहता है — "webhook हैंडलर में dedupe कुंजी रीट्राई को idempotent बनाती है" — लेकिन छह हफ़्ते बाद वह उस कोड को दोबारा नहीं ढूँढ पाता जिसके बारे में वह निष्कर्ष है। हैंडलर रीफैक्टर हो गया, फंक्शन का नाम बदल गया, फाइल दो हिस्सों में बँट गई। मेमोरी अब एक भरोसेमंद वाक्य है जो कहीं नहीं इशारा करता। एजेंट उस पर भरोसा करता है और एक ऐसे तथ्य पर काम करता है जो अब सच नहीं रहा।
दोनों टूल एक-दूसरे के अंधे धब्बे ढकते हैं:
| कोड ढूँढता है | फैसले याद रखता है | दूसरे के बिना | |
|---|---|---|---|
| सिमेंटिक सर्च | हाँ | नहीं | हर सत्र संदर्भ दोबारा निकालता है |
| स्थायी मेमोरी | नहीं | हाँ | ऐसे निष्कर्ष याद रखता है जिन्हें ढूँढ नहीं पाता |
एक नक्शा और एक याददाश्त। एक चलाएँ, तो एक आधा हिस्सा गायब है।
Muvon में हम दोनों आधे हिस्से ओपन-सोर्स MCP सर्वर के रूप में देते हैं — नक्शे के लिए Octocode, याददाश्त के लिए Octobrain — और इन्हें साथ चलाने वाला होस्ट Octomind। दोनों Apache-2.0 हैं। यह पोस्ट इन्हें जोड़ी के रूप में इस्तेमाल करने की वर्कफ़्लो गाइड है। अगर गहराई चाहिए, तो Octocode का सिमेंटिक कोड सर्च और Octobrain का परिचय हर टूल को अलग-अलग कवर करते हैं। मैं दोहराऊँगा नहीं, बस संदर्भ दूँगा।
हर पक्ष असल में क्या उजागर करता है
पहले बुनियाद, क्योंकि जोड़ तभी मायने रखता है जब आप असल टूल सतह जानते हों। ये MCP टूल हैं, कोई इच्छा-सूची नहीं।
Octocode आपकी रिपॉज़िटरी को tree-sitter AST पार्सिंग से इंडेक्स करता है — असली सिंबल, सपाट टेक्स्ट टुकड़े नहीं — और एजेंट को चार टूल देता है:
| टूल | क्या करता है |
|---|---|
semantic_search |
अवधारणा या व्यवहार से recall-केंद्रित सर्च। "ऑथेंटिकेशन कहाँ संभाला जाता है", "विफल अनुरोधों को रीट्राई करने वाला कोड"। नाम आपके शब्दों से मेल न खाएँ तब भी कोड ढूँढ लेता है। |
structural_search |
AST पैटर्न मिलान और सटीक सिंबल खोज। जब आप नाम, स्ट्रिंग या कॉल साइट जानते हों, तब सटीक और सस्ता। |
view_signatures |
बॉडी के बिना फंक्शन सिग्नेचर और टाइप परिभाषाएँ निकालता है — फाइल पढ़ने से पहले उसका नक्शा बनाने का सबसे सस्ता तरीका। |
graphrag |
imports, calls, implements, extends पर नॉलेज-ग्राफ क्वेरीज़। "पेमेंट मॉड्यूल पर क्या निर्भर है"। |
इंडेक्स प्रोजेक्ट-स्कोप्ड और local-first है। आप इसे octocode index से एक बार बनाते हैं और यह अद्यतित रहता है। याद रखने लायक बात: Octocode इस सवाल का जवाब देता है "यह कहाँ है और कैसे जुड़ा है?" — और हमेशा कोड को वैसा ही दिखाता है जैसा अभी है।
Octobrain एजेंट को दीर्घकालिक मेमोरी देता है, जो सामान्यीकृत Git रिमोट URL (host/org/repo) के हिसाब से प्रति-प्रोजेक्ट स्कोप्ड है। चार MCP टूल:
| टूल | क्या करता है |
|---|---|
memorize |
कोई इनसाइट, फैसला या तथ्य संग्रहीत करता है। title, content, एक memory_type (architecture, decision, bug_fix, security, …), importance, tags, related_files और दूसरी मेमोरीज़ से inline लिंक के लिए related_to[] लेता है। |
remember |
संग्रहीत मेमोरीज़ पर सिमेंटिक सर्च। 1-hop ग्राफ पड़ोसी अपने-आप लौटाता है। टेम्पोरल क्वेरीज़ के लिए created_after / created_before समर्थित। |
forget |
memory_id या क्वेरी से मेमोरी मिटाता है — अपरिवर्तनीय, confirm=true ज़रूरी। |
knowledge |
बाहरी दस्तावेज़ों और URL को इंडेक्स और सर्च करने के लिए अलग नॉलेज बेस (search, store, read, match, delete)। |
memorize का अपना विवरण एजेंट से कहता है कि डुप्लिकेट से बचने के लिए पहले remember कॉल करो, और तथ्यों को user_confirmed (उच्च महत्व) बनाम agent_inferred (निम्न) के रूप में चिह्नित करो। Octobrain Zettelkasten शैली में सिमेंटिक रूप से समान मेमोरीज़ को अपने-आप जोड़ता है, और supersedes संबंध समर्थित करता है ताकि एक सुधारा हुआ तथ्य उस पुराने तथ्य से ऊपर रैंक हो जिसे वह बदलता है — पुराना इतिहास के लिए क्वेरी-योग्य रहता है। यह याद रखें: Octobrain इस सवाल का जवाब देता है "हमने इसके बारे में क्या तय किया, और कब?" — और यही एकमात्र पक्ष है जो सत्रों के पार टिका रहता है।
समरूपता पर ध्यान दें। Octocode वर्तमान कोड जानता है पर हर बातचीत भूल जाता है। Octobrain हर बातचीत याद रखता है पर कोड नहीं जानता। कोई भी फ़ील्ड — मेमोरी पर related_files, सर्च परिणाम में फाइल पथ — दूसरे टूल के बिना सार्थक नहीं जो उसे हल करे।
ये कैसे जुड़ते हैं: चक्र
दोनों टूल सिर्फ़ साथ नहीं रहते — वे एक चक्र बनाते हैं, और वही चक्र पूरी तकनीक है। चार चालें:
1. ढूँढने के लिए सर्च। एजेंट नहीं जानता कि webhook idempotency लॉजिक कहाँ रहता है। वह semantic_search("webhook retry idempotency dedupe") कॉल करता है। Octocode हैंडलर और dedupe-कुंजी जाँच लौटाता है। अब एजेंट के पास स्थान और वर्तमान कोड है।
2. फैसला याद करो, स्थान नहीं। उस कोड पर सोचने के बाद — रीट्राई idempotent होने की पुष्टि, legacy रास्ता पहचान, आपके साथ स्कोप सीमा पर सहमति — एजेंट memorize कॉल करता है। अहम बात: वह निष्कर्ष और तर्क संग्रहीत करता है, related_files से टैग किया हुआ, कोड की कॉपी नहीं और लाइन नंबर नहीं। memory_type = "architecture", अगर आपने पुष्टि की तो ऊँचा importance। फैसला अब टिकाऊ है।
3. अगली बार याद करो। नया सत्र, संदर्भ विंडो खाली। कुछ छूने से पहले, एजेंट remember("webhook payments idempotency") कॉल करता है। Octobrain संग्रहीत फैसला लौटाता है साथ ही उसके 1-hop पड़ोसी — संबंधित सुरक्षा नोट, लिंक की हुई legacy-रास्ता चेतावनी। एजेंट सत्र की शुरुआत पहले से वह जानते हुए करता है जिसे समझने में पहले चार सत्र लगे थे।
4. जाँचने के लिए दोबारा सर्च। यह चाल लोग छोड़ देते हैं, और यही मेमोरी को ईमानदार रखती है। मेमोरी कहती है "idempotency webhook हैंडलर में रहती है"। उस पर काम करने से पहले, एजेंट related_files पर semantic_search या view_signatures कॉल करता है ताकि पुष्टि हो कि कोड अब भी मेमोरी से मेल खाता है। अगर हैंडलर रीफैक्टर हुआ और dedupe कुंजी हट गई, तो नया सर्च बेमेल उजागर कर देता है। एजेंट मेमोरी अपडेट करता है — पुरानी से supersedes लिंक के साथ memorize — और वर्तमान सच पर आगे बढ़ता है।
┌─────────────────────────────────────────────┐
│ │
▼ │
semantic_search ──► तर्क ──► memorize ──► remember
(कोड ढूँढो) (तय करो) (फैसला (अगला सत्र:
▲ संग्रहो) वापस लोड)
│ │
└────────── जाँचने के लिए दोबारा सर्च ◄───────┘
(कोड अब भी मेमोरी से मेल खाता है?)
नक्शा मेमोरी को असली कोड से बँधा रखता है। मेमोरी एजेंट को वह दोबारा निकालने से रोकती है जो वह पहले से जानता है। चरण 2 और 3 के बिना सर्च भुलक्कड़ एजेंट है। चरण 1 और 4 के बिना मेमोरी भरोसेमंद-पर-गलत एजेंट है। चक्र दोनों आधे हिस्सों का अपना काम करना है।
चरण 4 इतना मायने क्यों रखता है: मेमोरी एक निश्चित समय पर कोड के बारे में एक दावा है, और कोड चलता रहता है। Octobrain supersedes-सुधारे तथ्य को पुराने से ऊपर रैंक कर सकता है, पर किसी को पहले पुरानापन देखना होता है। Octocode वही "कोई" है। दोबारा सर्च एजेंट की अपनी मेमोरी के खिलाफ़ वास्तविकता की जाँच है।
दोनों सर्वर पंजीकृत करना ताकि एजेंट के पास दोनों साथ हों
कोई टूल मदद नहीं करता अगर एजेंट सिर्फ़ एक तक पहुँच सके। पूरा बिंदु यही है कि नक्शा और मेमोरी एक ही सत्र में उपलब्ध हों ताकि एजेंट चक्र चला सके बिना आपके बिचौलिए बने। यह रहा वायरिंग।
Octomind अपनी कॉन्फ़िग में [[mcp.servers]] के तहत MCP सर्वर घोषित करता है। बिल्ट-इन सर्वर (core, runtime, agent, orchestration) हमेशा रहते हैं; आप Octocode और Octobrain को दो stdio सर्वर के रूप में जोड़ते हैं:
[[mcp.servers]]
name = "octocode"
type = "stdio"
command = "octocode"
args = ["mcp", "--path=."]
timeout_seconds = 240
tools = []
[[mcp.servers]]
name = "octobrain"
type = "stdio"
command = "octobrain"
args = ["mcp"]
timeout_seconds = 60
tools = []
tools = [] का मतलब है "इस सर्वर के सभी टूल उजागर करो"। --path=. Octocode को वर्तमान रिपॉज़िटरी तक सीमित करता है; Octobrain खुद को सामान्यीकृत Git रिमोट URL (host/org/repo) से अपने-आप सीमित करता है, इसलिए एजेंट एक प्रोजेक्ट में जो मेमोरी संग्रहीत करता है वह दूसरे से अलग रहती है। Octocode का टाइमआउट उदार है क्योंकि इंडेक्स के बाद पहली सर्च एक लोकल एम्बेडिंग मॉडल को कैश में खींच सकती है; Octobrain का छोटा है क्योंकि मेमोरी लुकअप सस्ते हैं।
अगर आप Octomind के बजाय Claude Code पर हैं, तो वही दो सर्वर, CLI तरीके से पंजीकृत:
claude mcp add octocode -- octocode mcp --path .
claude mcp add octobrain -- octobrain mcp
Claude Desktop, Cursor और Windsurf वही mcpServers JSON ब्लॉक लेते हैं — प्रति सर्वर एक प्रविष्टि। मैकेनिक्स हर टूल के लिए दस्तावेज़ित है; यहाँ बस इतना मायने रखता है — दोनों, एक ही एजेंट में। Octocode वाला पर Octobrain बिना एजेंट बिना मेमोरी वाला नक्शा है। Octobrain वाला पर Octocode बिना एजेंट बिना नक्शे वाली मेमोरी है। आपको जोड़ी चाहिए।
पहली रन से पहले एक पूर्व-शर्त: रिपॉज़िटरी इंडेक्स करें। प्रोजेक्ट रूट में octocode index। Octobrain को कुछ नहीं चाहिए — यह खाली शुरू होता है और जैसे-जैसे एजेंट फैसले संग्रहीत करता है, भरता जाता है। अगर आपकी रिपॉज़िटरी इतनी बड़ी है कि इंडेक्सिंग एक असली ऑपरेशन है, तो बड़े कोडबेस को लोकली सिमेंटिक सर्च के लिए इंडेक्स करने वाली सहोदर पोस्ट इसे API कुंजियों के बिना कवर करती है।
व्यावहारिक उदाहरण: एक अनजान सर्विस में एजेंट को शामिल करना
यह रही पोस्ट की शुरुआत वाली वही पेमेंट सर्विस, इस बार सही तरीके से चलाई गई। देखिए चक्र वह काम कैसे करता है जो चार भुलक्कड़ सत्र नहीं कर सके।
सत्र 1 — ठंडी शुरुआत, नक्शा और पहली मेमोरीज़ बनाओ।
एजेंट ने यह सर्विस कभी नहीं देखी। वह पढ़ने से नहीं, नक्शा बनाने से शुरू करता है:
view_signatures("src/payments/**/*.rs")
→ webhook.rs: handle_webhook, verify_signature, dedupe_key
→ charge.rs: create_charge, capture, legacy_settle, legacy_refund, legacy_void
legacy_ उपसर्ग वाले तीन फंक्शन आँखों में उछलते हैं। एजेंट पूछता है; आप पुष्टि करते हैं कि ये एक deprecated सेटलमेंट रास्ता है जिसे एक cron job अब भी कॉल करता है और जिसे "साफ़" करने की अनुमति किसी को नहीं। यह संभालने लायक फैसला है — तो यह मेमोरी में जाता है, शून्य में नहीं:
memorize(
title: "legacy_ settlement path in charge.rs is load-bearing",
content: "legacy_settle/refund/void are called by the nightly
reconciliation cron. Deprecated but NOT dead. Do not remove
or refactor without checking cron/reconcile.rs.",
memory_type: "architecture",
importance: 0.9,
source: "user_confirmed",
tags: ["payments", "legacy", "cron"],
related_files: ["src/payments/charge.rs", "src/cron/reconcile.rs"]
)
फिर वह semantic_search("webhook retry idempotency") से idempotency ट्रेस करता है, dedupe_key पर पहुँचता है, उस पर सोचता है, और एक दूसरी मेमोरी संग्रहीत करता है — memory_type: "architecture", पहली से related_to के साथ लिंक की हुई ताकि बाद में दोनों साथ उभरें। सत्र समाप्त। दो मेमोरीज़ टिकती हैं; कोड इंडेक्स टिकता है। दोपहर का तर्क अब फेंकने लायक नहीं।
सत्र 2 — गर्म शुरुआत, तीन हफ़्ते बाद।
नई संदर्भ विंडो। दोबारा ट्रेस करने के बजाय, एजेंट पहले वह लोड करता है जो वह जानता है:
remember("payments webhook legacy settlement")
→ "legacy_ settlement path is load-bearing" (importance 0.9, CONFIRMED)
→ 1-hop पड़ोसी: "webhook idempotency via dedupe_key"
एक कॉल, और एजेंट वहीं से शुरू करता है जहाँ सत्र 1 खत्म हुआ था — उस लिंक किए पड़ोसी सहित जो उसने स्पष्ट रूप से नहीं माँगा था। अब जाँच चरण। मेमोरी src/payments/charge.rs की ओर इशारा करती है, तो उस पर भरोसा करने से पहले एजेंट दोबारा सर्च करता है:
view_signatures("src/payments/charge.rs")
→ create_charge, capture, settle_v2, refund_v2, void_v2
legacy_ फंक्शन चले गए हैं। किसी ने settle_v2 शिप किया और legacy रास्ता हटा दिया। मेमोरी अब बासी है — और चूँकि एजेंट ने मेमोरी पर आँख मूँदकर भरोसा करने के बजाय नक्शे के खिलाफ़ जाँचा, उसने इसे पकड़ लिया। वह तीन हफ़्ते पुराने तथ्य पर काम करने के बजाय पुराने फैसले को बदल देता है:
memorize(
title: "settlement path migrated to settle_v2",
content: "legacy_settle/refund/void removed in the v2 migration.
cron/reconcile.rs now calls settle_v2. Earlier 'do not remove'
note no longer applies.",
memory_type: "architecture",
related_to: [{ target_id: <old_memory_id>, relationship_type: "supersedes" }],
related_files: ["src/payments/charge.rs", "src/cron/reconcile.rs"]
)
भविष्य के remember कॉल अब सुधारे तथ्य को बासी से ऊपर रैंक करते हैं, जबकि पुराना नोट उनके लिए क्वेरी-योग्य रहता है जो पूछते हैं "यह पहले क्या करता था?"। एजेंट ने खुद को एक बार शामिल किया, परिणाम रखा, और वास्तविकता बदलने पर खुद को सुधारा — ठीक वही जो "दोपहर में चार सत्र" वाला एजेंट कभी नहीं कर सका, क्योंकि उसके पास नक्शा था और कोई मेमोरी नहीं।
एंटी-पैटर्न
चक्र सरल है। इसे तोड़ने के तरीके विशिष्ट हैं। इनसे बचें:
अस्थिर लाइन नंबर याद रखना। "बग charge.rs:142 पर है" उस पल बेकार हो जाता है जब कोई ऊपर एक import जोड़ता है। क्या और क्यों संग्रहीत करें, related_files और सिंबल नामों से बँधा हुआ — कहाँ को दोबारा-सर्च चरण से ढूँढने दें। Octocode dedupe_key को ढूँढ लेता है चाहे वह लाइन 142 पर हो या 90 पर; याद किया गया लाइन नंबर बस टाइमस्टैम्प वाला झूठ है।
मेमोरी में जरूरत से ज्यादा इंडेक्स करना। Octobrain का memorize विवरण स्पष्ट है: अस्थायी स्थिति और आसानी से दोबारा निकलने वाली चीज़ें छोड़ दें। अगर semantic_search इसे एक कॉल में ढूँढ ले, तो यह मेमोरी में नहीं रखना चाहिए — मेमोरी निष्कर्षों और फैसलों के लिए है, उन तथ्यों के लिए नहीं जो नक्शा पहले से रखता है। "auth मॉड्यूल src/auth में है" याद रखना उस चीज़ पर एक स्लॉट बर्बाद करना है जो नक्शा मुफ़्त देता है, और उन मेमोरीज़ का recall पतला करता है जो असल में मायने रखती हैं। मेमोरी वह संग्रहीत करती है जो कोड आपको नहीं बता सकता: क्यों, स्कोप सीमा, वह "इसे मत छुओ" जो आप सिर्फ़ इसलिए जानते हैं क्योंकि किसी ने कहा।
बासी मेमोरीज़ पर बिना दोबारा जाँचे भरोसा करना। यह सबसे ज़्यादा काटता है, और इसीलिए चरण 4 मौजूद है। मेमोरी एक निश्चित समय पर कोड के बारे में दावा है। कोड चलता रहता है। किसी पुराने फैसले पर काम करने से पहले हमेशा related_files दोबारा सर्च करें; जब कोड खिसक गया हो, तो पुराने निष्कर्ष को नए कोड पर थोपने के बजाय मेमोरी को supersede करें। जिस मेमोरी को आप कभी नहीं जाँचते, वह पलटकर जवाब देने वाला तकनीकी कर्ज़ है।
बदली गई मेमोरीज़ को लिंक करने के बजाय सड़ने देना। जब कोई तथ्य बदले, तो सिर्फ़ नया memorize कर के पुराने को अनाथ न छोड़ें — उन्हें supersedes से लिंक करें। Octobrain वर्तमान तथ्य को बासी से ऊपर रैंक करता है और इतिहास को क्वेरी-योग्य रखता है। अनाथ सुधार दो समान रूप से भरोसेमंद विरोधाभासी मेमोरीज़ छोड़ते हैं और यह जानने का कोई तरीका नहीं कि कौन-सी वर्तमान है।
एक आधा हिस्सा चलाकर इसे पूरा मान लेना। अकेली सर्च हमेशा के लिए दोबारा निकालती रहती है। अकेली मेमोरी कोड से बेसुर हो जाती है। मूल्य किसी एक टूल में नहीं है — यह उनके बीच के चक्र में है। अगर आप सिर्फ़ एक सर्वर पंजीकृत करते हैं, तो आपने आधा दिमाग बनाया है।
छोटा संस्करण
एक अनजान कोडबेस में AI एजेंट को दो चीज़ें चाहिए जिन्हें इंसान सहज मानता है: संबंधित कोड ढूँढने की क्षमता, और उसके बारे में जो तय हुआ उसे याद रखने की क्षमता। सिमेंटिक सर्च पहली है। स्थायी मेमोरी दूसरी है। इन्हें जोड़ी के रूप में चलाएँ — ढूँढने के लिए सर्च, फैसला याद करो, अगली बार याद करो, जाँचने के लिए दोबारा सर्च — और एजेंट हर सत्र में खुद को दोबारा शामिल करना और ऐसे निष्कर्षों पर भरोसा करना बंद कर देगा जिन्हें वह कोड में अब रख नहीं सकता।
नक्शा आपको बताता है कि चीज़ें कहाँ हैं। मेमोरी बताती है कि आपने उनके बारे में क्या तय किया। एजेंट को दोनों दें और उनके बीच चक्र जोड़ें। यही पूरी तकनीक है। अगर मेमोरी की स्वच्छता वह हिस्सा है जिस पर और चाहिए, तो शोर के बिना एजेंट मेमोरी वाली सहोदर पोस्ट इस पर गहराई से जाती है कि क्या रखना लायक है।
— Don
Octocode और Octobrain Apache-2.0 के तहत ओपन सोर्स हैं, और Octomind के अंदर साथ चलते हैं। चक्र में कोई तीखा किनारा मिला? एक issue खोलें — वर्कफ़्लो तब बेहतर होता है जब लोग हमें बताते हैं कि यह कहाँ टूटता है।


