संग्रहालय — एजेंट वैली में यादें

1. परिचय

ग्राउंड फ़्लोर पर डेस्क पर बैठी वेस्पर, जो एक आर्काइविस्ट है

पहले हफ़्ते में पूछा गया कि कौन कहता है कि क्या चलता है. दूसरे हफ़्ते में पूछा गया था कि यह कौन तय करता है कि आगे क्या चलेगा. तीसरे हफ़्ते में पूछा गया कि दौड़ के बाद क्या बचता है. इस हफ़्ते बातचीत खत्म हो जाती है. सवाल यह है कि इसमें क्या बचा है. जवाब यह है कि यह किस तरह की चीज़ है, इससे तय होता है कि यह कहां जाएगी.

जब कोई गड़बड़ी होती है, तो डेटा को संग्रह में रखा जाता है. एक टावर, जिसमें सब कुछ लिखा होता है. साथ ही, ग्राउंड फ़्लोर पर डेस्क पर बैठी वेस्पर, जो आर्काइविस्ट है. रात में आपकी लालटेन बुझ जाती है. जाओ और पूछो.

वह अच्छी कंपनी है. एक महीने बाद, उसे आपसे मिलकर भी खुशी हुई.

कोई रिकॉर्ड, यादगार पल नहीं होता.

यह वाक्य ही पूरी लैब है. आपको चार चरणों में ऊपर पहुंचना होगा. हर चरण, टावर का एक फ़्लोर है:

रंग

फ़्लोर

यह क्या याद रखता है

what keeps it

1

डेस्क और फ़्लोर लैंप

इस विज़िट

session.state · SqliteSessionService

2

दूसरी मंज़िल पर, आपकी दराज़

इस विज़िटर

user: प्रीफ़िक्स

3

तीसरा फ़्लोर, टॉवर

क्या कहा गया था

Vertex AI Memory Bank

4

फ़्लोर चार, द सीज़न

पूरी घाटी

BigQuery

हर लेवल में बढ़ोतरी, पिछले लेवल में हुई गिरावट की वजह से होती है.

पांच मंज़िल वाला यह आर्काइव, अंदर से ऐसा दिखता है. यहां कुछ लोग काम करते हैं, जो हर मंज़िल का ध्यान रखते हैं

आपको पहले से ही संग्रहपाल के पांच तरीकों के बारे में पता है, क्योंकि सहायता कॉल के दौरान इनमें से हर एक तरीका आपके साथ हुआ है:

उसने क्या कहा

क्या गड़बड़ी हुई

~~1~~

~~क्या आप मुझे वह रेफ़रंस फिर से दे सकते हैं?~~

~~एक बातचीत के दौरान भूल जाना~~ — तीसरे हफ़्ते में इस समस्या को ठीक कर दिया गया है

~~2~~

~~I've transferred you. कृपया शुरू से शुरू करें.~~

~~प्रोसेस बंद होने पर, इतिहास भी मिट जाता था~~ — तीसरे हफ़्ते में इस समस्या को भी ठीक कर दिया गया है

3

आपका स्वागत है! आज मैं आपकी किस तरह मदद कर सकता/सकती हूं?

उसे पिछले महीने किसी ऐसे व्यक्ति को भेजा गया था जिसने कोई केस खोला हो

4

क्या आपको हुए नुकसान के बारे में जानकारी मिल सकती है?

उसने पिछली बार लालटेन को देखा था

5

हमने ऐसा पहले कभी नहीं देखा.

इस सीज़न में 31 लोगों ने यह सवाल पूछा है

तीसरी लाइन में इस हफ़्ते का डेटा है. यह तीन अलग-अलग तरीकों से काम नहीं करता — नई विज़िट (दूसरा चैप्टर), स्लिप पर कोई लाइन न होने वाला वाक्य (तीसरा चैप्टर), और ऐसा संग्रह जो सिर्फ़ प्रोसेस के अंदर मौजूद होता है (चौथा चैप्टर). हर तरीके को एक चैप्टर के तौर पर दिखाया गया है. चौथी लाइन आपको लिखनी है: look() में archive/agent.py वह जगह है जहां वह फ़ोटो में दिख रहे निशान को पढ़ती है. पांचवीं लाइन में चैप्टर 5 है और यह ज़रूरी नहीं है.

आपको पहले से तीसरे हफ़्ते तक के डेटा की ज़रूरत नहीं है. एजेंट, निर्देशों और कुछ टूल वाला मॉडल होता है. बाकी सभी चीज़ों के बारे में, इस हफ़्ते की जानकारी से पता चल जाएगा.

आपको तीन लाइनें लिखनी होंगी. इनमें से हर लाइन में, मेमोरी का एक कॉन्सेप्ट होना चाहिए:

लाइन

यह क्या है

tool_context.state[CASE] = case

स्टेट को कोड के ज़रिए लिखा जाता है, बातचीत के ज़रिए नहीं

CASE = "user:case"

उपसर्ग का इस्तेमाल हमेशा के लिए किया जाता है

found = await ctx.search_memory(query)

सामान वापस मंगाने की नीति — फ़ाइल की गई जानकारी सेव नहीं की जाती

आपके लिए एक और लाइन पहले से मौजूद है, जिसे आपको पढ़ना है — लिखने की नीति, await ctx.add_events_to_memory(...) — और तीसरे चैप्टर में आपको यह पढ़ना है कि इसका इस्तेमाल करने से पहले क्या करना है.

अन्य दो चरणों में कोई बदलाव नहीं किया जाता: आपको एक टावर बनाना होता है (एक ऐसा एजेंट इंजन जो मेमोरी बैंक को होस्ट करता है). इसके बाद, वही कोड अपने-आप इससे कनेक्ट हो जाता है. साथ ही, आपको एक वेयरहाउस लोड करना होता है (BigQuery). इसके बाद, उस पर एक ग्राफ़ बनाना होता है. साथ ही, उसी एजेंट को दो मैनेज की गई क्वेरी देनी होती हैं. एक क्वेरी का मतलब होता है और दूसरी क्वेरी का कनेक्शन होता है.

हर चैप्टर में एक ही लूप चलता है. आपको अपने एजेंट के लिए भी इसी लूप का इस्तेमाल करना होगा: कोड पढ़ो → लाइन लिखो → उसे टावर में देखो. सबसे पहले, कुछ भी काम नहीं करता है, कुछ भी रीस्टार्ट नहीं होता है, और कुछ भी Ctrl+C नहीं होता है: हर बदलाव को अगले मैसेज में शामिल किया जाता है. साथ ही, टावर को कनेक्ट करना, फ़ाइल में एक लाइन होती है. Archive, हर अनुरोध पर इसे फिर से पढ़ता है. टावर एक ऐसी ड्राइंग है जो फिर से बनाई जाती है: यह उन फ़ाइलों को पढ़ता है जिन्हें आपने बदला है. इसमें तीन बटन होते हैं — 🌙 दिन खत्म करता है, 🗓 अगली विज़िट शुरू करता है, 🔥 आपको भूल जाता है. कोड और टर्मिनल में किए जाने वाले अन्य सभी काम.

दो जगहें, और वे कभी भी नौकरियां नहीं बदलते: टैब 1 टर्मिनल है, टैब 2 संग्रह है. वर्कबेंच (adk web) सिर्फ़ एक बार दिखता है. यह पहले चैप्टर में, सेशन की रॉ स्टेट को देखने के लिए दिखता है. इसके बाद, आपको इसकी ज़रूरत नहीं पड़ती. नीचे दिए गए हर 👉 में बताया गया है कि कौनसी कुकी किस तरह की है. 👉💻 पहला टैब है, 👉🖥 दूसरा टैब है, और 👉🔬 वर्कबेंच है. 👉📖 का मतलब है किसी फ़ाइल को खोलना और उसे पढ़ना. इसमें कोई बदलाव नहीं किया जा सकता. वहीं, 👉✏️ एक ऐसा चरण है जिसमें बदलाव किया जा सकता है. जब भी किसी चरण में आपको Vesper से कुछ कहने के लिए कहा जाए, तो ठीक उसके नीचे मौजूद ब्लॉक में वह मैसेज दिया गया होता है. उसे उसी तरह कॉपी करें. इसके अलावा, जिस सेक्शन के हेडिंग में — सिर्फ़ पढ़ें लिखा हो उसमें कुछ भी टाइप, चिपकाया या क्लिक नहीं करना होता है. उसमें मौजूद कोड पहले से ही repo में मौजूद होता है और चल रहा होता है. उसे सिर्फ़ पढ़ने के लिए प्रिंट किया जाता है.

वेस्पर के दरवाज़े पर लिखा वाक्य, सबसे ऊपर वाला वाक्य है. इस हफ़्ते का आखिरी वाक्य, पूरे सीज़न के चौथे हफ़्ते का आखिरी वाक्य है:

तथ्य और प्राथमिकताएं अलग-अलग स्टोर में मौजूद होनी चाहिए.

2. 🧰 सेटअप

  • क्या — किसी प्रोजेक्ट की ओर इशारा करें या कोई कुंजी चिपकाएं, इंस्टॉल करें, और यह साबित करें कि टूलचेन सही तरीके से काम कर रहा है.
  • क्यों — यहां कुछ भी बूट नहीं होता. हर सर्वर, उस चरण से ठीक पहले शुरू होता है जिसकी उसे ज़रूरत होती है. इसलिए, जब कोई स्क्रीन खुलती है, तो आपको पता होता है कि उसे कौनसी कमांड कंट्रोल करती है.
  • कैसे — एक स्क्रिप्ट जो प्रोजेक्ट बनाती है, एक जो Vertex AI को इंस्टॉल करती है और आपको उसके बारे में बताती है, और एक प्रीफ़्लाइट स्क्रिप्ट जो आपके कोड को पढ़ती है और आपको बताती है कि आप कहां हैं.

इस लैब में मौजूद हर चीज़ Cloud Shell में चलती है. इसमें Python, uv, और gcloud पहले से इंस्टॉल होते हैं. साथ ही, Gemini को Vertex AI के ज़रिए ऐक्सेस किया जाता है. इसके लिए, आपको अपने क्रेडेंशियल इस्तेमाल करने होते हैं. इस लैब में कहीं भी एपीआई कुंजी नहीं है. साथ ही, आपके लैपटॉप पर कुछ भी इंस्टॉल करने की ज़रूरत नहीं है.

इस लैब में आपको एक चीज़ नहीं मिलेगी: बिलिंग की सुविधा वाला Google Cloud प्रोजेक्ट. पहले चरण में, आपको एक ऐसा खाता मिलता है जिससे पेमेंट किया जा सकता है. चौथे चरण में, उस खाते को प्रोजेक्ट में बदल दिया जाता है. इसके अलावा, पहले, दूसरे या तीसरे हफ़्ते में बनाए गए Agent Valley प्रोजेक्ट को भी चुना जा सकता है. इन्हें इसी क्रम में करें — चौथे चरण के बाद के हर चरण में, उस प्रोजेक्ट को पढ़ा जाता है जिसे चौथे चरण में चुना गया है.

1 · बिलिंग की सुविधा वाला खाता पाएं (~1 मिनट)

🌐 सबसे पहले यह काम करें. उस Google खाते से साइन इन करें जिसमें बिलिंग की सुविधा चालू हो. इस तरह का कोई भी खाता काम करता है. अगर आपके पास ऐसा खाता नहीं है, तो बिना किसी शुल्क के आज़माएं. इससे आपको एक बिलिंग खाता मिलेगा, जो चौथे चरण के लिए ज़रूरी है.

2 · Cloud Shell खोलें (~1 मिनट)

🌐 Google Cloud Console में सबसे ऊपर मौजूद, Cloud Shell चालू करें पर क्लिक करें. यह हेडर में टर्मिनल के आकार का आइकॉन होता है.

Google Cloud Console के हेडर से Cloud Shell चालू करें

🌐 एडिटर खोलें (खुले फ़ोल्डर के साथ पेंसिल वाला आइकॉन) पर क्लिक करें. इससे Cloud Shell Editor खुल जाएगा. इसमें बाईं ओर फ़ाइल एक्सप्लोरर दिखेगा. जब भी किसी चरण को 👉✏️ के तौर पर मार्क किया जाता है, तब आपको यहीं काम करना होता है.

Cloud Shell Editor खोलना

🌐 अगर आज किसी भी समय आपको अनुमति देने के लिए कहा जाता है, तो जारी रखने के लिए अनुमति दें पर क्लिक करें.

🌐 एडिटर में एक टर्मिनल खोलें — यानी कि टैब 1. जब तक कोई और निर्देश न दिया जाए, तब तक हर 👉💻 चरण यहीं पर चलेगा. टैब 2, संग्रह है. इसे पहले चैप्टर में खोला जाता है. यह उस चरण से ठीक पहले खोला जाता है जिसमें इसकी ज़रूरत होती है. अगर टर्मिनल पहले से ही स्क्रीन के सबसे नीचे नहीं है, तो व्यू → टर्मिनल पर जाकर इसे खोलें:

Cloud Shell Editor में नया टर्मिनल खोलना

🌐 देखें कि आपने किस खाते से साइन इन किया है. यह वही खाता होना चाहिए जिसका इस्तेमाल आपने पहले चरण में किया था:

gcloud auth list

3 · लैब पाएं (~1 मिनट)

💻 रिपो को क्लोन करें — यह आर्काइव रिपो है, पहले, दूसरे या तीसरे हफ़्ते की नहीं:

cd ~
git clone https://github.com/cuppibla/agent-valley-archive
cd agent-valley-archive

4 · अपना प्रोजेक्ट बनाएं या पिछले हफ़्ते के प्रोजेक्ट का फिर से इस्तेमाल करें (~2 मिनट)

💻 एक स्क्रिप्ट आपके बिलिंग खाते का पता लगाती है, उस पर एक प्रोजेक्ट बनाती है, और Cloud Shell को उस प्रोजेक्ट पर ले जाती है. अगर आपने पहले, दूसरे या तीसरे हफ़्ते में कोई प्रोजेक्ट बनाया है, तो यह सुविधा सबसे पहले Agent Valley प्रोजेक्ट को ढूंढती है और उसे फिर से इस्तेमाल करने का विकल्प देती है — 'हां' पर क्लिक करें. इसके बाद, आपको किसी दूसरे बिल किए जाने वाले प्रोजेक्ट के बारे में सोचने की ज़रूरत नहीं है:

cd ~/agent-valley-archive
./setup_project.sh

👀 चुने गए बिलिंग खाते के लिए ✓, बनाए गए या फिर से इस्तेमाल किए गए प्रोजेक्ट के लिए ✓, और इस तरह का मैसेज मिल सकता है:

cd ~/agent-valley-archive
Project ready: agent-valley-4271
  Next:  ./setup_codelab.sh

agent-valley-4271 आपका प्रोजेक्ट आईडी है. आपके प्रोजेक्ट आईडी में अलग-अलग अंक होंगे. इसमें चार काम होते हैं:

बिलिंग

अगर आपके पास नया [YYYY-MM-DD] GDP Credit: खाता है, तो उसका इस्तेमाल करता है. अगर आपके पास नया खाता नहीं है, तो किसी दूसरे खुले हुए बिलिंग खाते का इस्तेमाल करता है

प्रोजेक्ट

यह देखता है कि आपके पास Agent Valley का कोई प्रोजेक्ट है या नहीं. यह पहले, दूसरे या तीसरे हफ़्ते का प्रोजेक्ट हो सकता है. अगर आपके पास कोई प्रोजेक्ट है, तो यह उसे फिर से इस्तेमाल करने का विकल्प देता है. अगर आपके पास कोई प्रोजेक्ट नहीं है, तो यह agent-valley-XXXX बनाता है और उस बिलिंग खाते को उससे लिंक करता है

selects

यह कुकी, आईडी को ~/project_id.txt में सेव करती है और gcloud config set project को चलाती है. इसलिए, इसके बाद आपसे आईडी टाइप करने के लिए नहीं कहा जाता

waits

जब तक प्रोजेक्ट को विज्ञापन दिखाने की अनुमति नहीं मिल जाती, तब तक दो मिनट तक पोल करता है

🌐 अब यही प्रोजेक्ट कंसोल में मौजूद है. इसका आईडी, डैशबोर्ड पर मौजूद प्रोजेक्ट की जानकारी कार्ड में दिखता है:

कंसोल डैशबोर्ड पर आपका प्रोजेक्ट आईडी

5 · Vertex AI को इंस्टॉल करें और उस पर पॉइंट करें (~3 मिनट)

💻 uv इंस्टॉल करें. साथ ही, उन तीन वैरिएबल को एक्सपोर्ट करें जो ADK को Vertex AI पर भेजते हैं. इसके बाद, सेटअप चलाएं:

cd ~/agent-valley-archive
curl -LsSf https://astral.sh/uv/install.sh | sh
source ~/.local/bin/env
export GOOGLE_GENAI_USE_VERTEXAI=TRUE
export GOOGLE_CLOUD_PROJECT=$(gcloud config get project)
export GOOGLE_CLOUD_LOCATION=global
./setup_codelab.sh

$(gcloud config get project) को कुछ लौटाना है, क्योंकि चरण 4 में इसे सेट किया गया था. इसलिए, चौथे चरण को सबसे पहले रखा गया है.

setup_codelab.sh एक आइडमपोटेंट फ़ंक्शन है. इसे जितनी बार चाहें उतनी बार फिर से चलाया जा सकता है. यह पांच काम करता है:

api

प्रोजेक्ट के चौथे चरण को पढ़ता है और उस पर aiplatform.googleapis.com (Vertex AI और Memory Bank को होस्ट करने वाला Agent Engine) और bigquery.googleapis.com (पांचवें चैप्टर का वेयरहाउस) को चालू करता है

uv env

uv venv बनाता है या पहले से मौजूद किसी .venv का फिर से इस्तेमाल करता है. इसके बाद, uv sync ठीक वही इंस्टॉल करता है जिसे uv.lock पिन करता है. जैसे, google-adk, google-genai, और उनके नीचे मौजूद सभी आइटम

site

npm ci, site/ में चलता है. Archive खुद एक Next.js ऐप्लिकेशन है. इसलिए, पहले चैप्टर में bash valley.sh को डाउनलोड करने के लिए कुछ भी नहीं बचा है. अगर पैकेज पहले से मौजूद हैं, तो इसे छोड़ दिया जाता है

.env

यह कुकी, लैब में पढ़े जाने वाले वैरिएबल लिखती है. जैसे, GOOGLE_GENAI_USE_VERTEXAI, GOOGLE_CLOUD_PROJECT, GOOGLE_CLOUD_LOCATION, MEMORY_BANK_LOCATION, और BQ_DATASET. साथ ही, इसमें कहीं भी एपीआई पासकोड नहीं होता

मॉडल की जांच करना

Gemini को एक असली कॉल करता है, ताकि सेटअप के समय ही खराब प्रोजेक्ट का पता चल जाए. ऐसा न हो कि बाद में किसी चैप्टर में जाकर पता चले

6 · साबित करें कि यह हरा है (~1 मिनट)

💻 प्रीफ़्लाइट चलाएं — हर टिक एक असली जांच है, अनुमान नहीं:

cd ~/agent-valley-archive
uv run python scripts/preflight.py

👀 प्रीफ़्लाइट में, मॉडल से एक सवाल पूछा जाता है, ताकि यह साबित किया जा सके कि आपके क्रेडेंशियल काम कर रहे हैं. इसके बाद, यह जांच की जाती है कि संग्रह के पैकेज मौजूद हैं या नहीं. इसके बाद, यह आपके कोड को पढ़ता है और इस हफ़्ते के प्रोग्रेस बार को प्रिंट करता है:

cd ~/agent-valley-archive
  desk      ▢ the slip      · write_down writes nothing         chapter 1 · EDIT ONE
  floor 1   ✓ the file      · SqliteSessionService              chapter 1, read only
  floor 2   ▢ the drawer    · CASE = "case"                     chapter 2 · EDIT TWO
  floor 3   ✓ what was said · closing time files the day        chapter 3, read only
  floor 3   ▢ the asking    · recall never looks                chapter 3 · EDIT THREE
  floor 3   ▢ the tower     · InMemoryMemoryService             chapter 4 · built, not edited
  floor 3   ✓ the rules     · USER_PREFERENCES, LANTERN_CONTEXT chapter 4, read only

इनमें से तीन पर पहले से ही सही का निशान लगा हुआ है. ये वे ईमेल होते हैं जिन्हें सिर्फ़ पढ़ा जाता है. इनमें से तीन लाइनें आपको लिखनी हैं और एक टावर आपको बनाना है. लैब में किसी भी समय प्रीफ़्लाइट की जांच फिर से करें. इससे आपको पता चलेगा कि आपकी फ़ाइलें कहां हैं. यह आपकी फ़ाइलों को पढ़ता है, न कि चेकलिस्ट को.

3. Session, State, SqliteSessionService

  • क्या — एक लाइन लिखें; वर्कबेंच को एक बार शुरू करें और स्लिप को भरते हुए देखें; इसके बाद, टावर में भी ऐसा ही करें; फिर पढ़ें कि यह रात भर क्यों चलता रहता है.
  • क्यों — मेमोरी के बारे में सबसे पहली बात यह है कि कुछ भी अपने-आप याद नहीं रहता. कोई व्यक्ति इसे लिखता है.
  • कैसे — agent.py में एक लाइन जोड़ें. इसके अलावा, कुछ और न बदलें.

EDIT ONE

👉📖 archive/agent.py खोलें और write_down ढूंढें. 👉 को पढ़कर सुनाओ:

    case = dict(tool_context.state.get(CASE, {}))
    if case.get(field):
        return {"already_written": {field: case[field]}}
    case[field] = value
    # 👉 EDIT ONE — chapter 1. She heard you. Nothing was written. Delete the
    #    "# " in front of the next line, then save — the slip is session state,
    #    and state is written by code, never by the conversation:
    # tool_context.state[CASE] = case
    return {"written": {field: value}}

यह फ़ंक्शन, स्लिप को लोकल डिक्ट में बनाता है. इसके बाद, इसे वापस भेजता है. साथ ही, कॉल के साथ लोकल डिक्ट खत्म हो जाता है. इसे ऐसे ही चलाएं. Vesper आपकी बात पूरी तरह से सुनता है: चार write_down कॉल फ़ायर होते हैं, हर एक "written" का जवाब देता है, और सेशन की स्थिति खाली रहती है, क्योंकि इसमें कभी कुछ नहीं पहुंचा. उसे आपकी बात सुनाई दी. कुछ भी नहीं लिखा गया.

👉✏️ अब भी archive/agent.py में, write_down के अंदर: किसी लाइन के आगे मौजूद # को मिटाएं. इसके साथ ही, # के बाद मौजूद स्पेस को भी मिटाएं. पहले:

    case[field] = value
    # 👉 EDIT ONE — chapter 1. She heard you. Nothing was written. Delete the
    #    "# " in front of the next line, then save — the slip is session state,
    #    and state is written by code, never by the conversation:
    # tool_context.state[CASE] = case
    return {"written": {field: value}}

इसके बाद:

    case[field] = value
    # 👉 EDIT ONE — chapter 1. She heard you. Nothing was written. Delete the
    #    "# " in front of the next line, then save — the slip is session state,
    #    and state is written by code, never by the conversation:
    tool_context.state[CASE] = case
    return {"written": {field: value}}

सेव करें पर क्लिक करें.

स्लिप में जानकारी अपने-आप भर जाती है

👉💻 वर्कबेंच शुरू करें. लैब में इसे सिर्फ़ एक बार खोला जाता है. यह ऐसी विंडो है जिसमें सेशन की स्थिति को रॉ JSON के तौर पर दिखाया जाता है:

cd ~/agent-valley-archive
uv run adk web . --allow_origins="*"

👉🔬 वेब प्रीव्यू → पोर्ट 8000 पर प्रीव्यू करें की मदद से वर्कबेंच खोलें. वेब प्रीव्यू बटन, Cloud Shell में सबसे ऊपर दाईं ओर मौजूद आंख वाला आइकॉन होता है. संग्रहित करें चुनें. इसके बाद, कुछ भी टाइप करने से पहले, बाएं पैनल में मौजूद स्टेट पर क्लिक करें.

👀 खाली है. अभी तक किसी ने कुछ नहीं कहा है.

👉🔬 अब एक ही मैसेज में यह लिखो:

Hi! My lantern keeps going out at night. My case number is k7f2, and there's a little q7 stamped on the base.

👀 चार write_down चिप ट्रिगर होते हैं — किसी एक पर क्लिक करें और JSON पढ़ें: "written": {"no": "k7f2"}. अब स्टेट पर फिर से क्लिक करें.

चार चीज़ें, चार फ़ील्ड, एक मैसेज

case   {"no": "k7f2", "item": "lantern", "mark": "q7",
        "symptom": "keeps going out at night"}

👀 एक ही मैसेज में, पहले खाली और फिर भरा हुआ. उसे यही याद है और यह अपने-आप नहीं आया. आपने उस लाइन को लिखा है जो इसे लिखती है. यह पूरा तरीका है: एक सामान्य फ़ंक्शन, जो tool_context.state में लिखता है. साथ ही, एक निर्देश जो उसे इसका इस्तेमाल तब करने के लिए कहता है, जब वेबसाइट पर आने वाला व्यक्ति कुछ ऐसा कहता है जो स्लिप पर एक लाइन में फ़िट हो जाता है.

👉🔬 उससे पूछें:

What's my case number?

👀 k7f2. वह पर्ची पर लिखा हुआ पढ़ती है. EDIT ONE के बिना, वह आपसे इसके लिए पूछती — सहायता सूची की पहली लाइन, एक बातचीत के अंदर.

दो गार्ड, पेपर फ़ॉर्म में मौजूद स्लिप हैं: चार छोटी लाइनें, हर लाइन को एक बार लिखा गया है. ये जितनी दिखती हैं उससे कहीं ज़्यादा ज़रूरी हैं. इनके बिना मॉडल को पता चलता है कि पूरी बातचीत को symptom में डाला जा सकता है. साथ ही, चैप्टर 3 — जिस चैप्टर का पूरा मकसद स्लिप में इसके लिए कोई लाइन नहीं है — चुपचाप से गलत हो जाता है. स्टोर की शेप को लिखने वाले कोड से लागू किया जाता है या इसे लागू नहीं किया जाता है.

अब टावर पर जाएं

👉💻 आपने वर्कबेंच का इस्तेमाल कर लिया है. इसे चालू रहने दें या इसका टैब बंद कर दें. लैब के बाकी हिस्से को संग्रहित किया जाता है. दूसरा टर्मिनल टैब (टैब 2 — संग्रह) खोलें:

cd ~/agent-valley-archive
bash valley.sh

👉🖥 वेब प्रीव्यू → पोर्ट बदलें की मदद से संग्रह खोलें. इसके बाद, 3440 टाइप करें और बदलें और झलक देखें पर क्लिक करें. 3440, वेब प्रीव्यू की क्विक लिस्ट में नहीं है. इसका डिफ़ॉल्ट पोर्ट 8080 है. इसलिए, आपको इसे एक बार मैन्युअल तरीके से सेट करना होगा. ▶ शुरू करें और फिर संग्रह दबाएं. दरवाज़े पर कोई है. जो भी आपसे मिलने आया है उसका नाम और प्रजाति पूछें और उसे अंदर आने दें.

टावर, कट ओपन

👀 एक बिल्डिंग. वेस्पर ग्राउंड फ़्लोर पर डेस्क पर बैठी है. आपको वहीं जाकर उससे बात करनी होगी. उसके ऊपर: पहली मंज़िल, दूसरी मंज़िल, तीसरी मंज़िल, और एक अंधेरी अटारी. चार सीढ़ियां, चार फ़्लोर हैं. आपका फ़ैमिलियर ग्राउंड फ़्लोर पर बैठा है, क्योंकि आपने सिर्फ़ ग्राउंड फ़्लोर तक की सीढ़ियां चढ़ी हैं. ड्राइंग के बगल में मौजूद कॉलम में बताया गया है कि हर फ़्लोर पर फ़िलहाल क्या-क्या है. इसमें, परिचय में दी गई टेबल में मौजूद चार स्टोर के बारे में बताया गया है. साथ ही, उनका क्रम भी वही है. दाईं ओर मौजूद कोई भी आइटम बटन नहीं है.

👉🖥 बातचीत वाले बॉक्स में, यहां दिया गया मैसेज चिपकाएं और Enter दबाएं:

Hi! My lantern keeps going out at night. My case number is k7f2, and there's a little q7 stamped on the base.

डेस्क पर चार लाइनें और उसके बगल में भी चार लाइनें

👀 डेस्क को देखें. स्लिप अपने-आप बनती है. इसमें एक बार में एक लाइन लिखी जाती है. यह लाइन, ड्राइंग पर और इसके बगल में मौजूद स्लिप में पूरी तरह से दिखती है. एक ही टूल, एक ही स्थिति: टावर सिर्फ़ वही लिख रहा है जो write_down ने लिखा है. यह लैब के बाकी हिस्से के लिए भी ऐसा ही करता रहेगा.

यह कुकी, रात भर की जानकारी सेव करती है. इसे सिर्फ़ पढ़ा जा सकता है

आपने क्या लिखा है और वह क्या है

लाइन

यह क्या है

यह कहां दिखता है

tool_context.state[CASE] = case

सेशन की स्थिति — इसे कोड लिखता है और निर्देश इसे पढ़ता है

डेस्क · session.state

SqliteSessionService(DB) — सिर्फ़ इसे पढ़ा जा सकता है

सेशन स्टोर — फ़ाइल में विज़िट, प्रोसेस में नहीं

पहली मंज़िल · archive.db

इस रंग में एक विज़िट शामिल है और यह बंद होने के समय तक मौजूद रहती है. यह कुकी, अगली बार वेबसाइट पर आने तक सेव नहीं रहती.

4. उपयोगकर्ता का राज्य

  • क्या — एक महीने बाद वापस आएं; स्लिप हट गई है. पाँच वर्णों का है और यह आपको फ़ॉलो करता है.
  • क्यों — सेशन, एक विज़िट होती है. अगली विज़िट एक नया सेशन है और इसमें पिछली विज़िट का डेटा नहीं दिखता.
  • How — state.py में पांच वर्ण हैं.

एक महीने बाद. आपसे मिलकर खुशी हुई.

इसे यहां दबाएं

👉🖥 🗓 एक महीने बाद को दबाएं. यह उसी विज़िटर के लिए एक नया सेशन है. यह उसी तरह से काम करता है जैसे तीसरे हफ़्ते में नई बातचीत शुरू करें काम करता था.

संग्रह में आपका स्वागत है. आज मैं आपकी किस तरह मदद कर सकता हूं?

👉🖥 टावर की ओर देखो. पहली मंज़िल पर एक और किताब है — इस विज़िट में. दूसरी मंज़िल पर मौजूद दराज खाली है. डेस्क पर रखा हुआ स्लिप खाली है.

पहली मंज़िल पर एक और किताब; दराज़ खाली; स्लिप खाली

👀 वजह: स्लिप को सेशन की स्थिति में लिखा जाता है और सेशन का मतलब इस विज़िट से है. विज़िट में बदलाव करना, सेशन में बदलाव करना. कोई भी जानकारी ट्रांसफ़र नहीं की गई, क्योंकि इसके बारे में कोई निर्देश नहीं दिया गया था. फ़ाइल में अब भी आखिरी बार की गई विज़िट की जानकारी मौजूद है. यह पहली मंज़िल की पहली किताब है. हालांकि, स्लिप को उस कुंजी के तहत लिखा गया था जो एक विज़िट के लिए मान्य होती है.

EDIT TWO

👉✏️ archive/state.py खोलें. 👉 ढूंढें. इससे पहले:

# 👉 EDIT TWO — chapter 2. Five characters. A key with no prefix lives for one
#    visit; `user:` follows the visitor into every visit after this.
CASE = "case"

इसके बाद:

CASE = "user:case"

सेव करें पर क्लिक करें. रीस्टार्ट नहीं किया जाता — Archive, हर मैसेज पर आपके कोड को फिर से इंपोर्ट करता है.

👉🖥 इन चार चीज़ों को फिर से चिपकाएं — यह मैसेज:

Hi! My lantern keeps going out at night. My case number is k7f2, and there's a little q7 stamped on the base.

👉🖥 इसके बाद, 🗓 एक महीने बाद बटन को फिर से दबाएं. यह वही बटन है जिसे आपने पहले दबाया था.

नाम लिखा हुआ दराज

👀 दूसरी मंज़िल पर मौजूद दराज़ पर आपका नाम लिखा है. इसमें चार फ़ील्ड हैं. डेस्क पर रखी हुई पर्ची में वही चार लाइनें हैं जो आपने कमरे में आते समय दराज़ से निकाली थीं. आपका पालतू जानवर एक फ़्लोर ऊपर चला गया है. हर विज़िट के लिए एक ही कुकी, एक ही वैल्यू: यह प्रीफ़िक्स का काम है.

प्रीफ़िक्स हमेशा के लिए होता है.

उपसर्ग

यह कितने समय तक जीवित रहता है

कौनसी मंज़िल

(कोई नहीं)

इस विज़िट के दौरान

डेस्क

user:

वेबसाइट पर आने वाले व्यक्ति की हर विज़िट

दूसरी मंज़िल पर, आपकी दराज़

app:

सभी के लिए, हमेशा के लिए

चौथे फ़्लोर का हिस्सा

temp:

सिर्फ़ इस मोड़ पर — सीढ़ियों पर कभी नहीं चढ़ता

—

एक टेबल, चार दराज़. इस चैप्टर में, इनमें से किसी एक के बारे में बताया गया है.

अब वह आपको जानती है

👉🖥 यह विज़िट बिलकुल नई है और आपने इसमें अब तक कुछ नहीं कहा है. उससे पूछें:

What did I bring in last time?

👀 मैंने लिख रखा है कि आपने एक लालटेन मंगाई थी, केस k7f2. इस पर q7 का निशान है और आपने बताया है कि यह रात में बंद हो जाता है. ड्रॉर से निकला हर शब्द, बातचीत का हिस्सा नहीं था. इस विज़िट में सिर्फ़ एक मैसेज है और इस मैसेज का कोई नाम नहीं है. यह उपयोगकर्ता-लेवल की स्थिति है. इसमें, वेबसाइट पर आने वाले व्यक्ति के कुछ भी कहने से पहले ही, हर बार विज़िट करने पर user: कुंजी मौजूद होती है.

दराज़ में स्लिप की चार लाइनें होती हैं. इसके अलावा, इसमें और कुछ नहीं होता. आपने जो भी कहा है, वह स्लिप पर नहीं लिखा गया है. आपने क्या कोशिश की, आपको इसकी परवाह क्यों है, आपको नया कार्ड चाहिए या नहीं, यह जानकारी कहीं नहीं जाती. एक महीने बाद, यह जानकारी मिट जाती है. दराज़ महीने की सीमा पार कर गया है. वाक्य में नहीं होता. तीसरा चैप्टर इसी के बारे में है.

आपने क्या लिखा है और वह क्या है

लाइन

यह क्या है

यह कहां दिखता है

CASE = "user:case"

प्रीफ़िक्स का इस्तेमाल हमेशा के लिए किया जाता है. यह विज़िट के बजाय, विज़िटर के लिए स्कोप की गई एक ही कुंजी होती है

दूसरी मंज़िल · user: राज्य

यह रंग एक विज़िटर तक पहुंचता है. ड्रॉर आपके साथ फ़ॉलो करता है; बातचीत अब भी नहीं करती.

5. InMemoryMemoryService

  • क्या — वह लाइन पढ़ो जिसमें दिन की जानकारी दी गई है. इसके बाद, वह लाइन लिखो जिसमें सवाल पूछा गया है. इसके बाद, बंद होने का समय और एक सवाल लिखो.
  • क्यों — स्लिप एक फ़ॉर्म है. फ़ॉर्म में वे लाइनें हैं जो आपने दी हैं. लोग लाइनों में नहीं बोलते. इसलिए, उन्होंने जो कहा है उसे फ़ाइल करना, उसे याद रखने का सिर्फ़ आधा हिस्सा है.
  • कैसे — file पढ़ें; recall में एक लाइन; इसके बाद, एक 🌙, एक 🗓, और एक सवाल.

बंद होने का समय. वह वापस शेल्फ़ के पास से गुज़रती है.

घर के रास्ते में वह क्या करती है — सिर्फ़ पढ़ने के लिए

फ़ाइल की जानकारी सेव नहीं की जाती

इस लाइन से दिन को शेल्फ़ पर रखा जाता है. इससे कुछ भी नहीं हटाया जाता. अगर कोई नहीं देखता है, तो कार्ड से भरी शेल्फ़ उतनी ही मदद करती है जितनी खाली शेल्फ़. कोड शिप होने के बाद, कोई नहीं देखता: recall, हर सवाल पर Vesper से पहले चलने वाला नोड, टावर से कुछ नहीं पूछता. जिस जानकारी को सही समय पर याद नहीं किया जा सकता वह मेमोरी नहीं, बल्कि लॉग है. दूसरा हिस्सा, देखने से जुड़ा है. इसे आपको लिखना है.

तीसरा बदलाव — सवाल पूछना

👉📖 archive/agent.py में, recall ढूंढें. यह file के ठीक ऊपर मौजूद फ़ंक्शन है. यह एक सामान्य फ़ंक्शन नोड है, जो हर सवाल पर Vesper से पहले चलता है. मॉडल यह तय नहीं करता कि कब देखना है. इसका मतलब है कि जब इसे कुछ नहीं मिलता, तो वह भी दिखता है. 👉 को पढ़कर सुनाओ:

    if query.strip():
        try:
            # 👉 EDIT THREE — chapter 3. Filed is not remembered: the cards are on
            #    the shelf and nobody is looking at them. Delete the "# " in front
            #    of the next line, then save:
            # found = await ctx.search_memory(query)
            pass
        except ValueError:
            # no memory service wired on this runner — degrade, do not crash
            pass

👉✏️ अब भी archive/agent.py में, recall के अंदर: किसी लाइन के आगे मौजूद # को मिटाएं. इसके साथ ही, # के बाद मौजूद स्पेस को भी मिटाएं. पहले:

        try:
            # 👉 EDIT THREE — chapter 3. Filed is not remembered: the cards are on
            #    the shelf and nobody is looking at them. Delete the "# " in front
            #    of the next line, then save:
            # found = await ctx.search_memory(query)
            pass
        except ValueError:

इसके बाद:

        try:
            # 👉 EDIT THREE — chapter 3. Filed is not remembered: the cards are on
            #    the shelf and nobody is looking at them. Delete the "# " in front
            #    of the next line, then save:
            found = await ctx.search_memory(query)
            pass
        except ValueError:

pass को वहीं रहने दें जहां वह है. अब यह कुछ नहीं करता, क्योंकि found पहले से ही None से ऊपर है.

सेव करें पर क्लिक करें. रीस्टार्ट करने की ज़रूरत नहीं है.

दो लाइनें, दो नीतियां — और आपने उनमें से एक लिखी है. लिखने की नीति यह तय करती है कि कौनसी जानकारी सेव की जाएगी और कब (स्टोर बंद होने का समय, पूरा दिन). रीकॉल करने की नीति यह तय करती है कि किस समय और किस जानकारी के साथ (हर सवाल, सवाल ही) जवाब खोजा जाए. ADK आपको क्रियाएं — add_events_to_memory, search_memory — देता है और नीति से बाहर रहता है. यह सही बंटवारा है. इसलिए, यह सवाल आपको लिखना था.

बंद होने का समय

👉🖥 तीन ऐसी चीज़ों के बारे में बताओ जिनके लिए स्लिप में कोई लाइन नहीं है. एक मैसेज या तीन:

I read by it at night, so night is exactly when I need it.
I've tried hanging it higher. No change.
I don't want a new one — it was a gift.

इसे यहां दबाएं

👉🖥 इसके बाद, 🌙 आज के लिए बस इतना ही को दबाएं.

शब्दों का ऊपर की ओर बढ़ना

👀 डेस्क को देखें. आपने कहा था कि तीन चीज़ें स्लिप से ऊपर उठती हैं और तैरती हैं और तीसरी मंज़िल पर उतरती हैं. टावर के बगल में मौजूद कार्ड में, भेजे गए हर मैसेज के लिए एक कार्ड दिखता है. इन कार्ड पर quote का निशान लगा होता है. साथ ही, इनमें आपके भेजे गए मैसेज के शब्द भी शामिल होते हैं. इस प्रोसेस में, ये कार्ड सबसे ऊपर दिखते हैं. डेस्क पर रखा लैंप तब तक जलता रहता है, जब तक वे लैंड नहीं कर लेते.

एक महीने बाद, उसे पता चलता है

👉🖥 🗓 एक महीने बाद दबाएं और पूछें:

What have I already tried?

👀 आपने इसे ऊपर टांगने की कोशिश की, लेकिन इससे कोई फ़र्क़ नहीं पड़ा. उसे पता है. स्लिप में इसके लिए कोई लाइन नहीं है और न ही कभी थी. इसलिए, दराज में मौजूद कार्ड के बारे में जानकारी नहीं दी जा सकती. recall को कार्ड मिला, उसने इसे ctx.state["recalled"] में लिखा, और उसके निर्देश में यह जानकारी दी गई है. दोनों में सिर्फ़ एक लाइन का अंतर है.

और यह सब उसके दिमाग़ में है

टावर के बगल में मौजूद कार्ड में जाकर देखें: इस प्रोसेस में. फ़िलहाल, मेमोरी InMemoryMemoryService है. यह bash valley.sh में मौजूद एक डिक्शनरी है. यह मेमोरी, प्रोसेस के खत्म होने तक ही रहती है. आज रात टावर बंद कर दो और इसे कल खोलना: किताबें पहली मंज़िल पर हैं, दराज दूसरी मंज़िल पर है, और तीसरी मंज़िल पर अंधेरा है. केस की जानकारी फ़ाइल में सेव है. आपने जो कहा था वह प्रोसेस में शामिल हो गया था और प्रोसेस खत्म हो गई है.

डेटा को सेव करके रखना, जानकारी याद रखने की सुविधा नहीं है.

तीसरी मंज़िल के बारे में दी गई जानकारी में दो चीज़ें गलत हैं: पहली, यह जानकारी प्रोसेस में है. दूसरी, यह जानकारी आपके शब्दों में है. यह एक उद्धरण है, तथ्य नहीं. अगले चैप्टर में, इन दोनों समस्याओं को ठीक किया गया है. इसके लिए, कोड की ज़रूरत नहींं है.

आपने क्या पढ़ा, क्या लिखा, और यह क्या है

लाइन

यह क्या है

यह कहां दिखता है

await ctx.add_events_to_memory(events, custom_metadata=FILING) — सिर्फ़ इसे पढ़ा जा सकता है

लिखने की नीति — पूरा दिन, बंद होने के समय

तीसरा फ़्लोर · मेमोरी सर्विस

found = await ctx.search_memory(query) — EDIT THREE

सामान वापस मंगाने की नीति — हर सवाल के जवाब से पहले

recall() → ctx.state["recalled"]

इस रंग से, बोली गई बात को समझा जाता है. साथ ही, इसे एक प्रोसेस के तहत, आपकी भाषा में डिक्शनरी में सेव किया जाता है. इस जवाब के दोनों हिस्से गलत हैं. अगले चैप्टर में, बिना किसी कोड के इन दोनों को ठीक किया गया है.

6. MemoryBank

  • क्या — एक स्क्रिप्ट मेमोरी बैंक बनाती है; आपके पास पहले से मौजूद दो लाइनें, इसमें तथ्यों को लिखना और उन्हें वापस पढ़ना शुरू करती हैं.
  • क्यों — मेमोरी सेवा एक सेवा है. संग्रह कहां सेव किया जाएगा, यह एजेंट के बजाय डिप्लॉयमेंट से जुड़ा फ़ैसला होता है. इसलिए, एजेंट में कोई बदलाव किए बिना इसे बदला जा सकता है.
  • कैसे — make_tower.py चलाओ, तीन वाक्य बोलो, 🌙 दबाओ, 🗓 दबाओ, एक सवाल पूछो. इसके बाद, लिखने और पढ़ने की अनुमति के बारे में जानकारी दी गई है.

टावर बनाना

तीसरे चैप्टर के तीसरे फ़्लोर में, bash valley.sh के अंदर एक Python डिक्शनरी थी. मेमोरी बैंक, फ़्लो का मैनेज किया गया वर्शन है: यह आपके प्रोजेक्ट में एजेंट इंजन इंस्टेंस पर मौजूद होता है. इसमें आपके वाक्यों के बजाय, दिन के हिसाब से तथ्य सेव होते हैं. साथ ही, यह शब्दों के बजाय मतलब के हिसाब से तथ्य ढूंढता है. Vesper का इस्तेमाल करने के लिए, आपको इसे किसी एजेंट इंजन पर डिप्लॉय करने की ज़रूरत नहीं है. जिस इंस्टेंस पर कुछ भी डिप्लॉय नहीं किया गया है वह अब भी मेमोरी बैंक को होस्ट करता है. स्क्रिप्ट इसी को बनाती है: एक ऐसा टावर जिसमें कोई नहीं रहता और जिसका काम सिर्फ़ कार्ड रखना है.

👉💻 पहले टैब में (लगभग एक मिनट):

cd ~/agent-valley-archive
uv run python scripts/make_tower.py

👀 अनुमानित:

  building the tower in YOUR_PROJECT / us-central1 — about a minute...
  built, with the two topics in archive/topics.py configured on it.

  resource: projects/.../locations/us-central1/reasoningEngines/6792...
  AGENT_ENGINE written to .env

  Next — nothing to restart. The Archive reads .env on every message:
    look at floor three — under the cards it now says Memory Bank.
    (adk web, if you use it:  --memory_service_uri "agentengine://projects/.../reasoningEngines/6792...")

एक एसडीके कॉल, agent_engines.create(), और .env में लिखी गई एक लाइन. संग्रह, हर अनुरोध पर उस फ़ाइल को फिर से पढ़ता है. इसलिए, इसे फिर से शुरू करने की कोई ज़रूरत नहीं है.

इसे काम करते हुए देखें

👉🖥 तीसरी मंज़िल पर मौजूद टावर को देखें. यह कुछ ही सेकंड में अपने-आप फिर से बन जाता है. कार्ड में जाकर, अब मेमोरी बैंक पर क्लिक करें. इसके बाद, शेल्फ़ खाली दिखेगी: तीसरे चैप्टर के तीन कोट प्रोसेस किए जा रहे थे. हालांकि, यह प्रोसेस नहीं है. इन तीन वाक्यों को एक मैसेज या तीन मैसेज में फिर से बोलें:

I read by it at night, so night is exactly when I need it.
I've tried hanging it higher. No change.
I don't want a new one — it was a gift.

👉🖥 🌙 आज के लिए बस इतना ही दबाएं. अब बंद होने में करीब आठ सेकंड लगते हैं — टावर बंद हो रहा है. इसके बाद, तीसरी मंज़िल पर जाएं.

बाएं: वह जानकारी जो उसने अपने दिमाग में रखी. दाईं ओर: टावर में मौजूद चीज़ें.

👀 कार्ड में दिए गए वाक्य आपके नहीं हैं. उन्होंने इस तरह की बातें कही हैं, जैसे कि मैं रात में पढ़ने के लिए लालटेन का इस्तेमाल करता हूं. इस दौरान, यह बंद होती रहती है और मैंने लालटेन को पहले ही ऊपर टांगने की कोशिश कर ली है. हर बात को fact के साथ तारीख के हिसाब से मार्क किया गया है. डिस्टिलेशन. इसमें बातचीत को शामिल किया गया था. इसमें तथ्यों को शामिल किया गया है.

👉🖥 🗓 एक महीने बाद दबाएं — यह एक नई विज़िट है, इसलिए आपने अभी जो कहा है वह अब बातचीत में नहीं है — और उससे यह सवाल पूछें. इस सवाल में कार्ड में मौजूद कोई भी शब्द नहीं है:

Should I just get a different lamp?

👀 यह एक तोहफ़ा था. इसलिए, आपने कहा है कि आपको अपनी लालटेन को बदलना नहीं है. साथ ही, आपने इसे पहले ही ज़्यादा ऊंचाई पर लटकाने की कोशिश कर ली है. कार्ड में मौजूद हर शब्द से पता चलता है कि यह विज़िट एक मैसेज पुरानी है. यह जानकारी सिर्फ़ कार्ड से मिल सकती है. मिलते-जुलते प्रॉडक्ट खोजें. टावर में शब्दों के बजाय उनके मतलब को मैच किया जाता है. जैसे, सवाल में लैंप और अलग लिखा है, जबकि कार्ड में लालटेन और बदलना लिखा है. अब यह प्रोसेस पूरी हो चुकी है: आज रात टावर बंद कर दिया जाएगा और कार्ड कल उपलब्ध होंगे, क्योंकि वे bash valley.sh में नहीं, बल्कि एजेंट इंजन पर मौजूद हैं.

लिखने और पढ़ने का ऐक्सेस — सिर्फ़ पढ़ने का ऐक्सेस

डेटा मिटाने का अधिकार

इसे यहां दबाएं

👉🖥 मैसेज बॉक्स में जाकर, 🔥 मुझे भूल जाओ दबाएं.

👀 तीन फ़्लोर की लाइट बंद हो जाती है और एक फ़्लोर की लाइट चालू रहती है:

इसमें क्या-क्या शामिल है

🔥 के बाद

तीसरे फ़्लोर पर कार्ड

उसे क्या याद है — मेमोरी बैंक में, आपकी यात्राओं से जुड़े तथ्यों को शामिल किया जाता है

गया — memories.delete, एक बार में एक कार्ड

दूसरी मंज़िल पर, दराज़ में

user:case, यह कुकी विज़िटर को एक विज़िट से दूसरी विज़िट तक ट्रैक करती है

हटाया गया

डेस्क, स्लिप

इस विज़िट के लिए केस की कॉपी

हटाया गया

पहली मंज़िल पर किताबें

विज़िट — हर विज़िट में archive.db का एक सेशन, उसका हर मैसेज

बदलाव नहीं हुआ — संख्या में कोई बदलाव नहीं हुआ

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

ADK की मेमोरी ऐब्स्ट्रैक्शन में add_events_to_memory और search_memory शामिल हैं. इसे मिटाया नहीं जा सकता. भूलने की सुविधा, गवर्नेंस से जुड़ी कार्रवाई है, न कि एजेंट से जुड़ी कार्रवाई. इसलिए, यह सुविधा ऐप्लिकेशन में मौजूद होती है. जैसे, रॉ क्लाइंट पर archive/tower.py, memories.delete. यहां मॉडल इसे गलती से ऐक्सेस नहीं कर सकता. किसी एजेंट को जानकारी याद रखने की सुविधा देने के साथ-साथ, उसे जानकारी भूलने की सुविधा भी दी जा सकती है.

आपने क्या बनाया और पढ़ा, और वह क्या है

चीज़

यह क्या है

यह कहां दिखता है

make_tower.py → AGENT_ENGINE in .env — बनाया गया, बदलाव नहीं किया गया, कुछ भी रीस्टार्ट नहीं किया गया

मेमोरी सेवा को सेवा के तौर पर इस्तेमाल करना: एजेंट के बाहर, डिप्लॉयमेंट का फ़ैसला

Agent Engine पर Vertex AI Memory Bank

tower_service(engine) — सिर्फ़ इसे पढ़ा जा सकता है

Runner(memory_service=...) का एक ही स्लॉट, लेकिन होम अलग-अलग हों

archive/service.py

"allowed_topics": TOPICS में FILING — सिर्फ़ पढ़ने के लिए

क्या रखा जा सकता है, यह लिखने के समय तय किया जाता है, प्रॉम्प्ट में नहीं

archive/topics.py + टावर का कॉन्फ़िगरेशन

🔥 → memories.delete — दबाया गया, लिखा नहीं गया

भूल जाना, ऐप्लिकेशन की कार्रवाई है; ADK के मेमोरी एपीआई में मिटाने का विकल्प नहीं है

archive/tower.py

इस रंग से पता चलता है कि जवाब में दी गई जानकारी, सवाल में पूछी गई जानकारी से कितनी मिलती-जुलती है. एक दिन बीत गया, एक तथ्य सामने आया, जिसे विषयों के हिसाब से तैयार किया गया था. हालांकि, पहली मंज़िल पर रखी किताब को कभी नहीं हटाया गया.

7. GraphRAG

ज़रूरी नहीं.

  • क्या — एक स्क्रिप्ट, घाटी के पिछले डेटा को BigQuery में लोड करती है. साथ ही, वेयरहाउस के अंदर एम्बेडिंग जनरेट करती है और किसी भी लाइन को बदले बिना टेबल पर एक ग्राफ़ बनाती है. इसके बाद, वेस्पर से दो सवाल पूछे जाते हैं. वेस्पर के पास इसके लिए दो क्वेरी हैं: एक क्वेरी, मिलती-जुलती आवाज़ के लिए है और दूसरी क्वेरी, कनेक्ट किए गए डेटा के लिए है.
  • क्यों — 'मिलता-जुलता' का मतलब 'कनेक्ट किया गया' नहीं होता. वेक्टर से यह पता चलता है कि जानकारी कहां से ली गई है. ग्राफ़ से यह पता चलता है कि जानकारी किस तरह से जुड़ी हुई है. जवाब में यह जानकारी भी शामिल होनी चाहिए कि जानकारी कहां से ली गई है.
  • कैसे — bash scripts/season.sh, एक बार. इस चैप्टर में मौजूद बाकी सभी चीज़ें सिर्फ़ पढ़ी जा सकती हैं.

निर्माण के दौरान, वेस्पर का टावर आप — (app_name, user_id) — के दायरे में आता है. दूसरे लोगों की विज़िट उसकी मेमोरी नहीं है. इसे ज़्यादा खोजने से भी यह नहीं बदलेगा. ये घाटी के हैं और घाटी इन्हें गोदाम में रखती है. इस सीज़न में 31 लोग, रात में Q7 लैंटर्न के बंद होने की समस्या के बारे में जानने के लिए आए. इनमें से एक व्यक्ति को इस समस्या की वजह पता चली. यह चैप्टर उस वेयरहाउस को लोड करता है और उसमें दो तय की गई क्वेरी डालता है.

ग्राफ़ आरएजी

आरएजी का मतलब है जानकारी पाना और फिर जवाब जनरेट करना: सही रिकॉर्ड ढूंढना, उन्हें मॉडल को देना, और मॉडल को उनसे जवाब देने देना. सामान्य आरएजी, मिलते-जुलते कॉन्टेंट को ढूंढता है. इसके लिए, सवाल को एम्बेड किया जाता है और मिलते-जुलते रिकॉर्ड को पुल किया जाता है. इससे ऐसे जवाब मिलते हैं जो सवाल से मिलते-जुलते हों. साथ ही, यह वह जगह है जहां चौथे चैप्टर का टावर खत्म हुआ था. Graph RAG में, जानकारी पाने का दूसरा चरण जोड़ा जाता है. यह edges — कुंजियों के हिसाब से काम करता है. वेयरहाउस में पहले से मौजूद जानकारी के आधार पर, मिलती-जुलती जानकारी को उससे जुड़ी जानकारी के साथ जोड़ता है. इन दो चरणों में अलग-अलग सवालों के जवाब दिए जाते हैं. इस चैप्टर में, आपको दोनों सवाल पूछने के लिए कहा गया है:

चरण

जिस सवाल का जवाब दिया गया है

कैसे

इस चैप्टर में

मिलती-जुलती

मुझे यह कहां दिखेगा?

सवाल एम्बेड करें, VECTOR_SEARCH

season_search — जब विज़िटर कोई मार्क नहीं लाता है

ट्रैवर्सल

उससे कौनसी डिवाइस कनेक्ट हैं?

MATCH प्रॉपर्टी ग्राफ़ में मौजूद कोई पाथ

season_known_issue — एक तय MATCH

जनरेशन

मुझे विज़िटर को क्या बताना चाहिए?

मॉडल, जिसमें पाथ को उद्धरण के तौर पर शामिल किया गया है

उसका जवाब

इसे चलाएं

सीज़न को season/ में सामान्य CSV फ़ाइलों के तौर पर शिप किया जाता है — विज़िटर, आइटम, अनुरोध, ठीक किए गए अनुरोध, सीज़न — ठीक उसी तरह जैसे कोई सहायता सिस्टम उन्हें एक्सपोर्ट करता है. एक स्क्रिप्ट उन्हें सीधे वेयरहाउस में ले जाती है. इस चैप्टर में सिर्फ़ यही स्क्रिप्ट चलाई जाती है.

👉💻 पहले टैब में (इसमें करीब तीन मिनट लगते हैं; यह हर चरण को प्रिंट करता है और उस चरण पर रुक जाता है जो पूरा नहीं हो पाता):

cd ~/agent-valley-archive
bash scripts/season.sh

👀 जब यह खत्म हो जाता है, तब टावर की चौथी मंज़िल की लाइट जल जाती है. साथ ही, इसके बगल में मौजूद लेजेंड में खुला है लिखा होता है.

क्या बनाया गया — सिर्फ़ पढ़ने का ऐक्सेस

वह इसे कैसे पढ़ती है — सिर्फ़ पढ़ने के लिए

उससे पूछो

👉🖥 टावर की चौथी मंज़िल खुली है. उससे उसी तरह सवाल पूछें जैसे कोई व्यक्ति पूछता है:

Has anyone else had a q7 lantern go out at night?

वह जवाब देती है और आखिरी लाइन में पाथ होता है

👀 उसने जवाब दिया — इकत्तीस अन्य लोगों ने... ज़्यादातर लोगों ने कहा कि मोमबत्ती की लौ कम हो गई थी और एक घंटे बाद बुझ गई थी... ऊद बिलाव मार्लो को पता चला कि बत्तियाँ बहुत कम डूबी हुई हैं. उसके जवाब की आखिरी लाइन में रास्ता बताया गया है. यह उसका जवाब है. इसे पढ़ें, इसे वापस न भेजें:

mark q7 → 31 visits this season → 10 different things said → the wicks in the q7 batch were dipped too shallow — they drown in the oil and starve in an hour

पाथ, उद्धरण होता है. इसमें हर हॉप, ग्राफ़ में एक किनारा होता है. साथ ही, एक किनारा एक कुंजी होता है. इसलिए, कोई भी व्यक्ति इसे फिर से दोहरा सकता है और उसे वही 31 मिल सकते हैं. किसी भी व्यक्ति के पास, समानता स्कोर को फिर से देखने का विकल्प नहीं होता. अगर वह पाथ से ठीक पहले कहती है कि तीन जॉइन की वजह से पंक्तियां वापस आ गईं, क्योंकि प्रोजेक्ट में कोई ग्राफ़ रिज़र्वेशन नहीं है, तो इसका मतलब है कि आपके प्रोजेक्ट का वर्शन GRAPH_TABLE को अस्वीकार कर रहा है. पंक्तियां और पाथ एक ही हैं.

👉🖥 अब मार्क हटा दें — यह मैसेज भेजें:

Has anyone else had a lantern that keeps dying once the sun is down?

👀 वह भी उसी 31 पर पहुंचती है और उसी रास्ते पर चलती है. बदलाव सड़क में हुआ: season_search पहले दौड़ा, उसे पांच ऐसे लोग मिले जिनकी आवाज़ एक जैसी थी — हर व्यक्ति के पास q7 था — उसने वह निशान लिया और उसके बाद ही चला. मिलता-जुलता प्रॉडक्ट कनेक्ट नहीं किया गया है; मिलता-जुलता प्रॉडक्ट कहां देखना है.

क्या लोड किया गया था और वह क्या है

चीज़

यह क्या है

यह कहां दिखता है

bq load में साफ़ तौर पर बताए गए स्कीमा — रन किए गए, लिखे नहीं गए

वेयरहाउस: नाम और टाइप वाले कॉलम

archive.visitors / items / asks / fixes / seasons

ML.GENERATE_EMBEDDING + VECTOR_SEARCH

मिलती-जुलती ऑडियंस का चरण — यह जानकारी कहां मिलेगी

archive.ask_embeddings, embedder मॉडल

CREATE PROPERTY GRAPH — कोई पंक्ति नहीं बदली गई

ट्रैवर्सल चरण — क्या कनेक्ट किया गया है; टेबल नोड और ऐरो बन जाती हैं

archive.season_graph

GQL में archive/season/__init__.py — एक पैरामीटर

वह सिर्फ़ चल सकती है; पाथ उद्धरण है

season_known_issue(mark)

कुछ दर्जन लोगों के आने से, गोदाम खरीदने की कोई वजह नहीं बनती. इस चैप्टर में, क्वेरी के स्ट्रक्चर के बारे में बताया गया है, न कि स्केल के बारे में. इस ग्राफ़ को हज़ार गुना बढ़ाएं. MATCH में एक भी वर्ण का बदलाव नहीं होगा.

8. बंद करें

तीन लाइनें, एक टावर, एक गोदाम — चार फ़्लोर. कोई भी सेवा फिर से शुरू नहीं हुई.

द रंग

आपने क्या किया

क्या खरीदा

ONE

tool_context.state[CASE] = case — बदलाव

कोई भी स्लिप मौजूद नहीं है: राज्य का नाम कोड के तौर पर लिखा गया है

दो

CASE = "user:case" — बदलाव

एक ऐसा ड्रॉअर जो विज़िटर को फ़ॉलो करता है

फ़ाइलिंग

await ctx.add_events_to_memory(..., custom_metadata=FILING) — पढ़ा गया, लिखा नहीं गया

क्या कहा गया, क्या रखा गया

तीन

found = await ctx.search_memory(query) — बदलाव

क्या रखा गया था, क्या मांगा गया था — फ़ाइल का नाम याद नहीं है

टॉवर

make_tower.py, फिर AGENT_ENGINE में .env — एक ही लाइन से बनाया और कनेक्ट किया गया है, कुछ भी रीस्टार्ट नहीं किया गया है

एक ऐसा टावर जो रात भर में पानी को साफ़ कर देता है

नियमों

allowed_topics में FILING — पढ़ा गया, लिखा नहीं गया

सिर्फ़ ज़रूरी जानकारी

सीज़न

season.sh — लोड किया गया, एम्बेड किया गया, इसके ऊपर एक ग्राफ़ रखा गया, एक MATCH के साथ चला गया

अन्य लोगों की यात्राओं की जानकारी, मतलब और कनेक्शन के हिसाब से

बदले गए हर हिस्से की जानकारी

ADK 2

इसके बजाय, आपको क्या लिखना है

इसके लिए आपको कितना शुल्क देना होगा

session.state + एक टूल, जिसे SqliteSessionService ने सेव किया है

चैट लूप के बगल में मौजूद डिक्ट, जिसे आपने खुद डिस्क में सेव किया हो

मॉडल इसे नहीं पढ़ सकता. इसलिए, आपको ही इसे फिर से शुरू करने और लॉक करने की सुविधा के बारे में लिखना होगा

user: प्रीफ़िक्स

उपयोगकर्ता टेबल और हर टर्न पर जॉइन

हर बार यह तय करना कि कुंजी कहां होनी चाहिए

फ़ंक्शन नोड में add_events_to_memory + search_memory

एक क्रॉन जो ट्रांसक्रिप्ट डंप करता है और मॉडल यह तय करता है कि कब देखना है

यह सिर्फ़ जानकारी देता है, कोई फ़ैसला नहीं लेता. साथ ही, आपको यह कभी नहीं पता चलता कि कब यह जानकारी काम की नहीं थी

VertexAiMemoryBankService + allowed_topics

वेक्टर स्टोर, डेटा निकालने का प्रॉम्प्ट, डेटा को एक जगह इकट्ठा करने का काम, और प्रॉम्प्ट में "कृपया सामान्य जानकारी याद न रखें"

तीन सेवाओं के लिए लागू होता है. साथ ही, यह नियम तब तक लागू रहता है, जब तक मॉडल को कोई और जानकारी नहीं मिलती

VECTOR_SEARCH + एक तय GQL MATCH

एक्सपोर्ट करना, किसी दूसरी जगह पर एम्बेड करना, ग्राफ़ डेटाबेस, सिंक करने का टास्क, और मॉडल का एसक्यूएल लिखना

डेटा वेयरहाउस से डेटा को समझने के लिए, क्वेरी की जाती है. साथ ही, आपको यह पता चलता है कि क्वेरी करने वाले व्यक्ति के हिसाब से, क्वेरी में कौनसे जॉइन शामिल किए गए हैं

तीन सवाल, पहले 'हां' पर रुकें

  1. क्या इससे कल कोई फ़र्क़ पड़ेगा? नहीं → कुछ भी न रखें. यह बातचीत के दौरान ही काम करता है.
  2. क्या कोई फ़ंक्शन इसकी जांच कर सकता है? हां → ड्रॉर. कोड इसे लिखता है, हर बार इसे पढ़ता है, और कोई भी वाक्य इसे बदल नहीं सकता.
  3. अन्य → टावर. यह जानकारी, बातचीत के दौरान कही गई बातों से निकाली जाती है. जब इसके बारे में पूछा जाता है, तब इसे खोजा जाता है. इसके बाद, बातचीत में कही गई बातों के आधार पर इसे अपडेट किया जाता है.

एक वाक्य

कोई रिकॉर्ड, यादगार पल नहीं होता. मेमोरी एक रिकॉर्ड है. साथ ही, इसमें दो फ़ैसले शामिल होते हैं — क्या रखना है और कब देखना है. यह किस तरह की चीज़ है, इससे यह तय होता है कि इसे किस फ़्लोर पर रखा जाएगा.

तथ्य और प्राथमिकताएं अलग-अलग स्टोर में मौजूद होनी चाहिए.

👀 हर फ़्लोर पर रोशनी है. सबसे ऊपर, आपको अपने जाने-पहचाने लोगों की जानकारी दिखेगी. पासपोर्ट में आर्काइव स्टैंप है. पाँचवें हफ़्ते में नाइट मार्केट खुलता है. यहाँ Nix, रीयल टाइम में स्टेज पर परफ़ॉर्म करता है. साथ ही, टावर को पता चलने वाली हर जानकारी आपके साथ शेयर करता है.