SSD Nodes Learn 🎉 VPS $5.50/माह से
गाइड Matt Connorलेखक: Matt Connor · अपडेट किया गया: 2026-08-21

Agent memory के प्रकार और उनकी स्टोरेज लागत क्या है

Semantic, episodic और procedural memory के बीच का अंतर समझें। इस लेख में प्रत्येक मेमोरी प्रकार को VPS पर स्टोर और re-embed करने की वास्तविक लागत का विस्तृत विश्लेषण दिया गया है।

एजेंट मेमोरी के तीन प्रकार क्या हैं

एजेंट मेमोरी के प्रकार तीन भागों में विभाजित हैं, और प्रत्येक का आपके द्वारा भुगतान किए जाने वाले हार्डवेयर पर अलग प्रभाव पड़ता है: सिमेंटिक मेमोरी तथ्यों को रखती है, एपिसोडिक मेमोरी घटनाओं को याद रखती है, और प्रोसीजरल मेमोरी किसी कार्य को करने का तरीका रखती है। नीचे दी गई तालिका प्रत्येक को एक सर्वर उदाहरण के साथ परिभाषित करती है। इसके बाद का भाग वह जानकारी है जिसे आमतौर पर नहीं लिखा जाता है, यानी प्रत्येक प्रकार को स्टोर करने और उसे फिर से बनाने (rebuild) की लागत क्या है।

ChartThe three agent memory types, with one server example of each
The data behind this chart
[
  {
    "label": "Semantic",
    "what_it_holds": "Facts the agent should treat as currently true",
    "server_example": "The database listens on 10.8.0.4:5432 and the nightly dump runs at 03:15 UTC"
  },
  {
    "label": "Episodic",
    "what_it_holds": "A record of one past event or session",
    "server_example": "On 2026-08-11 the deploy failed because the disk was full, and rotating logs fixed it"
  },
  {
    "label": "Procedural",
    "what_it_holds": "How to carry out a task, as steps the agent can run",
    "server_example": "The restore runbook: stop the service, load the dump, run migrations, start the service"
  }
]

ये नाम मानव मनोविज्ञान से लिए गए हैं और इनका उपयोग सामान्य संदर्भ में है। यह विभाजन एक व्यावहारिक कारण से महत्वपूर्ण है: इन तीनों प्रकारों का आकार और मरम्मत (repair) के रास्ते अलग-अलग होते हैं, इसलिए इन सभी को एक ही vector store में रखने से प्रत्येक की कार्यक्षमता कम हो जाती है।

Semantic memory छोटी होती है और आप इसे मैन्युअल रूप से एडिट करना चाहेंगे

अपने स्वयं के सर्वर्स के बारे में कुछ सौ तथ्य केवल कुछ दसियों किलोबाइट टेक्स्ट के बराबर होते हैं। यहाँ समस्या स्टोरेज की नहीं, बल्कि सुधार (correction) की है। Semantic memory में एक गलत तथ्य एजेंट द्वारा दिए जाने वाले हर बाद के उत्तर में गलत होगा, इसलिए स्टोर ऐसा होना चाहिए जहाँ आप नाम से एक तथ्य खोज सकें, उसे बदल सकें, और यह सुनिश्चित कर सकें कि पुरानी वैल्यू हट गई है।

यह एक keyed store की ओर इशारा करता है: एक primary key वाली Postgres table, या git में छोटी markdown फाइलों की एक डायरेक्टरी। दोनों आपको एक क्वेरी चलाने, वैल्यू देखने और उसे वहीं एडिट करने की सुविधा देते हैं। Similarity search आपको यह सुविधा नहीं देता, क्योंकि आप की (key) के बजाय समानता (resemblance) के आधार पर डेटा प्राप्त करते हैं। "Database port बदलें" का अर्थ "database port का उल्लेख करने वाले हर chunk को खोजना" हो जाता है, और आप यह साबित नहीं कर सकते कि आपने उन सभी को खोज लिया है। तथ्यों को keyed रखें। यदि आप loose recall भी चाहते हैं तो उन्हें embed करें, लेकिन keyed कॉपी को ही सत्य (truth) मानें।

पुराने (stale) तथ्य खुद अपनी सूचना नहीं देते। पोर्ट बदल जाता है और रो (row) वहीं रह जाती है, इसलिए एजेंट उस नंबर के साथ उत्तर देना जारी रखता है जो जून में सही था। एजेंट मेमोरी के लिए एक staleness और pruning नीति इस पेज का दूसरा हिस्सा है, और जब टेबल अभी छोटी है, तब इसे डिजाइन करना बहुत सस्ता पड़ता है।

एपिसोडिक मेमोरी बिना किसी सीमा के क्यों बढ़ती है

एपिसोडिक मेमोरी एक लॉग है, और लॉग बढ़ते रहते हैं। प्रत्येक सत्र, प्रत्येक टूल कॉल और प्रत्येक विफल कमांड एक संभावित एपिसोड है। जो एजेंट प्रति टर्न एक पंक्ति लिखता है, वह एक महीने में इतनी अधिक पंक्तियाँ लिख देगा कि कोई भी उन्हें कभी नहीं पढ़ पाएगा, और डिस्क ही एकमात्र लागत नहीं है: प्रत्येक एम्बेडेड एपिसोड उस इंडेक्स में भी जुड़ जाता है जिसे सर्च को स्कैन करना पड़ता है।

टेबल बनाते समय ही रिटेंशन नियम तय कर लें, जब डेटा हटाना अभी भी मुफ्त है। दो प्रश्न इसका अधिकांश समाधान कर देते हैं। पहला, क्या लिखना वास्तव में सार्थक है: एक सत्र का सारांश आमतौर पर सार्थक होता है, लेकिन एक ls -la का पूरा आउटपुट आमतौर पर नहीं होता। दूसरा, प्रत्येक श्रेणी का एपिसोड कितने समय तक रहता है: जैसे कि रॉ एपिसोड 30 दिनों के लिए और सत्र सारांश एक वर्ष के लिए।

प्रत्येक एपिसोड पंक्ति को एक created_at टाइमस्टैम्प और एक source कॉलम दें। created_at के बिना आप आयु के आधार पर डेटा नहीं हटा सकते। source के बिना आप उस सब कुछ को नहीं हटा सकते जो एक खराब स्रोत से आया है, और जिस दिन कोई वेब पेज या टिकट मेमोरी में निर्देश लिखना शुरू कर देता है, उस दिन आपको ठीक इसी की आवश्यकता होती है।

DELETE FROM episodes WHERE created_at < now() - interval '30 days';

इसे एक systemd timer से चलाएं, और उसके बाद पंक्ति गणना और टेबल के आकार को वास्तव में बदलते हुए देखें। एक रिटेंशन पॉलिसी जिसे कोई निष्पादित नहीं करता, वह केवल एक टिप्पणी है।

psql -d agentmem -c "SELECT count(*) FROM episodes;"
psql -d agentmem -c "SELECT pg_size_pretty(pg_total_relation_size('episodes'));"

प्रक्रियात्मक मेमोरी (procedural memory) एक रिपॉजिटरी में होनी चाहिए

प्रक्रियात्मक मेमोरी वह तरीका है जिससे एजेंट कोई कार्य पूरा करता है: जैसे कि एक shell script, एक skill file, या क्रमिक चरणों वाली एक runbook। यह कोड है, और कोड वहीं रहना चाहिए जहाँ कोड रहता है, यानी एक git repository में, जहाँ review, versioning और diff की सुविधा उपलब्ध हो।

यदि आप runbook को embedded chunks के रूप में स्टोर करते हैं, तो आपको केवल एक अनुमानित प्रतिलिपि ही वापस मिलती है। Retrieval प्रक्रिया उन chunks को लौटाती है जिनका स्कोर सबसे अधिक होता है, जिसके कारण एजेंट step 2 और step 5 पर तो कार्य कर सकता है, लेकिन step 3 कभी सामने ही नहीं आता, और इस बात का कोई रिकॉर्ड नहीं रहता कि प्रक्रिया का कौन सा version चलाया गया था। Git में, git log इन दोनों सवालों के जवाब देता है। इसका स्टोरेज खर्च लगभग शून्य है, जो कि इसे vector prices पर स्टोर न करने का एक और कारण है।

डिस्क पर एम्बेडिंग की वास्तविक लागत

ChartVector storage in pgvector, at 4 bytes per dimension plus an 8 byte header
The data behind this chart
[
  {
    "label": "bge-small-en-v1.5 (384 dims)",
    "bytes_per_vector": 1544,
    "mib_per_100k_rows": 147.2
  },
  {
    "label": "bge-base-en-v1.5 (768 dims)",
    "bytes_per_vector": 3080,
    "mib_per_100k_rows": 293.7
  },
  {
    "label": "bge-large-en-v1.5 (1024 dims)",
    "bytes_per_vector": 4104,
    "mib_per_100k_rows": 391.4
  },
  {
    "label": "text-embedding-3-small (1536 dims)",
    "bytes_per_vector": 6152,
    "mib_per_100k_rows": 586.7
  },
  {
    "label": "text-embedding-3-large (3072 dims)",
    "bytes_per_vector": 12296,
    "mib_per_100k_rows": 1172.6
  }
]

pgvector में एक vector प्रति डाइमेंशन 4 बाइट्स और 8 बाइट्स के हेडर के रूप में स्टोर होता है, इसलिए यह गणना निश्चित है और आप डेटा लोड करने से पहले इसकी योजना बना सकते हैं। 384 डाइमेंशन वाला एक वेक्टर 1544 बाइट्स का होता है, जिससे 100,000 चंक्स 147.2 MiB वेक्टर के बराबर होते हैं। वही कॉर्पस यदि 3,072 डाइमेंशन पर एम्बेड किया जाए तो वह 1172.6 MiB का होगा, जिसमें प्रति रो 12296 बाइट्स लगेंगे। टेक्स्ट वही है, लेकिन स्टोरेज लगभग आठ गुना हो गया है।

यह केवल वेक्टर कॉलम की बात है। चंक टेक्स्ट, प्राइमरी की, रो ओवरहेड और इंडेक्स इसके अतिरिक्त होते हैं, और इंडेक्स वह हिस्सा है जिसे लोग अक्सर भूल जाते हैं। HNSW (hierarchical navigable small world, जो pgvector द्वारा बनाया गया ग्राफ इंडेक्स है) उन वेक्टर्स की अपनी कॉपी रखता है जिन्हें वह लिंक करता है, इसलिए एक इंडेक्स किए गए स्टोर का आकार ऊपर दिए गए आंकड़ों से दोगुना से भी अधिक हो सकता है। अनुमान लगाने के बजाय अपने डेटा को मापें।

SELECT pg_size_pretty(pg_total_relation_size('memories')) AS total,
       pg_size_pretty(pg_relation_size('memories_embedding_idx')) AS idx;

RAM यह तय करती है कि सर्च तेज होगी या नहीं, क्योंकि ग्राफ तभी तेजी से काम करता है जब वह मेमोरी में हो। जब इंडेक्स उस मेमोरी से बड़ा हो जाता है जिसे Postgres होल्ड कर सकता है, तो सर्च डिस्क से डेटा पढ़ना शुरू कर देती है और लेटेंसी बढ़ जाती है। बिल्ड की अपनी एक सीमा होती है, maintenance_work_mem, और जब ग्राफ इससे बड़ा हो जाता है तो बिल्ड प्रक्रिया यह सूचित करती है और धीमी हो जाती है:

NOTICE:  hnsw graph no longer fits into maintenance_work_mem after 61440 tuples
HINT:  Increase maintenance_work_mem to speed up builds.

एक ही कॉर्पस को छोटा करने के लिए दो विकल्प हैं। एक छोटा मॉडल चुनें, क्योंकि 384 डाइमेंशन की लागत 1,536 डाइमेंशन का एक चौथाई है और अपने नोट्स को दोबारा खोजने के लिए सटीकता में अंतर अक्सर इतना कम होता है कि उसे स्वीकार किया जा सकता है। या फिर हाफ प्रिसिजन (half precision) में स्टोर करें: halfvec टाइप प्रति डाइमेंशन 2 बाइट्स लेता है और साथ ही वही 8 बाइट्स का हेडर, जो कॉलम और उसके इंडेक्स दोनों के आकार को लगभग आधा कर देता है।

मॉडल चुनने से पहले एक सीमा के बारे में जानना जरूरी है। अगस्त 2026 तक, एक vector कॉलम को 2,000 डाइमेंशन तक ही इंडेक्स किया जा सकता है, इसलिए 3,072 डाइमेंशन वाली एम्बेडिंग को कॉलम स्वीकार तो कर लेता है लेकिन इंडेक्स उसे अस्वीकार कर देता है:

ERROR:  column cannot have more than 2000 dimensions for hnsw index

halfvec 4,000 डाइमेंशन तक इंडेक्स कर सकता है, इसलिए इसका सामान्य समाधान कास्ट (cast) को इंडेक्स करना है:

CREATE INDEX ON memories USING hnsw ((embedding::halfvec(3072)) halfvec_cosine_ops);

जब pgvector एक अलग मेमोरी सर्विस से बेहतर प्रदर्शन करता है

यदि सर्वर पर पहले से ही Postgres चल रहा है, तो वेक्टर्स के लिए केवल एक पैकेज और एक स्टेटमेंट की आवश्यकता होती है।

psql -V
sudo apt install postgresql-16-pgvector
CREATE EXTENSION vector;

पैकेज नाम में दी गई संख्या आपके Postgres का मेजर वर्जन है, जो Ubuntu 24.04 पर 16 है, इसलिए टाइप करने से पहले psql -V को पढ़ें।

डेटाबेस में मेमोरी रखने से आपको एक ही समय पर मेमोरी और एप्लिकेशन डेटा का बैकअप मिलता है, एक कनेक्शन पूल मिलता है, और ट्रांजेक्शन की सुविधा मिलती है: एक फैक्ट और जिस रो (row) में उसका वर्णन है, वे एक साथ कमिट होते हैं या एक साथ फेल होते हैं। एक अलग सर्विस यह वादा नहीं कर सकती।

जब निम्नलिखित में से कोई भी स्थिति हो, तो एक समर्पित मेमोरी सर्विस पर शिफ्ट हो जाएं। सर्च लोड आपके एप्लिकेशन के साथ प्रतिस्पर्धा करता है और उसे अपने स्वयं के मशीन की आवश्यकता होती है। कई होस्ट पर कई एजेंट्स एक ही मेमोरी साझा करते हैं। या आप वह एक्सट्रैक्शन और डिडुप्लीकेशन लॉजिक चाहते हैं जो एक तैयार प्रोडक्ट के साथ आता है, जो एक सेल्फ-होस्टेड Mem0 मेमोरी सर्वर के पक्ष में तर्क है। एक एजेंट और कुछ मिलियन चंक्स के कॉर्पस के लिए, जिस बॉक्स पर आप पहले से काम कर रहे हैं, उस पर pgvector को चलाना आसान है और इसमें खराबी आने की संभावना कम है। इंजन का चुनाव और प्रत्येक इंजन को RAM में कितनी आवश्यकता होती है, इसे VPS पर वेक्टर डेटाबेस चलाने के लेख में कवर किया गया है।

मॉडल बदलने पर री-एम्बेडिंग (re-embedding) की लागत

दो अलग-अलग मॉडल्स से प्राप्त वेक्टर्स की तुलना नहीं की जा सकती है, इसलिए आप नए मॉडल के साथ नई मेमोरीज को एम्बेड करके पुरानी पंक्तियों (rows) को वैसे ही नहीं छोड़ सकते। एक मिश्रित टेबल निरर्थक परिणाम देगी, क्योंकि दो अलग-अलग कोऑर्डिनेट सिस्टम के बीच गणना की गई दूरी का कोई अर्थ नहीं होता। मॉडल बदलने का अर्थ है पूरे कॉर्पस (corpus) को फिर से एम्बेड करना।

इस खर्च के चार हिस्से हैं: टोकन्स (एक API शुल्क, या आपके अपने बॉक्स पर CPU और GPU का समय), इसे चलाने के दौरान लगा वास्तविक समय (wall clock time), बैकफिल के दौरान दोनों कॉलम्स के लिए एक साथ डिस्क का उपयोग, और अंत में इंडेक्स का पुनर्निर्माण। सुरक्षित तरीका यह है कि एक नया कॉलम जोड़ें, उसे बैचों में बैकफिल करें, क्वेरी को स्वैप करें, और फिर पुराने कॉलम और उसके इंडेक्स को हटा दें।

प्रकाशित आंकड़ों पर भरोसा करने के बजाय अपने हार्डवेयर पर दर को मापें, क्योंकि एक छोटे VPS पर केवल CPU का उपयोग करके एम्बेडिंग, GPU पर उसी मॉडल की तुलना में काफी धीमी चलती है। एक प्रतिनिधि हिस्से (chunk) का समय मापें, फिर उसे कॉर्पस के आकार से गुणा करें।

ollama pull nomic-embed-text
time curl -s http://localhost:11434/api/embed \
  -d '{"model": "nomic-embed-text", "input": "one representative chunk of your corpus"}' > /dev/null

एक लोकल एम्बेडिंग मॉडल अपने वेट्स (weights) को भी उसी डिस्क पर रखता है जहाँ मेमोरी स्टोर होता है, और Ollama कहाँ मॉडल्स स्टोर करता है यह बताता है कि वह स्पेस कहाँ जाता है।

एक आवश्यकता इस पूरी प्रक्रिया को संभव बनाती है: प्रत्येक वेक्टर के साथ उसका सोर्स टेक्स्ट सुरक्षित रखें। केवल वेक्टर्स रखने वाले स्टोर को दोबारा एम्बेड नहीं किया जा सकता, क्योंकि नए मॉडल को फीड करने के लिए कुछ भी शेष नहीं रहता। यदि आप यह उत्तर नहीं दे सकते कि "किस टेक्स्ट ने यह पंक्ति बनाई", तो आपका माइग्रेशन पाथ उस स्थान से पूर्ण पुनर्निर्माण (full rebuild) होगा जहाँ से टेक्स्ट मूल रूप से आया था।

मेमोरी भर जाने पर किन बातों का ध्यान रखें

जैसे-जैसे स्टोर भरता है, केवल लागत ही नहीं बदलती। पुराने तथ्य पुराने (out of date) हो जाते हैं और पुराने एपिसोड उपयोगी परिणामों की जगह ले लेते हैं, जो कि फिर से pruning की समस्या है। एक मेमोरी स्टोर एजेंट के भविष्य के व्यवहार के लिए एक writable इनपुट भी है, इसलिए इसमें कुछ भी लिखने की अनुमति देने से एजेंट बाद में प्रभावित हो सकता है। यदि वेब पेजों या टिकटों से टेक्स्ट मेमोरी तक पहुँचता है, तो agent memory poisoning कैसे काम करती है पढ़ें, इससे पहले कि आप यह दायरा बढ़ाएं कि कौन इसमें लिख सकता है। रिट्रीवल का आकार हर एक अनुरोध पर टोकन खर्च को भी बढ़ाता है, और यहीं से एजेंट की रनिंग कॉस्ट को अनुमानित रखना शुरू होता है।

FAQ

क्या मुझे एजेंट मेमोरी के लिए वेक्टर डेटाबेस की आवश्यकता है?

तथ्यों के लिए नहीं। सिमेंटिक मेमोरी छोटी होती है और आपको इसे नाम से सुधारने की आवश्यकता होती है, इसलिए एक 'की-वैल्यू' टेबल या git में markdown फाइलों की डायरेक्टरी बेहतर काम करती है, क्योंकि आप एक मान को देख सकते हैं और उसे संपादित कर सकते हैं। एम्बेडिंग (embeddings) तब अपनी लागत वसूल करती है जब आपको ऐसे कॉर्पस (corpus) में अर्थ के आधार पर जानकारी खोजनी हो जो इतना बड़ा है कि उसे सूचीबद्ध नहीं किया जा सकता, जो आमतौर पर एपिसोडिक मेमोरी और दस्तावेजों के लिए होता है। यदि आप पहले से ही Postgres चला रहे हैं, तो CREATE EXTENSION vector बिना किसी अतिरिक्त सर्विस को संचालित किए यह काम कर देता है।

एजेंट मेमोरी स्टोर कितनी डिस्क का उपयोग करेगा?

वेक्टर का आकार अनुमानित होता है, pgvector में प्रति डाइमेंशन 4 बाइट्स और 8 बाइट का हेडर होता है। 768 डाइमेंशन पर यह 293.7 MiB प्रति 100,000 पंक्तियाँ है, और 384 डाइमेंशन पर यह 147.2 MiB है। इसके बाद चंक टेक्स्ट, रो ओवरहेड और एक HNSW इंडेक्स जोड़ें जो वेक्टर की अपनी कॉपी रखता है, इसलिए वेक्टर आंकड़े से कम से कम दोगुना बजट रखें और वास्तविक संख्या को pg_total_relation_size के साथ मापें।

प्रोसीजरल मेमोरी कहाँ होनी चाहिए?

एक git रिपॉजिटरी में, उन स्क्रिप्ट्स या स्किल फाइलों के रूप में जिन्हें एजेंट सीधे चलाता है। एक प्रक्रिया को सटीक रिकॉल और वर्जन हिस्ट्री की आवश्यकता होती है, और सिमिलरिटी सर्च (similarity search) आपको इनमें से कुछ भी नहीं देता है। एक चंक किया हुआ रनबुक सबसे अधिक स्कोरिंग वाले टुकड़ों के साथ वापस आता है, जिसका अर्थ यह हो सकता है कि स्टेप 2 और स्टेप 5 तो आ गए लेकिन स्टेप 3 गायब है, और यह रिकॉर्ड नहीं होता कि कौन सा वर्जन चला था।

एम्बेडिंग मॉडल बदलने की क्या लागत है?

पूरे कॉर्पस को फिर से एम्बेड करना पड़ता है, क्योंकि अलग-अलग मॉडलों के वेक्टर की एक-दूसरे से तुलना नहीं की जा सकती। टोकन चार्ज या GPU समय का बजट रखें, साथ ही पुराने और नए कॉलम के लिए एक ही समय में डिस्क स्पेस और इंडेक्स को फिर से बनाने की लागत भी जोड़ें। नया कॉलम जोड़ें, बैचों में बैकफिल करें, क्वेरी को स्वैप करें, और फिर पुराने कॉलम को ड्रॉप करें। यह सब इस बात पर निर्भर करता है कि आपने प्रत्येक वेक्टर के साथ मूल टेक्स्ट को सुरक्षित रखा है या नहीं।

#agent-memory#semantic-memory#episodic-memory#pgvector#स्टोरेज