1. Einführung
In dieser interaktiven Sitzung erstellen Sie einen Smart Cafe Concierge – einen KI-Agenten, der auf Gemini basiert und als freundlicher Barista fungiert. Es nimmt Kaffeebestellungen entgegen, die im Sitzungsstatus erfasst werden, speichert langfristige Ernährungspräferenzen im nutzerbezogenen Status und speichert alles in einer Cloud SQL-PostgreSQL-Datenbank. Am Ende erinnert sich der Agent daran, dass Sie laktoseintolerant sind, auch nachdem Sie die Anwendung neu gestartet und eine neue Unterhaltung begonnen haben.
Hier sehen Sie die Systemarchitektur, die wir erstellen werden.

Voraussetzungen
- Ein Google Cloud-Konto mit einem Testabrechnungskonto
- Grundlegende Python-Kenntnisse
- Es sind keine Vorkenntnisse in Bezug auf das ADK, KI-Agents oder Cloud SQL erforderlich.
Lerninhalte
- Mit dem Agent Development Kit (ADK) von Google einen KI‑Agenten mit benutzerdefinierten Tools erstellen
- Tools definieren, die den Sitzungsstatus über
ToolContextlesen und schreiben - Unterscheidung zwischen Status auf Sitzungsebene und Status auf Nutzerebene (
user:-Präfix) - Cloud SQL PostgreSQL-Instanz bereitstellen und über Cloud Shell eine Verbindung zu ihr herstellen
- Von der lokalen Speicherung (Standard bei Verwendung des Befehls
adk web) zuDatabaseSessionServicefür die dauerhafte Speicherung mit dedizierter Datenbank migrieren - Prüfen, ob der Agent-Speicher über Anwendungsneustarts und separate Unterhaltungssitzungen hinweg erhalten bleibt
Voraussetzungen
- Ein funktionierender Computer und eine zuverlässige Internetverbindung
- Ein Browser wie Chrome für den Zugriff auf die Google Cloud Console
- Neugier und Lernbereitschaft
2. Umgebung einrichten
In diesem Schritt wird Ihre Cloud Shell-Umgebung vorbereitet und Ihr Google Cloud-Projekt konfiguriert.
Cloud Shell öffnen
Öffnen Sie Cloud Shell in Ihrem Browser. Cloud Shell bietet eine vorkonfigurierte Umgebung mit allen Tools, die Sie für dieses Codelab benötigen. Klicken Sie auf Autorisieren, wenn Sie dazu aufgefordert werden.
Die Benutzeroberfläche sollte in etwa so aussehen:

Dies ist unsere Hauptschnittstelle. Die IDE befindet sich oben und das Terminal unten.
Arbeitsverzeichnis einrichten
Erstellen Sie Ihr Arbeitsverzeichnis. Der gesamte Code, den Sie in diesem Codelab schreiben, befindet sich hier – getrennt vom Referenz-Repository:
# Create your working directory
mkdir -p ~/build-agent-adk-cloudsql
# Change cloudshell workspace and working directory into previously created dir
cloudshell workspace ~/build-agent-adk-cloudsql && cd ~/build-agent-adk-cloudsql
Um das Terminal zu öffnen, suchen Sie nach Ansicht > Terminal.

Google Cloud-Projekt und erste Umgebungsvariablen einrichten
Laden Sie das Skript zur Projekteinrichtung in Ihr Arbeitsverzeichnis herunter:
curl -sL https://raw.githubusercontent.com/alphinside/cloud-trial-project-setup/main/setup_verify_trial_project.sh -o setup_verify_trial_project.sh
Führen Sie das Skript aus. Es wird Ihr Testabrechnungskonto überprüft, ein neues Projekt erstellt (oder ein vorhandenes Projekt validiert), Ihre Projekt-ID in einer .env-Datei im aktuellen Verzeichnis gespeichert und das aktive Projekt im Terminal festgelegt.
bash setup_verify_trial_project.sh && source .env
Wenn Sie diesen Befehl ausführen, werden Sie aufgefordert, einen Namen für die Projekt-ID einzugeben. Drücken Sie Enter, um fortzufahren.

Wenn Sie nach einer Weile diese Ausgabe in der Console sehen, können Sie mit dem nächsten Schritt fortfahren. 
Das ausgeführte Skript führt die folgenden Schritte aus:
- Prüfen, ob Sie ein aktives Testabrechnungskonto haben
- Nach einem vorhandenen Projekt in
.envsuchen (falls vorhanden) - Neues Projekt erstellen oder vorhandenes Projekt wiederverwenden
- Test-Rechnungskonto mit Ihrem Projekt verknüpfen
- Projekt-ID in .env speichern
- Projekt als aktives gcloud-Projekt festlegen
Prüfen Sie, ob das Projekt richtig eingestellt ist. Sehen Sie sich dazu den gelben Text neben dem Arbeitsverzeichnis im Cloud Shell-Terminal-Prompt an. Dort sollte Ihre Projekt-ID angezeigt werden.

Erforderliche APIs aktivieren
Aktivieren Sie die für dieses Codelab erforderlichen Google Cloud APIs:
gcloud services enable \
aiplatform.googleapis.com \
sqladmin.googleapis.com \
compute.googleapis.com
- Vertex AI API (
aiplatform.googleapis.com): Ihr Agent verwendet Gemini-Modelle über Vertex AI. - Cloud SQL Admin API (
sqladmin.googleapis.com): Sie stellen eine PostgreSQL-Instanz für den persistenten Speicher bereit und verwalten sie. - Compute Engine API (
compute.googleapis.com): Erforderlich zum Erstellen von Cloud SQL-Instanzen.
Region für Gemini- und Cloud-Produkte konfigurieren
Bevor wir fortfahren, richten wir auch die erforderliche Standort-/Regionskonfiguration für das Produkt ein, mit dem wir interagieren. Fügen Sie der Datei .env die folgende Konfiguration hinzu:
# This is for our Gemini endpoint
echo "GOOGLE_CLOUD_LOCATION=global" >> .env
# This is for our other Cloud products
echo "REGION=us-central1" >> .env
source .env
Fahren wir mit dem nächsten Schritt fort.
3. Cloud SQL einrichten
Bei diesem Schritt wird eine Cloud SQL PostgreSQL-Instanz bereitgestellt und Ihr Agent wird von der In-Memory-Speicherung auf die datenbankbasierte Speicherung umgestellt. Das Erstellen der Instanz dauert einige Minuten. Wir können also damit beginnen und in der Zwischenzeit mit dem nächsten Thema fortfahren.
Instanzerstellung starten
Fügen Sie das Datenbankpasswort Ihrer .env-Datei hinzu und laden Sie sie neu. Wir verwenden cafe-agent-pwd-2025 als Passwort.
echo "DB_PASSWORD=cafe-agent-pwd-2025" >> .env
source .env
Führen Sie diesen Befehl aus, um eine Cloud SQL PostgreSQL-Instanz zu erstellen. Das kann einige Minuten dauern. Lassen Sie den Vorgang laufen und fahren Sie mit dem nächsten Abschnitt fort.
gcloud sql instances create cafe-concierge-db \
--database-version=POSTGRES_17 \
--edition=ENTERPRISE \
--region=${REGION} \
--availability-type=ZONAL \
--project=${GOOGLE_CLOUD_PROJECT} \
--tier=db-f1-micro \
--root-password=${DB_PASSWORD} \
--quiet &
Einige Hinweise zum oben genannten Befehl:
db-f1-microist die kleinste (und kostengünstigste) Cloud SQL-Stufe und reicht für dieses Codelab aus.- Mit
--root-passwordwird das Passwort für den Standard-Postgres-Nutzer festgelegt. - Das Suffix
&im Befehl führt den Befehl im Hintergrund aus, sodass Sie weiterarbeiten können.
Der Prozess wird im Hintergrund ausgeführt. Die Konsolenausgabe wird jedoch gelegentlich im aktuellen Terminal angezeigt. Öffnen wir einen neuen Terminaltab in Cloud Shell (klicken Sie auf das Pluszeichen), damit wir uns besser konzentrieren können.

Rufen Sie Ihr Arbeitsverzeichnis noch einmal auf und aktivieren Sie das Projekt mit dem vorherigen Einrichtungs-Script.
cd ~/build-agent-adk-cloudsql
bash setup_verify_trial_project.sh && source .env
Fahren wir dann mit dem nächsten Abschnitt fort.
4. Cafe Concierge-Agent erstellen
In diesem Schritt wird die Projektstruktur für Ihren ADK-Agenten erstellt und ein einfacher Cafe Concierge mit einem Menü-Tool definiert.
Python-Projekt initialisieren
In diesem Codelab wird uv verwendet, ein schneller Python-Paketmanager, der virtuelle Umgebungen und Abhängigkeiten in einem Tool verarbeitet. Das Tool ist in Cloud Shell vorinstalliert.
Initialisieren Sie ein Python-Projekt und fügen Sie das ADK als Abhängigkeit hinzu:
uv init
uv add google-adk==1.25.0 asyncpg
uv init erstellt eine pyproject.toml und eine virtuelle Umgebung. Mit uv wird die Abhängigkeit installiert und in pyproject.toml aufgezeichnet.
Agent-Projektstruktur initialisieren
Das ADK erwartet ein bestimmtes Ordnerlayout: ein Verzeichnis, das nach Ihrem Agenten benannt ist und __init__.py, agent.py und .env im Agentenverzeichnis enthält.
Das ADK verfügt über einen integrierten Befehl, mit dem Sie dies schnell einrichten können. Führen Sie dazu den folgenden Befehl aus:
uv run adk create cafe_concierge \
--model gemini-2.5-flash \
--project ${GOOGLE_CLOUD_PROJECT} \
--region ${GOOGLE_CLOUD_LOCATION}
Mit diesem Befehl wird eine Agentstruktur mit gemini-2.5-flash als Brain erstellt. Ihr Verzeichnis sollte nun so aussehen:
build-agent-adk-cloudsql/ ├── cafe_concierge/ │ ├── __init__.py │ ├── agent.py │ └── .env ├── pyproject.toml ├── .env ├── .venv/ └── ...
Agenten schreiben
cafe_concierge/agent.py im Cloud Shell-Editor öffnen
cloudshell edit cafe_concierge/agent.py
Überschreiben Sie die Datei mit dem folgenden Code.
# cafe_concierge/agent.py
from google.adk.agents import LlmAgent
from google.adk.tools import ToolContext
CAFE_MENU = {
"espresso": {
"price": 3.50,
"description": "Rich and bold single shot",
"tags": ["vegan", "dairy-free", "gluten-free"],
},
"latte": {
"price": 5.00,
"description": "Espresso with steamed milk",
"tags": ["gluten-free"],
},
"oat milk latte": {
"price": 5.50,
"description": "Espresso with steamed oat milk",
"tags": ["vegan", "dairy-free", "gluten-free"],
},
"cappuccino": {
"price": 4.50,
"description": "Espresso with equal parts steamed milk and foam",
"tags": ["gluten-free"],
},
"cold brew": {
"price": 4.00,
"description": "Slow-steeped for 12 hours, served over ice",
"tags": ["vegan", "dairy-free", "gluten-free"],
},
"matcha latte": {
"price": 5.50,
"description": "Ceremonial grade matcha with steamed milk",
"tags": ["gluten-free"],
},
"croissant": {
"price": 3.00,
"description": "Buttery, flaky French pastry",
"tags": [],
},
"banana bread": {
"price": 3.50,
"description": "Homemade with walnuts",
"tags": ["vegan"],
},
}
def get_menu() -> dict:
"""Returns the full cafe menu with prices, descriptions, and dietary tags.
Use this tool when the customer asks what's available, wants to see
the menu, or asks about specific items.
"""
return CAFE_MENU
root_agent = LlmAgent(
name="cafe_concierge",
model="gemini-2.5-flash",
instruction="""You are a friendly and knowledgeable barista at "The Cloud Cafe".
Your job:
- Help customers browse the menu and answer questions about items.
- Take coffee and food orders.
- Remember and respect dietary preferences.
Be conversational, warm, and concise. If a customer mentions a dietary
restriction, acknowledge it and suggest suitable options from the menu.
""",
tools=[get_menu],
)
Hier wird ein einfacher Agent mit einem Tool definiert: get_menu(). Der Agent kann Fragen zum Menü beantworten, aber noch keine Bestellungen verfolgen oder sich Präferenzen merken.
Prüfen, ob der Agent ausgeführt wird
Starten Sie die ADK-Entwicklungsoberfläche über Ihr Arbeitsverzeichnis:
cd ~/build-agent-adk-cloudsql
uv run adk web
Öffnen Sie die im Terminal angezeigte URL (in der Regel http://localhost:8000) mit der Webvorschau-Funktion von Cloud Shell. Wählen Sie links oben im Drop-down-Menü für den Agenten die Option cafe_concierge aus.
Geben Sie den folgenden Text in die Chatleiste ein und prüfen Sie, ob der Agent mit Menüpunkten und Preisen antwortet.
What's on the menu?

Beenden Sie die Entwickler-UI mit Strg+C, bevor Sie fortfahren.
5. Statusorientierte Bestellverwaltung hinzufügen
Der Agent kann das Menü anzeigen, aber keine Bestellungen aufnehmen oder sich Einstellungen merken. In diesem Schritt werden vier Tools hinzugefügt, die das Status-System des ADK verwenden, um Bestellungen in einer Unterhaltung zu verfolgen und Ernährungspräferenzen über mehrere Unterhaltungen hinweg zu speichern.
Sitzungsereignisse und ‑status
Jede ADK-Unterhaltung findet in einem Session-Objekt statt. In einer Sitzung werden zwei verschiedene Dinge erfasst: Ereignisse und Status. Wenn Sie den Unterschied kennen, können Sie Agenten erstellen, die sich die richtigen Dinge auf die richtige Weise merken.
Ereignisse sind das chronologische Protokoll aller Vorgänge in einer Unterhaltung. Jede Nutzernachricht, jede Agent-Antwort, jeder Tool-Aufruf und sein Rückgabewert werden als Event aufgezeichnet und an die Liste events der Sitzung angehängt. Ereignisse sind unveränderlich. Nach der Aufzeichnung werden sie nie geändert. Stellen Sie sich Ereignisse als das vollständige Transkript einer Unterhaltung vor.
Status ist ein Schlüssel/Wert-Notizblock, den der Agent während einer Unterhaltung liest und in den er schreibt. Im Gegensatz zu Ereignissen ist der Status veränderlich. Die Werte ändern sich im Laufe der Unterhaltung. Im Status speichert der Agent strukturierte Daten, die er für seine Aktionen benötigt, z. B. die aktuelle Bestellung, die Präferenzen des Kunden oder eine laufende Gesamtsumme. Stellen Sie sich den Status als Notizzettel vor, die der Agent neben dem Transkript aufbewahrt.
So hängen sie zusammen:

Tools lesen und schreiben den Status über ToolContext. Das ist ein Objekt, das ADK automatisch in jede Toolfunktion einfügt, die es als Parameter deklariert. Sie erstellen sie nicht selbst. Über tool_context.state kann ein Tool das Scratchpad für den Sitzungsstatus lesen und schreiben. ADK prüft die Funktionssignatur: Parameter mit dem Typ ToolContext werden eingefügt, alle anderen Parameter werden vom LLM basierend auf der Konversation ausgefüllt.
Wenn ein Tool in tool_context.state schreibt, wird diese Änderung von ADK als state_delta im Ereignis aufgezeichnet. SessionService wendet das Delta dann auf den aktuellen Status der Sitzung an. Das bedeutet, dass Statusänderungen immer auf das Ereignis zurückgeführt werden können, das sie verursacht hat. Das gilt auch für andere Arten von Kontext wie callback_context.
Statuspräfixe
Für Status-Schlüssel werden Präfixe verwendet, um ihren Bereich zu steuern:
Präfix | Ebene | Überlebt Neustart? (mit DB) |
(keine) | Nur aktuelle Sitzung | Ja |
| Alle Sitzungen für diesen Nutzer | Ja |
| Alle Sitzungen, alle Nutzer | Ja |
| Nur aktueller Aufruf | Nein |
In diesem Codelab verwenden Sie zwei dieser Präfixe: Schlüssel ohne Präfix für Daten auf Sitzungsebene (die aktuelle Bestellung – nur für diese Unterhaltung relevant) und user:-Schlüssel für Daten auf Nutzerebene (Ernährungsvorlieben – für alle Unterhaltungen dieses Nutzers relevant).
Statusbehaftete Tools hinzufügen
Öffnen Sie cafe_concierge/agent.py im Cloud Shell-Editor.
cloudshell edit cafe_concierge/agent.py
Fügen Sie dann die folgenden vier Funktionen über der Definition von „root_agent“ hinzu:
# cafe_concierge/agent.py (add below get_menu, above root_agent)
def place_order(tool_context: ToolContext, items: list[str]) -> dict:
"""Places an order for the specified menu items.
Use this tool when the customer confirms they want to order something.
Args:
tool_context: Provided automatically by ADK.
items: A list of menu item names the customer wants to order.
"""
valid_items = []
invalid_items = []
total = 0.0
for item in items:
item_lower = item.lower()
if item_lower in CAFE_MENU:
valid_items.append(item_lower)
total += CAFE_MENU[item_lower]["price"]
else:
invalid_items.append(item)
if not valid_items:
return {"error": f"None of these items are on our menu: {invalid_items}"}
order = {"items": valid_items, "total": round(total, 2)}
tool_context.state["current_order"] = order
result = {"order": order}
if invalid_items:
result["warning"] = f"These items are not on our menu: {invalid_items}"
return result
def get_order_summary(tool_context: ToolContext) -> dict:
"""Returns the current order summary for this session.
Use this tool when the customer asks about their current order,
wants to review what they ordered, or asks for the total.
Args:
tool_context: Provided automatically by ADK.
"""
order = tool_context.state.get("current_order")
if order:
return {"order": order}
return {"message": "No order has been placed yet in this session."}
def set_dietary_preference(tool_context: ToolContext, preference: str) -> dict:
"""Saves a dietary preference that persists across all conversations.
Use this tool when the customer mentions a dietary restriction or
preference (e.g., "I'm vegan", "I'm lactose intolerant",
"I have a nut allergy").
Args:
tool_context: Provided automatically by ADK.
preference: The dietary preference to save (e.g., "vegan",
"lactose intolerant", "nut allergy").
"""
existing = tool_context.state.get("user:dietary_preferences", [])
if not isinstance(existing, list):
existing = []
preference_lower = preference.lower().strip()
if preference_lower not in existing:
existing.append(preference_lower)
tool_context.state["user:dietary_preferences"] = existing
return {
"saved": preference_lower,
"all_preferences": existing,
}
def get_dietary_preferences(tool_context: ToolContext) -> dict:
"""Retrieves the customer's saved dietary preferences.
Use this tool when you need to check the customer's dietary
restrictions before making recommendations.
Args:
tool_context: Provided automatically by ADK.
"""
preferences = tool_context.state.get("user:dietary_preferences", [])
if preferences:
return {"preferences": preferences}
return {"message": "No dietary preferences saved yet."}
Beachten Sie Folgendes:
place_orderundget_order_summaryverwenden Schlüssel ohne Präfix (current_order). Dieser Status ist an die aktuelle Sitzung gebunden. Bei einer neuen Unterhaltung wird mit einer leeren Bestellung begonnen.set_dietary_preferenceundget_dietary_preferencesverwenden das Präfixuser:(user:dietary_preferences). Dieser Status wird für alle Sitzungen desselben Nutzers freigegeben.
KI-Agenten mit neuen Tools und Anweisungen aktualisieren
Ersetzen Sie die vorhandene root_agent-Definition unten in der Datei durch Folgendes:
# cafe_concierge/agent.py (replace the existing root_agent)
root_agent = LlmAgent(
name="cafe_concierge",
model="gemini-2.5-flash",
instruction="""You are a friendly and knowledgeable barista at "The Cloud Cafe".
Your job:
- Help customers browse the menu and answer questions about items.
- Take coffee and food orders.
- Remember and respect dietary preferences.
The customer's saved dietary preferences are: {user:dietary_preferences?}
IMPORTANT RULES:
- When a customer mentions a dietary restriction, ALWAYS save it using the
set_dietary_preference tool before doing anything else.
- Before recommending items, check the customer's dietary preferences. If they
have preferences saved, only recommend items compatible with those
restrictions. Check the menu item tags to determine compatibility.
- When placing an order, confirm the items and total with the customer.
Be conversational, warm, and concise.
""",
tools=[
get_menu,
place_order,
get_order_summary,
set_dietary_preference,
get_dietary_preferences,
],
)
In der Anleitung wird die Vorlage für die Statusinjektion {user:dietary_preferences?} verwendet, um die gespeicherten Einstellungen dieses Kunden direkt in den Prompt einzufügen.
Vollständige Datei überprüfen
Ihre cafe_concierge/agent.py-Datei sollte jetzt Folgendes enthalten:
- Das Wörterbuch „
CAFE_MENU“ - Fünf Tool-Funktionen:
get_menu,place_order,get_order_summary,set_dietary_preference,get_dietary_preferences - Die
root_agent-Definition mit allen fünf Tools
6. Agenten mit der ADK-Entwicklungsoberfläche testen
In diesem Schritt wird der Agent ausgeführt und alle zustandsbehafteten Funktionen werden getestet: Bestellung, Erfassung von Einstellungen und sitzungsübergreifender Speicher (innerhalb desselben Prozesses). Außerdem sehen Sie sich die Bereiche „Events“ und „State“ an, um zu sehen, wie das ADK die Unterhaltung intern verfolgt.
Entwicklungsoberfläche starten
cd ~/build-agent-adk-cloudsql
uv run adk web
Öffnen Sie die Webvorschau auf Port 8000 und wählen Sie cafe_concierge aus dem Drop-down-Menü aus.
Unterhaltung 1: Bestellung aufgeben und Einstellungen festlegen
Probieren Sie diese Prompts nacheinander aus:
What's on the menu?
I'm lactose intolerant
What would you recommend?
I'll have an oat milk latte and a banana bread
What's my order?
Sitzungsereignisse prüfen
Alle Ereignisse werden erfasst und in der Web-UI angezeigt. Im Chatfeld sehen Sie nicht nur Ihren Prompt und die Antwort, sondern auch tool_call und tool_response.

Sie sollten eine Liste der Ereignisse in chronologischer Reihenfolge sehen. Jedes Ereignis hat einen Autor (der es erstellt hat) und einen Typ (die Art der Interaktion, die es darstellt):
Author | Typ | Was wird dargestellt? |
|
| Eine Nachricht, die Sie in den Chat eingegeben haben |
|
| Die Textantwort des Agenten |
|
| Der Agent hat sich entschieden, ein Tool aufzurufen (zeigt Funktionsname + Argumente) |
|
| Der Rückgabewert eines Toolaufrufs |
Klicken Sie auf eines der tool_call-Ereignisse, z. B. den set_dietary_preference-Anruf. Hier sollten Sie dies sehen:
- Funktionsname:
set_dietary_preference - Argumente:
{"preference": "lactose intolerant"}
Klicken Sie nun direkt darunter auf das entsprechende tool_response-Ereignis. Sie sollten den Rückgabewert sehen:
- Antwort:
{"saved": "lactose intolerant", "all_preferences": ["lactose intolerant"]}

Suchen Sie im Ereignis „tool_response“ nach dem Feld state_delta. Hier sehen Sie genau, welcher Status sich durch diesen Tool-Aufruf geändert hat:
state_delta: {"user:dietary_preferences": ["lactose intolerant"]}
Jede Zustandsänderung lässt sich auf ein bestimmtes Ereignis zurückführen. So sorgt das ADK dafür, dass das State Scratchpad mit dem Unterhaltungsverlauf synchronisiert bleibt.
Sitzungsstatus prüfen
Klicken Sie auf den Tab Status. Im Gegensatz zum Ereignisprotokoll, in dem der vollständige Verlauf angezeigt wird, sehen Sie auf dem Tab „Status“ einen Snapshot des aktuellen Wissens des Agents – den aktuellen Wert jedes Statusschlüssels.

Sie sollten zwei Einträge sehen:
current_order–{"items": ["oat milk latte", "banana bread"], "total": 9.0}user:dietary_preferences–["lactose intolerant"]
Achten Sie auf den Unterschied bei den Schlüsselnamen:
current_orderhat kein Präfix, da sie auf Sitzungsebene gilt. Sie ist nur in dieser Unterhaltung vorhanden und verschwindet, wenn die Sitzung beendet wird.user:dietary_preferenceshat das Präfixuser:und ist nutzerbezogen. Er wird für jede Sitzung dieses Nutzers freigegeben.
Dieser Unterschied ist im Code nicht sichtbar (beide verwenden tool_context.state), er bestimmt aber, wie weit die Daten reichen. Das sehen Sie im nächsten Test.
Unterhaltung 2: Nutzerstatus über Sitzungen hinweg prüfen
Klicken Sie in der Entwickler-Benutzeroberfläche auf die Schaltfläche Neue Sitzung, um eine neue Unterhaltung zu starten. Dadurch wird eine neue Sitzung für denselben Nutzer erstellt.

Probieren Sie diesen Prompt aus:
What do you recommend for me?
Sehen Sie sich in der neuen Sitzung den Tab State (Status) an. Der user:dietary_preferences-Schlüssel wird übernommen, aber current_order ist nicht mehr vorhanden. Dieser Status war an die vorherige Sitzung gebunden.

7. Einschränkung des lokalen Speichers beachten
Der Agent merkt sich Einstellungen sitzungsübergreifend, aber nur solange der lokale Speicher vorhanden ist. In diesem Schritt wird die grundlegende Einschränkung des lokalen Speichers veranschaulicht.
Agent neu starten
Sie haben die Entwicklungsoberfläche am Ende des vorherigen Schritts beendet. Entfernen wir nun den lokalen Speicher und starten wir ihn neu, um eine serverlose Umgebung zu simulieren, die zustandslos ist:
cd ~/build-agent-adk-cloudsql
rm -f cafe_concierge/.adk/session.db
uv run adk web
Öffnen Sie nun die Webvorschau auf Port 8000 und wählen Sie cafe_concierge aus.
Testen, wie gut sich Nutzer an ihre Einstellungen erinnern
Typ:
Do you remember my dietary preferences?
Der Agent hat keine Erinnerung. Die Ernährungspräferenzen, der Bestellverlauf – alles weg.

Beim Löschen des lokalen Speichers wurde alles gelöscht. Das ist in der Regel der Fall, wenn wir eine serverlose Umgebung verwenden. Im session.db wird der gesamte Status im Prozessspeicher gespeichert. Wenn Sie sie entfernen, werden alle Daten gelöscht.
Die Lösung: Geben Sie DatabaseSessionService an. In dieser Anleitung werden alle Sitzungsdaten in einer PostgreSQL-Datenbank in Cloud SQL gespeichert. Der Agent-Code und die Tools bleiben genau gleich – nur das Speicher-Backend ändert sich.
Beenden Sie die Entwickler-UI mit Strg+C, bevor Sie fortfahren.
8. Datenbankeinrichtung überprüfen
An diesem Punkt sollte die Erstellung der Datenbankinstanz bereits abgeschlossen sein. Führen Sie den folgenden Befehl aus, um dies zu überprüfen:
gcloud sql instances describe cafe-concierge-db --format="value(state)"
Es sollte folgende Ausgabe angezeigt werden. Markieren Sie sie als abgeschlossen.
RUNNABLE
Datenbank erstellen
Erstellen Sie eine dedizierte Datenbank für die Sitzungsdaten des Agents:
gcloud sql databases create agent_db --instance=cafe-concierge-db
Cloud SQL Auth-Proxy starten
Der Cloud SQL Auth-Proxy bietet eine sichere, authentifizierte Verbindung von Cloud Shell zu Ihrer Cloud SQL-Instanz, ohne dass IP-Adressen auf die Zulassungsliste gesetzt werden müssen. Es ist bereits in der Cloud Shell vorinstalliert.
cloud-sql-proxy ${GOOGLE_CLOUD_PROJECT}:${REGION}:cafe-concierge-db --port 5432 &
Das Suffix & im Befehl sorgt dafür, dass der Proxy im Hintergrund ausgeführt wird. Sie sollten eine Ausgabe sehen, die bestätigt, dass der Proxy bereit ist, wie unten dargestellt.
[your-project-id:your-region:cafe-concierge-db] Listening on 127.0.0.1:5432 The proxy has started successfully and is ready for new connections!
Verbindung prüfen
Testen Sie, ob Sie über den Proxy eine Verbindung zur Datenbank herstellen können:
psql "host=127.0.0.1 port=5432 dbname=agent_db user=postgres password=$DB_PASSWORD" -c "SELECT 'Connection ok' AS status;"
Hier sollten Sie dies sehen:
status --------------------- Connection ok (1 row)
9. Persistent Memory über Sitzungen hinweg überprüfen
In diesem Schritt wird nachgewiesen, dass der Arbeitsspeicher Ihres Agent das Zurücksetzen übersteht, indem wir dafür sorgen, dass cafe_concierge/.adk/session_db (die lokale Datenbank) entfernt wird und sich über Gesprächssitzungen erstreckt.
Agent starten
Prüfen Sie, ob der Cloud SQL Auth-Proxy noch ausgeführt wird (mit Jobs). Wenn das nicht der Fall ist, starten Sie es neu:
if ss -tlnp | grep -q ':5432 '; then
echo "Cloud SQL Auth Proxy is already running."
else
cloud-sql-proxy ${GOOGLE_CLOUD_PROJECT}:${REGION}:cafe-concierge-db --port 5432 &
fi
Starten wir dann die ADK-Entwicklungsoberfläche, indem wir die Datenbank als Sitzungsdienst angeben.
uv run adk web --session_service_uri postgresql+asyncpg://postgres:${DB_PASSWORD}@127.0.0.1:5432/agent_db
Öffnen Sie die Webvorschau auf Port 8000 und wählen Sie „cafe_concierge“ aus.
Test 1: Bestellung aufgeben und Einstellungen festlegen
Führen Sie in der ersten Sitzung die folgenden Schritte aus:
Show me the menu
I'm vegan
What can I eat?
I'll have a cold brew and banana bread
Test 2: Neustart überstehen
Beenden Sie die Entwickler-UI mit Strg + C und entfernen Sie die lokale session.db.
rm -f cafe_concierge/.adk/session.db
Führen Sie den Dev-UI-Server dann noch einmal aus.
uv run adk web --session_service_uri postgresql+asyncpg://postgres:${DB_PASSWORD}@127.0.0.1:5432/agent_db
Öffnen Sie die Webvorschau auf Port 8000, wählen Sie cafe_concierge aus und starten Sie eine neue Sitzung. Fragen Sie dann
What are my dietary preferences?
Der Agent antwortet mit Ihren gespeicherten Einstellungen – vegan. Die Daten sind nach dem Neustart noch vorhanden, da sie jetzt in PostgreSQL und nicht mehr im lokalen Speicher gespeichert sind. Das ist auch der Fall, wenn wir eine neue Sitzung erstellen, da der user:-Status für diesen Nutzer in jede neue Sitzung übernommen wird.

Datenbank direkt prüfen
Öffnen Sie in Cloud Shell einen neuen Terminaltab und fragen Sie die Datenbank ab, um die gespeicherten Daten zu sehen:
psql "host=127.0.0.1 port=5432 dbname=agent_db user=postgres password=$DB_PASSWORD" -c "\dt"
Sie sollten Tabellen sehen, die vom ADK automatisch erstellt wurden, um Sitzungen, Ereignisse und Status zu speichern, wie in diesem Beispiel:
List of relations Schema | Name | Type | Owner --------+-----------------------+-------+---------- public | adk_internal_metadata | table | postgres public | app_states | table | postgres public | events | table | postgres public | sessions | table | postgres public | user_states | table | postgres (5 rows)
Zusammenfassung des Statusverhaltens
Status-Schlüssel | Präfix | Ebene | Über Sitzungen hinweg freigegeben? |
| (keine) | Sitzung | Nein |
|
| Nutzer | Ja |
10. Glückwunsch / Bereinigen
Glückwunsch! Sie haben mit dem ADK und Cloud SQL erfolgreich einen persistenten, zustandsorientierten KI-Agenten erstellt.
Lerninhalte
- ADK-Agent mit benutzerdefinierten Tools erstellen, die den Sitzungsstatus lesen und schreiben
- Der Unterschied zwischen dem sitzungsbezogenen Status (kein Präfix) und dem nutzerbezogenen Status (
user:-Präfix) - Warum die lokale ADK-Standardkonfiguration
session.dbnur für die Entwicklung geeignet ist: Alle Daten gehen beim Entfernen verloren (und lassen sich leicht entfernen, keine Sicherung), nicht geeignet für die serverlose Bereitstellung, die zustandslos ist. - Cloud SQL PostgreSQL-Instanz bereitstellen und mit dem Cloud SQL Auth-Proxy eine Verbindung herstellen
- Mit minimalen Codeänderungen über PostgreSQL in Cloud SQL eine Verbindung zu DatabaseSessionService herstellen – dieselben Tools, derselbe Agent, anderes Backend
- So wird der Status auf Nutzerebene über separate Unterhaltungssitzungen hinweg beibehalten
Aufräumen
Um zu vermeiden, dass Ihrem Google Cloud-Konto Gebühren in Rechnung gestellt werden, bereinigen Sie die in diesem Codelab erstellten Ressourcen.
Option 1: Projekt löschen (empfohlen)
Am einfachsten bereinigen Sie, indem Sie das Projekt löschen. Dadurch werden alle mit dem Projekt verknüpften Ressourcen entfernt.
gcloud projects delete ${GOOGLE_CLOUD_PROJECT}
Option 2: Einzelne Ressourcen löschen
Wenn Sie das Projekt behalten, aber nur die in diesem Codelab erstellten Ressourcen entfernen möchten:
gcloud sql instances delete cafe-concierge-db --quiet