1. Introducción

En la primera semana, se preguntó quién dice qué se publica. En la segunda semana, se preguntó quién decide qué se ejecutará a continuación. La tercera semana se preguntó qué deja atrás una carrera. Esta semana, la conversación termina, y la pregunta es qué sobrevive a ella. Resulta que qué tipo de cosa es decide a dónde va.
El Archivo es el lugar al que se recurre cuando algo salió mal. Una torre en la que se escribe todo y Vesper, el archivista, en el escritorio de la planta baja. La linterna se apaga por la noche. Ve y pregunta.
Es buena compañía. Un mes después, también se alegra de conocerte.
Un registro no es un recuerdo.
Esa oración es todo el lab. Subirás en cuatro tramos, y cada tramo es un piso de la torre:
peldaño | el piso | lo que recuerda | lo que la mantiene |
1 | el escritorio y el piso uno | esta visita |
|
2 | piso dos, tu cajón | este visitante | El prefijo |
3 | piso tres, la torre | lo que se dijo | Memory Bank de Vertex AI |
4 | piso cuatro, la temporada | todo el valle | BigQuery |
Cada peldaño que subes es porque algo se cayó del anterior.

Ya conoces las cinco formas de olvido del archivista, porque todas te sucedieron en una llamada de asistencia:
lo que dice | Qué salió mal | |
~~1~~ | ~~¿Podrías darme esa referencia de nuevo?~~ | ~~Se olvidó en una conversación~~: Se corrigió en la tercera semana |
~~2~~ | ~~Te transferí. Comienza desde el principio.~~ | ~~El historial se perdió con el proceso~~: La tercera semana también se corrigió este problema |
3 | ¡Te damos la bienvenida! ¿En qué puedo ayudarte? | a alguien con un caso abierto del mes pasado |
4 | ¿Podrías describir el daño? | ella miró la linterna la última vez |
5 | Nunca habíamos visto algo así. | treinta y una personas hicieron preguntas esta temporada |
La línea tres es la de esta semana. Falla de tres maneras diferentes: una visita nueva (capítulo 2), una oración sin línea en el papel (capítulo 3) y un archivo que solo existe dentro del proceso (capítulo 4), y cada manera es un capítulo. La cuarta línea es para ti: look() en archive/agent.py es donde lee una marca en una foto. La línea cinco es el capítulo 5 y es opcional.
No necesitas las semanas uno a tres. Un agente es un modelo con una instrucción y algunas herramientas. Todo lo demás se explica por sí solo esta semana.
Escribirás tres líneas, y cada una de ellas es un concepto de memoria:
la línea | Qué es |
| El estado se escribe con código, nunca con la conversación. |
| un prefijo es un tiempo de vida |
| No se recuerda la política de retiro: se presentó |
Ya hay una línea más para que leas: la política de escritura, await ctx.add_events_to_memory(...). En el capítulo 3, leerás lo que hace antes de escribir la línea que la usa.
Los otros dos peldaños no son ediciones en absoluto: construyes una torre (un Agent Engine que aloja Memory Bank) y el mismo código se conecta a ella por sí solo, y cargas un almacén (BigQuery), colocas un gráfico sobre él y le entregas al mismo agente dos consultas controladas: una por significado y otra por conexión.
Cada capítulo ejecuta el mismo bucle, y es el bucle que usarás en tus propios agentes: leer el código → escribir la línea → verla en la torre. Nada se ejecuta de forma incorrecta primero, nada se reinicia y nada se cancela con Ctrl+C: cada edición se toma en cuenta en el siguiente mensaje, y conectar la torre es una línea en un archivo que Archive vuelve a leer en cada solicitud. La torre es un dibujo que se vuelve a dibujar: lee los mismos archivos que editas y tiene tres botones: 🌙 termina el día, 🗓 comienza la próxima visita y 🔥 te olvida. Todo lo demás lo haces en el código y la terminal.
Dos lugares, y nunca cambian de trabajo: la pestaña 1 es la terminal y la pestaña 2 es el archivo. El banco de trabajo (adk web) aparece exactamente una vez, en el capítulo 1, para observar el estado de la sesión sin procesar, y luego ya no lo necesitas. Cada 👉 a continuación indica cuál. 👉💻 es la pestaña 1, 👉🖥 es la pestaña 2 y 👉🔬 es el banco de trabajo. 👉📖 es abrir un archivo y leerlo (no hay nada que cambiar), y 👉✏️ es el tipo de paso que edita. Siempre que un paso te indique que le digas algo a Vesper, el mensaje exacto se encuentra en el bloque que está justo debajo. Cópialo tal como está. Además, en una sección cuyo encabezado termina en — solo lectura, no tienes que escribir, pegar ni hacer clic en nada: el código ya está en el repo y ya se está ejecutando, y se imprimió para que lo leas.
La oración sobre la puerta de Vesper es la que está en la parte superior. La oración con la que termina esta semana es la última de la cuarta semana de toda la temporada:
Los hechos y las preferencias pertenecen a diferentes tiendas.
2. 🧰 Configuración
- Qué: Apunta a un proyecto o pega una clave, instala y demuestra que la cadena de herramientas funciona correctamente.
- Por qué: No se inicia nada aquí. Cada servidor se inicia justo antes del paso que lo necesita, por lo que, cuando se abre una pantalla, sabes qué comando la posee.
- Cómo: Una secuencia de comandos que crea el proyecto, otra que instala y te dirige a Vertex AI, y una verificación previa que lee tu código y te indica dónde estás.
Todo en este lab se ejecuta en Cloud Shell. Python, uv y gcloud ya están instalados allí, y se puede acceder a Gemini a través de Vertex AI con tus propias credenciales. En este lab, no hay ninguna clave de API ni nada que instalar en tu laptop.
Hay algo que este lab no puede proporcionarte: un proyecto de Google Cloud con la facturación habilitada. El paso 1 te permite obtener una cuenta que puede pagar por el proyecto, y el paso 4 convierte esa cuenta en un proyecto o retoma el proyecto de Agent Valley que ya creaste en la primera, segunda o tercera semana. Realízalos en ese orden. Cada paso después del 4 lee el proyecto en el que se establece el paso 4.
1 · Obtén una cuenta con facturación (aprox. 1 min)
🌐 Haz esto antes que cualquier otra cosa. Accede con una Cuenta de Google que tenga habilitada la facturación. Cualquier cuenta de este tipo funciona. Si no tienes una, comienza una prueba gratuita, que te proporcionará una cuenta de facturación, que es todo lo que se necesita para el paso 4.
2 · Abre Cloud Shell (1 min)
🌐 Haz clic en Activar Cloud Shell en la parte superior de la consola de Google Cloud. Es el ícono con forma de terminal en el encabezado.

🌐 Haz clic en Abrir editor (el ícono de carpeta abierta con un lápiz). Se abrirá el editor de Cloud Shell con un explorador de archivos a la izquierda, que es donde trabajarás cada vez que un paso esté marcado con 👉✏️.

🌐 Si se te solicita autorización en algún momento, haz clic en Autorizar para continuar.
🌐 Abre una terminal dentro del editor, es decir, la pestaña 1, y cada paso 👉💻 se ejecuta allí, a menos que se indique lo contrario. La pestaña 2 es el archivo, y la abres en el capítulo 1, justo antes del paso que la necesita. Si la terminal aún no está en la parte inferior de la pantalla, ábrela con Ver → Terminal:

🌐 Verifica con qué cuenta accediste. Debe ser la misma que usaste en el paso 1:
gcloud auth list
3 · Obtén el lab (alrededor de 1 min)
💻 Clona el repo. Este es el repo de Archive, no el de la semana uno, dos o tres:
cd ~
git clone https://github.com/cuppibla/agent-valley-archive
cd agent-valley-archive
4 · Crea tu proyecto o reutiliza el de una semana anterior (2 min aprox.)
💻 Un script encuentra tu cuenta de facturación, crea un proyecto en ella y dirige Cloud Shell a ese proyecto. Si hiciste la semana uno, la semana dos o la semana tres, primero se encuentra ese proyecto de Agent Valley y se ofrece reutilizarlo. Di que sí y no habrá un segundo proyecto facturable en el que pensar:
cd ~/agent-valley-archive
./setup_project.sh
👀 Espera un ✓ para la cuenta de facturación que eligió, un ✓ para el proyecto que creó o reutilizó, y un final como el siguiente:
cd ~/agent-valley-archive
Project ready: agent-valley-4271
Next: ./setup_codelab.sh
agent-valley-4271 es el ID de tu proyecto. El tuyo tendrá dígitos diferentes. Allí suceden cuatro cosas:
facturación | Toma la cuenta de | |
project | Busca un proyecto de Agent Valley que ya tengas (de la semana uno, dos o tres) y ofrece reutilizarlo. De lo contrario, crea | |
selecciona | Escribe el ID en | |
waits | realiza sondeos hasta que se permite que el proyecto publique anuncios, durante un máximo de dos minutos | |
🌐 El mismo proyecto ahora está en la consola. Su ID se encuentra en la tarjeta Información del proyecto del panel:

5 · Instala y apunta a Vertex AI (alrededor de 3 min)
💻 Instala uv, exporta las tres variables que envían el ADK a Vertex AI y ejecuta la configuración:
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) tiene algo que devolver porque el paso 4 lo configuró. Esa es la razón por la que el paso 4 es el primero.
setup_codelab.sh es idempotente, por lo que se puede volver a ejecutar una cantidad ilimitada de veces. Realiza cinco acciones, en orden:
api | Lee el paso 4 del proyecto seleccionado y habilita | |
uv env |
| |
site | Ejecuta | |
.env | Escribe las variables que lee el lab: | |
Verificación del modelo | Realiza una llamada real a Gemini, por lo que un proyecto incorrecto falla aquí en el momento de la configuración, no más adelante dentro de un capítulo. | |
6 · Demuestra que es verde (aprox. 1 min)
💻 Ejecuta la prueba previa al vuelo: Cada marca es una sonda real, no una suposición:
cd ~/agent-valley-archive
uv run python scripts/preflight.py
👀 La verificación previa le hace al modelo una pregunta para demostrar que tus credenciales funcionan, comprueba que los paquetes del archivo estén en su lugar, luego lee tu código y, por último, imprime la barra de progreso de esta semana:
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
Tres ya están marcadas. Esas son las que solo lees. Tres son líneas que escribes; una es una torre que construyes. Vuelve a ejecutar la verificación previa en cualquier momento del lab y te indicará dónde te encuentras, ya que lee tus archivos, no una lista de tareas.
3. Sesión, estado, SqliteSessionService
- Qué: Escribe una línea, inicia el banco de trabajo una vez y observa cómo se llena el deslizador; luego, haz lo mismo en la torre y, después, lee por qué sobrevive a la noche.
- Por qué: Lo primero que se debe saber sobre la memoria es que nada se recuerda por sí solo. Alguien la escribe.
- Cómo: Una línea en
agent.pyy no cambiar nada más.
EDIT ONE
👉📖 Abre archive/agent.py y busca write_down. Lee hasta el 👉:
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}}
La función compila el recibo en un diccionario local y, luego, lo devuelve. Un diccionario local muere con la llamada. Ejecuta este código tal como está y Vesper te escuchará perfectamente: se activan cuatro llamadas write_down, cada una responde "written" y el estado de la sesión permanece vacío, porque nunca llegó nada a él. Ella te escuchó. No se escribió nada.
👉✏️ Aún en archive/agent.py, dentro de write_down, borra el # que está delante de una línea, el # y el espacio que le sigue. Antes:
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}}
Después:
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}}
Guardar.
El recibo se completa.
👉💻 Inicia Workbench. Esta es la única vez que abrirás la ventana en el lab. Es la única ventana que muestra el estado de la sesión como el JSON sin procesar que es:
cd ~/agent-valley-archive
uv run adk web . --allow_origins="*"
👉🔬 Abre el banco de trabajo con Vista previa en la Web → Vista previa en el puerto 8000 (el botón Vista previa en la Web es el ícono de ojo sobre una ventana que se encuentra en la parte superior derecha de Cloud Shell). Elige archive y, antes de escribir algo, haz clic en State en el panel de la izquierda.
👀 Vacío. Nadie ha dicho nada todavía.
👉🔬 Ahora di lo siguiente en un solo mensaje:
Hi! My lantern keeps going out at night. My case number is k7f2, and there's a little q7 stamped on the base.
👀 Se activan cuatro chips de write_down. Haz clic en uno y lee el JSON: "written": {"no": "k7f2"}. Ahora, vuelve a hacer clic en Estado.

case {"no": "k7f2", "item": "lantern", "mark": "q7",
"symptom": "keeps going out at night"}
👀 Vacío y, luego, lleno, todo en un mismo mensaje. Eso es lo que recuerda, y no apareció por sí solo. Escribiste la línea que lo escribe. Ese es todo el mecanismo: una función simple que escribe en tool_context.state y una instrucción que le indica que la use cada vez que el visitante diga algo que quepa en una línea del recibo.
👉🔬 Pregúntale lo siguiente:
What's my case number?
👀 k7f2. Ella lo lee en el papel. Sin EDIT ONE, te lo habría pedido: la primera línea de la lista de asistencia, dentro de una conversación.
Los dos resguardos son el deslizamiento, que es un formulario en papel: cuatro líneas cortas, cada una escrita una vez. Son más importantes de lo que parecen. Sin ellos, el modelo descubre que puede volcar toda la conversación en symptom, y el capítulo 3, cuyo objetivo es el deslizamiento no tiene una línea para eso, deja de ser cierto en silencio. La forma de un comercio se aplica por el código que la escribe o no se aplica.
Ahora ve a la torre
👉💻 Terminaste con el banco de trabajo. Puedes dejarlo en ejecución o cerrar su pestaña. El resto del lab se encuentra en el archivo. Abre una segunda pestaña de la terminal (pestaña 2: Archive):
cd ~/agent-valley-archive
bash valley.sh
👉🖥 Abre el archivo con Vista previa en la Web → Cambiar puerto, escribe 3440 y haz clic en Cambiar y obtener vista previa. El puerto 3440 no está en la lista rápida de la vista previa web (8080 es el predeterminado), por lo que tendrás que configurarlo manualmente esta vez. Presiona ▶ Iniciar y, luego, El archivo. Estás en la puerta. Elige a quien haya venido a preguntar (un nombre y una especie) y entra.

👀 Un edificio. Vesper está en el escritorio de la planta baja, y ahí es donde hablas. Sobre ella: el primer, segundo y tercer piso, y un ático oscuro. Los cuatro peldaños son los cuatro pisos. Tu familiar está en la planta baja, ya que es lo más lejos que has subido. La columna junto al dibujo explica lo que contiene cada piso en este momento: las mismas cuatro tiendas que se muestran en la tabla de la introducción, en el mismo orden. Nada a la derecha es un botón.
👉🖥 Pega las mismas cuatro cosas en el cuadro debajo de la conversación (este mensaje exacto) y presiona Intro:
Hi! My lantern keeps going out at night. My case number is k7f2, and there's a little q7 stamped on the base.

👀 Observa el escritorio. El papel se escribe solo, una línea a la vez, en el dibujo y completo debajo de el papel que está junto a él. La misma herramienta, el mismo estado: La torre solo dibuja lo que escribió write_down, y seguirá haciéndolo durante el resto del lab.
Ella recuerda durante la noche (solo lectura)
Lo que escribiste y lo que es
la línea | Qué es | dónde se encuentra |
| Estado de la sesión: Lo escribe el código y lo lee la instrucción. | el escritorio · |
| El almacén de sesiones: una visita en un archivo, no en un proceso | piso uno · |
Este peldaño alcanza una visita y sobrevive a la hora de cierre. No sobrevive a la siguiente visita.
4. Estado del usuario
- Qué: Vuelve un mes después y el resbalón ya no está. Cinco caracteres y te sigue.
- Por qué: Una sesión es una visita. La próxima visita es una sesión nueva y nunca vio la anterior.
- Cómo: Cinco caracteres en
state.py.


👉🖥 Presiona 🗓 un mes después. Esa es una nueva sesión para el mismo visitante, de la misma manera que iniciar una nueva conversación lo fue en la tercera semana.
Te damos la bienvenida al Archivo. ¿En qué puedo ayudarte?
👉🖥 Mira la torre. En el piso uno, hay otro libro, esta visita. El cajón del segundo piso está vacío. El papel sobre el escritorio está en blanco.

👀 Por qué: El deslizamiento se escribe en el estado de la sesión, y una sesión es esta visita. Cambiar visitas y cambiar sesiones No se transfirió nada porque no se indicó que se hiciera. La última visita aún está en el archivo (es decir, el primer libro del piso), pero el recibo se escribió con una clave que dura una visita.
EDITAR DOS
👉✏️ Abre archive/state.py. Busca el emoji de dedo índice hacia la derecha 👉. Antes:
# 👉 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"
Después:
CASE = "user:case"
Guardar. Sin reinicio: Archive vuelve a importar tu código en cada mensaje.
👉🖥 Vuelve a pegar las mismas cuatro cosas, este mensaje exacto:
Hi! My lantern keeps going out at night. My case number is k7f2, and there's a little q7 stamped on the base.
👉🖥 Luego, vuelve a presionar 🗓 un mes después, el mismo botón que antes.

👀 El cajón del segundo piso tiene tu nombre, y los cuatro campos están adentro. El papel sobre el escritorio tiene las mismas cuatro líneas, lo sacó del cajón cuando usted entró. Tu familiar subió un piso. La misma clave, cada visita, un valor: ese es el prefijo haciendo su trabajo.
El prefijo es de por vida.
prefijo | cuánto tiempo dura | en qué piso |
(ninguno) | esta visita | el escritorio |
| Cada visita que realiza este visitante | piso dos, tu cajón |
| para todos, para siempre | parte del piso cuatro |
| Solo en este turno, ni siquiera sube las escaleras | — |
Una mesa, cuatro cajones. En este capítulo, se aborda uno de ellos.
Ella te conoce ahora
👉🖥 Esta visita es nueva y aún no has dicho nada en ella. Pregúntale lo siguiente:
What did I bring in last time?
👀 Tengo anotado que trajiste una linterna, caso k7f2. Está marcado con q7 y mencionaste que se apaga por la noche. Cada palabra que salió del cajón, no de la conversación, esta visita tiene un mensaje de antigüedad, y el mensaje no nombró nada. Ese es el estado a nivel del usuario haciendo su trabajo: una clave user: está allí antes de que el visitante diga una palabra, en cada visita que realiza.
El cajón sostiene las cuatro líneas que tiene el deslizador y nada más. Lo que dices que no tiene línea en el recibo (lo que intentaste, por qué te importa, si quieres uno nuevo) no tiene a dónde ir, y un mes después desaparece. El panel lateral cruza el mes. Una oración no lo hace. El capítulo 3 trata sobre eso.
Lo que escribiste y lo que es
la línea | Qué es | dónde se encuentra |
| Un prefijo es un tiempo de vida útil: la misma clave, pero con alcance para el visitante en lugar de la visita. | piso dos · estado |
Este peldaño llega a un visitante. El cajón te sigue, pero la conversación no.
5. InMemoryMemoryService
- Qué: Lee la línea que archiva el día, escribe la línea que pregunta y, luego, una hora de cierre y una pregunta.
- Por qué: El resbalón es una forma. Un formulario tiene las líneas que le proporcionaste. Las personas no hablan en líneas, y registrar lo que dijeron es solo la mitad de recordarlo.
- Cómo: Lee
file, una línea enrecally, luego, una 🌙, una 🗓 y una pregunta.

Lo que hace durante el trayecto a casa (solo lectura)
No se recuerda el campo.
Esa línea deja el día en suspenso. No le quita nada. Un estante lleno de tarjetas ayuda tanto como uno vacío si nadie lo mira, y, a medida que se envía el código, nadie lo mira: recall, el nodo que se ejecuta antes de Vesper en cada pregunta, no le pregunta nada a la torre. El almacenamiento que no puedes recordar en el momento adecuado no es memoria, sino un registro. La otra mitad es la observación, y te corresponde escribirla.
EDIT THREE: La pregunta
👉📖 En archive/agent.py, busca recall, la función que está justo encima de file. Es un nodo de función simple que se ejecuta antes de Vesper en cada pregunta, no el modelo que decide cuándo buscar, lo que significa que también se ven los momentos en los que no encuentra nada. Lee hasta el 👉:
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
👉✏️ Aún en archive/agent.py, dentro de recall, borra el # que está delante de una línea, el # y el espacio que le sigue. Antes:
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:
Después:
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:
Deja el pass donde está. Ahora no hace nada, porque found ya es None arriba.
Guardar. No se reinicia.
Dos líneas, dos políticas, y tú escribiste una de ellas. La política de escritura decide qué se conserva y cuándo (hora de cierre, todo el día). La política de recuperación decide cuándo buscar y con qué (cada pregunta, la pregunta en sí). El ADK te proporciona los verbos (add_events_to_memory, search_memory) y no se involucra en la política. Esa es la división correcta, y es por eso que la pregunta era tuya.
Horario de cierre
👉🖥 Menciona tres cosas para las que el recibo no tiene una línea. Un mensaje o tres:
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.

👉🖥 Luego, presiona 🌙 Eso es todo por hoy.

👀 Observa el escritorio. Las tres cosas que dijiste se desprenden del resbalón y flotan hacia arriba, y aterrizan en el piso tres. Debajo de las tarjetas junto a la torre, se enumeran una tarjeta para cada mensaje que enviaste, marcada con quote, tus oraciones palabra por palabra y en este proceso arriba de ellas. La lámpara del escritorio permanece encendida hasta que aterriza.
Un mes después, sabe
👉🖥 Presiona 🗓 un mes después y pregunta lo siguiente:
What have I already tried?
👀 Intentaste colgarlo más alto, pero no funcionó. Ella lo sabe. El recibo no tiene una línea para eso y nunca la tuvo, por lo que el cajero no pudo responder esto; recall encontró la tarjeta, la escribió en ctx.state["recalled"] y su instrucción dice eso. Una línea es la diferencia.
Y todo está en su cabeza.
Mira debajo de las tarjetas junto a la torre: en este proceso. Actualmente, la memoria es InMemoryMemoryService, un diccionario dentro de bash valley.sh, y existe exactamente durante el tiempo que dura ese proceso. Cierra la torre esta noche y ábrela mañana: los libros están en el piso uno, el cajón está en el piso dos y el piso tres está oscuro. El caso se conservó en el archivo. Lo que dijiste quedó en el proceso, y el proceso ya no está.
La persistencia no es memoria.
Hay dos cosas incorrectas en el piso tres tal como está: está en proceso y está en tus propias palabras, una cita, no un hecho. En el próximo capítulo, se solucionarán ambos problemas sin escribir código.
Lo que lees, lo que escribes y lo que es
la línea | Qué es | dónde se encuentra |
| la política de escritura: un día completo, a la hora de cierre | piso tres · el servicio de memoria |
| la política de recuperación: cada pregunta, antes de responder |
|
Este peldaño alcanza lo que se dijo y lo mantiene en un diccionario dentro de un proceso, en tus propias palabras. Ambas partes de esa afirmación son incorrectas, y el siguiente capítulo las corrige sin usar código.
6. MemoryBank
- Qué: Un script compila un Memory Bank. Las dos líneas que ya tienes comienzan a escribir hechos en él y a leerlos.
- Por qué: Un servicio de memoria es un servicio. La ubicación del archivo es una decisión de implementación, no del agente. Puedes cambiarla sin modificar el agente.
- Cómo: Ejecuta
make_tower.py, di tres oraciones, presiona 🌙, presiona 🗓 y haz una pregunta. Luego, una vista de solo lectura de la escritura y la lectura.
Construye la torre
El piso tres del capítulo 3 era un diccionario de Python dentro de bash valley.sh. Memory Bank es la versión administrada de ese piso: reside en una instancia de Agent Engine en tu proyecto, conserva hechos destilados del día en lugar de tus oraciones y los encuentra por significado en lugar de por palabras compartidas. No es necesario que implementes Vesper en un Agent Engine para usarlo. Una instancia sin nada implementado en ella aún aloja un Memory Bank, y eso es lo que compila la secuencia de comandos: una torre sin nadie que viva en ella, cuyo único trabajo es guardar las tarjetas.
👉💻 En la pestaña 1 (aproximadamente un minuto):
cd ~/agent-valley-archive
uv run python scripts/make_tower.py
👀 Qué esperar:
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...")
Una llamada al SDK, agent_engines.create(), y una línea escrita en .env. Archive vuelve a leer ese archivo en cada solicitud, por lo que no es necesario reiniciar nada.
Observe cómo funciona
👉🖥 Mira el piso tres: La torre se vuelve a dibujar por sí sola en unos segundos. En las tarjetas, ahora se indica Memory Bank, y la biblioteca está vacía: las tres citas del capítulo 3 estaban en el proceso, y este no es el proceso. Vuelve a decir las tres oraciones, ya sea en un solo mensaje o en tres:
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.
👉🖥 Presiona 🌙 Eso es todo por hoy. El tiempo de cierre ahora es de unos ocho segundos, ya que la torre se está retirando. Luego, mira el piso tres.

👀 Las tarjetas no son tus oraciones. Dicen cosas como Uso mi linterna para leer de noche, que es cuando se apaga y Ya intenté colgar mi linterna más alto, cada una marcada fact con una fecha. Destilación. Lo que se ingresó fue una conversación. Lo que surgió fueron hechos.
👉🖥 Presiona 🗓 un mes después (una nueva visita, por lo que nada de lo que acabas de decir está en la conversación) y pregúntale esto, una pregunta que no comparte ni una palabra con las tarjetas:
Should I just get a different lamp?
👀 Como fue un regalo, mencionaste que no quieres reemplazar la linterna y que ya intentaste colgarla más alto. Cada palabra de esa frase provenía de la tarjeta, y solo la tarjeta podría haberle dicho: esta visita tiene un mensaje de antigüedad. Búsqueda de similitud: La torre coincide en significado, no en palabras: la pregunta decía lámpara y diferente, y la tarjeta dice linterna y reemplazar. Y ya no forma parte del proceso: cierra la torre esta noche y las tarjetas estarán allí mañana, porque residen en Agent Engine, no en bash valley.sh.
La escritura y la lectura (solo lectura)
El derecho al olvido

👉🖥 Presiona 🔥 Olvídame, debajo del cuadro de mensaje.
👀 Tres pisos se oscurecen y uno no:
lo que contiene | después de 🔥 | |
piso tres, las tarjetas | lo que recordó: los hechos que Memory Bank extrajo de tus visitas | Desapareció: |
piso dos, el cajón |
| borrado |
el escritorio, el recibo | copia de este caso de la visita | borrado |
piso uno, los libros | las visitas en sí mismas: una sesión en | Sin cambios: El recuento no se modifica. |
Los libros son el registro de que se produjo una visita, en qué día y qué se dijo en ella. Las tarjetas y el panel lateral son la memoria: lo que aprendió de esas visitas y lo que lleva a la siguiente. Una solicitud de olvido se relaciona con la memoria, es decir, los hechos derivados sobre una persona y el estado que la acompaña. Si el registro de una visita también se va es una decisión independiente, que se toma por motivos separados (un registro de auditoría, un historial de asistencia), y este lab lo mantiene a propósito, para que puedas ver cómo se separan ante ti: el registro y la memoria no son lo mismo, y olvidar uno no afecta al otro. Esa es la frase sobre la puerta de Vesper, vista desde el otro lado.
La abstracción de memoria del ADK tiene add_events_to_memory y search_memory. No tiene la opción de borrar. El olvido es una acción de gobernanza, no una acción del agente, por lo que reside en la aplicación (archive/tower.py, memories.delete en el cliente sin procesar), donde el modelo no puede alcanzarlo por accidente. Si un agente puede olvidar es algo que diseñas, al igual que si puede recordar.
Qué compilaste y leíste, y qué es
la cosa | Qué es | dónde se encuentra |
| El servicio de memoria, como servicio: una decisión de implementación, fuera del agente | Banco de memoria de Vertex AI en un Agent Engine |
| la misma ranura de |
|
| lo que se puede conservar, que se decide en el momento de la escritura, no en la instrucción |
|
🔥 → | El olvido es una acción de la aplicación; la API de memoria del ADK no tiene la opción de borrar. |
|
Este peldaño alcanza lo que se dijo. Un día entra, un hecho sale, destilado a lo que permiten los temas, y el libro del primer piso nunca se movió.
7. GraphRAG
Opcional.
- Qué: Un script carga el pasado del valle en BigQuery, genera incorporaciones dentro del almacén y coloca un gráfico sobre las tablas sin mover una fila. Luego, se hacen dos preguntas a Vesper, que tiene dos consultas gobernadas para responderlas: una para lo que suena similar y otra para lo que está conectado.
- Por qué: Sonar parecido no es lo mismo que estar conectado. Un vector encuentra dónde buscar, un gráfico encuentra lo que está adjunto y la respuesta debe llevar el camino que recorrió.
- Cómo:
bash scripts/season.sh, una vez. Todo lo demás en este capítulo es de solo lectura.
La torre de Vesper se limita a ti ((app_name, user_id)) por construcción. Las visitas de otras personas no son su recuerdo, y buscarlo con más intensidad no cambiaría eso. Son del valle, y el valle los guarda en un almacén. Treinta y un visitantes esta temporada vinieron por una linterna Q7 que se apagó por la noche, y uno de ellos encontró la causa. En este capítulo, se carga ese almacén y se le entregan dos consultas fijas.
Graph RAG
La RAG es recuperar y, luego, generar: encuentra los registros correctos, entrégalos al modelo y deja que responda a partir de ellos. El RAG simple recupera por similitud: incorpora la pregunta y extrae los registros más cercanos. Allí se encuentran las cosas que suenan como la pregunta, y es donde se detuvo la torre del capítulo 4. La RAG basada en gráficos agrega un segundo paso de recuperación que sigue las aristas (claves que un almacén ya tiene) desde cualquier similitud encontrada hasta lo que esté adjunto a ella. Los dos pasos responden preguntas diferentes, y este capítulo te hace hacer ambas:
paso | la pregunta que responde | how | en este capítulo |
similitud | ¿Dónde debería buscar? | incorporar la pregunta, |
|
recorrido | ¿Qué está conectado a eso? |
|
|
generación | ¿Qué le digo al visitante? | el modelo, con la ruta de acceso como cita | su respuesta |
Ejecución
La temporada se envía como archivos CSV simples en season/ (visitantes, elementos, preguntas, correcciones, temporadas), de la misma manera en que un sistema de asistencia los exportaría. Una secuencia de comandos los lleva hasta el almacén, y es lo único que ejecutarás en este capítulo.
👉💻 En la pestaña 1 (aproximadamente tres minutos; imprime cada paso a medida que avanza y se detiene en el primero que falla):
cd ~/agent-valley-archive
bash scripts/season.sh
👀 Cuando finaliza, se ilumina el piso cuatro de la torre y la leyenda junto a él dice abierto.
Qué se compiló: Solo lectura
Cómo lo lee (solo lectura)
Pregúntale.
👉🖥 El piso cuatro está abierto en la torre. Pregúntale cómo lo haría cualquier visitante:
Has anyone else had a q7 lantern go out at night?

👀 Ella responde: Treinta y una personas más… la mayoría dijo que la llama era pequeña y se apagó después de una hora… Marlow, la nutria, descubrió que las mechas estaban sumergidas demasiado poco, y la última línea de su respuesta es la ruta. Este es el resultado. Léelo, pero no se lo envíes de vuelta:
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
La ruta de acceso es la cita. Cada salto es una arista en el gráfico, y una arista es una clave, por lo que cualquiera puede volver a recorrerla y obtener los mismos treinta y uno. Nadie puede volver a recorrer una ubicación con una puntuación de similitud. Si dice, justo antes de la ruta, que las filas volvieron a través de tres uniones porque el proyecto no tiene una reserva de gráfico, esa es la edición de tu proyecto que rechaza GRAPH_TABLE: las filas y la ruta son las mismas.
👉🖥 Ahora, quita la marca y envía lo siguiente:
Has anyone else had a lantern that keeps dying once the sun is down?
👀 Llega a la misma salida treinta y uno y sigue el mismo camino. Lo que cambió fue el camino: season_search corrió primero, encontró cinco visitantes que suenan parecidos (cada uno con q7), tomó esa marca y solo entonces caminó. Similar no está conectado; similar es dónde buscar.
Qué se cargó y qué es
la cosa | Qué es | dónde se encuentra |
| Un almacén: columnas con nombres y tipos |
|
| El paso de similitud: dónde buscar |
|
| El paso de recorrido: qué está conectado; las tablas se convierten en nodos y flechas |
|
| el único paseo que puede dar; el camino es la cita |
|
Unas pocas docenas de visitantes no son motivo para comprar un almacén. Este capítulo enseña la forma de la consulta, no la escala. Si aumentas este gráfico mil veces, el MATCH no cambia ni un carácter.
8. Cerrar
Tres líneas, una torre, un almacén: cuatro pisos. No se reinició nada.
el peldaño | lo que hiciste | lo que compró |
ONE |
| Un deslizamiento que existe en absoluto: El estado se escribe con código |
DOS |
| Un cajón que sigue al visitante |
la presentación |
| lo que se dijo, se mantuvo |
TRES |
| Lo que se conservó, lo que se pidió (lo que se archivó) no se recuerda. |
la torre |
| una torre que destila y sobrevive a la noche |
las reglas |
| solo lo que se debe conservar |
la temporada |
| Las visitas de todos los demás, por significado y por conexión |
Qué reemplazó cada pieza
ADK 2 | lo que escribirías en su lugar | cuánto te cuesta |
| Un diccionario junto al bucle de chat, serializado en disco por ti mismo | el modelo no puede leerlo, y tú escribes el resumen y el bloqueo |
El prefijo | Una tabla de usuarios y una unión en cada turno | Decidir dónde pertenece una clave, cada vez |
| un cron que vuelca transcripciones y el modelo que decide cuándo buscar | no se descarta nada, no se destila nada, y nunca ves las veces que no funcionó. |
| un almacén de vectores, una instrucción de extracción, un trabajo de consolidación y "no recuerdes trivialidades" en la instrucción | tres servicios, y la regla se mantiene hasta que el modelo indique lo contrario |
| exportar, incorporar en otro lugar, una base de datos de gráficos, un trabajo de sincronización y el modelo que escribe SQL | Los datos salen del almacén para que se comprendan, y descubres qué uniones adivinó cuando un cliente |
Tres preguntas, detente en el primer sí
- ¿Importará mañana? No → No se conserva nada. Se basa en la conversación.
- ¿Una función puede verificarlo? Sí → el cajón. El código lo escribe, cada turno lo lee y ninguna oración puede cambiarlo.
- De lo contrario, la torre. Se extrae de lo que se dice, se busca cuando se solicita y se revisa según lo que se dice a continuación.
La oración
Un registro no es un recuerdo. Un recuerdo es un registro más dos decisiones: qué conservar y cuándo buscar. Además, qué tipo de cosa es decide en qué piso se encuentra.
Los hechos y las preferencias pertenecen a diferentes tiendas.
👀 Todos los pisos están iluminados. Tu familiar aparece en la parte superior. El sello de Archivo está en el pasaporte, y la semana cinco abre el Mercado Nocturno, donde Nix dirige el escenario en voz alta, en tiempo real, y todo lo que sabe la torre te acompaña.