Next ‘26 Developer Keynote: Enhancing Agents with Memory

1. Wprowadzenie

W tym ćwiczeniu rozwiniesz swoje umiejętności w zakresie tworzenia agentów ADK, dodając do nich trwałą i specjalistyczną wiedzę. Dowiesz się, jak zarządzać stanem rozmowy za pomocą sesji Agent Platform, włączyć długoterminowe uczenie się za pomocą Banku zapamiętanych informacji oraz zintegrować złożone dane dotyczące zasad miejskich za pomocą Spark i AlloyDB na potrzeby RAG (generowania wspomaganego wyszukiwaniem).

Jakie zadania wykonasz

  • Skonfiguruj sesje Agent Platform, aby zapewnić trwałość rozmowy.
  • Wdróż Bank zapamiętanych informacji, aby umożliwić agentom uczenie się na podstawie wcześniejszych interakcji.
  • Użyj Spark Lightning Engine, aby wczytać i przetworzyć dokumentację reguł miejskich.
  • Tworzenie systemu RAG za pomocą AlloyDB i wyszukiwania wektorowego.
  • Wdróż ulepszonego agenta w usłudze Agent Platform.

Czego potrzebujesz

Szacowany czas trwania: 60 minut

Zasoby utworzone w tym laboratorium powinny kosztować mniej niż 5 USD.

2. Zanim zaczniesz

Tworzenie projektu Google Cloud

  1. W konsoli Google Cloud na stronie selektora projektu wybierz lub utwórz projekt w chmurze Google.
  2. Sprawdź, czy w projekcie Cloud włączone są płatności. Dowiedz się, jak sprawdzić, czy w projekcie są włączone płatności.

Uruchamianie Cloud Shell

Cloud Shell to środowisko wiersza poleceń działające w Google Cloud, które zawiera niezbędne narzędzia.

  1. Kliknij Aktywuj Cloud Shell u góry konsoli Google Cloud.
  2. Po połączeniu z Cloud Shell sprawdź uwierzytelnianie:
    gcloud auth list
    
  3. Sprawdź, czy projekt jest skonfigurowany:
    gcloud config get project
    
  4. Jeśli projekt nie jest ustawiony zgodnie z oczekiwaniami, ustaw go:
    export PROJECT_ID=<YOUR_PROJECT_ID>
    gcloud config set project $PROJECT_ID
    

Potwierdź uwierzytelnianie:

gcloud auth list

Potwierdź projekt:

gcloud config get project

W razie potrzeby ustaw:

export PROJECT_ID=<YOUR_PROJECT_ID>
gcloud config set project $PROJECT_ID

Włącz interfejsy API

Aby włączyć wszystkie interfejsy API wymagane do zarządzania sesjami, przetwarzania w Sparku i AlloyDB, uruchom to polecenie:

gcloud services enable \
  aiplatform.googleapis.com \
  run.googleapis.com \
  alloydb.googleapis.com \
  dataproc.googleapis.com \
  documentai.googleapis.com \
  storage.googleapis.com \
  secretmanager.googleapis.com

3. Konfigurowanie środowiska

W tym ćwiczeniu użyjesz wstępnie skonfigurowanego środowiska w repozytorium keynote.

  1. Sklonuj repozytorium i przejdź do folderu projektu:
git clone https://github.com/GoogleCloudPlatform/next-26-keynotes
cd next-26-keynotes/devkey/enhancing-agents-with-memory
  1. Skonfiguruj środowisko wirtualne Pythona i zainstaluj wymagane pakiety ADK:
uv venv
source .venv/bin/activate
uv sync

Konfigurowanie zmiennych środowiskowych

Aby połączyć się z usługami Agent Platform i AlloyDB, agent wymaga określonej konfiguracji.

  1. Skopiuj przykładowy plik środowiska:
cp .env.example .env
  1. Otwórz .env i zaktualizuj te pola:
    • GOOGLE_CLOUD_PROJECT: identyfikator projektu.
    • GOOGLE_CLOUD_LOCATION: us-central1.
    • ALLOYDB_CLUSTER_ID: rules-db.
GOOGLE_CLOUD_PROJECT=<YOUR_PROJECT_ID>
GOOGLE_CLOUD_LOCATION=global
GOOGLE_GENAI_USE_VERTEXAI=TRUE
GOOGLE_CLOUD_REGION=us-central1
ALLOYDB_CLUSTER_ID=rules-db
  1. Uruchom poniższy skrypt pomocniczy, aby utworzyć instancję silnika agenta, która będzie używana w sesjach rozmowy i pamięci długotrwałej. Spowoduje to automatyczne wypełnienie AGENT_ENGINE_ID w pliku .env:
uv run utils/setup_agent_engine.py

Po pomyślnym zakończeniu operacji zobaczysz:

Creating Agent Engine instance...
Successfully created Agent Engine. ID: 1234567890
Updated .env with AGENT_ENGINE_ID=1234567890

4. Tworzenie agenta za pomocą funkcji zarządzania sesjami

W tym kroku zainicjujesz agenta Marathon Planner, który może przechowywać historię rozmów w wielu turach. Można to osiągnąć za pomocą klasy App pakietu ADK i sesji platformy agentów.

Zainicjuj usługę agenta i sesji

Otwórz pokój planner_agent/agent.py. Zobaczysz, jak dodajemy klasę ADK, aby zintegrować sesje platformy agenta. Dzięki temu możemy sprawić, że z czasem nasi agenci będą zachowywać stan, i w razie potrzeby modyfikować kontekst.

from google.adk.agents import LlmAgent
from google.adk.sessions import VertexAiSessionService
from vertexai.agent_engines import AdkApp

PROJECT_ID = os.environ.get("GOOGLE_CLOUD_PROJECT")
REGION = os.environ.get("GOOGLE_CLOUD_REGION", "us-central1")

# Initialize Vertex AI for regional services
if PROJECT_ID:
    vertexai.init(project=PROJECT_ID, location=REGION)

# Define the agent logic
root_agent = LlmAgent(
    name="planner_agent",
    model="gemini-3-flash-preview",
    instruction="You are a helpful marathon planning assistant...",
    tools=[] # We will add tools in the next steps
)

def session_service_builder():
    """Builder for Agent Platform Sessions."""
    return VertexAiSessionService(project=PROJECT_ID, location=REGION)

# Wrap the agent in an AdkApp to manage stateful context
app = AdkApp(
    agent=root_agent,
    session_service_builder=session_service_builder
)

5. Włączanie uczenia długoterminowego za pomocą Banku zapamiętanych informacji

Zarządzanie sesjami śledzi poszczególne rozmowy, ale możesz zrobić to samo w przypadku pamięci długotrwałej. W tym kroku połączysz agenta z Bankiem zapamiętanych informacji na platformie Agent Platform, czyli w pełni zarządzaną usługą pamięci gotową do użycia w firmie.

Inicjowanie usługi Bank zapamiętanych informacji

Bank zapamiętanych informacji umożliwia agentowi przywoływanie kontekstu w różnych sesjach. Zaktualizuj planner_agent/agent.py, aby uwzględnić usługę pamięci:

from google.adk.memory import VertexAiMemoryBankService

def memory_service_builder():
    """Builder for Agent Platform Memory Bank."""
    return VertexAiMemoryBankService(
        project=PROJECT_ID,
        location=REGION,
        agent_engine_id=AGENT_ENGINE_ID
    )

Wdrażanie automatycznego pozyskiwania danych o pamięci

Aby mieć pewność, że agent uczy się na każdym etapie, dodajemy znak after_agent_callback. Ta funkcja jest wywoływana po tym, jak agent zakończy odpowiadanie. Umożliwia mu to „przetrawienie” sesji i zapisanie odpowiednich informacji w pamięci.

  1. Zdefiniuj funkcję wywołania zwrotnego:
async def auto_save_memories(callback_context):
    """Callback to ingest the session into the memory bank after the turn."""
    # In AdkApp, the memory service is available via the invocation context
    if hasattr(callback_context._invocation_context, 'memory_service') and callback_context._invocation_context.memory_service:
        await callback_context._invocation_context.memory_service.add_session_to_memory(
            callback_context._invocation_context.session
        )
  1. Dołącz wywołanie zwrotne do LlmAgent:
root_agent = LlmAgent(
    # ... other params
    after_agent_callback=[auto_save_memories],
)

6. Konfigurowanie AlloyDB na potrzeby RAG

Zanim będziemy mogli przetwarzać dane reguł miejskich, musimy mieć wydajną bazę danych do ich przechowywania. W tym kroku utworzysz klaster AlloyDB i zainicjujesz schemat bazy danych na potrzeby wyszukiwania wektorowego.

1. Tworzenie klastra AlloyDB i instancji głównej

Aby utworzyć klaster i jego instancję główną, uruchom te polecenia w Cloud Shell:

# Create the cluster
gcloud alloydb clusters create rules-db \
  --password=postgres \
  --region=us-central1

# Create the primary instance with IAM authentication enabled
gcloud alloydb instances create rules-db-primary \
  --instance-type=PRIMARY \
  --cpu-count=2 \
  --region=us-central1 \
  --cluster=rules-db \
  --database-flags=alloydb.iam_authentication=on

2. Przyznawanie wymaganych ról uprawnień

Aby korzystać z zarządzanego serwera MCP AlloyDB, Twoja tożsamość musi mieć określone uprawnienia. Aby przypisać wymagane role, uruchom te polecenia:

export USER_EMAIL=$(gcloud config get-value account)

# Role to use MCP tools
gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member="user:$USER_EMAIL" \
  --role="roles/mcp.toolUser"

# Role to execute SQL in AlloyDB
gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member="user:$USER_EMAIL" \
  --role="roles/alloydb.admin"

# Role for IAM database authentication
gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member="user:$USER_EMAIL" \
  --role="roles/alloydb.databaseUser"

# Create the IAM-based database user
gcloud alloydb users create "$USER_EMAIL" \
  --cluster=rules-db \
  --region=us-central1 \
  --type=IAM_BASED

3. Tworzenie bazy danych i tabel za pomocą AlloyDB Studio

Bazy danych i tabele AlloyDB są zarządzane za pomocą SQL, więc do sfinalizowania schematu użyjemy AlloyDB Studio w konsoli Google Cloud.

  1. Otwórz AlloyDB > Klastry i kliknij rules-db.
  2. W menu nawigacyjnym po lewej stronie kliknij AlloyDB Studio.
  3. Zaloguj się jako użytkownik postgres, podając ustawione hasło (postgres).
  4. Aby utworzyć bazę danych, uruchom ten kod SQL:
    CREATE DATABASE city_rules;
    
  5. Przełącz połączenie z bazą danych na city_rules w AlloyDB Studio i uruchom ten kod SQL, aby zainstalować rozszerzenia i utworzyć tabelę rules:
    -- Install extensions for vector search and ML
    CREATE EXTENSION IF NOT EXISTS vector;
    CREATE EXTENSION IF NOT EXISTS google_ml_integration CASCADE;
    
    -- Create the rules table
    CREATE TABLE IF NOT EXISTS rules (
        id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
        text TEXT NOT NULL,
        city TEXT NOT NULL,
        embedding vector(3072) DEFAULT NULL
    );
    
    -- Grant your IAM user access to the table (replace with your email)
    GRANT ALL PRIVILEGES ON TABLE rules TO "YOUR_EMAIL_ADDRESS";
    

7. Przetwarzanie danych reguł miejskich za pomocą mechanizmu Spark Lightning

Aby zapewnić naprawdę dokładne planowanie, agent potrzebuje nie tylko dobrze sformułowanego prompta, ale też uzasadnienia w postaci danych i kontekstu organizacyjnego. W tym kroku użyjesz Spark Lightning Engine w Dataproc Serverless do przetworzenia dużych plików PDF z zasadami dotyczącymi miast i wczytania ich do AlloyDB.

Dlaczego warto wybrać Spark Lightning Engine?

Uziemianie agentów na dużą skalę wymaga przetwarzania ogromnych ilości nieustrukturyzowanych danych. Spark Lightning Engine to silnik wykonywania o wysokiej wydajności dla Sparka, który znacznie przyspiesza te zadania. Używamy go do semantycznego dzielenia dokumentów na części za pomocą Document AI od Google.

Poznaj potok Spark

Logika pozyskiwania jest zdefiniowana w spark-setup/spark_alloydb_processor.py. Proces przebiega w tych krokach:

  1. Lista plików PDF: pobiera identyfikatory URI dokumentów z zasobnika Cloud Storage.
  2. Wyodrębnianie semantyczne: używa funkcji zdefiniowanej przez użytkownika (UDF) do wywoływania interfejsu Document AI API.
  3. Zapisz w AlloyDB: zapisuje wyodrębnione fragmenty tekstu w tabeli AlloyDB o nazwie rules.
# Extract from spark_alloydb_processor.py
def process_document(gcs_uri: str):
    # ... calls Document AI to parse PDF ...
    return chunks

# Parallel processing with Spark Lightning Engine
process_udf = udf(process_document, chunk_schema)
chunked_df = uri_df.withColumn("chunks", process_udf(col("gcs_uri"))) \
                   .select(explode(col("chunks")).alias("chunk")) \
                   .select("chunk.*")

# Save to AlloyDB for Vector Search
chunked_df.write.format("jdbc") \
    .option("url", jdbc_url) \
    .option("dbtable", "rules") \
    .mode("append") \
    .save()

Uruchamianie zadania pozyskiwania

Uruchom proces pozyskiwania za pomocą podanego skryptu:

./spark-setup/run_dataproc.sh

8. RAG z AlloyDB

Teraz, gdy dane o zasadach obowiązujących w mieście znajdują się w AlloyDB, agent może ich używać do generowania wspomaganego wyszukiwaniem (RAG). Dzięki temu plan maratonu będzie zgodny z określonymi kodami miast.

Potęga AlloyDB w przypadku RAG

AlloyDB doskonale sprawdza się w wyszukiwaniu wektorowym, co pozwala nam przechowywać zarówno dane strukturalne, jak i wektory dystrybucyjne w tym samym miejscu. Agent może użyć wbudowanej funkcji embedding w AlloyDB, aby znaleźć najbardziej odpowiednie informacje o zasadach.

Aby umożliwić agentowi dostęp do tych danych, udostępniamy narzędzie, które wysyła zapytania do AlloyDB za pomocą podobieństwa wektorowego. Logikę tę możesz zobaczyć w hybrid_recall.sql, gdzie pokazujemy, jak obliczyć odległość między zapytaniem a przechowywanymi przez nas regułami:

SELECT
    text,
    (embedding <=> 
     embedding('gemini-embedding-001', 
               'Restrictions for running a race on the Las Vegas strip')::vector) 
    as distance
FROM
    rules
WHERE city = 'Las Vegas'
ORDER BY
    distance ASC
LIMIT 5;

Powiązanie agenta z lokalnymi regułami za pomocą narzędzia RAG

Aby udostępnić narzędzie agentowi, musisz zdefiniować je w usłudze planner_agent/tools.py, a następnie zarejestrować w usłudze planner_agent/agent.py. Do połączenia z bazą danych użyjemy zarządzanego zdalnego serwera MCP AlloyDB z Google Cloud.

  1. Zdefiniuj narzędzie w planner_agent/tools.py, korzystając z wzorca „Hybrid Recall”. Do połączenia z zarządzanym serwerem MCP AlloyDB użyjemy protokołu streamable_http:
from mcp import ClientSession
from mcp.client.streamable_http import streamablehttp_client

async def get_local_and_traffic_rules(query: str) -> str:
    """Uses vector search in AlloyDB via managed MCP server."""
    # Vector search query using built-in AlloyDB embedding functions
    sql = f"SELECT text FROM rules WHERE city = 'Las Vegas' ORDER BY embedding <=> google_ml.embedding('gemini-embedding-001', '{query}')::vector ASC LIMIT 5;"
    
    # Establish a streamable HTTP connection to the MCP server
    async with streamablehttp_client(url, headers=get_auth_headers()) as (read_stream, write_stream, _):
        async with ClientSession(read_stream, write_stream) as session:
            await session.initialize()
            result = await session.call_tool(
                "execute_sql",
                arguments={
                    "instance": full_instance_name,
                    "database": "city_rules",
                    "sqlStatement": sql
                }
            )
            return "\n".join([c.text for c in result.content if hasattr(c, 'text')])
  1. Zarejestruj narzędzie i zakończ proces planner_agent/agent.py:
# ... imports ...

# Assemble the Agent
root_agent = LlmAgent(
    name="planner_agent",
    model="gemini-3-flash-preview",
    instruction="You are a helpful marathon planning assistant...",
    tools=[
        get_local_and_traffic_rules,
    ],
    after_agent_callback=[auto_save_memories],
)

# 2. Wrap the agent in an AdkApp to manage the stateful lifecycle
app = AdkApp(
    agent=root_agent,
    session_service_builder=session_service_builder,
    memory_service_builder=memory_service_builder
)

9. Wskazówki ekspertów dotyczące umiejętności agenta

Umiejętności agenta to samodzielne moduły, które zawierają konkretne instrukcje, wskazówki i zasoby, aby pomóc agentom w efektywniejszym wykonywaniu zadań. Zamiast zaśmiecać prompta systemowego złożonymi instrukcjami dla każdego narzędzia, możesz zamknąć tę wiedzę w umiejętności, która jest wczytywana tylko wtedy, gdy jest potrzebna.

Google udostępnia gotowe umiejętności dla usług Google (takich jak AlloyDB i BigQuery), aby mieć pewność, że Twoi agenci postępują zgodnie z najlepszymi praktykami branżowymi w zakresie wykonywania zapytań o dane i zarządzania zasobami. Te i inne specjalistyczne wzorce znajdziesz w Google Skills Depot. Podstawowe umiejętności związane z AlloyDB znajdziesz tutaj.

1. Poznaj plik umiejętności

Otwórz wstępnie skonfigurowany plik umiejętności w lokalizacji planner_agent/skills/get-local-and-traffic-rules/SKILL.md. Wygląda to w ten sposób:

---
name: get-local-and-traffic-rules
description: Retrieve local rules and traffic information for a specific jurisdiction.
---
# get_local_and_traffic_rules Skill

This skill provides guidelines on how to effectively use the `get_local_and_traffic_rules` tool.

## Overview
The `get_local_and_traffic_rules` tool interfaces with an AlloyDB database to perform vector similarity searches on a corpus of rules and traffic information using a provided natural language query.

## Usage Guidelines
1. **Query Specificity**: When calling the tool, provide specific details in the `query` argument. For example, instead of querying "food rules", use "rules regarding food vendors during public events".
2. **Contextual Use**: Use the tool when planning events or activities that require adherence to local municipal or state rules (e.g., street closures, noise ordinances, environmental rules).
3. **Handling Results**: The tool returns a string containing the text of the top 5 most relevant rules. If no error occurs, parse the returned string to inform your planning tasks.
4. **Error Handling**: If an error string is returned (e.g., "Error querying rules: ..."), you must report this failure or attempt an alternative approach if applicable.

## Underlying Mechanism
- The tool uses `google_ml.embedding` to convert the query into a vector representation.
- It calculates distance (`<=>`) against the `embedding` column in the `rules` table on an AlloyDB instance.
- Results are fetched in descending order of similarity, limited to 5 results.

2. Sposób rejestracji umiejętności

planner_agent/agent.py umiejętność jest wczytywana z katalogu i dodawana do narzędzi agenta. Oto jak wygląda kod:

import pathlib
from google.adk.skills import load_skill_from_dir
from google.adk.tools import skill_toolset

# Load the AlloyDB skill from its directory
alloydb_skill = load_skill_from_dir(pathlib.Path(__file__).parent / "skills" / "get-local-and-traffic-rules")

# Assemble the Agent with the Skill Toolset
root_agent = LlmAgent(
    name="planner_agent",
    model="gemini-3-flash-preview",
    instruction="You are a helpful marathon planning assistant...",
    tools=[
        get_local_and_traffic_rules,
        skill_toolset.SkillToolset(skills=[alloydb_skill])
    ],
    after_agent_callback=[auto_save_memories],
)

10. Testowanie agenta

  1. Uruchom agenta lokalnie:
uv run adk run planner_agent
  1. Zadaj pytanie dotyczące zasad obowiązujących w mieście: [user]: What are the rules for running a race on the Las Vegas strip?

Agent wywoła narzędzie get_local_and_traffic_rules, przeprowadzi wyszukiwanie wektorowe w AlloyDB i zwróci odpowiedź na podstawie oficjalnych fragmentów reguł przetworzonych przez Sparka.

11. Wdrażanie agenta

Wdrażanie w usłudze Agent Platform

uv run adk deploy agent_engine \
  --env_file .env \
  planner_agent

12. Czyszczenie danych

Aby uniknąć bieżących opłat, usuń zasoby utworzone podczas tego laboratorium.

Usuwanie klastra AlloyDB

# Delete the AlloyDB Cluster
gcloud alloydb clusters delete rules-db --region=us-central1 --force

Usuwanie aplikacji środowiska wykonawczego agenta

Instancję Reasoning Engine możesz usunąć w konsoli lub za pomocą polecenia gcloud (jeśli masz nazwę zasobu). Aby uprościć proces, użyj konsoli:

  1. Otwórz stronę Środowisko wykonawcze agentów.
  2. Kliknij planner_agent –> przycisk z trzema kropkami po prawej stronie.
  3. Kliknij Usuń.

13. Gratulacje

Gratulacje! Udało Ci się rozszerzyć agenta ADK o zaawansowane funkcje pamięci i uzasadniania danych.

Czego się dowiedziałeś(-aś)

  • Agenty stanowe: integracja z sesjami Agent Platform w celu zachowania kontekstu rozmowy.
  • Długoterminowe uczenie się: dołączenie Banku zapamiętanych informacji Agent Platform, aby umożliwić agentowi uczenie się na podstawie interakcji z użytkownikami.
  • Pozyskiwanie danych: przetwarzanie nieustrukturyzowanych dokumentów za pomocą Spark Lightning EngineDocument AI.
  • RAG: tworzenie systemu wyszukiwania wektorowego w AlloyDB, aby osadzić agenta w regułach świata rzeczywistego.

Następne kroki