Agent memory जुनी झाल्यावर pruning आणि expiry कसे करावे
Agent memory मधील जुनी माहिती शांतपणे चुकीची कशी होते, time-bound facts साठी expiry आणि TTL कसे द्यावे, deletes cascade कसे करावे आणि sqlite3 ने SQLite store कसे तपासावे हे शिका.
एजंटची memory जुनी का होते
एजंटची memory जुनी होते कारण एखादी वस्तुस्थिती एकदा लिहिली जाते आणि पुन्हा तपासली जात नाही. Store तीच माहिती पुन्हा देत राहतो. Retrieval layer ती माहिती तारीख नसलेल्या साध्या मजकूराच्या स्वरूपात prompt मध्ये ठेवतो. त्यानंतर model ती माहिती लिहिली गेल्याच्या दिवशी जितक्या खात्रीने सांगत होता, तितक्याच खात्रीने पुन्हा सांगतो. कोणतीही error निर्माण होत नाही. हीच मुख्य अडचण आहे: model आणि तुमच्यासाठीही जुनी memory आणि ताजी memory अगदी सारखी दिसते.
माहिती save करताना अधिक चांगले लेखन केल्याने ही समस्या सुटत नाही. ज्या वस्तुस्थितींना expiry लागू आहे त्यांच्यासाठी expiry देणे, आणि ज्यांना expiry लागू नाही त्यांच्यासाठी review routine ठेवणे, हेच उपाय आहेत. ही दोन्ही कामे छोट्या database ची नेहमीची देखभाल आहेत. त्यातील बहुतांश काम SQL (structured query language) मध्ये केले जाते.
Decay आणि drift हे वेगवेगळे अपयशप्रकार आहेत
Decay म्हणजे नैसर्गिकरीत्या संपण्याची तारीख असलेली वस्तुस्थिती. "या आठवड्यात प्रवास करत आहे." "Migration साठी staging box बंद आहे." "Budget draft चे पुनरावलोकन करत आहे." लिहिताना ही विधाने खरी होती आणि ती लिहितानाच त्यांची उपयुक्तता किती काळ राहील हे सांगता येते. Decay ची समस्या सोडवता येते. Expiry जोडा; याला कधीकधी TTL (time to live) म्हणतात. तो कालावधी संपल्यावर row delete करा.
Drift म्हणजे एकदा साठवलेली आणि त्यानंतर पुन्हा कधीही पडताळली न गेलेली वस्तुस्थिती. "pnpm पसंत आहे." "Database Postgres 15 आहे." "Deployments staging branch मधून होतात." कोणतेही घड्याळ ही विधाने चुकीची ठरवत नाही. इतरत्र घेतलेला निर्णय ती विधाने बदलतो आणि तुमच्या memory store ला त्याची कोणतीही माहिती मिळत नाही.
Drift साठी स्वच्छ automated उपाय नाही. Store ने कधीही पाहिलेला बदल तो detect करू शकत नाही. त्यामुळे store वाचून त्यावर reasoning करणारे job तेच जुने text पुन्हा वाचत असते. कार्य करणारी पद्धत म्हणजे ज्या गोष्टीचे वर्णन केले आहे त्याच्याशी fact पुन्हा पडताळणे. यासाठी एखादी व्यक्ती किंवा current state वाचू शकणारे tool असलेला agent आवश्यक असतो.
म्हणून plan दोन भागांत विभागा. Decay होणाऱ्या गोष्टी expire करा. Drift होणाऱ्या गोष्टींचे review करा. दुसरी समस्या पहिल्या समस्येसारखी हाताळू नका.
कालबद्ध तथ्यांना expiry द्या
प्रत्येक memory row मध्ये बहुतेक stores देत नसलेले तीन columns आवश्यक असतात: तथ्य कुठून आले, ते शेवटचे कधी निश्चित केले गेले आणि ते कधीपर्यंत सत्य राहते. हा store तुम्ही फक्त sqlite3 वापरून तयार करू शकता. तुम्ही आधीपासून चालवत असलेल्या store मध्येही हेच columns जोडता येतात.
CREATE TABLE memory (
id TEXT PRIMARY KEY,
subject TEXT NOT NULL,
fact TEXT NOT NULL,
source TEXT NOT NULL,
created_at TEXT NOT NULL DEFAULT (datetime('now')),
confirmed_at TEXT NOT NULL DEFAULT (datetime('now')),
expires_at TEXT,
superseded_by TEXT REFERENCES memory(id) ON DELETE CASCADE
);
CREATE INDEX memory_expires ON memory(expires_at);
CREATE INDEX memory_superseded ON memory(superseded_by);datetime('now') UTC (coordinated universal time) हे YYYY-MM-DD HH:MM:SS म्हणून परत करते. हा format text म्हणून योग्य क्रमवारी लावता आणि compare करता येतो. त्यामुळे खालील प्रत्येक date प्रश्न हा साधा WHERE clause असतो. source column optional नाही. एखादे तथ्य message, file किंवा command output पर्यंत trace करता येत नसेल, तर त्याची पुन्हा पडताळणी करता येत नाही. आणि ज्या तथ्याची पुन्हा पडताळणी करता येत नाही, ते फक्त delete करता येते.
Expiry असलेली memory लिहिणे:
INSERT INTO memory (id, subject, fact, source, expires_at)
VALUES ('m_0191', 'availability', 'Away from keyboard, replies are delayed',
'chat 2026-08-08', datetime('now', '+7 days'));Retrieval ने table कधीही थेट वाचू नये. त्याऐवजी expired आणि superseded rows लपवणारे view वाचावे:
CREATE VIEW live_memory AS
SELECT id, subject, fact, source, confirmed_at, expires_at
FROM memory
WHERE superseded_by IS NULL
AND (expires_at IS NULL OR expires_at > datetime('now'));View हा महत्त्वाचा भाग आहे, कारण prune चुकले तरी त्यामुळे समस्या निर्माण होत नाही. एखादी row expire होताच ती retrieval मधून वगळली जाते, delete job चालली किंवा नाही तरीही. त्यामुळे delete job फक्त disk वापर आणि review load नियंत्रित करते; correctness नाही.
sqlite3 memory.db "SELECT count(*) FROM memory;" वापरून gap तपासा आणि live_memory विरुद्ध तोच count तपासा. आरोग्यदायी store मध्ये हे दोन आकडे जवळपास समान असतात. मोठा gap म्हणजे dead rows चा backlog.
मेमरी हटवल्यानंतर जुनी मेमरी का शिल्लक राहते
दुरुस्त्या जोड्यांमध्ये येतात. तुम्ही npm वरून pnpm वर गेल्याचे agent शिकतो, नवीन row लिहितो आणि जुन्या row ला तिच्याकडे निर्देशित करतो:
UPDATE memory SET superseded_by = 'm_0207' WHERE id = 'm_0140';जुनी row आता live_memory ला दिसत नाही आणि chain मध्ये काय बदलले ते नोंदलेले राहते. आता m_0207 हटवा, कारण ती चुकीची असल्याचे स्पष्ट झाले. superseded_by वरील ON DELETE CASCADE ने m_0140 सोबत हटवले पाहिजे, कारण त्या संबंधात जुनी row ही child आहे. परंतु सामान्यतः तसे होत नाही, कारण SQLite foreign keys सुरू करेपर्यंत त्यांच्याकडे दुर्लक्ष करते आणि default स्थिती off असते:
sqlite3 memory.db "PRAGMA foreign_keys;"Stock build मध्ये हे 0 मुद्रित करते. Foreign keys बंद असताना DELETE FROM memory WHERE id = 'm_0207'; यशस्वी होते आणि m_0140 शिल्लक राहते; ते आता अस्तित्वात नसलेल्या id कडे निर्देश करते. कोणतीही warning मिळत नाही. आता ती row चुकीच्या कारणामुळे लपलेली असते आणि dangling pointers ला NULL वर reset करणारी पहिली tidy-up script "prefers npm" थेट live_memory मध्ये पुन्हा लिहिते.
तुटलेल्या chains शोधा:
sqlite3 memory.db "PRAGMA foreign_key_check;"Enforcement बंद असतानाही foreign_key_check violations नोंदवते, त्यामुळे आधीपासून असलेल्या या विस्कळीत डेटावरही ते कार्य करते. प्रत्येक violation साठी ते एक row मुद्रित करते: table, rowid, parent table आणि कोणती foreign key अयशस्वी झाली ते. रिकामा output म्हणजे chains अखंड आहेत.
यानंतरचा नियम संक्षिप्त आहे. PRAGMA foreign_keys = ON; ही प्रति-connection setting आहे, त्यामुळे प्रत्येक connection साठी ती आवश्यक आहे: तुमचे application, तुमची prune script आणि तुम्ही ज्या sqlite3 session मध्ये commands टाइप करता ती. कोणतीही गोष्ट delete करणाऱ्या प्रत्येक SQL file ची पहिली line म्हणून ती लिहा.
तुमच्या memories प्रत्यक्षात कुठे साठवल्या जातात
काहीही delete करण्यापूर्वी तुमच्याकडे किती stores आहेत ते शोधा. Self-hosted memory service साधारणपणे memory text आणि त्याचे embedding vector database मध्ये ठेवते आणि बदलांचा log SQLite मध्ये ठेवते. हे वेगवेगळ्या lifecycle असलेले वेगवेगळे files आहेत. त्यामुळे त्यांपैकी एक fail झाला तरी दुसरा स्वतंत्रपणे उपलब्ध राहू शकतो.
mem0 हे याचे योग्य उदाहरण आहे आणि हीच रचना इतर ठिकाणीही आढळते. त्याची open source library default म्हणून /tmp/qdrant येथे Qdrant vector store वापरते. त्यात mem0 नावाचा collection असतो. याशिवाय ~/.mem0/history.db येथे SQLite change log असतो. त्याचे location MEM0_DIR environment variable नुसार ठरते. history table मध्ये memory_id, old_memory, new_memory, event, created_at आणि is_deleted असतात.
तो column list पुन्हा वाचा. SQLite file हा change log आहे. Memories स्वतः Qdrant मध्ये असतात. त्यामुळे history.db मधून rows delete केल्यास काहीतरी बदलले याची नोंद काढली जाते, पण memory retrieve करता येत राहते. Deletes library च्या स्वतःच्या API (application programming interface) मधूनच करावे लागतात, जेणेकरून दोन्ही ठिकाणी update होईल:
from mem0 import Memory
memory = Memory()
memory.delete(memory_id="mem_123")
memory.delete_all(user_id="alice")/tmp default बाबत स्वतंत्रपणे सावध राहा. Ubuntu 24.10 आणि त्यानंतरच्या आवृत्त्यांमध्ये /tmp हा tmpfs आहे. हा memory मध्ये ठेवलेला filesystem असतो. त्यामुळे प्रत्येक reboot नंतर तो रिकामा होतो आणि संपूर्ण store नष्ट होतो. तुमची configuration findmnt /tmp वापरून तपासा. tmpfs दाखवणारी line आढळल्यास path आजच बदला:
config = {
"vector_store": {
"provider": "qdrant",
"config": {"collection_name": "mem0", "path": "/srv/agent/qdrant"},
}
}
memory = Memory.from_config(config)तुम्ही कोणतीही service चालवत असलात तरी हा प्रश्न लागू होतो. Configuration वाचा आणि service ज्या प्रत्येक path वर लिहिते ते नोंदवून ठेवा. तुमच्या स्वतःच्या VPS वर mem0 memory server चालवणे या विषयाच्या service-संबंधित भागाचे वर्णन करते. agent memory एका machine वर local ठेवणे हे त्याच maintenance गरजा असलेले छोटे store आहे.
sqlite3 वापरून store वाचणे
ते उपलब्ध नसल्यास sudo apt install -y sqlite3 वापरून CLI (command line interface) install करा. त्यानंतर तुमच्या disk वरील कोणत्याही store विषयीच्या बहुतेक प्रश्नांची उत्तरे चार commands देतात.
sqlite3 ~/.mem0/history.db ".tables"tables ची सूची दाखवते. रिकामा output दिसल्यास तुम्ही चुकीची file उघडली आहे.sqlite3 ~/.mem0/history.db ".schema history"अचूक columns दाखवते. store ची रचना समजून घेण्यासाठी हेच एकमेव विश्वसनीय documentation आहे.sqlite3 -cmd ".mode line" ~/.mem0/history.db "SELECT * FROM history ORDER BY created_at DESC LIMIT 5;"सर्वात अलीकडील पाच changes दाखवते. प्रत्येक field स्वतंत्र ओळीत दिसतो, त्यामुळे एखाद्या column मध्ये paragraph असल्यासही output वाचणे सोपे राहते.sqlite3 ~/.mem0/history.db "SELECT event, count(*) FROM history GROUP BY event;"store मध्ये कोणते बदल होत आहेत आणि तुमची library प्रत्यक्षात कोणती event names लिहिते हे दाखवते.
प्रत्येक memory store हा database असेलच असे नाही. प्रत्येक session च्या सुरुवातीला वाचली जाणारी notes ची साधी file ही दोन्ही समस्यांनी ग्रस्त असते आणि तिला आवश्यक tooling देखील नसते: expiry column नसतो, confirmed date नसते आणि जुन्या rows लपवण्यासाठी view नसतो. तुम्ही लिहिलेल्या प्रत्येक line ला स्वतःहून date द्या आणि ती monthly पुन्हा वाचा. Claude Code sessions मध्ये कायम राहणारी memory याच समस्येचे लहान स्वरूप आहे.
मुदत संपत नाही अशा तथ्यांचे पुनरावलोकन
Drift व्यवस्थापित करण्यासाठी queue, cap आणि नियमित सवय आवश्यक आहे. Queue मध्ये सर्वांत जुन्या पुष्टीकरणांचा समावेश असतो:
SELECT id, subject, fact, source, confirmed_at
FROM live_memory
WHERE confirmed_at < datetime('now', '-90 days')
ORDER BY confirmed_at
LIMIT 20;आठवड्याला वीस rows असतील, तर प्रत्यक्षात कोणी तरी ते पुनरावलोकन करेल. चारशे rows असतील, तर कोणीही ते पुनरावलोकन करणार नाही. त्यामुळे स्थिती पुन्हा सुरुवातीसारखीच राहते. प्रत्येक row साठी दोन पर्याय असतात. ती row तिच्या source विरुद्ध पुन्हा तपासा आणि तिच्यावर नोंद करा:
UPDATE memory SET confirmed_at = datetime('now') WHERE id = 'm_0140';किंवा ती बदलून टाका: नवीन fact insert करा, जुन्या row चे superseded_by नवीन id वर सेट करा आणि chain ला इतिहास जतन करू द्या.
ही प्रक्रिया कमी खर्चिक करण्यासाठी दोन सवयी उपयुक्त ठरतात. Store लहान ठेवा, कारण सतत वाढणाऱ्या store चे पुनरावलोकन करणे अशक्य होते: last_used_at column जोडा, row प्रत्यक्ष retrieve झाल्यावर तो update करा आणि सहा महिन्यांपासून वापरल्या न गेलेल्या rows deletion candidates म्हणून हाताळा. प्रत्येक retrieval साठी एक write लागतो. त्यामुळे agent कडून वारंवार retrieval होत असल्यास ते batch करा.
दुसऱ्या सवयीसाठी कोणताही अतिरिक्त खर्च नाही. Prompt मध्ये age समाविष्ट करा. Retriever ने तयार केलेल्या memory block मध्ये प्रत्येक fact च्या बाजूला confirmed 2026-05-02 असल्यास, model ते सरळ विधान म्हणून सांगण्याऐवजी "मे महिन्यापर्यंत तुम्ही pnpm वापरत होतात" असे सांगू शकते. Date जोडलेले नसलेले fact language model ला प्रत्येक वेळी वर्तमानकाळातील माहिती वाटते.
वेळापत्रकानुसार prune चालवा
तुम्हाला आठवेल तेव्हा चालवलेला prune प्रत्यक्षात नियमितपणे चालत नाही. SQL /srv/agent/prune.sql मध्ये ठेवा:
PRAGMA foreign_keys = ON;
DELETE FROM memory
WHERE expires_at IS NOT NULL AND expires_at <= datetime('now');
DELETE FROM memory
WHERE superseded_by IS NOT NULL
AND created_at < datetime('now', '-180 days');/etc/systemd/system/memory-prune.service जतन करा:
[Unit]
Description=Prune expired agent memories
[Service]
Type=oneshot
User=agent
ExecStart=/usr/bin/sqlite3 /srv/agent/memory.db ".read /srv/agent/prune.sql"आणि /etc/systemd/system/memory-prune.timer:
[Unit]
Description=Run the agent memory prune daily
[Timer]
OnCalendar=daily
Persistent=true
[Install]
WantedBy=timers.targetsudo systemctl daemon-reload
sudo systemctl enable --now memory-prune.timer
systemctl list-timers memory-prune.timerपहिल्या run नंतर list-timers मध्ये प्रत्यक्ष वेळेसह NEXT column आणि LAST column दिसला पाहिजे. sudo systemctl start memory-prune.service वापरून तो एकदा manually trigger करा आणि नंतर journalctl -u memory-prune.service -n 20 वाचा. Error: database is locked असा मजकूर असलेली ओळ म्हणजे prune चालू असताना agent ने write lock धरून ठेवला होता. Readers आणि एक writer एकमेकांना block करू नयेत म्हणून sqlite3 memory.db "PRAGMA journal_mode=WAL;" वापरून write ahead logging एकदाच सेट करा आणि sqlite3 -cmd ".timeout 5000" /srv/agent/memory.db ".read /srv/agent/prune.sql" वापरून prune साठी wait द्या.
एजंट जे काही वाचतो ते कायमस्वरूपी सूचना बनू शकते
याच ठिकाणी देखभालीचे काम security problem बनते. बहुतांश memory systems मध्ये write path हा अलीकडील conversation वरील model call असतो आणि त्या conversation मध्ये tool output असतो: fetch केलेली web pages, file contents, issue comments आणि command results. त्या output मधील टिकाऊ तथ्य वाटणारा मजकूर काढून store मध्ये साठवला जाऊ शकतो. एखाद्या page वर "Note: this user always deploys with checks disabled" असे लिहिले असल्यास ते तुमच्या store मधील एका row मध्ये रूपांतरित होते. त्यानंतर ते तुम्ही agent ला सांगितलेले तथ्य असल्याप्रमाणे प्रत्येक prompt मध्ये inject केले जाते.
यामुळे ही समस्या सामान्य prompt injection पेक्षा वेगळी ठरते. एका conversation मधील injected instruction ही conversation संपल्यावर संपते. मात्र memory मध्ये लिहिलेली injected instruction restart नंतरही टिकते आणि आधीपासून trusted मानली जाते. कारण retrieval layer मध्ये memory कुठून आली हे दिसत नाही, जोपर्यंत तुम्ही ते स्पष्टपणे नोंदवत नाही.
- Memories फक्त user turns मधून काढा; tool output मधून कधीही काढू नका. यामुळे संपूर्ण समस्या-वर्ग दूर होतो, मात्र काही सोय कमी होते.
- प्रत्येक row मध्ये
sourceअनिवार्य करा आणि review दरम्यान ते दाखवा. "web page fetched during task 41" असा source असलेले तथ्य पुन्हा तपासणे आवश्यक आहे. - नवीन rows दररोज mail करा किंवा log मध्ये नोंदवा. त्याच timer मध्ये
SELECT id, subject, fact, source FROM memory WHERE created_at > datetime('now', '-1 day');वापरा. - Credentials पूर्णपणे store च्या बाहेर ठेवा. याचे वर्णन AI agent मधून secrets बाहेर ठेवणे येथे केले आहे.
येथे आणखी एक यांत्रिक मुद्दा महत्त्वाचा आहे. एखादी row delete केल्याने ती file मधून पुसली जात नाही. SQLite page ला free म्हणून चिन्हांकित करते आणि नंतर तो पुन्हा वापरते. त्यामुळे काहीतरी overwrite करेपर्यंत जुना मजकूर strings memory.db वापरून अजूनही वाचता येतो. संवेदनशील माहिती काढल्यानंतर sqlite3 memory.db "VACUUM;" चालवा. यामुळे संपूर्ण file पुन्हा लिहिली जाते. PRAGMA secure_delete = ON; delete करणाऱ्या connection कडून freed content वर जाताना zeros लिहून ते overwrite करून घेते.
कोणत्या गोष्टींचा आणि कोणत्या क्रमाने बॅकअप घ्यावा
हा store लहान आहे आणि पुन्हा तयार करणे कठीण आहे. त्यामुळे त्याचा योग्य पद्धतीने बॅकअप घ्या. Live database file कधीही cp ने कॉपी करू नका, कारण write सुरू असताना घेतलेली कॉपी उघडता येणार नाही. त्याऐवजी SQLite मध्ये उपलब्ध असलेला snapshot वापरा:
sqlite3 /srv/agent/memory.db "VACUUM INTO '/srv/backup/memory-$(date +%F).db'"
sqlite3 /srv/backup/memory-$(date +%F).db "PRAGMA integrity_check;"integrity_check printing ok हीच backup file वापरण्यायोग्य असल्याचा एकमेव पुरावा आहे. याशिवाय इतर कोणताही परिणाम मिळाल्यास मागील backup ठेवून द्या आणि तो overwrite करण्यापूर्वी कारणाचा शोध घ्या.
याच job मध्ये आणि त्याच वेळी vector store चा snapshot घ्या. दोन्ही भाग काही तासांच्या अंतराने घेतल्यास restore प्रक्रियेत नवीन change log जुन्या memories च्या संचासोबत मिसळतो आणि deleted facts पुन्हा उपलब्ध होतात. दोन्ही files एकाच दिनांकित directory मध्ये लिहा, म्हणजे त्या एकत्रच restore करता येतील. VPS वर SQLite production मध्ये चालवणे यामध्ये locking, backups आणि दीर्घकाळ चालणाऱ्या service साठी आवश्यक settings यांचे अधिक सविस्तर वर्णन आहे.
FAQ
Agent memory expire होण्यापूर्वी किती काळ ठेवावे?
Expiry global default नुसार नव्हे, तर त्या fact नुसार ठरवा. प्रवासाची नोंद किंवा "या आठवड्यात या project वर काम करत आहे" अशी नोंद सात दिवसांसाठी ठेवा. Team convention किंवा personal preference ला expiry देऊ नका; त्याऐवजी ती review queue मध्ये पाठवा. Software version बद्दलच्या fact साठी त्या project च्या release cadence इतका साधारण expiry कालावधी ठेवा. Fact लिहिताना त्याचा shelf life सांगता येत नसेल, तर ती नोंद decay न होता drift होण्याची शक्यता आहे. त्यामुळे तिला confirmed_at date द्या आणि expire करण्याऐवजी review करा.
साठवलेली fact चुकीची झाली आहे हे आपोआप शोधता येते का?
विश्वसनीयपणे नाही. Store ला त्याबाहेरील जगाची माहिती नसते. त्यामुळे एखादी fact चुकीची करणारा बदल तो पाहू शकत नाही. Store पुन्हा वाचणारे job चालवले तरी तोच जुना text पुन्हा वाचला जातो. मात्र surfacing automate करता येते. confirmed_at नुसार sort करून सर्वात जुन्या rows एखाद्या व्यक्तीसमोर ठेवा. किंवा repository, config file किंवा monitoring endpoint मधून current state वाचू शकणाऱ्या tool असलेल्या agent समोर त्या ठेवा. Queue automate करणे उपयुक्त आहे. Verdict automate करण्याची क्षमता अद्याप उपलब्ध नाही.
मी memory delete केली, पण ती पुन्हा दिसली. का?
सामान्यतः दोन stores असतात आणि तुम्ही त्यापैकी एका store मध्येच बदल केला असतो. Memory text आणि त्याचे embedding सहसा vector database मध्ये असतात. SQLite file मध्ये change log असतो. त्यामुळे SQLite file मधील rows delete केल्यास audit record हटतो, पण memory पुन्हा retrieve करता येते. Library API द्वारे delete करा, म्हणजे दोन्ही stores update होतील. दुसरे सामान्य कारण म्हणजे restore. Vector store आणि SQLite file वेगवेगळ्या वेळी snapshot केलेले असू शकतात. त्यामुळे restore केल्यावर दुसऱ्या भागाने आधीच हटवलेल्या rows पुन्हा येतात.
Agent चालू असताना memory database हाताने edit करणे सुरक्षित आहे का?
Reads सुरक्षित आहेत. Writes फक्त write ahead logging mode मध्ये सुरक्षित आहेत, आणि त्यातही एका वेळी एकच writer असावा. कोणता mode वापरात आहे हे पाहण्यासाठी sqlite3 memory.db "PRAGMA journal_mode;" चालवा. तुम्हाला हवा असलेला उत्तर wal आहे. Error: database is locked दिसल्यास दुसरी process write lock धरून आहे. त्यामुळे sqlite3 -cmd ".timeout 5000" वापरून तुमच्या session ला wait द्या किंवा प्रथम agent service थांबवा. Vector store हाताने edit करण्याची पद्धत वेगळी आहे. ते library कडे सोपवा, कारण embedding आणि text एकमेकांशी सुसंगत राहणे आवश्यक आहे.