The Archive — Memory at Agent Valley

1. مقدمة

"فيسبر"، أمين الأرشيف، على المكتب في الطابق الأرضي

في الأسبوع الأول، طرحنا السؤال من يحدد ما يتم عرضه. في الأسبوع الثاني، طرحنا السؤال من يحدّد ما سيتم تشغيله بعد ذلك؟. في الأسبوع الثالث، طرحنا السؤال ما الذي تتركه الركض خلفك؟ تنتهي المحادثة هذا الأسبوع، والسؤال هو ما الذي سيبقى منها، وقد تبيّن أنّ نوع المحتوى هو الذي يحدّد مكان عرضه.

الأرشيف هو المكان الذي تظهر فيه المشاكل. برج يسجّل كل شيء، وفيسبر، وهو أمين الأرشيف، يجلس على مكتب في الطابق الأرضي. ينطفئ فانوسك في الليل. يمكنك الذهاب وطرح السؤال.

إنّها صحبة جيدة. بعد شهر، يسعدها أيضًا مقابلتك.

السجلّ ليس ذاكرة.

هذه الجملة هي الدرس التطبيقي بأكمله. ستصعد إلى البرج على أربع درجات، وكل درجة هي طابق من طوابق البرج:

درجة السلم

الأرضية

ما يتذكره

ما الذي يحافظ عليه؟

1

المكتب والأرضية

هذه الزيارة

session.state · SqliteSessionService

2

الطابق الثاني، درجك

هذا الزائر

البادئة user:

3

الطابق الثالث، البرج

ما قيل

Memory Bank في Vertex AI

4

floor four, the season

الوادي بأكمله

BigQuery

كل مستوى أعلى يعني أنّ شيئًا ما قد تم استبعاده من المستوى الأدنى.

مبنى الأرشيف، مقطّع من الداخل — خمسة طوابق، وفريق صغير يحافظ على كل طابق

أنت تعرف بالفعل الطرق الخمس التي يتبعها أمين الأرشيف للنسيان، لأنّك مررت بها جميعًا خلال مكالمة دعم:

ما تقوله

ما المشكلة؟

~~1~~

~~هل يمكنك تزويدي بهذا المرجع مرة أخرى؟~~

~~نسيان المعلومات خلال محادثة واحدة~~ — تم إصلاح هذه المشكلة في الأسبوع الثالث

~~2~~

~~لقد تم تحويلك. يُرجى البدء من البداية.~~

~~the history died with the process~~ — week three fixed this too

3

مرحبًا، كيف يمكنني مساعدتك اليوم؟

إلى مستخدم لديه طلب مفتوح من الشهر الماضي

4

هل يمكنك وصف الضرر؟

نظرت إلى الفانوس آخر مرة

5

لم نرَ هذا من قبل.

طرح 31 شخصًا أسئلة هذا الموسم

السطر الثالث هو هذا الأسبوع. تتعطّل هذه الآلة بثلاث طرق مختلفة: زيارة جديدة (الفصل 2)، وجملة بدون سطر على الورقة (الفصل 3)، وأرشيف لا يمكن الوصول إليه إلا من خلال العملية (الفصل 4)، وكل طريقة هي فصل. السطر الرابع متروك لك: look() في archive/agent.py هو المكان الذي تقرأ فيه علامة من صورة. السطر الخامس هو الفصل 5، وهو اختياري.

لا تحتاج إلى الأسابيع من 1 إلى 3. الوكيل هو نموذج يتضمّن تعليمات وبعض الأدوات. أما بقية الأسبوع، فستتضح الصورة بنفسها.

ستكتب ثلاثة أسطر، وكل سطر منها يمثّل مفهومًا متعلقًا بالذاكرة:

السطر

ما هي؟

tool_context.state[CASE] = case

تتم كتابة الحالة بواسطة الرمز البرمجي، وليس بواسطة المحادثة

CASE = "user:case"

البادئة هي فترة صلاحية

found = await ctx.search_memory(query)

لا يتم تذكُّر سياسة الاستدعاء التي تمّت تعبئتها

يتوفّر سطر آخر يمكنك قراءته، وهو سياسة الكتابة، await ctx.add_events_to_memory(...). في الفصل 3، يمكنك قراءة ما تفعله قبل كتابة السطر الذي يستخدمها.

أمّا الخطوتان الأخريان، فلا تتطلّبان أي تعديلات: يمكنك بناء برج (محرك وكيل يستضيف "بنك الذاكرة") وسيتم ربط الرمز نفسه به تلقائيًا، ويمكنك تحميل مستودع (BigQuery) ووضع رسم بياني عليه وتسليم الوكيل نفسه استعلامَين مُدارَين، أحدهما حسب المعنى والآخر حسب الربط.

تتضمّن كلّ وحدة الحلقة نفسها التي ستستخدمها في برامجك: قراءة الرمز → كتابة السطر → مشاهدته في البرج. لا يتم تشغيل أي شيء بشكل غير صحيح أولاً، ولا تتم إعادة تشغيل أي شيء، ولا يتم الضغط على Ctrl+C: يتم رصد كل تعديل في الرسالة التالية، ويتم ربط البرج بسطر واحد في ملف يعيد "الأرشيف" قراءته في كل طلب. البرج هو رسم يعيد الرسم: فهو يقرأ الملفات نفسها التي تعدّلها، ويتضمّن ثلاثة أزرار: 🌙 ينهي اليوم، و🗓 يبدأ الزيارة التالية، و🔥 ينسى بياناتك. كل ما تفعله في الرمز والوحدة الطرفية.

مكانان لا يتغيران أبدًا: علامة التبويب 1 هي نافذة الأوامر، وعلامة التبويب 2 هي الأرشيف. تظهر مساحة العمل (adk web) مرة واحدة فقط، في الفصل 1، لإلقاء نظرة على حالة الجلسة الأولية، وبعد ذلك لن تحتاج إليها. توضّح كل إشارة 👉 أدناه نوع المحتوى. ‫👉💻 هي علامة التبويب 1، و👉🖥 هي علامة التبويب 2، و👉🔬 هي مساحة العمل. يشير 👉📖 إلى فتح ملف وقراءته، أي لا يلزم إجراء أي تغيير، بينما يشير 👉✏️ إلى نوع الخطوة التي يتم فيها التعديل. عندما تطلب منك إحدى الخطوات أن تقول شيئًا إلى Vesper، ستجد الرسالة الدقيقة في المربّع أسفلها مباشرةً، لذا عليك نسخها كما هي. أما القسم الذي ينتهي عنوانه بعبارة إذن بالقراءة فقط، فلا يتضمّن أي نص يجب كتابته أو لصقه أو النقر عليه، لأنّ الرمز البرمجي الوارد فيه موجود في مستودع الرموز البرمجية ويتم تنفيذه حاليًا، وهو معروض لك لقراءته.

الجملة فوق باب "فيسبير" هي الجملة في الأعلى. الجملة التي تنتهي بها هذه الحلقة هي الجملة الختامية للأسبوع الرابع من الموسم بأكمله:

يجب تخزين الحقائق والإعدادات المفضّلة في مستودعات مختلفة.

2. الإعداد

  • ماذا: أشر إلى مشروع أو الصِق مفتاحًا، ثم ثبِّت سلسلة الأدوات وأثبِت أنّها تعمل بشكل سليم.
  • السبب: لا يتم حظر أي شيء هنا. يبدأ كل خادم قبل الخطوة التي يحتاجها مباشرةً، لذا عندما تفتح شاشة، ستعرف الأمر الذي يملكها.
  • كيفية: نص برمجي واحد لإنشاء المشروع، ونص برمجي آخر لتثبيت Vertex AI وتوجيهك إليه، ونص برمجي ثالث للتحقّق من صحة الرمز البرمجي وإعلامك بمكانك.

يتم تشغيل كل شيء في هذا التمرين العملي في Cloud Shell، حيث تم تثبيت Python وuv وgcloud مسبقًا، ويمكن الوصول إلى Gemini من خلال Vertex AI باستخدام بيانات الاعتماد الخاصة بك. لا يتضمّن هذا التمرين المعملي مفتاح واجهة برمجة تطبيقات في أي مكان، ولا يتطلّب تثبيت أي شيء على الكمبيوتر المحمول.

هناك أمر واحد لا يمكن أن يوفّره لك هذا المختبر، وهو مشروع على Google Cloud مع تفعيل الفوترة. تمنحك الخطوة 1 حسابًا يمكنك استخدامه للدفع، وتحوّل الخطوة 4 هذا الحساب إلى مشروع، أو تختار مشروع Agent Valley الذي سبق أن أنشأته في الأسبوع الأول أو الثاني أو الثالث. اتّبِع الترتيب نفسه، لأنّ كل خطوة بعد الخطوة 4 تقرأ المشروع الذي تم تحديده في الخطوة 4.

‫1 · الحصول على حساب يتضمّن إعدادات الفوترة (حوالى دقيقة واحدة)

🌐 يجب إجراء ذلك قبل أي شيء آخر. سجِّل الدخول باستخدام حساب Google مفعَّل فيه الفوترة. يمكن استخدام أي حساب من هذا النوع. إذا لم يكن لديك حساب، يمكنك بدء فترة تجريبية مجانية، إذ تمنحك هذه الفترة حساب فوترة، وهو كل ما تتطلبه الخطوة 4.

‫2 · فتح Cloud Shell (حوالى دقيقة واحدة)

🌐 انقر على تفعيل Cloud Shell في أعلى "وحدة تحكّم Google Cloud"، وهو الرمز الذي يشبه نافذة الأوامر في العنوان.

تفعيل Cloud Shell من عنوان Google Cloud Console

🌐 انقر على فتح أداة التعديل (رمز المجلد المفتوح الذي يتضمّن قلمًا). سيؤدي ذلك إلى فتح "محرّر Cloud Shell" مع مستكشف الملفات على اليمين، وهو المكان الذي تعمل فيه كلما تم وضع العلامة 👉✏️ على إحدى الخطوات.

فتح "محرِّر Cloud Shell"

🌐 إذا طُلب منك منح الإذن في أي وقت اليوم، انقر على تفويض للمتابعة.

🌐 افتح نافذة طرفية داخل المحرِّر، أي علامة التبويب 1، وسيتم تنفيذ كل خطوة 👉💻 هناك ما لم يُذكر خلاف ذلك. علامة التبويب 2 هي الأرشيف، ويمكنك فتحها في الفصل 1، قبل الخطوة التي تحتاج إليها مباشرةً. إذا لم تكن النافذة الطرفية في أسفل الشاشة، افتحها باستخدام عرض → النافذة الطرفية:

فتح نافذة طرفية جديدة في "محرِّر Cloud Shell"

🌐 تحقَّق من الحساب الذي سجّلت الدخول إليه، يجب أن يكون هو الحساب الذي استخدمته في الخطوة 1:

gcloud auth list

‫3. الحصول على المختبر (حوالى دقيقة واحدة)

💻 استنسِخ المستودع، وهو مستودع الأرشيف وليس مستودع الأسبوع الأول أو الثاني أو الثالث:

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: إذا كان لديك حساب، وأي حساب فوترة آخر مفتوح في حال عدم توفّر حساب.

project

يبحث عن مشروع 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 قد ضبطتها. هذا هو السبب الرئيسي في أنّ الخطوة 4 تأتي أولاً.

‫setup_codelab.sh هو دالة متكررة، أي يمكن إعادة تشغيلها أي عدد من المرات. ويتم تنفيذ خمسة إجراءات بالترتيب التالي:

api

يقرأ الخطوة 4 المحدّدة في المشروع ويفعّل aiplatform.googleapis.com (Vertex AI وAgent Engine الذي يستضيف "بنك الذاكرة") وbigquery.googleapis.com (مستودع الفصل 5)

uv env

ينشئ uv venv .venv أو يعيد استخدام العنصر المتوفّر، ثم يثبّت uv sync تمامًا ما يثبّته uv.lock، أي google-adk وgoogle-genai وكل ما يندرج تحتهما

site

يتم تشغيل npm ci في site/، والأرشيف نفسه هو تطبيق Next.js، لذا لا يتبقى أي شيء لتنزيله في bash valley.sh في الفصل 1، ويتم تخطّيه عندما تكون الحِزم متوفرة.

‎.env

تكتب المتغيرات التي يقرأها المختبر، وهي GOOGLE_GENAI_USE_VERTEXAI وGOOGLE_CLOUD_PROJECT وGOOGLE_CLOUD_LOCATION وMEMORY_BANK_LOCATION وBQ_DATASET، ولا يتضمّن أي مفتاح لواجهة برمجة التطبيقات

التحقّق من النموذج

يُجري مكالمة واحدة حقيقية مع Gemini، لذا سيفشل المشروع غير المناسب هنا في وقت الإعداد، وليس لاحقًا داخل أحد الفصول

‫6 · إثبات أنّها خضراء (حوالى دقيقة واحدة)

💻 تشغيل عملية التحقّق المبدئية، وكل علامة صح هي عملية فحص حقيقية وليست تخمينًا:

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، ثم لا تغيّر أي شيء آخر.

تعديل واحد

👉📖 افتح 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. ولاية المستخدم

  • ماذا: يمكنك العودة بعد شهر، وستختفي القسيمة. خمسة أحرف، وستتبعك.
  • السبب: الجلسة هي زيارة واحدة. الزيارة التالية هي جلسة جديدة، ولم يتم تسجيل أي زيارة سابقة لها.
  • كيف: خمسة أحرف في state.py

بعد شهر يسرّني التواصل معك.

اضغط هنا

👉🖥 اضغط على 🗓 بعد شهر. هذه جلسة جديدة للزائر نفسه، كما كان الحال في بدء محادثة جديدة في الأسبوع الثالث.

مرحبًا بك في "الأرشيف". كيف يمكنني مساعدتك اليوم؟

👉🖥 انظر إلى البرج. في الطابق الأول، يوجد كتاب آخر في هذه الزيارة. الدرج في الطابق الثاني فارغ. الورقة على المكتب فارغة.

كتاب آخر في الطابق الأول، والدرج فارغ، والإيصال فارغ

👀 السبب: يتمّ تسجيل الانزلاق في حالة الجلسة، والجلسة هي هذه الزيارة. تغيير الزيارات، تغيير الجلسات لم يتم نقل أي بيانات لأنّه لم يتم تحديد أي بيانات. لا يزال آخر كتاب تمت زيارته في الملف، أي الكتاب الأول في الطابق الأول، ولكن تمّت كتابة الإيصال بمفتاح صالح لزيارة واحدة.

تعديل اثنين

👉✏️ افتح 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"

حفظ. بدون إعادة تشغيل: يعيد الأرشيف استيراد الرمز في كل رسالة.

👉🖥 الصِق العناصر الأربعة نفسها مرة أخرى، أي هذه الرسالة تحديدًا:

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: قبل أن يقول الزائر أي كلمة، وفي كل زيارة يجريها.

يحتوي الدرج على الأسطر الأربعة التي يتضمّنها الإيصال فقط. فكل ما تقوله ولا يظهر في إيصال الإصلاح، مثل ما حاولت إصلاحه وسبب أهميته بالنسبة إليك وما إذا كنت تريد إيصالاً جديدًا، لا يتم تسجيله، وبعد شهر يختفي. يعبر الدرج الشهر. لا يمكن ذلك في جملة. يتناول الفصل 3 هذا الموضوع.

النص الذي كتبته ونوع المحتوى

السطر

ما هي؟

مكان تخزينها

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 أعلاه.

حفظ. لا يمكن إعادة البدء.

سطران وسياستان، وقد كتبت إحداهما. تحدّد سياسة الكتابة البيانات التي يتم الاحتفاظ بها ووقت الاحتفاظ بها (وقت الإغلاق، اليوم بأكمله). تحدّد سياسة الاستدعاء وقت البحث ونوع البحث (كل سؤال، السؤال نفسه). تمنحك "مجموعة تطوير الإعلانات" الأفعال — 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) — تعديل ثلاثة

سياسة الاسترجاع — كل سؤال، قبل أن تجيب

recall() ‏← ctx.state["recalled"]

تصل هذه المرحلة إلى ما تم قوله، وتحتفظ به في قاموس داخل عملية واحدة، وبكلماتك الخاصة. كلا الجزأين خاطئان، ويتم تصحيحهما في الفصل التالي بدون استخدام رمز على الإطلاق.

6. MemoryBank

  • ما هي: ينشئ أحد البرامج النصية "بنك ذاكرة"، ويبدأ السطران اللذان لديك بكتابة الحقائق فيه وقراءتها.
  • السبب: خدمة الذاكرة هي خدمة. إنّ مكان الأرشيف هو قرار نشر وليس قرار وكيل، ويمكنك تغييره بدون تعديل الوكيل.
  • كيف: تشغيل make_tower.py، قول ثلاث جمل، الضغط على 🌙، الضغط على 🗓، طرح سؤال واحد بعد ذلك، يمكنك الاطّلاع على عمليات الكتابة والقراءة.

بناء البرج

كان الطابق الثالث من الفصل 3 عبارة عن قاموس بايثون داخل bash valley.sh. بنك الذاكرة هو الإصدار المُدار من تلك الطبقة: وهو متوفّر على مثيل محرك الوكيل في مشروعك، ويحتفظ بالحقائق المستخلصة من اليوم بدلاً من جملك، ويعثر عليها حسب المعنى بدلاً من الكلمات المشتركة. لست بحاجة إلى نشر Vesper في Agent Engine لاستخدامه، إذ إنّ مثيلاً بدون أي عمليات نشر يظل يستضيف "بنك الذاكرة"، وهذا ما ينشئه النص البرمجي: برج لا يسكنه أحد، ومهمته الوحيدة هي الاحتفاظ بالبطاقات.

👉💻 في علامة التبويب 1 (بعد دقيقة واحدة تقريبًا):

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...")

طلب واحد من حزمة تطوير البرامج (SDK)، وهو agent_engines.create()، وسطر واحد مكتوب في .env. يعيد "الأرشيف" قراءة هذا الملف في كل طلب، لذا ليس هناك ما يجب إعادة تشغيله.

مشاهدة طريقة عملها

👉🖥 انظر إلى الطابق الثالث، سيتم إعادة رسم البرج تلقائيًا في غضون بضع ثوانٍ. ضمن البطاقات، يظهر الآن بنك الذاكرة، والرف فارغ: كانت الاقتباسات الثلاثة من الفصل 3 قيد المعالجة، وهذه ليست المعالجة. أعِد قول الجُمل الثلاث، رسالة واحدة أو ثلاث رسائل:

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?

👀 بما أنّها كانت هدية، ذكرت أنّك لا تريد استبدال الفانوس، وأنّك حاولت تعليقه في مكان أعلى. كل كلمة من ذلك جاءت من البطاقة، والبطاقة فقط هي التي يمكن أن تخبرها: هذه الزيارة هي رسالة واحدة قديمة. البحث المشابه: تطابق البرج مع المعنى، وليس الكلمات، فقد ورد في السؤال مصباح ومختلف، بينما ورد في البطاقة فانوس واستبدال. وقد تم إيقاف هذه العملية الآن: سيتم إيقاف البرج الليلة وستكون البطاقات متاحة غدًا، لأنّها مخزّنة في Agent Engine وليس في bash valley.sh.

الكتابة والقراءة — إذن بالقراءة فقط

حق المرء في أن يُنسى

اضغط هنا

👉🖥 انقر على 🔥 لا تتذكرني تحت مربّع الرسالة.

👀 ثلاثة طوابق مظلمة وطابق واحد مضاء:

ما يحتويه

بعد 🔥

الطابق الثالث، البطاقات

ما تتذكره، أي الحقائق التي استخلصها "بنك الذاكرة" من زياراتك

gone — memories.delete, one card at a time

الطابق الثاني، الدرج

‫user:case، وهي الإيصال الذي يتلقّاه الزائر نفسه في كل زيارة

تم محوها

المكتب، الإيصال

نسخة الزيارة من طلب الدعم

تم محوها

الطابق الأول، الكتب

الزيارات نفسها، أي جلسة واحدة في archive.db لكل زيارة، وكل رسالة فيها

لم يتم تعديلها — لا يتغيّر العدد

الكتب هي السجلّ الذي يوضّح أنّ الزيارة قد حدثت وفي أي يوم، وما قيل فيها. البطاقات والدرج هما الذاكرة: ما استخلصته من تلك الزيارات وما ستستفيد منه في الزيارة التالية. يتعلّق طلب "الحق في أن يُنسى" بالذاكرة، أي الحقائق المستخلَصة عن شخص ما والحالة التي تلازمه. إنّ قرار الاحتفاظ بسجلّ الزيارة هو قرار منفصل يتم اتخاذه لأسباب مختلفة، مثل سجلّ التدقيق وسجلّ الدعم، ويحتفظ هذا المختبر به عمدًا، حتى تتمكّن من رؤية الفرق بينهما: السجلّ والذاكرة ليسا الشيء نفسه، ونسيان أحدهما لا يؤثر في الآخر. هذه هي الجملة فوق باب "فيسبير"، كما تُرى من الجانب الآخر.

يتضمّن تجريد ذاكرة ADK السمتَين add_events_to_memory وsearch_memory. لا يتضمّن خيار الحذف. النسيان هو إجراء حوكمة، وليس إجراء وكيل، لذا يتم تنفيذه في التطبيق — archive/tower.py، memories.delete على العميل الأوّلي — حيث لا يمكن للنموذج الوصول إليه عن طريق الخطأ. تحديد ما إذا كان بإمكان الوكيل نسيان المعلومات هو أمر يمكنك تصميمه، تمامًا مثل تحديد ما إذا كان بإمكانه تذكُّرها.

المحتوى الذي أنشأته وقرأته، وما هو

الشيء

ما هي؟

مكان تخزينها

‫make_tower.py → AGENT_ENGINE في .env — تم الإنشاء، ولم يتم التعديل، ولم تتم إعادة التشغيل

خدمة الذاكرة، كخدمة: قرار نشر خارج الوكيل

‫Vertex AI Memory Bank على Agent Engine

tower_service(engine): يمكنك قراءة الرسالة فقط

فتحة Runner(memory_service=...) نفسها، منزل مختلف

archive/service.py

‫"allowed_topics": TOPICS في FILING — إذن بالقراءة فقط

ما يمكن الاحتفاظ به، ويتم تحديد ذلك في وقت الكتابة وليس في الطلب

‫archive/topics.py + إعدادات البرج

🔥 → memories.delete — تم الضغط على المفتاح، ولم تتم كتابة أي شيء

النسيان هو إجراء في التطبيق، ولا تتضمّن واجهة برمجة التطبيقات الخاصة بالذاكرة في "حزمة تطوير التطبيقات" أي عملية حذف

archive/tower.py

تصل هذه الدرجة إلى ما قيل. يمر يوم، وتظهر حقيقة، يتم تقطيرها إلى ما تسمح به المواضيع، ولم يتحرّك الكتاب الموجود في الطابق الأول أبدًا.

7. GraphRAG

اختياري.

  • ما: يحمّل نص برمجي واحد بيانات الوادي السابقة إلى BigQuery، وينشئ عمليات تضمين داخل مستودع البيانات، ويضع رسمًا بيانيًا على الجداول بدون نقل أي صف، ثم يطرح سؤالَين على Vesper، الذي لديه طلبا بحث مُداران: أحدهما عن العناصر المتشابهة، والآخر عن العناصر المرتبطة.
  • لماذا — التشابه في الصوت لا يعني التطابق. يحدد المتّجه مكان البحث، ويحدد الرسم البياني العناصر المرتبطة، ويجب أن تتضمّن الإجابة المسار الذي تم اتّباعه.
  • كيف — bash scripts/season.sh، مرة واحدة كل ما عدا ذلك في هذا الفصل متاح للقراءة فقط.

يقتصر نطاق برج Vesper على المستخدم — (app_name, user_id) — حسب التصميم. زيارات المستخدمين الآخرين ليست جزءًا من ذاكرتها، ولن يؤدي البحث بشكل مكثّف إلى تغيير ذلك. إنّها ملك للوادي، ويحتفظ بها الوادي في مستودع. خلال هذا الموسم، تلقّينا 31 شكوى من الزوّار بشأن انطفاء مصباح q7 ليلاً، وتمكّن أحد الزوّار من تحديد السبب. يحمّل هذا الفصل مستودع البيانات ويسلّمها استعلامَين ثابتَين.

التوليد المعزّز بالاسترجاع (RAG) للرسوم البيانية

التوليد المعزّز بالاسترجاع هو استرجاع، ثم توليد: العثور على السجلات المناسبة، وتسليمها إلى النموذج، والسماح له بالردّ استنادًا إليها. يسترجع نظام RAG العادي المعلومات حسب التشابه، أي أنّه يضمّن السؤال ويستخرج السجلات الأقرب. يؤدي ذلك إلى العثور على محتوى يشبه السؤال، وهو المكان الذي توقّفت فيه في الفصل 4. تضيف Graph RAG خطوة استرجاع ثانية تتبع الحواف، أي المفاتيح التي يتضمّنها مستودع البيانات، من أي تشابه تم العثور عليه إلى أي شيء مرتبط به. تجيب الخطوتان عن أسئلة مختلفة، ويجعلك هذا الفصل تطرح السؤالين معًا:

بخطوة

السؤال الذي تجيب عنه

كيف

في هذا الفصل

التشابه

أين يمكنني العثور على هذه المعلومات؟

تضمين السؤال، VECTOR_SEARCH

season_search: عندما لا يحضر الزائر أي علامة

التنقّل

ما هو الجهاز المرتبط به؟

MATCH مسار عبر رسم بياني للممتلكات

season_known_issue — واحد ثابت MATCH

الجيل

ماذا يمكنني أن أقول للزائر؟

النموذج، مع تضمين المسار كمصدر

إجابتها

تشغيلها

يتم شحن الموسم كملفات CSV عادية في season/ — الزوّار، والعناصر، والطلبات، والإصلاحات، والمواسم — بالطريقة التي يصدّر بها نظام الدعم هذه الملفات. يتم استخدام نص برمجي واحد لنقل البيانات إلى مستودع البيانات، وهو الشيء الوحيد الذي يتم تنفيذه في هذا الفصل.

👉💻 في علامة التبويب 1 (حوالي ثلاث دقائق؛ تطبع كل خطوة أثناء تنفيذها، وتتوقف عند الخطوة الأولى التي يتعذّر تنفيذها):

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 في عقدة دالة

مهمة cron التي تنقل النصوص، والنموذج الذي يحدّد وقت البحث

يتم عرض كلّ اللحظات، ولا يتم استبعاد أيّ منها، ولن ترى أبدًا اللحظات التي لم يتم فيها التقاط صور

VertexAiMemoryBankService + allowed_topics

مستودع متّجه، وطلب استخراج، ومهمة دمج، و"يُرجى عدم تذكُّر المعلومات التافهة" في الطلب

ثلاث خدمات، وتبقى القاعدة سارية إلى أن يرى النموذج خلاف ذلك

‫VECTOR_SEARCH + GQL ثابت واحد MATCH

التصدير والتضمين في مكان آخر وقاعدة بيانات رسومية ومهمة مزامنة وكتابة نموذج SQL

تغادر البيانات مستودع البيانات ليتم فهمها، وتكتشف عمليات الربط التي تم تخمينها عندما ينفّذ أحد العملاء

ثلاثة أسئلة، توقّف عند الإجابة بنعم للمرة الأولى

  1. هل سيكون ذلك مهمًا غدًا؟ لا → عدم الاحتفاظ بأي بيانات فالمحادثة هي أساسها.
  2. هل يمكن لدالة التحقّق من ذلك؟ نعم → الدرج يكتب الرمز هذا السجلّ، ويقرأه كل دور، ولا يمكن لأي جملة تغييره.
  3. بخلاف ذلك → البرج يتم استخلاصها من الكلام الذي تم قوله، والبحث عنها عند الطلب، وتعديلها بناءً على الكلام الذي يقال بعد ذلك.

الجملة الواحدة

السجلّ ليس ذاكرة. الذاكرة هي سجلّ بالإضافة إلى قرارَين: ما يجب الاحتفاظ به ومتى يجب البحث عنه، ويحدّد نوع الشيء الطابق الذي سيتم تخزينه فيه.

يجب تخزين الحقائق والإعدادات المفضّلة في مخزنَين مختلفَين.

👀 كل طابق مضاء. يظهر الشخص المألوف في أعلى الصفحة. يظهر ختم "الأرشيف" في جواز السفر، ويفتح الأسبوع الخامس "السوق الليلية"، حيث تدير "نيكس" المسرح بصوت عالٍ وفي الوقت الفعلي، وتصطحب معك كل ما تعرفه البرج.