1. Pengantar

Minggu pertama menanyakan siapa yang mengatakan apa yang sedang berjalan. Minggu kedua menanyakan siapa yang memutuskan apa yang akan dijalankan berikutnya. Minggu ketiga menanyakan apa yang ditinggalkan oleh lari. Minggu ini percakapan berakhir, dan pertanyaannya adalah apa yang bertahan — dan ternyata jenis benda yang dibicarakan menentukan ke mana benda itu akan pergi.
Arsip adalah tempat lembah muncul saat terjadi kesalahan. Menara yang mencatat semuanya, dan Vesper, sang arsiparis, di meja di lantai dasar. Lentera Anda padam di malam hari. Pergi dan tanyalah.
Dia adalah teman yang baik. Sebulan kemudian, dia juga senang bertemu dengan Anda.
Rekaman bukanlah ingatan.
Kalimat tersebut adalah seluruh lab. Anda akan mendakinya dalam empat anak tangga, dan setiap anak tangga adalah lantai menara:
berdering | lantai | apa yang diingatnya | apa yang membuatnya |
1 | meja, dan lantai | kunjungan ini |
|
2 | lantai dua, laci Anda | pengunjung ini | awalan |
3 | lantai tiga, menara | apa yang dikatakan | Memory Bank Vertex AI |
4 | lantai empat, musim | seluruh lembah | BigQuery |
Setiap anak tangga yang naik adalah karena sesuatu jatuh dari anak tangga di bawahnya.

Anda sudah mengetahui lima cara pelupa seorang arsiparis, karena setiap cara tersebut pernah terjadi pada Anda saat panggilan dukungan:
apa yang dia katakan | apa yang salah | |
~~1~~ | ~~Bisa berikan referensi itu lagi?~~ | ~~lupa dalam satu percakapan~~ — minggu ketiga memperbaikinya |
~~2~~ | ~~Kami telah mengalihkan Anda. Mulai dari awal.~~ | ~~histori hilang bersama proses~~ — minggu ketiga juga memperbaiki hal ini |
3 | Selamat datang. Ada yang bisa saya bantu? | kepada seseorang yang memiliki kasus yang belum selesai dari bulan lalu |
4 | Dapatkah Anda mendeskripsikan kerusakannya? | dia melihat lentera terakhir kali |
5 | Kita belum pernah melihat ini sebelumnya. | tiga puluh satu orang telah bertanya musim ini |
Baris ketiga adalah minggu ini. Kegagalan terjadi dalam tiga cara yang berbeda — kunjungan baru (bab 2), kalimat tanpa garis pada slip (bab 3), dan arsip yang hanya ada di dalam proses (bab 4) — dan setiap cara adalah bab. Baris keempat diserahkan kepada Anda: look() di archive/agent.py adalah tempat dia membaca tanda dari foto. Baris kelima adalah bab 5, dan bersifat opsional.
Anda tidak memerlukan minggu satu hingga tiga. Agen adalah model dengan petunjuk dan beberapa alat. Segala sesuatu yang lain, minggu ini sudah jelas.
Anda akan menulis tiga baris, dan setiap baris adalah konsep memori:
baris | Apa itu |
| ditulis oleh kode, bukan oleh percakapan |
| awalan adalah seumur hidup |
| kebijakan panggilan balik — yang diajukan tidak diingat |
Ada satu lagi baris yang sudah tersedia untuk Anda baca — kebijakan penulisan, await ctx.add_events_to_memory(...) — dan di bab 3 Anda akan membaca apa yang dilakukannya sebelum menulis baris yang menggunakannya.
Dua anak tangga lainnya bukan pengeditan sama sekali: Anda membangun menara (Agent Engine yang menghosting Memory Bank) dan kode yang sama terhubung ke menara tersebut dengan sendirinya, serta Anda memuat gudang (BigQuery), menempatkan grafik di atasnya, dan memberikan dua kueri yang diatur kepada agen yang sama — satu berdasarkan makna, satu berdasarkan koneksi.
Setiap bab menjalankan loop yang sama, dan loop ini akan Anda gunakan pada agen Anda sendiri: baca kode → tulis baris → lihat di menara. Tidak ada yang rusak saat pertama kali dijalankan, tidak ada yang dimulai ulang, dan tidak ada yang di-Ctrl+C: setiap pengeditan akan diambil pada pesan berikutnya, dan menghubungkan menara adalah satu baris dalam file yang dibaca ulang oleh Arsip pada setiap permintaan. Menara adalah gambar yang digambar ulang: menara membaca file yang sama yang Anda edit, dan memiliki tiga tombol — 🌙 mengakhiri hari, 🗓 memulai kunjungan berikutnya, 🔥 melupakan Anda. Semua hal lainnya yang Anda lakukan dalam kode dan terminal.
Dua tempat, dan mereka tidak pernah berganti pekerjaan: tab 1 adalah terminal, tab 2 adalah Arsip. Workbench (adk web) muncul persis satu kali, di bab 1, untuk melihat status sesi mentah, lalu Anda selesai menggunakannya. Setiap 👉 di bawah menunjukkan jenisnya. 👉💻 adalah tab 1, 👉🖥 adalah tab 2, 👉🔬 adalah workbench. 👉📖 adalah membuka file dan membaca — tidak ada yang perlu diubah — dan 👉✏️ adalah salah satu jenis langkah yang mengedit. Setiap kali langkah-langkah memberi tahu Anda untuk mengucapkan sesuatu kepada Vesper, pesan persisnya ada di blok tepat di bawahnya — salin apa adanya. Bagian yang judulnya diakhiri dengan — hanya baca tidak perlu diketik, ditempel, atau diklik: kode di dalamnya sudah ada di repo dan sudah berjalan, dicetak untuk Anda baca.
Kalimat di atas pintu Vesper adalah kalimat yang ada di bagian atas. Kalimat yang mengakhiri minggu ini adalah kalimat penutup minggu keempat seluruh musim:
Fakta dan preferensi berada di toko yang berbeda.
2. 🧰 Penyiapan
- Apa — arahkan ke project atau tempel kunci, instal, dan buktikan bahwa toolchain berwarna hijau.
- Mengapa — tidak ada yang di-boot di sini. Setiap server dimulai tepat sebelum langkah yang memerlukannya, jadi saat layar terbuka, Anda tahu perintah mana yang memilikinya.
- Cara — satu skrip yang membuat project, satu skrip yang menginstal dan mengarahkan Anda ke Vertex AI, dan satu skrip pra-penerbangan yang membaca kode Anda dan memberi tahu Anda posisi Anda.
Semua yang ada di lab ini berjalan di Cloud Shell — Python, uv, dan gcloud sudah diinstal di sana, dan Gemini dapat diakses melalui Vertex AI menggunakan kredensial Anda sendiri. Tidak ada kunci API di mana pun dalam lab ini, dan tidak ada yang perlu diinstal di laptop Anda.
Ada satu hal yang tidak dapat diberikan oleh lab ini: project Google Cloud dengan penagihan yang diaktifkan. Langkah 1 memberi Anda akun yang dapat membayar; langkah 4 mengubah akun tersebut menjadi project — atau mengambil project Agent Valley yang sudah Anda buat pada minggu pertama, minggu kedua, atau minggu ketiga. Lakukan secara berurutan — setiap langkah setelah 4 membaca project yang ditentukan oleh langkah 4.
1 · Dapatkan akun dengan penagihan (~1 menit)
🌐 Lakukan langkah ini sebelum melakukan hal lain. Login dengan Akun Google yang penagihannya diaktifkan. Akun apa pun yang demikian akan berfungsi. Jika akun Anda tidak memiliki akun penagihan, mulai uji coba gratis; uji coba ini akan memberi Anda akun penagihan, yang diperlukan untuk langkah 4.
2 · Buka Cloud Shell (~1 menit)
🌐 Klik Activate Cloud Shell di bagian atas Konsol Google Cloud — ikon ini berbentuk terminal di header.

🌐 Klik Open Editor (ikon folder terbuka dengan pensil). Tindakan ini akan membuka Cloud Shell Editor dengan file explorer di sebelah kiri — di sinilah Anda bekerja setiap kali langkah ditandai 👉✏️.

🌐 Jika Anda diminta untuk memberikan otorisasi kapan saja hari ini, klik Authorize untuk melanjutkan.
🌐 Buka terminal di dalam editor — yaitu tab 1, dan setiap langkah 👉💻 dijalankan di sana kecuali jika dinyatakan lain. Tab 2 adalah Arsip, dan Anda membukanya di bab 1, tepat sebelum langkah yang memerlukannya. Jika terminal belum berada di bagian bawah layar, buka dengan View → Terminal:

🌐 Periksa akun yang Anda gunakan untuk login — akun tersebut harus sama dengan akun yang digunakan di langkah 1:
gcloud auth list
3 · Ikuti lab (~1 menit)
💻 Clone repo — ini adalah repo Archive, bukan repo minggu pertama, minggu kedua, atau minggu ketiga:
cd ~
git clone https://github.com/cuppibla/agent-valley-archive
cd agent-valley-archive
4 · Buat project Anda — atau gunakan kembali project dari minggu sebelumnya (~2 menit)
💻 Satu skrip menemukan akun penagihan Anda, membuat project di akun tersebut, dan mengarahkan Cloud Shell ke project tersebut. Jika Anda mengerjakan minggu pertama, minggu kedua, atau minggu ketiga, project Agent Valley akan ditemukan terlebih dahulu dan ditawarkan untuk digunakan kembali — pilih ya dan tidak ada project kedua yang dapat ditagih:
cd ~/agent-valley-archive
./setup_project.sh
👀 Harapkan ✓ untuk akun penagihan yang dipilihnya, ✓ untuk project yang dibuat atau digunakan ulang, dan akhiran seperti:
cd ~/agent-valley-archive
Project ready: agent-valley-4271
Next: ./setup_codelab.sh
agent-valley-4271 adalah project ID Anda — ID Anda akan memiliki digit yang berbeda. Empat hal terjadi di sana:
penagihan | menggunakan akun | |
project | mencari project Agent Valley yang sudah Anda miliki — minggu pertama, minggu kedua, atau minggu ketiga — dan menawarkan untuk menggunakannya kembali; jika tidak, project akan membuat | |
memilih | menulis ID ke | |
waits | polling hingga proyek benar-benar diizinkan untuk ditayangkan, hingga dua menit | |
🌐 Project yang sama kini ada di konsol — ID-nya ada di kartu Project info di Dasbor:

5 · Menginstal dan mengarahkan ke Vertex AI (~3 menit)
💻 Instal uv, ekspor tiga variabel yang mengirim ADK ke Vertex AI, dan jalankan penyiapan:
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) memiliki sesuatu untuk dikembalikan karena langkah 4 telah menyetelnya. Itulah alasan mengapa langkah 4 dilakukan terlebih dahulu.
setup_codelab.sh bersifat idempoten — aman untuk dijalankan kembali beberapa kali. Metode ini melakukan lima hal, secara berurutan:
api | membaca project yang dipilih pada langkah 4 dan mengaktifkan | |
uv env |
| |
lahan | menjalankan | |
.env | menulis variabel yang dibaca lab — | |
model check | melakukan satu panggilan nyata ke Gemini, sehingga project yang buruk akan gagal di sini saat penyiapan, bukan nanti di dalam bab | |
6 · Buktikan bahwa ini ramah lingkungan (~1 mnt)
💻 Jalankan pra-penerbangan — setiap tanda centang adalah pemeriksaan yang sebenarnya, bukan tebakan:
cd ~/agent-valley-archive
uv run python scripts/preflight.py
👀 Pra-penerbangan menanyakan satu pertanyaan kepada model untuk membuktikan bahwa kredensial Anda berfungsi, memeriksa apakah paket Arsip sudah ada, lalu membaca kode Anda dan mencetak progres minggu ini:
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
Tiga sudah dicentang. Itulah yang hanya Anda baca. Tiga adalah garis yang Anda tulis; satu adalah menara yang Anda bangun. Jalankan pra-pemeriksaan lagi kapan saja di lab dan alat ini akan memberi tahu Anda posisi Anda — alat ini membaca file Anda, bukan daftar periksa.
3. Sesi, Status, SqliteSessionService
- Apa — tulis satu baris; mulai workbench sekali dan lihat pengisian slip; lalu hal yang sama di menara; lalu baca mengapa ia bertahan di malam hari.
- Mengapa — hal pertama yang perlu diketahui tentang memori adalah bahwa tidak ada yang diingat dengan sendirinya. Seseorang menulisnya.
- How — satu baris di
agent.py, lalu jangan ubah apa pun.
EDIT SATU
👉📖 Buka archive/agent.py dan temukan write_down. Baca hingga 👉:
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}}
Fungsi ini membangun slip dalam dict lokal, lalu menampilkannya — dan dict lokal akan berakhir dengan panggilan. Jalankan seperti apa adanya dan Vesper akan mendengar Anda dengan sempurna: empat panggilan write_down diaktifkan, masing-masing menjawab "written", dan status sesi tetap kosong, karena tidak ada yang pernah mencapainya. Dia mendengarmu. Tidak ada yang ditulis.
👉✏️ Masih di archive/agent.py, di dalam write_down: hapus # di depan satu baris — # dan spasi setelahnya. Sebelum:
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}}
Setelah:
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}}
Simpan.
Slip diisi
👉💻 Mulai workbench. Ini adalah satu-satunya saat Anda membukanya di lab — ini adalah satu-satunya jendela yang menampilkan status sesi sebagai JSON mentah:
cd ~/agent-valley-archive
uv run adk web . --allow_origins="*"
👉🔬 Buka workbench dengan Web Preview → Preview on port 8000 (tombol Web Preview adalah ikon mata di atas jendela di kanan atas Cloud Shell). Pilih archive, dan sebelum Anda mengetik apa pun, klik State di panel kiri.
👀 Kosong. Belum ada yang mengatakan apa pun.
👉🔬 Sekarang ucapkan ini, semuanya dalam satu pesan:
Hi! My lantern keeps going out at night. My case number is k7f2, and there's a little q7 stamped on the base.
👀 Empat chip write_down diaktifkan — klik salah satunya dan baca JSON: "written": {"no": "k7f2"}. Sekarang klik State lagi.

case {"no": "k7f2", "item": "lantern", "mark": "q7",
"symptom": "keeps going out at night"}
👀 Kosong, lalu penuh, di dalam satu pesan. Itulah yang dia ingat, dan hal itu tidak muncul dengan sendirinya. Anda menulis baris yang menuliskannya. Itulah seluruh mekanisme: fungsi biasa yang menulis ke tool_context.state, dan petunjuk yang menyuruhnya untuk menggunakannya setiap kali pengunjung mengatakan sesuatu yang sesuai dengan baris pada kertas.
👉🔬 Tanyakan padanya:
What's my case number?
👀 k7f2. Dia membacanya dari kertas. Tanpa EDIT ONE, dia akan memintanya dari Anda — baris pertama daftar dukungan, di dalam satu percakapan.
Dua penjaga tersebut adalah slip yang berupa formulir kertas: empat garis pendek, yang masing-masing ditulis satu kali. Mereka lebih penting daripada yang terlihat. Tanpa itu, model menemukan bahwa ia dapat menuangkan seluruh percakapan ke dalam symptom, dan bab 3 — bab yang intinya adalah ketergelinciran tidak memiliki garis untuk itu — diam-diam berhenti menjadi benar. Bentuk toko diterapkan oleh kode yang menuliskannya, atau tidak diterapkan.
Sekarang, pergi ke menara
👉💻 Anda telah selesai menggunakan workbench — biarkan tetap berjalan atau tutup tabnya; bagian lab lainnya ada di Arsip. Buka tab terminal kedua (tab 2 — Arsip):
cd ~/agent-valley-archive
bash valley.sh
👉🖥 Buka Arsip dengan Web Preview → Change port, ketik 3440, lalu klik Change and Preview. 3440 tidak ada dalam daftar cepat Pratinjau Web — 8080 adalah defaultnya — jadi Anda harus menyetelnya secara manual sekali ini. Tekan ▶ Mulai, lalu Arsip. Anda berada di depan pintu. Pilih siapa pun yang datang untuk bertanya — nama dan spesies — lalu masuk.

👀 Satu bangunan. Vesper berada di meja di lantai dasar, dan di sanalah Anda berbicara. Di atasnya: lantai satu, lantai dua, lantai tiga, dan loteng gelap. Empat anak tangga adalah empat lantai. Hewan peliharaan Anda duduk di lantai dasar, karena itulah jarak yang telah Anda daki. Kolom di samping gambar menjelaskan apa yang ada di setiap lantai saat ini — empat toko yang sama seperti tabel di pengantar, dalam urutan yang sama. Tidak ada tombol di sebelah kanan.
👉🖥 Tempelkan empat hal yang sama ke dalam kotak di bawah percakapan — pesan ini persis — lalu tekan Enter:
Hi! My lantern keeps going out at night. My case number is k7f2, and there's a little q7 stamped on the base.

👀 Perhatikan meja. Kertas akan menulis sendiri, satu baris dalam satu waktu — pada gambar, dan sepenuhnya di bawah kertas di sampingnya. Alat yang sama, status yang sama: menara hanya menggambar apa yang ditulis write_down, dan akan terus melakukannya selama sisa lab.
Dia mengingat semalam — hanya baca
Apa yang Anda tulis, dan apa itu
baris | Apa itu | tempatnya berada |
| status sesi — ditulis oleh kode, dibaca oleh petunjuk | meja · |
| penyimpanan sesi — kunjungan dalam file, bukan dalam proses | lantai satu · |
Anak tangga ini mencapai satu kunjungan, dan bertahan hingga waktu tutup. Cookie ini tidak bertahan saat kunjungan berikutnya.
4. Negara Bagian Pengguna
- Apa — kembali sebulan kemudian; selipnya sudah hilang. Lima karakter, dan dia akan mengikuti Anda.
- Mengapa — sesi adalah satu kunjungan. Kunjungan berikutnya adalah sesi baru, dan belum pernah melihat sesi terakhir.
- How — lima karakter dalam
state.py.


👉🖥 Tekan 🗓 sebulan kemudian. Itu adalah sesi baru untuk pengunjung yang sama — seperti cara memulai percakapan baru pada minggu ketiga.
Selamat datang di Arsip. Ada yang bisa saya bantu?
👉🖥 Lihat menara. Lantai satu memiliki buku lain — kunjungan ini. Laci di lantai dua kosong. Kertas di atas meja kosong.

👀 Alasan: slip ditulis ke dalam status sesi, dan sesi adalah kunjungan ini. Mengubah kunjungan, mengubah sesi. Tidak ada yang diteruskan karena tidak ada yang diperintahkan. Kunjungan terakhir masih ada dalam file — yaitu buku pertama lantai satu — tetapi slip ditulis di bawah kunci yang berlaku untuk satu kunjungan.
EDIT DUA
👉✏️ Buka archive/state.py. Temukan 👉. Sebelum:
# 👉 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"
Setelah:
CASE = "user:case"
Simpan. Tidak ada mulai ulang — Archive mengimpor ulang kode Anda di setiap pesan.
👉🖥 Tempelkan lagi empat hal yang sama — pesan ini persis:
Hi! My lantern keeps going out at night. My case number is k7f2, and there's a little q7 stamped on the base.
👉🖥 Kemudian, tekan 🗓 sebulan kemudian lagi — tombol yang sama seperti sebelumnya.

👀 Laci di lantai dua memiliki nama Anda, dan keempat kolom tersebut ada di dalamnya. Kertas di atas meja adalah empat baris yang sama — dikeluarkan dari laci saat Anda masuk. Hewan peliharaan Anda telah pindah ke lantai atas. Kunci yang sama, setiap kunjungan, satu nilai: itulah tugas awalan.
Awalan adalah masa berlaku.
awalan | berapa lama ia hidup | lantai yang mana |
(tidak ada) | kunjungan ini | meja |
| setiap kunjungan yang dilakukan pengunjung ini | lantai dua, laci Anda |
| semua orang, selamanya | bagian dari lantai empat |
| giliran ini saja — bahkan tidak pernah menaiki tangga | — |
Satu meja, empat laci. Bab ini membahas salah satunya.
Dia sekarang mengenal Anda
👉🖥 Kunjungan ini benar-benar baru dan Anda belum mengatakan apa pun di dalamnya. Tanyakan padanya:
What did I bring in last time?
👀 Saya mencatat bahwa Anda membawa lentera, kasus k7f2. Perangkat ini ditandai dengan q7 dan Anda menyebutkan bahwa perangkat ini terus mati pada malam hari. Setiap kata itu keluar dari laci, bukan percakapan — kunjungan ini hanya berisi satu pesan, dan pesan tersebut tidak menyebutkan apa pun. Itulah status tingkat pengguna yang melakukan tugasnya: kunci user: ada sebelum pengunjung mengucapkan sepatah kata pun, pada setiap kunjungan yang mereka lakukan.
Laci berisi empat baris yang ada di slip, dan tidak ada yang lain. Apa yang Anda katakan yang tidak memiliki garis pada slip — apa yang Anda coba, mengapa Anda peduli, apakah Anda menginginkan yang baru — tidak akan ke mana-mana, dan sebulan kemudian hilang. Laci melintasi bulan. Kalimat tidak. Bab 3 membahas hal itu.
Apa yang Anda tulis, dan apa itu
baris | Apa itu | tempatnya berada |
| awalan adalah seumur hidup — kunci yang sama, yang dicakup ke pengunjung, bukan kunjungan | floor dua · |
Anak tangga ini menjangkau satu pengunjung. Panel mengikuti Anda; percakapan tetap tidak.
5. InMemoryMemoryService
- Apa — baca baris yang mencatat hari, tulis baris yang bertanya; lalu satu waktu penutup dan satu pertanyaan.
- Mengapa — slip adalah formulir. Formulir memiliki garis yang Anda berikan. Orang tidak berbicara dalam baris — dan mencatat apa yang mereka katakan hanya setengah dari mengingatnya.
- Bagaimana — baca
file; satu baris direcall; lalu satu 🌙, satu 🗓, satu pertanyaan.

Aktivitasnya dalam perjalanan pulang — hanya baca
File tidak diingat
Baris tersebut menempatkan hari di rak. Tidak ada yang diambil dari sana. Rak yang penuh dengan kartu sama sekali tidak membantu jika tidak ada yang melihatnya — dan saat kode dikirim, tidak ada yang melihatnya: recall, node yang berjalan sebelum Vesper pada setiap pertanyaan, tidak menanyakan apa pun kepada menara. Penyimpanan yang tidak dapat Anda ingat pada saat yang tepat bukanlah memori; itu adalah log. Bagian yang mencari adalah bagian lainnya, dan Anda yang akan menuliskannya.
EDIT TIGA — permintaan
👉📖 Di archive/agent.py, temukan recall — fungsi tepat di atas file. Ini adalah node fungsi biasa yang berjalan sebelum Vesper pada setiap pertanyaan — bukan model yang memutuskan kapan harus mencari, yang berarti waktu saat tidak menemukan apa pun juga terlihat. Baca hingga 👉:
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
👉✏️ Masih di archive/agent.py, di dalam recall: hapus # di depan satu baris — # dan spasi setelahnya. Sebelum:
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:
Setelah:
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:
Biarkan pass di tempatnya — sekarang tidak melakukan apa pun, karena found sudah None di atas.
Simpan. Tidak ada mulai ulang.
Dua baris, dua kebijakan — dan Anda menulis salah satunya. Kebijakan penulisan menentukan apa yang disimpan dan kapan (waktu tutup, sepanjang hari). Kebijakan mengingat menentukan kapan harus melihat dan dengan apa (setiap pertanyaan, pertanyaan itu sendiri). ADK memberi Anda kata kerja — add_events_to_memory, search_memory — dan tidak termasuk dalam kebijakan. Itulah bagian yang tepat, dan itulah alasan mengapa permintaan itu harus Anda tulis.
Jam tutup
👉🖥 Sebutkan tiga hal yang tidak memiliki garis pada slip. Satu atau tiga pesan:
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.

👉🖥 Kemudian, tekan 🌙 cukup sekian untuk hari ini.

👀 Perhatikan meja. Ketiga benda yang Anda sebutkan terlepas dari alas dan melayang ke atas, lalu mendarat di lantai tiga. Di bagian kartu di samping menara, kartu tersebut dicantumkan — satu kartu untuk setiap pesan yang Anda kirim, ditandai quote, kalimat Anda kata demi kata, dan dalam proses ini di atasnya. Lampu di meja akan tetap menyala hingga mereka mendarat.
Sebulan kemudian, dia tahu
👉🖥 Tekan 🗓 sebulan kemudian, lalu tanyakan:
What have I already tried?
👀 Anda mencoba menggantungnya lebih tinggi — tetapi tidak membantu. Dia tahu. Slip tidak memiliki baris untuk itu dan tidak pernah memilikinya, sehingga laci tidak dapat menjawabnya; recall menemukan kartu, menulisnya ke ctx.state["recalled"], dan instruksinya berbunyi demikian. Satu baris adalah perbedaannya.
Dan semuanya ada di benaknya
Lihat di bagian kartu di samping menara: dalam proses ini. Saat ini, memori adalah InMemoryMemoryService — kamus di dalam bash valley.sh, dan akan ada selama proses tersebut berjalan. Tutup menara malam ini dan buka besok: buku ada di lantai satu, laci ada di lantai dua, dan lantai tiga gelap. Kasus ini tetap ada dalam file. Apa yang Anda katakan ada dalam proses, dan prosesnya sudah selesai.
Persistensi bukan memori.
Ada dua hal yang salah dengan lantai tiga saat ini: masih dalam proses, dan menggunakan kata-kata Anda sendiri — kutipan, bukan fakta. Bab berikutnya akan memperbaiki keduanya, tanpa kode sama sekali.
Apa yang Anda baca, apa yang Anda tulis, dan apa itu
baris | Apa itu | tempatnya berada |
| kebijakan penulisan — sepanjang hari, pada waktu tutup | floor three · the memory service |
| kebijakan mengingat — setiap pertanyaan, sebelum dia menjawab |
|
Anak tangga ini mencapai apa yang dikatakan — dan menyimpannya dalam kamus di dalam satu proses, dengan kata-kata Anda sendiri. Kedua bagian tersebut salah, dan bab berikutnya memperbaikinya tanpa kode sama sekali.
6. MemoryBank
- Apa — satu skrip membangun Bank Memori; dua baris yang sudah Anda miliki mulai menulis fakta ke dalamnya dan membacanya kembali.
- Mengapa — layanan memori adalah layanan. Lokasi arsip adalah keputusan deployment, bukan keputusan agen. Anda dapat mengubahnya tanpa memengaruhi agen.
- Bagaimana — jalankan
make_tower.py, ucapkan tiga kalimat, tekan 🌙, tekan 🗓, ajukan satu pertanyaan. Kemudian, lihat penulisan dan pembacaan hanya baca.
Membangun menara
Tingkat tiga di bab 3 adalah kamus Python di dalam bash valley.sh. Memory Bank adalah versi terkelola dari lantai tersebut: berada di instance Agent Engine di project Anda, menyimpan fakta yang disarikan dari hari itu, bukan kalimat Anda, dan menemukannya berdasarkan makna, bukan berdasarkan kata-kata yang sama. Anda tidak perlu men-deploy Vesper ke Agent Engine untuk menggunakannya. Instance yang tidak memiliki apa pun yang di-deploy di dalamnya tetap menghosting Bank Memori, dan itulah yang dibangun skrip: menara tanpa penghuni, yang satu-satunya tugasnya adalah menyimpan kartu.
👉💻 Di tab 1 (sekitar satu menit):
cd ~/agent-valley-archive
uv run python scripts/make_tower.py
👀 Perkiraan:
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...")
Satu panggilan SDK, agent_engines.create(), dan satu baris yang ditulis ke dalam .env. Arsip membaca ulang file tersebut pada setiap permintaan, jadi tidak ada yang perlu dimulai ulang.
Lihat cara kerjanya
👉🖥 Lihat lantai tiga — menara akan digambar ulang dengan sendirinya dalam beberapa detik. Di bagian kartu, kini tertulis Memory Bank, dan galeri kosong: tiga kutipan dari bab 3 sedang dalam proses, dan ini bukan prosesnya. Ucapkan tiga kalimat lagi, satu pesan atau tiga:
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.
👉🖥 Tekan 🌙 itu saja untuk hari ini. Waktu penutupan sekarang sekitar delapan detik — menara sedang mengekstrak. Kemudian, lihat lantai tiga.

👀 Kartu tersebut bukan kalimat Anda. Mereka mengatakan hal-hal seperti Saya menggunakan lentera untuk membaca di malam hari, dan lentera tersebut terus mati dan Saya sudah mencoba menggantung lentera lebih tinggi, yang masing-masing ditandai fact dengan tanggal. Distilasi. Yang masuk adalah percakapan. Yang keluar adalah fakta.
👉🖥 Tekan 🗓 sebulan kemudian — kunjungan baru, jadi tidak ada lagi yang Anda katakan dalam percakapan — dan tanyakan hal ini, pertanyaan yang tidak memiliki satu kata pun dengan kartu:
Should I just get a different lamp?
👀 Karena ini adalah hadiah, Anda menyebutkan bahwa Anda tidak ingin mengganti lentera — dan Anda sudah mencoba menggantungnya lebih tinggi. Setiap kata itu berasal dari kartu, dan hanya kartu yang dapat memberitahunya: kunjungan ini adalah satu pesan lama. Penelusuran kemiripan. Menara mencocokkan makna, bukan kata-kata — pertanyaan mengatakan lampu dan berbeda, kartu mengatakan lentera dan ganti. Dan sekarang sudah keluar dari proses: matikan menara malam ini dan kartu akan tersedia besok, karena kartu tersebut berada di Agent Engine, bukan di bash valley.sh.
Penulisan dan pembacaan — hanya baca
Hak untuk dilupakan

👉🖥 Tekan 🔥 lupakan saya, di bawah kotak pesan.
👀 Tiga lantai menjadi gelap dan satu tidak:
apa yang dipegangnya | setelah 🔥 | |
lantai tiga, kartu | apa yang dia ingat — fakta yang disarikan Memory Bank dari kunjungan Anda | hilang — |
lantai dua, laci |
| dihapus |
meja, slip | salinan kasus kunjungan ini | dihapus |
lantai satu, buku | kunjungan itu sendiri — satu sesi di | tidak berubah — jumlah tidak bergerak |
Buku tersebut adalah catatan: bahwa kunjungan terjadi, pada hari apa, dan apa yang dikatakan di dalamnya. Kartu dan panel adalah kenangan: apa yang dia dapatkan dari kunjungan tersebut dan dibawa ke kunjungan berikutnya. Permintaan untuk dilupakan adalah tentang ingatan — fakta yang diperoleh tentang seseorang, dan status yang mengikutinya. Apakah catatan kunjungan juga dihapus atau tidak adalah keputusan terpisah, yang dibuat karena alasan terpisah — jejak audit, histori dukungan — dan lab ini sengaja mempertahankannya, sehingga Anda dapat melihat keduanya terpisah di depan Anda: catatan dan memori bukanlah hal yang sama, dan melupakan salah satunya tidak memengaruhi yang lain. Itulah kalimat di atas pintu Vesper, yang terlihat dari sisi lain.
Abstraksi memori ADK memiliki add_events_to_memory dan search_memory. Tidak ada opsi hapus. Proses melupakan adalah tindakan tata kelola, bukan tindakan agen, sehingga berada di aplikasi — archive/tower.py, memories.delete di klien mentah — tempat model tidak dapat menjangkaunya secara tidak sengaja. Apakah agen dapat melupakan sesuatu adalah sesuatu yang Anda desain, sama seperti apakah agen dapat mengingat sesuatu.
Yang Anda bangun dan baca, serta apa itu
hal | Apa itu | tempatnya berada |
| layanan memori, sebagai layanan: keputusan deployment, di luar agen | Vertex AI Memory Bank di Agent Engine |
| slot |
|
| apa yang dapat dipertahankan, diputuskan pada saat penulisan, bukan dalam perintah |
|
🔥 → | melupakan adalah tindakan aplikasi; API memori ADK tidak memiliki penghapusan |
|
Anak tangga ini mencapai apa yang dikatakan. Satu hari berlalu; satu fakta muncul — yang disarikan dari apa yang diizinkan oleh topik — dan buku di lantai satu tidak pernah berpindah.
7. GraphRAG
Opsional.
- Apa — satu skrip memuat masa lalu lembah ke BigQuery, membuat embedding di dalam gudang dan menempatkan grafik di atas tabel tanpa memindahkan baris; lalu dua pertanyaan untuk Vesper, yang memiliki dua kueri yang diatur untuknya: satu untuk apa yang terdengar serupa, satu untuk apa yang terhubung.
- Mengapa — terdengar sama tidak sama dengan terhubung. Vektor menemukan tempat untuk mencari; grafik menemukan apa yang terlampir; dan jawaban harus membawa jalur yang dilaluinya.
- Bagaimana —
bash scripts/season.sh, sekali. Semua hal lainnya dalam bab ini bersifat hanya baca.
Menara Vesper dicakup untuk Anda — (app_name, user_id) — berdasarkan konstruksi. Kunjungan orang lain bukanlah ingatannya, dan mencarinya lebih keras tidak akan mengubah hal itu. Mereka adalah milik lembah, dan lembah menyimpannya di gudang. Tiga puluh satu pengunjung musim ini datang karena lentera q7 padam di malam hari, dan salah satu dari mereka menemukan penyebabnya. Bab ini memuat gudang tersebut dan memberikan dua kueri tetap ke dalamnya.
Graph RAG
RAG adalah ambil, lalu buat: temukan data yang tepat, berikan kepada model, biarkan model menjawab dari data tersebut. RAG biasa mengambil berdasarkan kemiripan — sematkan pertanyaan, tarik catatan terdekat. Hal ini menemukan hal-hal yang terdengar seperti pertanyaan, dan di sinilah menara di chapter 4 berhenti. Graph RAG menambahkan langkah pengambilan kedua yang mengikuti tepi — kunci, yang sudah dimiliki gudang — dari kesamaan apa pun yang ditemukan, hingga apa pun yang terlampir padanya. Kedua langkah tersebut menjawab pertanyaan yang berbeda, dan bab ini membuat Anda mengajukan keduanya:
langkah | pertanyaan yang dijawabnya | cara | dalam bab ini |
kemiripan | di mana saya harus mencarinya? | menyematkan pertanyaan, |
|
traversal | apa yang terhubung ke sana? |
|
|
pembuatan | Apa yang harus saya katakan kepada tamu? | model, dengan jalur sebagai kutipannya | jawabannya |
Menjalankan aplikasi
Musim dikirimkan sebagai CSV biasa di season/ — pengunjung, item, permintaan, perbaikan, musim — seperti yang diekspor oleh sistem dukungan. Satu skrip akan membawanya ke gudang, dan hanya skrip itu yang Anda jalankan di bab ini.
👉💻 Di tab 1 (sekitar tiga menit; mencetak setiap langkah saat berjalan, dan berhenti pada langkah pertama yang gagal):
cd ~/agent-valley-archive
bash scripts/season.sh
👀 Saat berakhir, lantai empat di menara akan menyala, dan legenda di sampingnya bertuliskan buka.
Yang dibangunnya — hanya baca
Cara dia membacanya — hanya baca
Tanyakan padanya
👉🖥 Tingkat empat sudah dibuka di menara. Tanyakan arah jalan kepadanya seperti yang dilakukan pengunjung lainnya:
Has anyone else had a q7 lantern go out at night?

👀 Dia menjawab — tiga puluh satu orang lainnya... sebagian besar mengatakan bahwa api menyala rendah dan padam setelah satu jam... Berang-berang Marlow menemukan bahwa sumbu dicelupkan terlalu dangkal — dan baris terakhir jawabannya adalah jalur. Berikut outputnya — baca, jangan kirimkan kembali kepadanya:
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
Jalur adalah kutipan. Setiap lompatan di dalamnya adalah tepi dalam grafik, dan tepi adalah kunci, sehingga siapa pun dapat melaluinya lagi dan mendapatkan tiga puluh satu yang sama. Skor kemiripan tidak dapat diakses lagi oleh siapa pun. Jika dia mengatakan, tepat sebelum jalur, bahwa baris kembali melalui tiga gabungan karena project tidak memiliki reservasi grafik, maka edisi project Anda menolak GRAPH_TABLE — baris dan jalur sama.
👉🖥 Sekarang hapus tanda tersebut — kirim ini:
Has anyone else had a lantern that keeps dying once the sun is down?
👀 Dia mencapai angka tiga puluh satu yang sama, dan jalur yang sama. Yang berubah adalah jalannya: season_search berjalan lebih dulu, menemukan lima pengunjung yang terdengar serupa — masing-masing membawa q7 — mengambil tanda itu, dan baru kemudian berjalan. Serupa tidak terhubung; serupa adalah tempat untuk mencari.
Apa yang dimuat, dan apa itu
hal | Apa itu | tempatnya berada |
| gudang: kolom dengan nama dan jenis |
|
| langkah kesamaan — tempat mencari |
|
| langkah penelusuran — apa yang terhubung; tabel menjadi node dan panah |
|
| satu-satunya jalan yang mungkin ia lalui; jalur tersebut adalah kutipan |
|
Beberapa lusin pengunjung bukanlah alasan untuk membeli gudang. Yang diajarkan dalam bab ini adalah bentuk kueri — bukan skala. Perbesar grafik ini seribu kali dan MATCH tidak akan berubah satu karakter pun.
8. Tutup
Tiga jalur, satu menara, satu gudang — empat lantai. Tidak ada yang dimulai ulang.
anak tangga | apa yang Anda lakukan | apa yang dibeli |
ONE |
| kesalahan yang ada: status ditulis oleh kode |
DUA |
| laci yang mengikuti pengunjung |
pengarsipan |
| apa yang dikatakan, disimpan |
TIGA |
| apa yang disimpan, diminta — yang diajukan tidak diingat |
menara |
| menara yang menyuling, dan bertahan di malam hari |
aturan |
| hanya yang harus disimpan |
musim |
| kunjungan orang lain, berdasarkan makna dan koneksi |
Bagian yang diganti
ADK 2 | apa yang akan Anda tulis sebagai gantinya | biayanya |
| dict di samping loop chat, di-pickle ke disk sendiri | model tidak dapat membacanya, dan Anda menulis resume dan penguncian |
imbuhan | tabel pengguna dan gabungan di setiap giliran | memutuskan tempat kunci berada, setiap saat |
| cron yang membuang transkrip, dan model yang memutuskan kapan harus melihat | tidak ada yang diekstrak, tidak ada yang disuling — dan Anda tidak pernah melihat saat tidak terlihat |
| penyimpanan vektor, perintah ekstraksi, tugas penggabungan, dan "jangan ingat trivia" dalam perintah | tiga layanan, dan aturan ini berlaku hingga model merasa sebaliknya |
| mengekspor, menyematkan di tempat lain, database grafik, tugas sinkronisasi, dan penulisan SQL model | data keluar dari gudang untuk dipahami, dan Anda mengetahui gabungan mana yang ditebak saat pelanggan melakukannya |
Tiga pertanyaan, berhenti di jawaban ya pertama
- Apakah hal ini akan penting besok? Tidak → jangan simpan apa pun. Hal ini muncul dan hilang dalam percakapan.
- Dapatkah fungsi memeriksanya? Ya → laci. Kode menuliskannya, setiap giliran membacanya, dan tidak ada kalimat yang dapat mengubahnya.
- Selain itu → menara. Disarikan dari apa yang dikatakan, dicari saat diminta, direvisi oleh apa yang dikatakan selanjutnya.
Satu kalimat
Rekaman bukanlah ingatan. Memori adalah catatan ditambah dua keputusan — apa yang harus disimpan, dan kapan harus dicari — dan jenis memori menentukan lantai mana yang akan dituju.
Fakta dan preferensi berada di toko yang berbeda.
👀 Setiap lantai diterangi. Hewan peliharaan Anda berada di bagian atas. Stempel Arsip ada di paspor, dan minggu kelima membuka Pasar Malam — tempat Nix menjalankan panggung secara lisan, secara real time, dan semua yang diketahui menara akan menyertai Anda.