The Archive — Memory at Agent Valley

1. บทนำ

เวสเปอร์ นักจดบันทึก นั่งอยู่ที่โต๊ะบนชั้นล่าง

สัปดาห์แรกถามว่าใครพูดว่าอะไร สัปดาห์ที่ 2 ถามว่าใครเป็นคนตัดสินใจว่าจะเล่นอะไรต่อ สัปดาห์ที่ 3 ถามว่าการวิ่งทิ้งอะไรไว้เบื้องหลัง สัปดาห์นี้การสนทนาจบลง และคำถามคืออะไรที่อยู่รอดได้ และปรากฏว่าสิ่งนั้นเป็นอะไรเป็นตัวกำหนดว่าสิ่งนั้นจะไปที่ไหน

ที่เก็บคือที่ที่หุบเขามาถึงเมื่อเกิดข้อผิดพลาด หอคอยที่จดทุกสิ่งทุกอย่าง และ Vesper นักจดบันทึกที่โต๊ะทำงานชั้นล่าง โคมไฟจะดับในตอนกลางคืน คุณไปถามได้เลย

เธอเป็นเพื่อนที่ดี และในอีก 1 เดือนต่อมา เธอก็ยินดีที่ได้พบคุณ

บันทึกไม่ใช่ความทรงจำ

ประโยคดังกล่าวคือห้องทดลองทั้งหมด คุณจะไต่ขึ้นไป 4 ขั้น และแต่ละขั้นก็คือชั้นของหอคอย

rung

the floor

สิ่งที่จำได้

สิ่งที่ทำให้

1

โต๊ะทำงาน และชั้น 1

การเข้าชมนี้

session.state · SqliteSessionService

2

ชั้น 2 ลิ้นชักของคุณ

ผู้เข้าชมรายนี้

คำนำหน้าuser:

3

ชั้น 3 ของหอคอย

สิ่งที่พูด

Memory Bank ของ Vertex AI

4

ชั้น 4 ฤดูกาล

ทั้งหุบเขา

BigQuery

การเลื่อนขึ้นแต่ละขั้นเป็นเพราะมีบางอย่างหลุดออกจากขั้นที่อยู่ด้านล่าง

The Archive, cut open — five floors, and a small crew keeping every one of them

คุณคงทราบอยู่แล้วว่านักจดหมายเหตุมีวิธีลืม 5 วิธี เนื่องจากคุณเคยเจอวิธีเหล่านี้ในการโทรติดต่อทีมสนับสนุน

สิ่งที่เธอพูด

มีอะไรผิดพลาด

~~1~~

~~ช่วยบอกข้อมูลอ้างอิงนั้นอีกครั้งได้ไหม~~

~~ลืมภายใน 1 การสนทนา~~ - สัปดาห์ที่ 3 แก้ไขปัญหานี้แล้ว

~~2~~

~~เราจะโอนสายให้ โปรดเริ่มตั้งแต่ต้น~~

~~ประวัติการเข้าชมหายไปพร้อมกับกระบวนการ~~ - สัปดาห์ที่ 3 แก้ปัญหานี้แล้ว

3

ยินดีต้อนรับ วันนี้จะให้ฉันช่วยเรื่องอะไรได้บ้าง

ถึงผู้ที่มีเคสที่ยังไม่ปิดจากเดือนที่แล้ว

4

คุณช่วยอธิบายความเสียหายได้ไหม

ครั้งที่แล้วเธอเห็นโคมไฟ

5

เราไม่เคยเห็นอะไรแบบนี้มาก่อน

มีผู้ถามคำถามนี้ 31 คนในซีซันนี้

บรรทัดที่ 3 คือสัปดาห์นี้ โดยจะล้มเหลวใน 3 รูปแบบ ได้แก่ การเข้าชมใหม่ (บทที่ 2) ประโยคที่ไม่มีบรรทัดในสลิป (บทที่ 3) และที่เก็บถาวรที่อยู่ในกระบวนการเท่านั้น (บทที่ 4) และแต่ละรูปแบบก็เป็นบท บรรทัดที่ 4 เป็นของคุณ: look() ใน archive/agent.py คือที่ที่เธออ่านเครื่องหมายออกจากรูปภาพ บรรทัดที่ 5 คือบทที่ 5 และเป็นแบบไม่บังคับ

คุณไม่จำเป็นต้องมีสัปดาห์ที่ 1-3 เอเจนต์คือโมเดลที่มีคำสั่งและเครื่องมือ 2-3 อย่าง ส่วนเรื่องอื่นๆ สัปดาห์นี้ก็อธิบายได้ด้วยตัวมันเอง

คุณจะเขียนสามบรรทัด และแต่ละบรรทัดเป็นแนวคิดความทรงจำ

บรรทัด

คำอธิบาย

tool_context.state[CASE] = case

สถานะเขียนโดยโค้ด ไม่ใช่การสนทนา

CASE = "user:case"

คำนำหน้ามีอายุการใช้งานตลอดชีพ

found = await ctx.search_memory(query)

นโยบายการเรียกคืน - ระบบจะไม่จดจำไฟล์ที่ส่ง

และมีอีกบรรทัดหนึ่งให้คุณอ่าน นั่นคือนโยบายการเขียน await ctx.add_events_to_memory(...) และบทที่ 3 คือที่ที่คุณอ่านว่านโยบายการเขียนทำอะไรได้บ้างก่อนที่จะเขียนบรรทัดที่ใช้นโยบายการเขียน

ส่วนอีก 2 ขั้นตอนไม่ได้เป็นการแก้ไขเลย คุณสร้างหอคอย (Agent Engine ที่โฮสต์ Memory Bank) และโค้ดเดียวกันจะเชื่อมต่อกับหอคอยนั้นได้เอง และคุณโหลดคลังสินค้า (BigQuery) วางกราฟทับคลังสินค้า และส่งการค้นหาที่ควบคุมแล้ว 2 รายการให้กับ Agent เดียวกัน โดยรายการหนึ่งจะอิงตามความหมาย และอีกรายการหนึ่งจะอิงตามการเชื่อมต่อ

ทุกบทจะวนลูปเดียวกัน และเป็นลูปที่คุณจะใช้กับเอเจนต์ของคุณเอง: อ่านโค้ด → เขียนบรรทัด → ดูในหอคอย ไม่มีอะไรที่ทำงานไม่ถูกต้องตั้งแต่แรก ไม่มีการรีสตาร์ท และไม่มีการกด Ctrl+C: ระบบจะเลือกการแก้ไขทุกครั้งในข้อความถัดไป และการเชื่อมต่อหอคอยคือบรรทัดเดียวในไฟล์ที่ Archive จะอ่านซ้ำทุกครั้งที่มีคำขอ หอคอยคือภาพวาดที่วาดใหม่ โดยจะอ่านไฟล์เดียวกันกับที่คุณแก้ไข และมีปุ่ม 3 ปุ่ม ได้แก่ 🌙 สิ้นสุดวัน 🗓 เริ่มการเข้าชมครั้งถัดไป และ 🔥 ลืมคุณ ส่วนที่เหลือทั้งหมดที่คุณทำในโค้ดและเทอร์มินัล

โดยมี 2 ที่และไม่เคยเปลี่ยนงานเลย นั่นคือ แท็บ 1 คือเทอร์มินัล และแท็บ 2 คือที่เก็บถาวร เวิร์กเบนช์ (adk web) จะปรากฏขึ้นเพียงครั้งเดียวในบทที่ 1 เพื่อดูสถานะเซสชันดิบ จากนั้นคุณก็ไม่ต้องใช้เวิร์กเบนช์อีก โดย 👉 ด้านล่างจะระบุว่าข้อใด 👉💻 คือแท็บ 1, 👉🖥 คือแท็บ 2, 👉🔬 คือเวิร์กเบนช์ 👉📖 คือเปิดไฟล์และอ่าน ซึ่งไม่มีการเปลี่ยนแปลงใดๆ และ 👉✏️ คือขั้นตอนประเภทหนึ่งที่ใช้แก้ไข เมื่อใดก็ตามที่ขั้นตอนบอกให้คุณพูดบางอย่างกับ Vesper ข้อความที่แน่นอนจะอยู่ในบล็อกใต้ขั้นตอนนั้น ให้คัดลอกข้อความตามที่ปรากฏ และส่วนที่มีส่วนหัวลงท้ายด้วย — อ่านอย่างเดียว จะไม่มีอะไรให้พิมพ์ วาง หรือคลิก เนื่องจากโค้ดในส่วนนั้นอยู่ในที่เก็บและทำงานอยู่แล้ว โดยจะพิมพ์ออกมาให้คุณอ่าน

ประโยคเหนือประตูของเวสเปอร์คือประโยคที่อยู่ด้านบน ประโยคที่ปิดท้ายสัปดาห์นี้คือประโยคปิดท้ายของสัปดาห์ที่ 4 ของทั้งซีซัน

ข้อเท็จจริงและความชอบควรอยู่ในร้านค้าที่แตกต่างกัน

2. 🧰 การตั้งค่า

  • ทำอะไร - ชี้ไปที่โปรเจ็กต์หรือวางคีย์ ติดตั้ง และตรวจสอบว่า Toolchain เป็นสีเขียว
  • เหตุผล - ไม่มีการบูตระบบที่นี่ เซิร์ฟเวอร์ทุกตัวจะเริ่มทำงานก่อนขั้นตอนที่ต้องใช้เซิร์ฟเวอร์นั้นๆ ดังนั้นเมื่อหน้าจอเปิดขึ้น คุณจะทราบว่าคำสั่งใดเป็นเจ้าของหน้าจอนั้น
  • วิธี - สคริปต์ 1 รายการที่สร้างโปรเจ็กต์ สคริปต์ 1 รายการที่ติดตั้งและนำคุณไปยัง Vertex AI และสคริปต์ 1 รายการสำหรับการตรวจสอบล่วงหน้าที่อ่านโค้ดและบอกตำแหน่งของคุณ

ทุกอย่างในแล็บนี้ทำงานใน Cloud Shell ซึ่งมีการติดตั้ง Python, uv และ gcloud ไว้แล้ว และเข้าถึง Gemini ได้ผ่าน Vertex AI โดยใช้ข้อมูลเข้าสู่ระบบของคุณเอง ไม่มีคีย์ API ในแล็บนี้ และคุณไม่จำเป็นต้องติดตั้งอะไรในแล็ปท็อป

แต่สิ่งหนึ่งที่แล็บนี้ไม่สามารถมอบให้คุณได้คือโปรเจ็กต์ Google Cloud ที่มีการเรียกเก็บเงิน ขั้นตอนที่ 1 จะช่วยให้คุณมีบัญชีที่ใช้ชำระเงินได้ ส่วนขั้นตอนที่ 4 จะเปลี่ยนบัญชีนั้นให้เป็นโปรเจ็กต์ หรือเลือกโปรเจ็กต์ Agent Valley ที่คุณสร้างไว้แล้วในสัปดาห์ที่ 1, 2 หรือ 3 โดยทำตามลำดับดังกล่าว ซึ่งทุกขั้นตอนหลังจากขั้นตอนที่ 4 จะอ่านโปรเจ็กต์ที่ขั้นตอนที่ 4 สร้างขึ้น

1 · สร้างบัญชีที่มีการเรียกเก็บเงิน (~1 นาที)

🌐 ทำสิ่งนี้ก่อนสิ่งอื่นใด ลงชื่อเข้าใช้ด้วยบัญชี Google ที่เปิดใช้การเรียกเก็บเงิน บัญชีใดก็ได้ หากยังไม่มี ให้เริ่มทดลองใช้ฟรี ซึ่งจะทำให้คุณมีบัญชีสำหรับการเรียกเก็บเงิน ซึ่งเป็นสิ่งเดียวที่ขั้นตอนที่ 4 ต้องการ

2 · เปิด Cloud Shell (~1 นาที)

🌐 คลิกเปิดใช้งาน Cloud Shell ที่ด้านบนของ คอนโซล Google Cloud ซึ่งเป็นไอคอนรูปเทอร์มินัลในส่วนหัว

เปิดใช้งาน Cloud Shell จากส่วนหัวของคอนโซล Google Cloud

🌐 คลิกเปิดเอดิเตอร์ (ไอคอนโฟลเดอร์เปิดที่มีดินสอ) ซึ่งจะเปิด Cloud Shell Editor พร้อมกับ File Explorer ทางด้านซ้าย ซึ่งเป็นที่ที่คุณจะทำงานเมื่อใดก็ตามที่มีการทำเครื่องหมายขั้นตอนด้วย 👉✏️

เปิด Cloud Shell Editor

🌐 หากระบบแจ้งให้คุณให้สิทธิ์ในวันนี้ ให้คลิกให้สิทธิ์เพื่อดำเนินการต่อ

🌐 เปิดเทอร์มินัลภายในเครื่องมือแก้ไข ซึ่งก็คือแท็บ 1 และทุกขั้นตอน 👉💻 จะทำงานที่นั่น เว้นแต่จะระบุไว้เป็นอย่างอื่น แท็บ 2 คือ Archive และคุณจะเปิดแท็บนี้ในบทที่ 1 ก่อนขั้นตอนที่ต้องใช้แท็บนี้ หากเทอร์มินัลยังไม่ได้อยู่ที่ด้านล่างของหน้าจอ ให้เปิดโดยไปที่ดู → เทอร์มินัล

เปิดเทอร์มินัลใหม่ใน Cloud Shell Editor

🌐 ตรวจสอบว่าคุณลงชื่อเข้าใช้บัญชีใดอยู่ ซึ่งควรเป็นบัญชีจากขั้นตอนที่ 1

gcloud auth list

3 · รับห้องทดลอง (~1 นาที)

💻 โคลนที่เก็บ - นี่คือที่เก็บ Archive ไม่ใช่ที่เก็บของสัปดาห์ที่ 1, 2 หรือ 3

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

4 · สร้างโปรเจ็กต์หรือนำโปรเจ็กต์ของสัปดาห์ก่อนหน้ามาใช้ซ้ำ (~2 นาที)

💻 สคริปต์หนึ่งจะค้นหาบัญชีสำหรับการเรียกเก็บเงิน สร้างโปรเจ็กต์ในบัญชีนั้น และชี้ Cloud Shell ไปยังโปรเจ็กต์ดังกล่าว หากคุณทำสัปดาห์ที่ 1, 2 หรือ 3 ระบบจะค้นหาโปรเจ็กต์ Agent Valley ก่อนและเสนอให้ใช้ซ้ำ ให้ตอบว่า "ใช่" แล้วคุณก็ไม่ต้องกังวลเรื่องโปรเจ็กต์ที่เรียกเก็บเงินที่ 2 อีก

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

👀 คาดการณ์✓สำหรับบัญชีสำหรับการเรียกเก็บเงินที่เลือก ✓สำหรับโปรเจ็กต์ที่สร้างหรือนำกลับมาใช้ใหม่ และตอนจบ เช่น

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

agent-valley-4271 คือรหัสโปรเจ็กต์ของคุณ ซึ่งจะมีตัวเลขต่างกัน โดยมี 4 สิ่งที่เกิดขึ้นในนั้น

การเรียกเก็บเงิน

ใช้บัญชี [YYYY-MM-DD] GDP Credit: ที่ใหม่ที่สุดหากคุณมี และใช้บัญชีสำหรับการเรียกเก็บเงินอื่นๆ ที่เปิดอยู่หากไม่มี

project

จะมองหาโปรเจ็กต์ Agent Valley ที่คุณเป็นเจ้าของอยู่แล้ว ไม่ว่าจะเป็นของสัปดาห์ที่ 1, 2 หรือ 3 แล้วเสนอให้ใช้ซ้ำ หรือไม่เช่นนั้นก็จะสร้าง agent-valley-XXXX และลิงก์บัญชีสำหรับการเรียกเก็บเงินนั้นกับโปรเจ็กต์

เลือก

เขียนรหัสไปยัง ~/project_id.txt และเรียกใช้ gcloud config set project ดังนั้นหลังจากนี้คุณจึงไม่ต้องพิมพ์รหัส

รอ

จนกว่าโปรเจ็กต์จะได้รับอนุญาตให้แสดงโฆษณาได้จริง โดยใช้เวลาสูงสุด 2 นาที

🌐 ตอนนี้โปรเจ็กต์เดียวกันอยู่ในคอนโซลแล้ว โดยรหัสจะอยู่ในข้อมูลโปรเจ็กต์ในการ์ดแดชบอร์ด

รหัสโปรเจ็กต์ในแดชบอร์ดของคอนโซล

5 · ติดตั้งและชี้ไปที่ Vertex AI (~3 นาที)

💻 ติดตั้ง uv ส่งออกตัวแปร 3 รายการที่ส่ง 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 เป็นแบบไอดีมโพเทนต์ ซึ่งหมายความว่าสามารถเรียกใช้ซ้ำได้หลายครั้งอย่างปลอดภัย โดยจะดำเนินการ 5 อย่างตามลำดับต่อไปนี้

api

อ่านขั้นตอนที่ 4 ของโปรเจ็กต์ที่เลือกและเปิดใช้ aiplatform.googleapis.com (Vertex AI และ Agent Engine ที่โฮสต์ Memory Bank) และ bigquery.googleapis.com (คลังของบทที่ 5) ในโปรเจ็กต์

uv env

uv venv จะสร้าง .venv หรือใช้ซ้ำรายการที่มีอยู่แล้ว จากนั้น uv sync จะติดตั้งสิ่งที่ uv.lock ปักหมุดไว้ทั้งหมด ซึ่งได้แก่ google-adk, google-genai และทุกอย่างที่อยู่ใต้รายการเหล่านั้น

เว็บไซต์

ทำงาน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 และไม่มีคีย์ API ที่ใดเลย

การตรวจสอบโมเดล

โทรหา Gemini จริงๆ 1 ครั้ง ดังนั้นโปรเจ็กต์ที่ไม่ดีจะล้มเหลวตั้งแต่ตอนตั้งค่า ไม่ใช่ในภายหลังภายในบท

6 · พิสูจน์ว่าสีเขียว (~1 นาที)

💻 เรียกใช้การตรวจสอบล่วงหน้า - ทุกเครื่องหมายถูกคือการตรวจสอบจริง ไม่ใช่การคาดเดา

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

👀 การตรวจสอบเบื้องต้นจะถามคำถาม 1 ข้อกับโมเดลเพื่อพิสูจน์ว่าข้อมูลเข้าสู่ระบบของคุณใช้งานได้ ตรวจสอบว่าแพ็กเกจของ Archive อยู่ในตำแหน่งที่ถูกต้อง จากนั้นอ่านโค้ดของคุณและพิมพ์แถบความคืบหน้าของสัปดาห์นี้

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 รายการที่เลือกไว้แล้ว ซึ่งเป็นข้อความที่คุณอ่านเท่านั้น สามคือบรรทัดที่คุณเขียน หนึ่งคือหอคอยที่คุณสร้าง เรียกใช้การตรวจสอบก่อนส่งอีกครั้งได้ทุกเมื่อใน Lab แล้วระบบจะบอกว่าคุณอยู่ที่ใด เนื่องจากระบบจะอ่านไฟล์ ไม่ใช่รายการตรวจสอบ

3. Session, State, SqliteSessionService

  • อะไร - เขียน 1 บรรทัด เริ่มเวิร์กเบนช์ 1 ครั้งและดูการเติมสลิป จากนั้นทำเช่นเดียวกันในหอคอย แล้วอ่านว่าทำไมมันถึงรอดพ้นค่ำคืนไปได้
  • เหตุใด - สิ่งแรกที่ต้องรู้เกี่ยวกับความทรงจำคือไม่มีสิ่งใดที่จดจำได้ด้วยตัวของมันเอง มีคนเขียน
  • วิธี — 1 บรรทัดใน 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 4 ครั้ง แต่ละครั้งจะตอบกลับ "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.

👀 ชิป 4 write_down ตัวทำงาน - คลิก 1 ตัวแล้วอ่าน JSON: "written": {"no": "k7f2"} ตอนนี้คลิกรัฐอีกครั้ง

4 สิ่ง 4 ฟิลด์ 1 ข้อความ

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

👀 ว่างเปล่าแล้วเต็มภายในข้อความเดียว นั่นคือสิ่งที่เธอจำได้ และภาพนั้นไม่ได้ปรากฏขึ้นมาเอง คุณเขียนบรรทัดที่เขียนบรรทัดนั้น กลไกทั้งหมดนี้คือฟังก์ชันธรรมดาที่เขียนลงใน tool_context.state และคำสั่งที่บอกให้ใช้ฟังก์ชันนี้เมื่อใดก็ตามที่ผู้เข้าชมพูดอะไรที่ตรงกับบรรทัดในสลิป

👉🔬 ถามเธอว่า

What's my case number?

👀 k7f2. เธออ่านจากสลิป หากไม่มี EDIT ONE เธอคงขอให้คุณส่งมาให้แล้ว ซึ่งจะอยู่ในบรรทัดแรกของรายการสนับสนุนในการสนทนา

โดยมีเจ้าหน้าที่ 2 คนที่ถือแบบกระดาษซึ่งเป็นใบสลิปที่มีเส้นสั้นๆ 4 เส้น แต่ละเส้นเขียนเพียงครั้งเดียว ซึ่งมีความสำคัญมากกว่าที่เห็น หากไม่มีข้อมูลดังกล่าว โมเดลจะพบว่าสามารถเทการสนทนาทั้งหมดลงใน symptom และบทที่ 3 ซึ่งเป็นบทที่มีประเด็นทั้งหมดคือ สลิปไม่มีบรรทัดสำหรับสิ่งนั้น จะหยุดเป็นจริงอย่างเงียบๆ รูปร่างของร้านค้าจะบังคับใช้โดยโค้ดที่เขียนรูปร่างนั้น หรือไม่บังคับใช้

ตอนนี้ไปที่หอคอย

👉💻 คุณทำเวิร์กเบนช์เสร็จแล้ว คุณจะปล่อยให้เวิร์กเบนช์ทำงานต่อไปหรือปิดแท็บก็ได้ ส่วนที่เหลือของแล็บจะอยู่ในที่เก็บถาวร เปิดแท็บเทอร์มินัลที่ 2 (แท็บ 2 - ที่เก็บถาวร)

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

👉🖥 เปิดที่เก็บถาวรด้วยตัวอย่างเว็บ → เปลี่ยนพอร์ต พิมพ์ 3440 แล้วคลิกเปลี่ยนและแสดงตัวอย่าง 3440 ไม่อยู่ในรายการด่วนของตัวอย่างเว็บ แต่ 8080 เป็นค่าเริ่มต้น ดังนั้นคุณจึงต้องตั้งค่าด้วยตนเองในครั้งนี้ กด ▶ เริ่ม แล้วกดที่เก็บ คุณอยู่หน้าประตู เลือกผู้ที่มาขอเข้าชม โดยระบุชื่อและสายพันธุ์ แล้วเข้าไป

หอคอยที่ถูกตัดออก

👀 อาคาร 1 หลัง Vesper อยู่ที่โต๊ะที่ชั้นล่าง และคุณจะพูดคุยกับ Vesper ได้ที่นั่น เหนือเธอขึ้นไปคือชั้น 1 ชั้น 2 ชั้น 3 และห้องใต้หลังคาที่มืด ขั้นบันไดทั้ง 4 ขั้นคือชั้นทั้ง 4 ชั้น โดยตัวแทนของคุณจะนั่งอยู่ที่ชั้นล่าง เนื่องจากคุณปีนขึ้นไปได้แค่นั้น คอลัมน์ข้างภาพวาดจะระบุว่าแต่ละชั้นมีอะไรอยู่บ้างในตอนนี้ ซึ่งก็คือร้านค้า 4 ร้านเดิมตามลำดับเดียวกับตารางในส่วนบทนำ ไม่มีปุ่มทางด้านขวา

👉🖥 วางทั้ง 4 อย่างลงในช่องใต้การสนทนา (ข้อความนี้) แล้วกด Enter

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

มีเส้น 4 เส้นบนโต๊ะ และอีก 4 เส้นข้างๆ

👀 มองที่โต๊ะ ระบบจะเขียนสลิปทีละบรรทัดในภาพวาดและแบบเต็มใต้สลิปข้างภาพวาด เครื่องมือเดิม สถานะเดิม: หอคอยเพียงวาดสิ่งที่ write_down เขียน และจะทำเช่นนั้นต่อไปตลอดทั้งห้องทดลอง

เธอจำได้ในชั่วข้ามคืน - อ่านอย่างเดียว

สิ่งที่คุณเขียนและสิ่งที่เป็น

บรรทัด

คำอธิบาย

ตำแหน่งที่อยู่

tool_context.state[CASE] = case

สถานะเซสชัน - เขียนโดยโค้ด อ่านโดยคำสั่ง

โต๊ะ · session.state

SqliteSessionService(DB) — คุณอ่านได้อย่างเดียว

ที่เก็บเซสชัน - การเข้าชมในไฟล์ ไม่ใช่ในกระบวนการ

ชั้น 1 · archive.db

ขั้นนี้จะนับเป็นการเข้าชม 1 ครั้งและจะยังคงอยู่แม้จะถึงเวลาปิดทำการแล้ว และจะอยู่ได้ไม่นานกว่าการเข้าชมครั้งถัดไป

4. รัฐของผู้ใช้

  • อะไร — กลับมาอีก 1 เดือนต่อมา แต่ใบรับเงินหายไปแล้ว มีตัวละคร 5 ตัวและจะติดตามคุณ
  • เหตุผล - เซสชันคือการเข้าชม 1 ครั้ง การเข้าชมครั้งถัดไปคือเซสชันใหม่ และไม่เคยเห็นเซสชันก่อนหน้า
  • อย่างไร - 5 อักขระใน state.py

1 เดือนต่อมา ยินดีที่ได้รู้จัก

กดที่นี่

👉🖥 กด 🗓 อีก 1 เดือนต่อมา นั่นคือเซสชันใหม่สำหรับผู้เข้าชมรายเดียวกัน ซึ่งเป็นวิธีที่เริ่มการสนทนาใหม่ในสัปดาห์ที่ 3

ยินดีต้อนรับสู่ที่เก็บถาวร วันนี้มีอะไรให้ช่วยบ้าง

👉🖥 มองไปที่หอคอย ชั้น 1 มีหนังสืออีกเล่มในการเข้าชมนี้ ลิ้นชักที่ชั้น 2 ว่างเปล่า กระดาษที่วางอยู่บนโต๊ะว่างเปล่า

หนังสืออีกเล่มที่ชั้น 1 ลิ้นชักว่างเปล่า ใบสลิปว่างเปล่า

👀 เหตุผล: ระบบจะเขียนสลิปลงในสถานะเซสชัน และเซสชันคือการเข้าชมนี้ เปลี่ยนการเข้าชม เปลี่ยนเซสชัน ไม่มีการโอนข้อมูลใดๆ เนื่องจากไม่มีการสั่งให้โอน การเข้าชมครั้งล่าสุดยังคงอยู่ในไฟล์ ซึ่งก็คือหนังสือเล่มแรกของชั้น 1 แต่มีการเขียนใบยืมไว้ภายใต้คีย์ที่มีอายุการใช้งาน 1 ครั้ง

แก้ไข 2

👉✏️ เปิด 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 จะนำเข้าโค้ดของคุณในทุกข้อความอีกครั้ง

👉🖥 วางข้อมูล 4 อย่างเดิมอีกครั้ง ซึ่งก็คือข้อความนี้

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

👉🖥 จากนั้นกด 🗓 อีก 1 เดือนต่อมาอีกครั้ง ซึ่งเป็นปุ่มเดียวกับก่อนหน้า

ลิ้นชักที่มีชื่อ

👀 ลิ้นชักที่ชั้น 2 มีชื่อของคุณติดอยู่ และฟิลด์ทั้ง 4 จะอยู่ข้างใน กระดาษที่วางอยู่บนโต๊ะก็มี 4 บรรทัดเหมือนกัน ซึ่งดึงออกมาจากลิ้นชักตอนที่คุณเดินเข้ามา สัตว์เลี้ยงของคุณย้ายขึ้นไปอีกชั้น คีย์เดียวกัน ทุกครั้งที่เข้าชม ค่าเดียว: นั่นคือสิ่งที่คำนำหน้าทำหน้าที่ของมัน

คำนำหน้าจะอยู่ตลอดไป

คำนำหน้า

อายุการใช้งาน

ชั้นไหน

(ไม่มี)

การเข้าชมนี้

โต๊ะ

user:

ทุกครั้งที่ผู้เข้าชมรายนี้เข้าชม

ชั้น 2 ลิ้นชักของคุณ

app:

ทุกคนตลอดไป

ส่วนหนึ่งของชั้น 4

temp:

เลี้ยวตรงนี้เท่านั้น ไม่เคยขึ้นบันไดเลย

—

โต๊ะ 1 ตัว ลิ้นชัก 4 อัน บทนี้จะกล่าวถึงหนึ่งในนั้น

ตอนนี้เธอรู้จักคุณแล้ว

👉🖥 การเข้าชมนี้เป็นครั้งแรกและคุณยังไม่ได้พูดอะไรเลย ถามเธอว่า

What did I bring in last time?

👀 เราจดไว้ว่าคุณนำโคมไฟเข้ามา เคส k7f2 โดยมีเครื่องหมาย q7 และคุณบอกว่าไฟดับตอนกลางคืน ทุกคำพูดที่ออกมาจากลิ้นชัก ไม่ใช่จากการสนทนา การเข้าชมนี้มีข้อความเดียว และข้อความนั้นไม่มีชื่อ นั่นคือสถานะระดับผู้ใช้ที่ทําหน้าที่ของมัน โดยuser:คีย์จะอยู่ที่นั่นก่อนที่ผู้เข้าชมจะพูดอะไรก็ตาม ในทุกครั้งที่เข้าชม

ลิ้นชักมีเส้น 4 เส้นที่สลิปมี และไม่มีอะไรอื่น สิ่งที่คุณพูดที่ไม่มีบรรทัดในสลิป ไม่ว่าจะเป็นสิ่งที่คุณพยายามทำ เหตุผลที่คุณสนใจ หรือไม่ว่าคุณจะต้องการสลิปใหม่หรือไม่ ก็จะไม่มีที่ไป และจะหายไปในอีก 1 เดือนต่อมา ลิ้นชักข้ามเดือน แต่ประโยคไม่เป็นเช่นนั้น บทที่ 3 จะพูดถึงเรื่องนี้

สิ่งที่คุณเขียนและสิ่งที่เป็น

บรรทัด

คำอธิบาย

ตำแหน่งที่อยู่

CASE = "user:case"

คำนำหน้าคืออายุการใช้งาน ซึ่งเป็นคีย์เดียวกันที่กำหนดขอบเขตให้กับผู้เข้าชมแทนการเข้าชม

ชั้น 2 · user: รัฐ

ขั้นตอนนี้เข้าถึงผู้เข้าชม 1 ราย ลิ้นชักจะติดตามคุณ แต่การสนทนายังคงไม่ติดตาม

5. InMemoryMemoryService

  • อะไร - อ่านบรรทัดที่ระบุวันที่ยื่นเรื่อง เขียนบรรทัดที่ถาม จากนั้นระบุเวลาปิดรับเรื่องและคำถาม
  • เหตุผล - สลิปเป็นแบบฟอร์ม แบบฟอร์มจะมีบรรทัดที่คุณระบุ ผู้คนไม่ได้พูดเป็นบรรทัด และการบันทึกสิ่งที่พวกเขาพูดเป็นเพียงครึ่งหนึ่งของการจดจำ
  • วิธี — อ่าน file; 1 บรรทัดใน recall; จากนั้น 1 🌙, 1 🗓, 1 คำถาม

เวลาปิดทำการ เธอเดินกลับผ่านชั้นวาง

สิ่งที่เธอทำระหว่างทางกลับบ้าน - อ่านอย่างเดียว

ระบบไม่จดจำฟิลด์

เส้นนั้นจะทำให้วันนั้นๆ อยู่ในชั้นวาง แต่จะไม่นำข้อมูลใดๆ ออก ชั้นวางที่เต็มไปด้วยการ์ดก็ช่วยได้มากพอๆ กับชั้นวางที่ว่างเปล่าหากไม่มีใครดู และเมื่อโค้ดพร้อมใช้งาน ก็จะไม่มีใครดู recall โหนดที่ทำงานก่อน Vesper ในทุกคำถามจะไม่ถามอะไรกับหอคอยเลย การจัดเก็บที่คุณนึกไม่ออกในเวลาที่เหมาะสมไม่ใช่ความทรงจำ แต่เป็นบันทึก การมองหาคืออีกครึ่งหนึ่ง และคุณเป็นผู้เขียน

การแก้ไขที่ 3 - การขอ

👉📖 ใน 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 แล้ว

บันทึก ไม่ต้องรีสตาร์ท

2 บรรทัด 2 นโยบาย และคุณเป็นผู้เขียนนโยบาย 1 ใน 2 รายการนี้ นโยบายการเขียนจะกำหนดว่าระบบจะเก็บข้อมูลใดไว้และเมื่อใด (เวลาปิดทำการ ทั้งวัน) นโยบายการเรียกคืนจะกำหนดเวลาที่ต้องค้นหาและสิ่งที่ต้องค้นหา (ทุกคำถาม ตัวคำถามเอง) ADK จะให้คำกริยาแก่คุณ เช่น add_events_to_memory, search_memory และจะไม่เกี่ยวข้องกับนโยบาย นั่นคือการแบ่งที่ถูกต้อง และเป็นเหตุผลว่าทำไมคุณถึงเป็นคนเขียนคำขอ

เวลาปิดร้าน

👉🖥 บอก 3 สิ่งที่ไม่มีในสลิป ข้อความ 1 หรือ 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.

กดที่นี่

👉🖥 จากนั้นกด 🌙 วันนี้มีเพียงเท่านี้

คำพูดผุดขึ้นมา

👀 มองที่โต๊ะ คุณบอกว่าเลื่อนหลุดและลอยขึ้น แล้วลงจอดที่ชั้น 3 ในส่วนการ์ดข้างหอคอยที่แสดงรายการไว้ จะมีการ์ด 1 ใบสำหรับแต่ละข้อความที่คุณส่ง โดยมีเครื่องหมาย quote ประโยคของคุณแบบคำต่อคำ และในกระบวนการนี้เหนือการ์ด โคมไฟบนโต๊ะจะสว่างอยู่จนกว่าจะลงจอด

1 เดือนต่อมา เธอก็รู้

👉🖥 กด 🗓 1 เดือนต่อมา แล้วถามว่า

What have I already tried?

👀 คุณลองแขวนสูงขึ้นแล้ว แต่ก็ไม่ได้ผล She knows. ในสลิปไม่มีบรรทัดสำหรับรายการนี้และไม่เคยมี ดังนั้นพนักงานจึงตอบคำถามนี้ไม่ได้ recall พบการ์ดดังกล่าว เขียนลงใน ctx.state["recalled"] และคำสั่งของเธอระบุไว้เช่นนั้น มีเส้นกั้นเพียงเส้นเดียว

และทุกอย่างอยู่ในหัวของเธอ

ดูในส่วนการ์ดข้างหอคอยในกระบวนการนี้ ตอนนี้หน่วยความจำคือ InMemoryMemoryService ซึ่งเป็นพจนานุกรมภายใน bash valley.sh และจะคงอยู่ตราบเท่าที่กระบวนการนั้นยังทำงานอยู่ ปิดหอคอยคืนนี้และเปิดพรุ่งนี้ หนังสืออยู่ชั้น 1 ลิ้นชักอยู่ชั้น 2 และชั้น 3 มืด เคสยังคงอยู่ในไฟล์ สิ่งที่คุณพูดจะอยู่ในกระบวนการ และกระบวนการนั้นก็หายไป

การคงอยู่ไม่ใช่ความทรงจำ

ชั้น 3 มีข้อผิดพลาด 2 อย่างคือ อยู่ในกระบวนการและเป็นคำพูดของคุณเอง ซึ่งเป็นคำพูด ไม่ใช่ข้อเท็จจริง บทถัดไปจะแก้ไขทั้ง 2 อย่างโดยไม่ต้องเขียนโค้ดเลย

สิ่งที่คุณอ่าน สิ่งที่คุณเขียน และสิ่งที่เป็น

บรรทัด

คำอธิบาย

ตำแหน่งที่อยู่

await ctx.add_events_to_memory(events, custom_metadata=FILING) — คุณอ่านได้อย่างเดียว

นโยบายการเขียน - ทั้งวัน ณ เวลาปิดทำการ

ชั้น 3 · บริการหน่วยความจำ

found = await ctx.search_memory(query) — แก้ไข 3

นโยบายการเรียกคืน - ทุกคำถามก่อนที่เธอจะตอบ

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

ขั้นตอนนี้จะเข้าถึงสิ่งที่พูดและเก็บไว้ในพจนานุกรมภายในกระบวนการเดียวด้วยคำพูดของคุณเอง ทั้ง 2 ส่วนนั้นผิด และบทถัดไปจะแก้ไขทั้ง 2 ส่วนโดยไม่ต้องใช้โค้ดเลย

6. MemoryBank

  • อะไร - สคริปต์หนึ่งสร้างคลังความทรงจำ ส่วน 2 บรรทัดที่คุณมีอยู่แล้วจะเริ่มเขียนข้อเท็จจริงลงในคลังความทรงจำและอ่านข้อเท็จจริงนั้นกลับมา
  • เหตุใด - บริการหน่วยความจำคือบริการ ที่เก็บถาวรจะอยู่ในส่วนการตัดสินใจในการติดตั้งใช้งาน ไม่ใช่ Agent คุณสามารถเปลี่ยนได้โดยไม่ต้องแตะต้อง Agent
  • วิธี — เรียกใช้ make_tower.py พูด 3 ประโยค กด 🌙 กด 🗓 ถามคำถาม 1 ข้อ จากนั้นดูการเขียนและการอ่านแบบอ่านอย่างเดียว

สร้างหอคอย

ชั้น 3 ของบทที่ 3 เป็นพจนานุกรม Python ภายใน bash valley.sh Memory Bank เป็นเวอร์ชันที่มีการจัดการของชั้นนั้น โดยจะอยู่ในอินสแตนซ์ Agent Engine ในโปรเจ็กต์ของคุณ ซึ่งจะเก็บข้อเท็จจริงที่กลั่นกรองจากวันนั้นแทนที่จะเป็นประโยคของคุณ และจะค้นหาตามความหมายแทนที่จะเป็นคำที่ใช้ร่วมกัน คุณไม่จำเป็นต้องติดตั้งใช้งาน Vesper กับ Agent Engine เพื่อใช้งาน เนื่องจากอินสแตนซ์ที่ไม่มีการติดตั้งใช้งานใดๆ จะยังคงโฮสต์ Memory Bank อยู่ และนั่นคือสิ่งที่สคริปต์สร้างขึ้น นั่นคือหอคอยที่ไม่มีใครอาศัยอยู่ ซึ่งมีหน้าที่เพียงเก็บการ์ด

👉💻 ในแท็บ 1 (ประมาณ 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 1 ครั้ง agent_engines.create() และเขียน 1 บรรทัดลงใน .env Archive จะอ่านไฟล์นั้นอีกครั้งในทุกคำขอ จึงไม่ต้องรีสตาร์ท

ดูวิธีการทำงาน

👉🖥 ดูชั้น 3 - หอคอยจะวาดใหม่เองภายใน 2-3 วินาที ในส่วนการ์ด ตอนนี้จะแสดงธนาคารความทรงจำ และชั้นวางว่างเปล่า คำพูด 3 คำจากบทที่ 3 อยู่ในกระบวนการ และนี่ไม่ใช่กระบวนการ พูดประโยคทั้ง 3 อีกครั้ง ไม่ว่าจะเป็นข้อความเดียวหรือ 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.

👉🖥 กด 🌙 วันนี้มีเพียงเท่านี้ ตอนนี้เวลาปิดใช้เวลาประมาณ 8 วินาที ซึ่งหอคอยกำลังดึงข้อมูล จากนั้นมองไปที่ชั้น 3

ซ้าย: สิ่งที่เธอเก็บไว้ในหัว ขวา: สิ่งที่หอคอยเก็บไว้

👀 การ์ดไม่ใช่ประโยคของคุณ โดยผู้ใช้จะพูดว่า ฉันใช้ตะเกียงอ่านหนังสือตอนกลางคืน ซึ่งเป็นเวลาที่ตะเกียงดับ และ ฉันลองแขวนตะเกียงให้สูงขึ้นแล้ว โดยแต่ละข้อความจะมีเครื่องหมาย fact พร้อมวันที่ การกลั่น สิ่งที่เกิดขึ้นคือการสนทนา สิ่งที่ออกมาคือข้อเท็จจริง

👉🖥 กด 🗓 1 เดือนต่อมา ซึ่งเป็นการเข้าชมครั้งใหม่ ดังนั้นสิ่งที่เพิ่งพูดไปจะไม่อยู่ในการสนทนาอีกต่อไป แล้วถามคำถามนี้ ซึ่งไม่มีคำใดที่ตรงกับการ์ด

Should I just get a different lamp?

👀 เนื่องจากเป็นของขวัญ คุณจึงบอกว่าไม่ต้องการเปลี่ยนโคมไฟ และได้ลองแขวนโคมไฟให้สูงขึ้นแล้ว ทุกคำพูดนั้นมาจากบัตร และมีเพียงบัตรเท่านั้นที่บอกเธอได้ว่าการเข้าชมนี้เป็นข้อความเก่า การค้นหาที่คล้ายกัน หอคอยตรงกับความหมาย ไม่ใช่คำ โดยคำถามระบุว่าตะเกียงและเปลี่ยน ส่วนการ์ดระบุว่าโคมไฟและแทนที่ และตอนนี้ก็อยู่นอกกระบวนการแล้ว ปิดหอส่งสัญญาณคืนนี้และบัตรจะพร้อมใช้งานในวันพรุ่งนี้ เนื่องจากบัตรจะอยู่ใน Agent Engine ไม่ใช่ใน bash valley.sh

การเขียนและการอ่าน - อ่านอย่างเดียว

สิทธิที่จะถูกลืม

กดที่นี่

👉🖥 กด 🔥 ลืมฉัน ใต้กล่องข้อความ

👀 3 ชั้นดับไฟและ 1 ชั้นไม่ดับ

สิ่งที่เก็บไว้

หลัง 🔥

ชั้น 3 การ์ด

สิ่งที่เธอจำได้ — ข้อเท็จจริงที่ธนาคารความทรงจำกลั่นกรองจากการเข้าชมของคุณ

memories.delete ทีละใบ

ชั้น 2 ลิ้นชัก

user:case สลิปที่ติดตามผู้เข้าชมรายนี้จากการเข้าชมครั้งหนึ่งไปยังอีกครั้งหนึ่ง

ล้างข้อมูลแล้ว

เดสก์ ใบสลิป

สำเนาเคสของการเข้าชมนี้

ล้างข้อมูลแล้ว

ชั้น 1 หนังสือ

การเข้าชมเอง - 1 เซสชันใน archive.db ต่อการเข้าชม 1 ครั้ง ทุกข้อความของการเข้าชม

ไม่มีการเปลี่ยนแปลง - จำนวนไม่เปลี่ยนแปลง

สมุดบันทึกคือบันทึกที่แสดงว่ามีการเข้าชมเกิดขึ้นในวันใดและมีการพูดอะไรในการเข้าชมนั้น การ์ดและลิ้นชักคือความทรงจำ: สิ่งที่เธอได้รับจากการเข้าชมเหล่านั้นและนำไปใช้ในการเข้าชมครั้งถัดไป คำขอที่จะถูกลืมนั้นเกี่ยวข้องกับความทรงจำ ซึ่งก็คือข้อเท็จจริงที่ได้มาจากบุคคลหนึ่งๆ และสถานะที่ติดตามบุคคลนั้นไป การตัดสินใจว่าจะลบบันทึกการเข้าชมด้วยหรือไม่นั้นเป็นการตัดสินใจแยกต่างหาก ซึ่งมีเหตุผลแยกต่างหาก ได้แก่ บันทึกการตรวจสอบ ประวัติการสนับสนุน และห้องทดลองนี้จะเก็บไว้โดยเจตนาเพื่อให้คุณเห็นว่าทั้ง 2 อย่างแยกจากกัน บันทึกกับความทรงจำไม่ใช่สิ่งเดียวกัน และการลืมอย่างใดอย่างหนึ่งไม่ได้ส่งผลกระทบต่ออีกอย่าง นั่นคือประโยคเหนือประตูของเวสเปอร์ ซึ่งมองจากอีกด้านหนึ่ง

การแยกหน่วยความจำของ 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 — กด ไม่ได้เขียน

การลืมคือการดำเนินการของแอป API หน่วยความจำของ ADK ไม่มีฟังก์ชันลบ

archive/tower.py

ขั้นตอนนี้จะไปถึงสิ่งที่พูด วันเวลาผ่านไป ข้อเท็จจริงก็ปรากฏขึ้น โดยกลั่นกรองให้เหลือเพียงสิ่งที่หัวข้ออนุญาต และหนังสือที่ชั้น 1 ก็ไม่เคยถูกย้าย

7. GraphRAG

ไม่บังคับ

  • อะไร - สคริปต์หนึ่งจะโหลดอดีตของหุบเขาลงใน BigQuery สร้างการฝังภายในคลังข้อมูล และวางกราฟไว้เหนือตารางโดยไม่ต้องย้ายแถว จากนั้นก็ถามคำถาม 2 ข้อกับ Vesper ซึ่งมีคำค้นหาที่ควบคุม 2 รายการสำหรับคำถามนั้น ได้แก่ คำค้นหาหนึ่งสำหรับสิ่งที่ฟังดูคล้ายกัน และอีกคำค้นหาหนึ่งสำหรับสิ่งที่เชื่อมต่อกัน
  • เหตุใด - เสียงคล้ายกันไม่เหมือนกับเชื่อมต่อ เวกเตอร์จะค้นหาตำแหน่งที่ต้องดู กราฟจะค้นหาสิ่งที่แนบมา และคำตอบต้องมีเส้นทางที่ใช้
  • วิธี — bash scripts/season.sh ครั้ง ส่วนอื่นๆ ในบทนี้เป็นแบบอ่านอย่างเดียว

หอคอยของเวสเปอร์จะมองเห็นคุณ — (app_name, user_id) — โดยการก่อสร้าง การเข้าชมของผู้อื่นไม่ใช่ความทรงจำของเธอ และการค้นหาอย่างหนักก็ไม่ได้ช่วยให้เกิดการเปลี่ยนแปลง โดยหุ่นยนต์เหล่านี้เป็นของหุบเขา และหุบเขาจะเก็บหุ่นยนต์ไว้ในคลังสินค้า ผู้เข้าชม 31 คนในฤดูกาลนี้มาที่นี่เพราะโคมไฟ Q7 ดับในตอนกลางคืน และหนึ่งในนั้นพบสาเหตุ บทนี้จะโหลดคลังข้อมูลนั้นและส่งการค้นหาที่แก้ไขแล้ว 2 รายการให้

Graph RAG

RAG คือดึงข้อมูล แล้วสร้าง: ค้นหาระเบียนที่ถูกต้อง ส่งให้โมเดล แล้วปล่อยให้โมเดลตอบจากระเบียนเหล่านั้น RAG แบบธรรมดาจะดึงข้อมูลตามความคล้ายคลึงกัน โดยฝังคำถามและดึงระเบียนที่ใกล้เคียงที่สุด ซึ่งจะค้นหาสิ่งที่ฟังดูเหมือนคำถาม และเป็นจุดที่หอคอยของบทที่ 4 หยุดลง Graph RAG จะเพิ่มขั้นตอนการดึงข้อมูลที่ 2 ซึ่งจะติดตามขอบ ซึ่งเป็นคีย์ที่คลังสินค้ามีอยู่แล้ว จากความคล้ายคลึงที่พบ ไปยังสิ่งที่แนบมากับขอบนั้น ทั้ง 2 ขั้นตอนจะตอบคำถามที่แตกต่างกัน และบทนี้จะทำให้คุณถามคำถามทั้ง 2 ข้อ

ขั้นตอน

คำถามที่ตอบ

อย่างไร

ในบทนี้

ความคล้ายคลึง

ฉันควรดูที่ไหน

ฝังคำถาม VECTOR_SEARCH

season_search — เมื่อผู้เข้าชมไม่มีเครื่องหมาย

การส่งผ่าน

อะไรที่เชื่อมต่อกับสิ่งนั้น

MATCH เส้นทางผ่านกราฟพร็อพเพอร์ตี้

season_known_issue — 1 รายการแบบอยู่กับที่ MATCH

รุ่น

ฉันควรบอกอะไรแก่ผู้เข้าชม

โมเดลที่มีเส้นทางเป็นข้อมูลอ้างอิง

คำตอบของเธอ

ดำเนินการ

โดยซีซันจะส่งออกเป็น CSV ธรรมดาใน season/ — ผู้เข้าชม ไอเทม คำขอ การแก้ไข ซีซัน — ในลักษณะที่ระบบสนับสนุนจะส่งออก สคริปต์เดียวจะนำผู้ใช้ไปยังคลังสินค้า และเป็นสิ่งเดียวที่คุณจะเรียกใช้ในบทนี้

👉💻 ในแท็บ 1 (ประมาณ 3 นาที โดยจะพิมพ์แต่ละขั้นตอนเมื่อดำเนินการ และหยุดที่ขั้นตอนแรกที่ล้มเหลว)

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

👀 เมื่อการแข่งขันสิ้นสุดลง ชั้น 4 ของหอคอยจะสว่างขึ้น และข้อความข้างๆ จะระบุว่าเปิด

สิ่งที่สร้างขึ้น - อ่านอย่างเดียว

วิธีที่เธออ่าน - อ่านอย่างเดียว

ถามเธอ

👉🖥 ชั้น 4 เปิดแล้วในหอคอย ถามเธอในลักษณะเดียวกับที่ผู้เข้าชมจะทำ

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

เธอตอบกลับมาและบรรทัดสุดท้ายคือเส้นทาง

👀 เธอตอบกลับว่า อีก 31 คน... ส่วนใหญ่บอกว่าไฟลุกโชนอยู่ได้ไม่นานและดับไปหลังจากผ่านไป 1 ชั่วโมง... Marlow the otter พบว่าไส้เทียนจุ่มตื้นเกินไป และบรรทัดสุดท้ายของคำตอบคือเส้นทาง นี่คือผลลัพธ์ของเธอ โปรดอ่านและอย่าส่งกลับไปให้เธอ

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 เหมือนเดิม ไม่มีใครสามารถเดินคะแนนความคล้ายคลึงได้อีก หากเธอพูดก่อนหน้าเส้นทางว่าแถวกลับมาผ่านการรวม 3 รายการเนื่องจากโปรเจ็กต์ไม่มีการจองกราฟ นั่นคือการปฏิเสธ GRAPH_TABLE ของการแก้ไขโปรเจ็กต์ของคุณ แถวและเส้นทางจะเหมือนกัน

👉🖥 ตอนนี้ให้นำเครื่องหมายออกแล้วส่งข้อความนี้

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

👀 เธอได้เลข 31 เหมือนกันและเส้นทางเดียวกัน สิ่งที่เปลี่ยนไปคือเส้นทาง: season_search วิ่งเป็นคนแรก พบผู้เข้าชม 5 คนที่ดูคล้ายกัน ซึ่งแต่ละคนมี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. ปิด

3 สาย 1 เสา 1 คลังสินค้า 4 ชั้น ไม่มีการรีสตาร์ท

ขั้น

สิ่งที่คุณทำ

สิ่งที่ซื้อ

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 + เครื่องมือ 1 อย่างที่ SqliteSessionService เก็บไว้

a dict beside the chat loop, pickled to disk yourself

โมเดลอ่านไม่ได้ และคุณเขียนเรซูเม่และการล็อก

คำนำหน้า user:

ตารางผู้ใช้และการรวมทุกครั้ง

การตัดสินใจว่าคีย์ควรอยู่ที่ใดทุกครั้ง

add_events_to_memory + search_memory ในโหนดฟังก์ชัน

Cron ที่ทิ้งข้อความถอดเสียง และโมเดลที่ตัดสินใจว่าจะดูเมื่อใด

มันทิ้งทุกอย่าง ไม่มีการกลั่นกรอง และคุณไม่เคยเห็นช่วงเวลาที่มันไม่ดี

VertexAiMemoryBankService + allowed_topics

ที่เก็บเวกเตอร์ พรอมต์การแยก งานการรวม และ"โปรดอย่าจดจำเรื่องไม่สำคัญ" ในพรอมต์

3 บริการ และกฎนี้จะใช้ได้จนกว่าโมเดลจะรู้สึกว่าควรเปลี่ยนแปลง

VECTOR_SEARCH + GQL แบบคงที่ 1 รายการ MATCH

ส่งออก ฝังที่อื่น ฐานข้อมูลกราฟ งานซิงค์ และโมเดลที่เขียน SQL

ข้อมูลจะออกจากคลังเพื่อทำความเข้าใจ และคุณจะพบว่าระบบเดาการรวมใดเมื่อลูกค้าดำเนินการ

คำถาม 3 ข้อ หยุดเมื่อตอบว่า "ใช่"

  1. พรุ่งนี้จะยังสำคัญอยู่ไหม ไม่ → ไม่เก็บอะไรเลย ซึ่งจะเกิดขึ้นและจบลงในการสนทนา
  2. ฟังก์ชันตรวจสอบได้ไหม ใช่ → ลิ้นชัก โค้ดเขียนไว้ ทุกเทิร์นจะอ่าน และไม่มีประโยคใดเปลี่ยนได้
  3. มิเช่นนั้น → หอคอย กลั่นกรองจากสิ่งที่พูด ค้นหาเมื่อมีการขอ และแก้ไขตามสิ่งที่พูดถัดไป

ประโยคเดียว

บันทึกไม่ใช่ความทรงจำ โดยความทรงจำคือบันทึกบวกกับการตัดสินใจ 2 อย่าง ได้แก่ สิ่งที่ควรเก็บไว้และเวลาที่ควรดู และประเภทของความทรงจำจะเป็นตัวกำหนดว่าความทรงจำนั้นจะไปอยู่ชั้นใด

ข้อเท็จจริงและความชอบควรอยู่ในร้านค้าที่แตกต่างกัน

👀 ทุกชั้นมีแสงสว่าง สัตว์เลี้ยงจะอยู่ด้านบน โดยแสตมป์ในคลังจะอยู่ในหนังสือเดินทาง และสัปดาห์ที่ 5 จะเปิดตลาดกลางคืน ซึ่งเป็นที่ที่ Nix จะพูดคุยบนเวทีแบบเรียลไทม์ และทุกสิ่งที่หอคอยรู้จะติดตามคุณไปด้วย