1. Übersicht
Die Überschrift von ADK 2 lautet Drei Orchestrierungsmuster. In diesem Codelab werden alle drei Konzepte anhand einer App – einem Marathon Race Day Coach – nach und nach erklärt. Jedes Level beantwortet eine einzelne Frage, fügt eine Idee hinzu und wird eigenständig ausgeführt.
Lerninhalte
- Graph-Workflows (Säule 1): Hier können Sie den Ablauf zeichnen, bevor die Eingabe erfolgt.
- Kollaborative Agents (Säule 2): Hier kennen Sie das Team, aber die Anfrage wählt die Teilmenge aus. Alle drei Kollaborationsmodi (
chat/task/single_turn) werden live ausgeführt. - Dynamische Workflows (Säule 3): Hier hängt die Form der Arbeit selbst von der Eingabe ab.
- Auswahl – ein Entscheidungsbaum mit einer Frage und wie die Muster zusammengesetzt werden.
Der rote Faden
Bekannte Struktur → bekannte Teilmenge von Teams / Variablen → unbekannte Form → die richtige auswählen

Aufgaben
Eine App – der Marathon Race Day Coach – hat jeweils eine laufbare Ebene zusammengestellt. Jedes Level ist ein einfaches Python-Modul, das Sie über das Terminal ausführen. Ab L5 sind die folgenden Teile alle Ihre.
Das Bild wird aus dem laufenden Code generiert: Jede durchgezogene Linie wurde aus Workflow.graph.edges gelesen. Das ist die erste Lektion: Die Teile, die im Voraus erstellt werden können, sind genau Säule 1. Die Teile, die nicht im Voraus erstellt werden können, sind der Grund für die Existenz von Säule 2 und 3.

Voraussetzungen
- Ein Google-Konto (für Colab) – keine lokale Einrichtung erforderlich.
- ~50 Minuten (die beiden L4-Stufen sind die längsten – plane sie ein).
- Eine von zwei Möglichkeiten, ein Gemini-Modell zu erreichen. Wähle eine Methode aus: Du führst einen Einrichtungsschritt aus und überspringst den anderen:
🎓 Workshop | 🏠 Take-home | |
Wer | Sie nehmen an einem Live-Workshop teil und der Kursleiter hat Ihnen einen Link zum Einlösen von Guthaben gegeben. | Alle anderen, einschließlich der Workshopteilnehmer, danach |
Sie benötigen | Der Anspruchslink und ein Google-Konto, mit dem ein Cloud-Projekt erstellt werden kann | Ein kostenloser AI Studio-API-Schlüssel |
Läuft auf | Vertex AI in einem Projekt, das über Ihr Workshop-Guthaben abgerechnet wird | Google AI Studio |
Kosten | Durch das Guthaben abgedeckt | Kostenlose Stufe |
Einrichtungsschritt | Workshop-Einrichtung (nächster Schritt) | Einrichtung zu Hause (der nächste Schritt) |
Alles ab dem Prolog ist in beiden Fällen identisch. Die Lane bestimmt nur, mit welchem Modellendpunkt das Notebook kommuniziert.
Zwei Möglichkeiten, um mitzumachen
Jeder Schritt unten entspricht einer Zelle im Colab-Notebook und einem Ordner im GitHub-Repository. Wählen Sie eine der folgenden Optionen aus:
- ▶ Colab (empfohlen) : Notebook öffnen → Zellen von oben nach unten ausführen.
- 💻 Lokal :
git clonedas Repository,./setup_venv.shund dann jede Ebene als Modul (python -m ...) ausführen oder alle mit./run.sh(adk web) durchsuchen.
2. Workshop-Einrichtung · Guthaben einlösen und zu Vertex AI wechseln
Im Workshop erhalten Sie Google Cloud-Guthaben. Sie beanspruchen es, erstellen ein Projekt, das darüber abgerechnet wird, und verweisen das Notebook auf Vertex AI anstelle von AI Studio. Eine Zelle erledigt alles nach dem Anspruch.
1. Guthaben sichern (~1 Min.)
- Öffnen Sie den Link zum Einlösen, den Ihr Kursleiter geteilt hat. Er sieht so aus:
https://me.developers.google.com/benefits/claim/your-workshop-name. - Melden Sie sich an und folgen Sie der Anleitung auf der Seite, um die Gutschrift zu akzeptieren.
- Notieren Sie sich, welches Google-Konto Sie verwendet haben. Jeder der folgenden Schritte muss mit diesem Konto ausgeführt werden.
2. Notebook öffnen und ADK 2 installieren (ca. 1 Minute)
Klicken Sie auf In Colab öffnen ▶ und führen Sie dann die erste Codezelle aus. Damit wird die genaue ADK 2-Version festgelegt, mit der dieses Codelab getestet wurde, und ✓ installed wird ausgegeben.
3. Führen Sie die Zelle „Workshop setup“ aus. (ca. 3 Minuten)
Das ist die Zelle mit dem Titel 🎓 Pfad A · Workshop. Führen Sie es aus. Sie werden von Colab aufgefordert, die Autorisierung zu bestätigen. Wählen Sie dasselbe Google-Konto aus, mit dem Sie gerade das Guthaben eingelöst haben, und gewähren Sie den Zugriff.
Dabei werden vier Dinge erledigt: Es wird ein Projekt namens adk-2-tutorial-XXXX auf Ihrem Guthaben erstellt, die Vertex AI API wird aktiviert, die vier Umgebungsvariablen werden festgelegt, die in jeder späteren Zelle gelesen werden, und dann wird ein Testaufruf an Vertex gesendet und gewartet, bis eine Antwort erfolgt. Die Einrichtung wird also entweder abgeschlossen oder Sie erfahren, warum sie nicht abgeschlossen wurde, anstatt dass sie später in einem Level fehlschlägt.
Erwartete Ausgabe – die letzte Zeile ist wichtig:
Signed in as: you@example.com
...
Successfully created GCP project 'adk-2-tutorial-4817'.
Successfully linked 'adk-2-tutorial-4817' to billing account '01ABCD-...'.
waiting for Vertex AI to come up on the new project... (10s)
waiting for Vertex AI to come up on the new project... (20s)
✅ Vertex AI on adk-2-tutorial-4817 · us-central1 · gemini-2.5-flash — answered a test call
4. Schritt „Einrichtung zu Hause“ überspringen
Führen Sie die AI Studio-Schlüsselzelle nicht aus, da das Notebook sonst wieder zu AI Studio zurückwechselt und Ihre Änderungen rückgängig gemacht werden. (Die Zelle schützt vor diesem Fehler und wird nicht ausgeführt. Es ist jedoch besser, sie einfach zu überspringen.) Direkt zur Zelle „Gemeinsame Bausteine“ springen
5. Zelle „Gemeinsam genutzte Bausteine“ ausführen
Führen Sie sie einmal aus. Hier werden die Pydantic-Schemas und vordefinierten Marathon-Szenarien definiert, die ab L2 wiederverwendet werden. Sie sehen ✓ schemas + scenarios ready.
Nach dem Workshop
Ihr Guthaben und das damit erstellte Projekt sind nicht unbegrenzt gültig. Wenn Sie diese Levels nach dem Workshop kostenlos wiederholen möchten, führen Sie stattdessen den Schritt Take-home setup aus. Dazu benötigen Sie einen kostenlosen AI Studio-Schlüssel, aber kein Cloud-Projekt und keine Abrechnung. Nur diese eine Zelle wird geändert.
Wenn Sie die Bereinigung früher durchführen möchten, öffnen Sie die Cloud Console, wählen Sie adk-2-tutorial-XXXX aus und löschen Sie sie. Durch nichts anderes in diesem Codelab werden kostenpflichtige Ressourcen erstellt.
3. Einrichtung zu Hause · AI Studio-API-Schlüssel
Alles auf diesem Pfad wird mit einem kostenlosen Google AI Studio-API-Schlüssel ausgeführt – kein Google Cloud-Projekt, keine Abrechnung, keine lokale Installation. Dieser Schritt dauert etwa 3 Minuten.
1 · Notebook öffnen
Klicken Sie auf In Colab öffnen ▶. Sie werden zum Notebook weitergeleitet. Es enthält eine Markdown-Einführung und dann eine ausführbare Zelle pro Level. Sie führen Zellen von oben nach unten aus. Die Ausgabe jeder Zelle wird direkt darunter ausgegeben.
2. ADK 2 installieren (ca. 1 Minute)
Führen Sie die erste Codezelle aus. Damit wird die genaue Version festgelegt, mit der dieses Codelab getestet wurde:
%pip install -q "google-adk==2.3.0" python-dotenv pydantic nest_asyncio
Warten Sie, bis der Vorgang abgeschlossen ist. Dann sehen Sie ✓ installed. Die Installation dauert beim ersten Mal etwa 30–60 Sekunden. Danach wird sie im Cache gespeichert.
3. Gemini API-Schlüssel aus AI Studio abrufen (ca. 1 Minute)
- Öffnen Sie aistudio.google.com/app/apikey in einem neuen Browsertab.
- Melde dich mit deinem Google-Konto an.
- Klicken Sie rechts oben auf API-Schlüssel erstellen.
- Wählen Sie ein vorhandenes Google-Projekt aus oder lassen Sie eines erstellen.
- Kopieren Sie den Schlüssel. Er beginnt mit
AIza...und ist etwa 40 Zeichen lang.
4. Schlüssel in Colab hinzufügen (ca. 1 Minute)
Option A: Colab Secrets (empfohlen; der Schlüssel bleibt verborgen):
- Klicken Sie in der linken Seitenleiste von Colab auf das Schlüsselsymbol 🔑.
- Klicken Sie auf + Neues Secret hinzufügen.
- Legen Sie als Name genau
GOOGLE_API_KEYfest. - Fügen Sie den Schlüssel in Value ein.
- Stellen Sie den Notebook-Zugriff auf EIN.
Option B: Einfügen, wenn Sie dazu aufgefordert werden (schnell): Überspringen Sie das Secret. Wenn Sie die nächste Zelle ausführen, wird eine verborgene Aufforderung 🔑 Enter your Google AI Studio API key: angezeigt. Fügen Sie das Secret ein und drücken Sie die Eingabetaste.
5. Schlüsselzelle ausführen
Das Geheimnis wird gelesen (oder es wird auf den Einfüge-Prompt zurückgegriffen) und das ADK verweist auf AI Studio (nicht auf Vertex AI):
import os
# 🏠 TAKE-HOME ONLY — if you ran the Workshop setup cell, skip this one.
if os.environ.get("GOOGLE_GENAI_USE_VERTEXAI") == "True":
raise SystemExit("✋ You're set up on the workshop path (Vertex AI). Skip this cell.")
# Google AI Studio API key — add GOOGLE_API_KEY in the 🔑 Secrets panel (or paste when prompted).
try:
from google.colab import userdata
key = userdata.get("GOOGLE_API_KEY")
except Exception:
import getpass
key = getpass.getpass("Enter your Google AI Studio API key: ")
os.environ["GOOGLE_API_KEY"] = "".join(key.split()) # drop any stray whitespace/newlines
os.environ["GOOGLE_GENAI_USE_VERTEXAI"] = "False" # use AI Studio, not Vertex AI
print("✅ API key set — using Google AI Studio.")
Erwartete Ausgabe: ✅ API key set — using Google AI Studio.
6. Zelle „Gemeinsam genutzte Bausteine“ ausführen
Führen Sie die Zelle Shared building blocks einmal aus. Hier werden die Pydantic-Schemas und vordefinierten Marathon-Szenarien definiert, die ab L2 wiederverwendet werden. Sie sehen ✓ schemas + scenarios ready.
Das war's! 🎽 Bevor wir uns L0 ansehen, die Version, die jeder zuerst erstellt, machen wir einen kurzen Abstecher.
4. Prolog · Warum nicht nur ein großer Prompt?
⚡ Bevor du den Code ausführst, solltest du dir genau ansehen, woher die einzelnen Zahlen stammen. Das ist die gesamte Übung – alles andere ist Dekoration.
Vor der Leiter: Führen Sie das aus, was die Leiter ersetzt: ein Agent, dessen Prompt alles verspricht – das Wetter abrufen, den Kurs analysieren, das Trainingsprotokoll lesen, die Route nach Bedingungen festlegen, den Plan ausgeben.
Was Sie sehen: eine überzeugende, spezifische und gut formatierte Strategie, deren Zahlen erfunden sind. Bei einem Live-Lauf wurde die Antwort mit „Ich habe die Wetterdaten von heute abgerufen“ eingeleitet und es wurden 11 °C, ein Wind mit 14 km/h und eine Analyse eines Trainingsprotokolls ausgegeben, das noch nie zuvor gesehen wurde. Es gibt keine Wetter-API, keine Kursdaten und kein Log. Ein undurchsichtiger Modellaufruf erfindet entweder seine Eingaben oder schränkt sie so ein, dass sie nutzlos sind.
Das ist die Krankheit und sie hat vier Symptome, die es wert sind, genannt zu werden:
- Sie können sich nicht darauf verlassen: Die Daten werden fließend erfunden.
- Sie können sie nicht testen: Das Routing von Schritt 4 ist im Fließtext enthalten. Es gibt kein
iffür Einheitentests. - Schritt kann nicht getauscht werden: Es gibt keine Stelle, an der eine echte Wetter-API eingebunden werden könnte.
- Sie zahlen jedes Mal für alles – fünf Schritte, ein riesiger Aufruf, kein Caching eines deterministischen Teils.
Halte dieses Gefühl fest. In den nächsten neun Stufen werden diese Schritte einzeln aus dem Prompt entfernt: Funktionen rufen Daten ab (L1–L2a), eine if-Anweisung leitet Anfragen weiter (L2b), Spezialisten teilen die Arbeit auf (L3a–L3b) und Code begrenzt die Form (L4a–L4b).

💻 Lokal : python -m shared.prologue
5. L0 · Ihr erster ADK2-Agent

⚡ Kurz gesagt:Ein Agent ist ein Modell + eine Anleitung + Tools, die er aufrufen kann. Ein Runner führt ihn aus. Danach kommen nur noch mehr Agenten, die in besseren Formen angeordnet sind.
Die Frage:Kann ein Modell so trainiert werden, dass es Fragen beantwortet und echten Code verwendet, wenn es um Arithmetik geht?
Eine Idee – drei Teile:
Agent: Das Element, das Schlussfolgerungen zieht (ein Gemini-Modell + eine Anleitung).Runner: Das Element, das einen Agenten in einer Sitzung ausführt und Ereignisse streamt.- Tool: Eine einfache Python-Funktion (
pace_splits), die vom Modell aufgerufen wird. Das ADK liest die Signatur und den Docstring und übergibt dem Modell eine Deklaration. Es muss kein Schema geschrieben werden.
Nach dem Prolog ist dies die erste Reparatur: Ein LLM, das im Kopf mit dem Tempo rechnet, wird wahrscheinlich falsch liegen – pace_splits ist deterministisches Python-Code, sodass die Zahlen in der Antwort berechnet und nicht improvisiert werden.
▶ Colab:Führen Sie die L0-Zelle aus. · 📁 GitHub: L0_first_agent/ · 💻 Lokal: python -m L0_first_agent.agent

def pace_splits(target_finish: str) -> dict:
"""Convert a goal time like '3:30:00' into exact per-mile / per-km paces."""
... # deterministic Python — no LLM
pace_coach = Agent(
name="pace_coach", model=MODEL,
tools=[pace_splits], # the model may call it; ADK reads the signature
instruction="You are a friendly, concise marathon coach. ... If the runner "
"mentions a goal time, call pace_splits — never do arithmetic yourself.",
)
runner = Runner(node=pace_coach, session_service=InMemorySessionService(), auto_create_session=True)
async for event in runner.run_async(user_id="u1", session_id="s1", new_message=msg):
... # events carry the model's text
🔍 Die Markierungen : Agent(...) · tools=[pace_splits] · Runner(...). In der Ausgabe ist die Zeile 🔧 zu sehen. Das ist das Modell, das sich mitten in der Antwort entscheidet, Ihren Code aufzurufen.
Das erwartet Sie:
🔧 model called tool → pace_splits({'target_finish': '3:30:00'})
🔧 tool returned → {'per_mile': '8:00', 'per_km': '4:58', ...}
🧠 Coach: To finish in 3:30:00, you need an average pace of 8:00 per mile...
Die Zeilen mit 🔧 sind die Lektion: In der Mitte der Antwort hat das Modell entschieden, Ihre Funktion aufzurufen, und die genaue 8:00/mile in der Antwort stammt aus Ihrem Code – nicht aus Tokenstatistiken.
❓ Sie fragen sich vielleicht , ob das Modell das Tool immer aufruft. Nein. Die Entscheidung wird für jede Frage einzeln getroffen. Wenn Sie etwas ohne Zahlen fragen, verschwinden die 🔧-Zeilen (im Playground wird genau das ausprobiert).
👀 Lesen : pace_splits (eine einfache Funktion) und die Zeile tools=[pace_splits]. · ▶ Führen Sie die Datei aus. · ✏️ Änderung:Stelle die allgemeine Frage (ohne Zielzeit). Die 🔧-Zeilen verschwinden: Das Modell entscheidet, wann es sich lohnt, ein Tool aufzurufen. Schreiben Sie dann instruction um und führen Sie den Befehl noch einmal aus. Die Anweisung ist der Rest des Programms.
6. L1 · Ihr erster Workflow

⚡ Kurz gesagt:Eine einfache Funktion und ein LLM-Agent sind dieselbe Art von Knoten. Vorhersagbare Arbeit → Funktion (0 LLM, deterministisch); Schlussfolgerung → Agent.
Die Frage: Wie können Sie einfachen Code und ein LLM in einem Flow kombinieren, ohne für einen Modellaufruf für die Teile zu bezahlen, die nur Code sind?
Die eine Idee:In einem Workflow sind eine einfache Python-Funktion und ein LLM-Agent beides nur Knoten in derselben edges-Liste.
START ──► fetch_conditions (function, 0 LLM) ──► advise (agent, 1 LLM)
▶ Colab:Führen Sie die L1-Zelle aus. · 📁 GitHub: L1_graph_basics/ · 💻 Lokal: python -m L1_graph_basics.workflow

Der Funktionsknoten gibt die von ihm erstellten Daten aus (kein Modellaufruf). Der Agent gibt dann Ratschläge, die sich auf die tatsächliche Temperatur und den Wind beziehen, die er erhalten hat:
def fetch_conditions(node_input): # function node — 0 LLM
return Event(output=Conditions(temp_f=78, wind_mph=12, conditions="sunny").model_dump())
advise = Agent(name="advise", model=MODEL, mode="single_turn",
input_schema=Conditions, instruction="...give pacing + gear advice...")
workflow = Workflow(edges=[(START, fetch_conditions, advise)])
🔍 Die Markierungen:Ein Edge-Tupel – (START, fetch_conditions, advise) – mit einer einfachen Python-Funktion in der Mitte und input_schema= zur Validierung der Übergabe.
Neuerungen im Vergleich zu L0 : Workflow(edges=[...]), START (wo die Eingabe erfolgt), ein Funktionsknoten, der Event(output=...) zurückgibt, und input_schema=Conditions. Die Ausgabe der Funktion wird also anhand dieses Schemas validiert, bevor der Agent sie sieht (als JSON-Text – input_schema validiert die Grenze, übergibt dem Agenten aber kein Python-Objekt).
❓ Häufig gestellte Frage : Muss die Reihenfolge „Funktion – Agent“ eingehalten werden? Nein – beliebige Reihenfolge, beliebige Mischung, beliebige Anzahl. advise wird erst an zweiter Stelle ausgeführt, da die Daten von fetch_conditions benötigt werden. Die Lektion ist die Gleichrangigkeit, nicht die Reihenfolge.
👀 Lesen: fetch_conditions gibt Daten ohne Modellaufruf zurück; advise enthält input_schema=Conditions. · ▶ Führen Sie die Datei aus. · ✏️ Änderung:Legen Sie temp_f=30 in der Funktion fest und führen Sie sie noch einmal aus. Die Empfehlung wird umgekehrt und die Funktion kostet weiterhin 0 LLM-Aufrufe.
7. L2a · Paralleler Fan-out + JoinNode (Pillar 1a)

⚡ Zusammenfassung:Parallel ausführen (kostenlos), auf alle warten, bündeln und einem Agenten das Gesamtbild übergeben.
Die Frage:Sie können den Ablauf zeichnen, bevor die Eingabe erfolgt. Beginnen Sie mit dem Gerüst: Erfassen Sie Daten parallel, bündeln Sie sie und übergeben Sie sie an einen Agenten.
Die Form:
START ──► fetch_weather ──┐
START ──► analyze_course ─┼─► JoinNode ─► strategy (1 agent)
START ──► pull_fitness ───┘ (bundles)
▶ Colab:Führen Sie die L2a-Zelle aus. · 📁 GitHub: L2a_parallel_join/ · 💻 Lokal: python -m L2a_parallel_join.workflow

🔍 Die Markierungen:drei Kanten, die alle bei START beginnen – das ist der Fan-out – und JoinNode, der Treffpunkt.
- Die drei Abrufe sind Funktionen, die parallel ausgeführt werden. Es sind keine LLM-Aufrufe erforderlich.
JoinNodewartet auf alle drei und fasst sie in einer typisierten Nutzlast (BundledRunData) zusammen, die nach Funktionsname verschlüsselt ist.- Ein
strategy-Agent liest das Bundle und schreibt eineRaceStrategy.
Was Sie sehen:Bei jedem Abruf wird ein started- / finished-Zeitstempel ausgegeben. Alle drei beginnen bei 0,0 s und der Fan-out endet bei 2,0 s – dem langsamsten Abruf, nicht bei den 4,5 s, die sich aus der Summe der Dauern ergeben würden. Diese Überschneidung ist die Parallelität. Die Gesamt-Echtzeit, die am Ende ausgegeben wird, beträgt etwa 8 Sekunden, da sie auch den LLM-Aufruf des Strategie-Agents enthält. Lesen Sie die Abruf-Zeitstempel für die parallele Anforderung, nicht die Gesamtdauer.
💡 Prologue-Callback:Der Mega-Prompt hat das Wetter erfunden. Die Temperatur stammt hier aus einer Fetch-Funktion – echter Code, echte Nahtstelle. Ersetzen Sie das vordefinierte Dict durch eine tatsächliche Wetter-API. Ansonsten ändert sich nichts.
❓ Sie fragen sich vielleicht: Wie viel
JoinNode
muss ich verstehen? In einem Satz: Es wird gewartet, bis alle parallelen Zweige abgeschlossen sind. Die Ausgaben werden in einem Dictionary mit dem Namen der Upstream-Funktion als Schlüssel zusammengefasst. Es wird nichts selbst berechnet. Genau deshalb kann der Router von L2b node_input["fetch_weather"]["temp_f"] schreiben.
👀 Lesen:Drei Kanten gehen von START aus; JoinNode bündelt sie für einen Agenten. · ▶ Führen Sie die Analyse aus und lesen Sie die Zeitstempel, nicht die Gesamtzahl. · ✏️ Änderung:Ein Abruf wird in den Ruhemodus versetzt 3.0 – zuerst die neue Endzeit für den Fan-out vorhersagen und dann bestätigen.
8. L2b · Deterministischen Router hinzufügen (Säule 1b)

⚡ Kurzfassung:L2a bleibt unverändert + ein einfacher if entscheidet, welcher eine Agent ausgeführt wird. Verzweigung ohne das Modell zu fragen.
Die Frage:Der Plan sollte sich bei heißem und kaltem Wetter unterscheiden. Wie verzweigen Sie sich, ohne das Modell zu bitten, eine Entscheidung zu treffen?
Die Form (L2a + Router):
... JoinNode ─► route_by_weather ─► hot_strategy
(if-statement) ─► normal_strategy
─► cold_strategy
▶ Colab:Führen Sie die L2b-Zelle aus – versuchen Sie es mit run("NORMAL") / run("COLD") · 📁 GitHub: L2b_router/ · 💻 Lokal: python -m L2b_router.workflow COLD

def route_by_weather(node_input): # an if-statement, 0 LLM
temp = node_input["fetch_weather"]["temp_f"]
route = "HOT" if temp >= 70 else "COLD" if temp <= 40 else "NORMAL"
return Event(output=node_input, route=route)
(route_by_weather, {"HOT": hot_strategy, "NORMAL": normal_strategy, "COLD": cold_strategy})
🔍 Die Markierungen : Event(output=..., route=...) – ein Funktionsknoten, der den Pfad benennt – und die Dict-Kante {"HOT": ..., "NORMAL": ..., "COLD": ...}, die Namen Knoten zuordnet.
Das Wichtigste – drei Arten von Arbeit, drei Arbeitsplätze:
- Vorhersehbare Arbeit → Funktionen (die drei parallelen Abrufe)
- Eine klare Regel → explizites Routing (
route_by_weatherist eineif-Anweisung, keine Modellentscheidung) - Begründung → das Modell (genau ein Strategie-Agent wird ausgeführt)
Was Sie sehen : temp=78F -> route=HOT, gefolgt von einer strukturierten RaceStrategy. Nettokosten: 1 LLM-Aufruf
⚠️ Wenn Sie einen vierten Zweig hinzufügen,geben Sie dem Routen-Dictionary auch einen DEFAULT_ROUTE-Eintrag. Eine Route, die nicht mit dem Dict übereinstimmt, ist kein Fehler. Der Zweig wird einfach beendet und das Programm wird mit dem Exit-Code 0 ohne Ausgabe beendet. Das ist eine verwirrende Sackgasse für das Debugging.
❓ Sie fragen sich vielleicht: Ist L2b also im Grunde L2a plus ein Router? Ja. Die Abrufe und der Join bleiben unverändert und es ist weiterhin genau 1 LLM-Aufruf. Was hat sich geändert: „immer derselbe Kundenservicemitarbeiter“ wurde zu „einer von drei, ausgewählt anhand von Daten“.
👀 Lesen: route_by_weather – der Router ist eine if-Anweisung, kein Agent. · ▶ Lauf run("COLD") · ✏️ Ändern:Fügen Sie einen WINDY-Zweig mit einem vierten Agenten hinzu. Lesen Sie dazu vorher den DEFAULT_ROUTE-Warnhinweis oben.
9. L3a · Collaborative Agents: one flag, two worlds – Pillar 2

⚡ Zusammenfassung: Gleiches Team, ein Flag. chat übergibt die gesamte Unterhaltung an einen Spezialisten und kehrt nie zurück. single_turn macht jeden Spezialisten zu einem Tool – parallele Teilmenge, automatische Rückgabe, eine Synthese.
Die Frage:Sie kennen das Team, aber die Anfrage entscheidet, welche Mitglieder antworten sollen. Wie lassen Sie ein LLM die Teilmenge auswählen und gleichzeitig ausführen?
Die Form:ein Koordinator für sechs Spezialisten (medizinisch, Wetter, Tempo, Ausrüstung, Ernährung, mental). Auf dieser Ebene wird dasselbe Team zweimal eingesetzt – mit demselben Coordinator-Prompt und denselben sechs Spezialisten. Der einzige Unterschied ist ein Flag für die untergeordneten Vertreter. Der Kontrast ist die Lektion.
▶ Colab:Führen Sie die L3a-Zelle aus. · 📁 GitHub: L3a_collaborative/ · 💻 Lokal: python -m L3a_collaborative.concierge --mode chat "What about fueling?"

🔍 Die Markierungen : mode="single_turn" in der Fabrik und in der Ausgabe, TRANSFER → (Beat 1) im Vergleich zu einem Burst von DISPATCH → Zeilen mit einem gemeinsamen Zeitstempel (Beat 2).
Beat 1: Führen Sie zuerst den Standard aus und beobachten Sie, wie der Job fehlschlägt.
Keine mode= geschrieben → Sub-Agents haben standardmäßig chat. Was wird angezeigt?
TRANSFER → nutrition_specialist (transfer_to_agent — the only tool chat subagents provide)
Final speaker: nutrition_specialist
Der Koordinator hat keine Delegierungstools – Chat-Sub-Agents geben ihm nur transfer_to_agent, eine serielle Übergabe der gesamten Unterhaltung an einen Spezialisten. Dieser Spezialist antwortet dem Nutzer direkt und der Lauf wird beendet. Kein paralleler Versand. Keine Rückgabe. Keine Synthese. Wenn Sie die allgemeine Frage stellen, wird es noch schlimmer: sechs Spezialisten, eine Weiterleitung.
Das ist kein Fehler, sondern der Chat-Modus macht genau das, was er soll. Die Unterhaltung gehört demjenigen, der sie führt, bis sie explizit übertragen wird. Richtig für einen Assistant mit offenem Ende, falsch für einen Pipelineschritt.
Beat 2 · Eine Flagge, zwei Welten
Einziger Unterschied: mode="single_turn" für jeden Spezialisten. Dieselbe Frage, noch einmal ausführen:
[t= 7.8s] DISPATCH → medical_specialist ← same timestamp =
[t= 7.8s] DISPATCH → weather_specialist one turn, many calls
[t=14.5s] ↩ medical_specialist replied ← replies land inside
[t=14.5s] ↩ weather_specialist replied one short window
🧠 Concierge (synthesized): <one answer>
Das ADK fügt jetzt ein Delegierungstool pro Spezialist ein, das nach dem untergeordneten Kundenservicemitarbeiter benannt und durch seine description= beschrieben wird. Dieser Text wird vom Koordinator gelesen, wenn er die Teilmenge auswählt. Wenn Sie ihn überspringen, wird nur anhand der Namen weitergeleitet. Der Koordinator gibt mehrere Aufrufe in einem Zug aus, das ADK führt sie parallel aus, jedes gibt sein Ergebnis automatisch zurück und der Koordinator synthetisiert.
Frage | Spezialisten, die feuern |
„Wie sieht es mit dem Auftanken aus?“ | Nur Ernährung |
„Mein Knie schmerzt bei Kilometer 29.“ | Nur medizinisch |
„Soll ich heute ein Rennen fahren?“ | medizinisch + Wetter + Tempo |
„Muss ich mir Sorgen machen?“ | alle 6 |
Warum jeder Spezialist das gesamte Briefing erhält:Jeder single_turn-Sub-Agent wird in einem eigenen isolierten Sitzungszweig ausgeführt. Er kann die Unterhaltung oder seine Peers nicht sehen. Nichts ist ambient: Der Koordinator muss die gesamte SpecialistInput (Frage + Strategie + Runner-Daten) separat an jeden parallelen Aufruf weiterleiten.
💡 Hier ist ADK2 direkt anwendbar:Ein LLM wählt eine Teilmenge pro Anfrage aus UND führt sie parallel aus – deklariert über sub_agents + mode="single_turn". In Version 1.x konnten Sie dieselbe Form erstellen, indem Sie jeden Spezialisten in AgentTool eingeschlossen haben. Der Unterschied besteht darin, dass es sich jetzt um eine Deklaration und nicht mehr um eine Infrastruktur handelt. (ParallelAgent ist immer „all“ und transfer_to_agent ist „serial“.)
⚠️ Zwei wichtige Hinweise: (1) Das Modell wählt die Teilmenge aus. Daher ist es weniger deterministisch als der hartcodierte Router von L2. Die genaue Teilmenge kann sich von Ausführung zu Ausführung unterscheiden. (2) Gelegentlich sehen Sie für einen Spezialisten eine Error validating input: ...-Zeile. Es ist fast nie die Ausgabe des Spezialisten – output_schema sorgt dafür, dass Gemini dies serverseitig erzwingt. Es ist die Eingabe: Der Koordinator muss das gesamte verschachtelte SpecialistInput für jeden parallelen Aufruf wortwörtlich reproduzieren, was ihm manchmal nicht gelingt. Das ADK gibt den Fehler als Ergebnis des Tools zurück, der Koordinator wird wiederhergestellt und die Synthese wird trotzdem abgeschlossen.
❓ Sie fragen sich vielleicht: Ist
chat
Nur die Delegation im 1.x-Stil – jeweils nur ein Agent? Im Grunde ja: Es ist das Standardverhalten von Version 1.x, nur mit einem Namen. Die Lücke zu single_turn ist dreidimensional: Was der Koordinator hält (ein transfer_to_agent im Vergleich zu einem Tool pro Spezialist) · wie viele arbeiten können (einer, der die Konversation besitzt, im Vergleich zu N parallel) · ob die Kontrolle zurückkehrt (nie im Vergleich zu automatisch, mit Ergebnissen). Zum Code:Der if mode ==-Branch der Fabrik existiert nur, damit ein Team für diesen Kontrast auf beide Arten erstellt werden kann. In einer echten App wird ein Modus fest codiert und if verschwindet.
👀 Lesen:Die _specialist-Fabrik – der mode-Parameter ist das gesamte Level. · ▶ Führe beide Beats aus. · ✏️ Änderung:Frage „Mein Knie schmerzt bei Kilometer 29“ – erst die Teilmenge vorhersagen, dann die DISPATCH-Zeilen prüfen.
# The factory's mode parameter is THE variable this level teaches:
def _specialist(name, domain, focus, mode):
kwargs = {}
if mode == "single_turn": # the structured contract only makes sense for a TOOL
kwargs = dict(mode="single_turn",
input_schema=SpecialistInput, output_schema=SpecialistResponse)
return Agent(name=name, model=MODEL,
description=f"Marathon {domain} specialist. Consult for: {focus}.",
instruction=..., **kwargs)
race_concierge = Agent(name="race_concierge", model=MODEL,
sub_agents=[...six specialists...], # NOTE: no `mode` on the coordinator
instruction="...DECIDE which specialists are relevant... call them IN PARALLEL... SYNTHESIZE...")
10. L3b · Aufgabenmodus: Eine Unterhaltung mit einem Ziel – Säule 2

⚡ Kurz gesagt:Im mittleren Modus unterhalten Sie sich mit dem Nutzer, bis die Felder erfasst sind, und kehren dann automatisch mit einem validierten Objekt zurück.
Die Frage:L3a hat eine Lücke hinterlassen. chat führt die gesamte Unterhaltung; single_turn spricht nie mit dem Nutzer. Die eigentliche Aufnahme erfolgt jedoch dazwischen: „Sprich mit dem Nutzer, BIS du X gesammelt hast – dann kehre mit einem validierten Objekt zurück.“ Welcher Modus ist das?
Die Form:
race_desk (coordinator)
└─ gear_fitter (mode="task", output_schema=GearOrder)
▶ Colab:Führen Sie die L3b-Zelle aus. · 📁 GitHub: L3b_task_desk/ · 💻 Lokal: python -m L3b_task_desk.desk


🔍 Die Markierungen : mode="task" + output_schema= im selben Agent – und in der Ausgabe die ⏸-Pause und der finish_task-Aufruf.
Das erwartet Sie:
━━ TURN 1 ━━ user: 'I need shoes for the marathon.'
race_desk → delegate: gear_fitter
gear_fitter: What is your shoe size?
⏸ The run ENDED — but nothing failed. This is a PAUSED task.
━━ TURN 2 ━━ user: 'Size 9, wide.' (same session → resumes the task)
gear_fitter → finish_task (payload validates as GearOrder)
race_desk: Your order ... in size 9 Wide has been confirmed.
Dabei sind drei Dinge passiert, die im L3a-Modus nicht möglich sind:
- Der Lauf wurde mitten in einer Aufgabe beendet: Eine Aufgabe wurde pausiert, es handelt sich nicht um einen Hänger oder Fehler. Der KI-Agent hat seine klärende Frage gestellt und hält die Aufgabe offen. In
adk webwürden Sie die Antwort einfach eingeben. In den Harness-Scripts wird sie als zweite Nachricht in derselben Sitzung behandelt. - Die nächste Nachricht wurde vom SELBEN Task-Agenten fortgesetzt – kein Umleiten, keine erneute Delegation. In der Sitzung wird gespeichert, wer gewartet hat.
finish_taskhat den Vorgang beendet – ein Tool-ADK wurde aufgrund vonmode="task"eingefügt. Der Agent muss ihn aufrufen, um den Vorgang abzuschließen, und seine Nutzlast muss anhand vonoutput_schemavalidiert werden. Eine Unterhaltung mit einer eingegebenen Schlusszeile – die Steuerung wird automatisch an den Koordinator zurückgegeben, das Ergebnis ist angehängt.
Die Ein-Fragen-Regel für die Auswahl eines Modus
💡 „Muss der Nutzer mit dem Agent interagieren und bis WANN?“: chat = unbegrenzt · task = bis die Felder ausgefüllt sind · single_turn = nie.
Modus | Human in the Loop | Parallel? | Zurück zum übergeordneten Element |
| Vollständige Unterhaltung | Nein | manuell (über Übertragung) |
| nur klärende Fragen | Nein | automatisch (über |
| Keine | ja | automatisch (mit Ergebnis) |
mode wird nur für untergeordnete Vertreter und nie für den Koordinator ausgeführt. Knoten im Workflow haben standardmäßig die Stufe single_turn (weshalb L1–L2b sie nie geschrieben haben), während Unter-Agents standardmäßig die Stufe chat haben (weshalb L3a sie schreiben musste).
⚠️ Zwei Versionshinweise, bevor Sie darauf aufbauen: (1) task
als statischer Knoten im Diagramm ist versionsabhängig – in Version 2.0.0b1–2.3.0 (der Pin dieses Codelabs) wird Workflow(...) bei der Erstellung ausgelöst. Verwenden Sie genau das, was auf dieser Ebene passiert (ein Chat-Koordinator mit Task-Unteragenten), oder senden Sie die Anfrage über ctx.run_node. In Version 2.5.0 aufgehoben. (2) Aufgaben-Agents müssen Leaf-Agents sein (keine eigenen Sub-Agents) ist eine dokumentierte ADK-Einschränkung, aber eine Vertragsbedingung, keine Laufzeitbeschränkung: weder 2.3.0 noch 2.5.0 werden Sie daran hindern. Das Fehlen eines Fehlers bedeutet nicht, dass Sie die Inhalte verwenden dürfen.
💡 Weitere Informationen:Ein task-Agent, der in einen Graph-Workflow eingebettet ist (Version 2.5.0 oder höher), mit Routing, das die Konversation für einen erneuten Versuch zurückschleifen kann: Companion-Repository 22_agent_in_workflow · Leitfaden für den vollständigen Modus: docs/agent-modes.md.
❓ Sie fragen sich vielleicht : Was bedeutet
task
buy me that the other two can't? Drei Dinge: Automatische Rückgabe (der Chat führt die Unterhaltung fort), eingegebene Ziellinie (die Nutzlast von finish_task muss dem Schema entsprechen – Sie erhalten Daten zurück, nicht ein Transkript) und Pausieren/Fortsetzen (das ⏸ ist eine angehaltene Aufgabe, die auf einen Menschen wartet, nicht ein Hängenbleiben).
👀 Lesen : gear_fitter – mode="task" + output_schema ist der gesamte Vertrag. · ▶ Führen Sie die Datei aus. · ✏️ Änderung : run_desk("I need a hydration vest", "2 liters, medium") – Die klärende Frage wird angepasst, die Ziellinie bleibt bestehen.
11. L4a · Laufzeitbasierter paralleler Fan-out (Säule 3a)

⚡ Kurz gesagt:Das Skelett besteht weiterhin aus drei statischen Schritten. Der dynamische Schritt wird innerhalb des mittleren Schritts ausgeführt, wobei die Breite zur Laufzeit anhand von Daten festgelegt wird.
⚠️ Achtung: Dies ist die steilste Stufe der Leiter. Die vorherige Ebene hatte 44 Zeilen, diese hat etwa 120 Zeilen – drei Agents und zwei Workflow-Knoten, und nichts davon ist Padding. Planen Sie etwa 15 Minuten ein und konzentrieren Sie sich am Ende auf die Zeile „Lesen/Ausführen/Ändern“. Sie müssen nicht jede Zeile beim ersten Durchgang erfassen.
Die Frage:Die Form des Ergebnisses hängt von der Eingabe ab. Sie können das Diagramm nicht im Voraus zeichnen. Beginnen Sie mit der Laufzeit-Breite: Lassen Sie das LLM entscheiden, wie viele untergeordnete Fragen es gibt.
Die Form (eine Ebene tief):
START ─► decompose ─► research_topic (parallel_worker) ─► synthesize
│ │ │
└──┴──┴─ (flat: no children yet)
Eine offene Frage wird in N Unterfragen zerlegt. N wird vom LLM zur Laufzeit ausgewählt (3–7). Jede Unterfrage wird parallel recherchiert und dann zu einem Briefing zusammengefasst.
▶ Colab:Führen Sie die L4a-Zelle aus. · 📁 GitHub: L4a_flat_research/ · 💻 Lokal: python -m L4a_flat_research.deep_research

🔍 Die Markierungen – es gibt keine
dynamic=True
-Schalter. „Dynamisch“ ist eine Art des Schreibens, keine Konfiguration. Es gibt nur zwei Markierungen: @node(parallel_worker=True) (nimmt eine Liste in Laufzeitgröße entgegen und führt einen Worker pro Element aus) und ctx.run_node(...) (plant Codierungsknoten direkt). Wenn Sie eine der beiden Optionen sehen, verwenden Sie dynamische Anzeigen.
Was Sie sehen:Der Decomposer gibt z.B. fünf Unterfragen aus, die parallel recherchiert werden, und dann eine zusammenfassende Übersicht. Die Zahl ist bei jedem Lauf unterschiedlich – das war beim statischen Diagramm nicht möglich.
Zwei Flags für den Worker, die Sie kennen sollten:
rerun_on_resume=Trueist für jeden Knoten erforderlich, derctx.run_nodeaufruft. Andernfalls wird im ADK einValueErrorausgelöst. Beim Fortsetzen muss der Dispatching-Knoten noch einmal ausgeführt werden, um die untergeordneten Knoten neu zu erstellen, da diese nicht im statischen Diagramm enthalten sind.retry_config=begrenzt, wie dieser Fehler auftritt. Ein paralleler Worker bricht alle gleichgeordneten Elemente ab und löst sofort einen Fehler aus, wenn ein untergeordnetes Element fehlschlägt. Ohne Wiederholungsversuch wird der gesamte Lauf durch einen einzelnen vorübergehenden 429-Fehler verworfen, einschließlich aller bereits bezahlten Aufrufe. Der Wiederholungsversuch wird auf dem inneren Knoten „per-item“ ausgeführt, sodass jeder Zweig unabhängig wiederholt wird.
❓ Vielleicht fragen Sie sich: Woher „weiß“ das ADK, dass es sich um eine dynamische Variable handelt? Das ist auch nicht nötig, da nirgends etwas deklariert ist. Der Decomposer erstellt zur Laufzeit eine Liste. Die Größe des parallelen Workers wird automatisch angepasst. Die Dynamik ist eine Eigenschaft des von Ihnen erstellten Datenflusses und kein Modus, den Sie aktiviert haben.
👀 Lesen:die beiden Flags auf research_topic – parallel_worker und rerun_on_resume. · ▶ Führen Sie die Datei aus. · ✏️ Ändern:Tauschen Sie Ihre eigene offene Frage ein – N ändert sich, da die Breite durch die Eingabe bestimmt wurde.
12. L4b · Rekursives Erstellen von untergeordneten Knoten hinzufügen (Säule 3b)

⚡ Kurz gesagt:Rekursion wird geschrieben, nicht vorgegeben – der Worker ruft sich selbst über ctx.run_node auf, normales Python – daher muss auch die Bremse geschrieben werden. Das sind MAX_DEPTH.
Die Frage:Manchmal ergibt sich aus einem Forschungsergebnis ein enges Unterthema, das eine eigene Untersuchung wert ist. Wie können Sie in einem Branch mehr parallele Arbeit ermöglichen und gleichzeitig die Grenzen einhalten?
Die Form (jetzt rekursiv):
START ─► decompose ─► research_topic (parallel_worker, recursive) ─► synthesize
│ │ │
│ │ └─ research(q3) ─► maybe spawn children
│ └─── research(q2) ─► maybe spawn children
└────── research(q1) ─► maybe spawn children
▶ Colab:Führen Sie die L4b-Zelle aus. · 📁 GitHub: L4b_recursion/ · 💻 Lokal: python -m L4b_recursion.deep_research

@node(parallel_worker=True, rerun_on_resume=True)
async def research_topic(ctx, node_input):
finding = coerce(await ctx.run_node(research_agent, node_input=...), ResearchFinding)
if finding.needs_deeper and finding.deeper_questions and depth < MAX_DEPTH: # boundary in CODE
children = await ctx.run_node(research_topic, node_input=deeper) # recursive fan-out
yield Event(output={..., "children": children})
🔍 Die Markierungen: ctx.run_node(research_topic, ...) innerhalb vonresearch_topic selbst – der Selbstverweis ist die Rekursion – und die Bedingung depth < MAX_DEPTH eine Zeile darüber.
Was Sie sehen:Forschungs-Nodes, die spawning N deeper ausgeben – Rekursion in Echtzeit – und dann eine Laufzeitbaumstruktur (z.B. 5 top-level + 10 recursive children). Der Baum unterscheidet sich bei jedem Lauf.
⚠️ Bevor Sie den Regler hochdrehen:Die Obergrenze steigt schnell – MAX_DEPTH=3 nimmt den Worst-Case-Wert von etwa 30 Anrufen auf etwa 93. Ganz am Ende eines Laufs sehen Sie möglicherweise eine cancelling N leftover tasks-Logzeile. Das bedeutet, dass das ADK seine parallele Aufgabengruppe beendet, nachdem das Ergebnis bereits fertig ist. Harmlos – je nach Protokollierungskonfiguration wird sie Ihnen möglicherweise nie angezeigt.
❓ Sie fragen sich vielleicht : Ist dynamisch nicht standardmäßig rekursiv? Nein. L4a ist vollständig dynamisch und hat keine Rekursion. Mit „Dynamic“ haben Sie nur den normalen Python-Kontrollfluss zur Verfügung. L4b entscheidet sich, Rekursion damit zu schreiben. Und da Sie die Rekursion geschrieben haben, müssen Sie auch die Grenze festlegen. Hier hört „LLM die Arbeit gestalten lassen, Grenzen im Code festlegen“ auf, nur ein Slogan zu sein.
👀 Lesen:Die Guard-Datei: if finding.needs_deeper and depth < MAX_DEPTH. · ▶ Führen Sie die Datei aus. · ✏️ Ändern:Legen Sie MAX_DEPTH = 1 fest und führen Sie den Vorgang noch einmal aus. Der Baum wird vereinfacht und der Lauf wird günstiger. Die Grenze ist IHRE, im Code.
13. L5 · Welches Muster sollten Sie verwenden?

⚡ Kurzfassung:Eine Achse entscheidet alles – wer wählt den nächsten Schritt aus: das von Ihnen gezeichnete Diagramm, das LLM oder Ihr Code?
Sie haben alle drei erstellt. Das ist das Modell, das sie nützlich macht: Das Muster muss zur Form Ihres Problems passen.
Die Achse: Wer entscheidet, was als Nächstes ausgeführt wird?
Säule | Wer entscheidet, was als Nächstes ausgeführt wird? | Integriert |
1 · Diagramm | das Diagramm, das Sie gezeichnet haben | L2a / L2b |
2. Zusammenarbeit | das LLM | L3a / L3b |
3 · Dynamisch | Ihr Python-Code zur Laufzeit | L4a / L4b |
Schritt 0: Benötigen Sie überhaupt ein Diagramm?
Das ADK enthält vorgefertigte Workflow-Agenten – SequentialAgent, ParallelAgent, LoopAgent. Bei einer einfachen Kette von Agents ist das die günstigste richtige Antwort und es muss kein Graph zusammengestellt werden. Verwenden Sie sie, wenn Sie explizites Routing (den Router von L2b), einen Join (JoinNode von L2a) oder Knoten, die keine Agenten sind (eine einfache Funktion, keine LLM-Aufrufe) benötigen. Letzteres ist in der Regel der Grund.
Would a prebuilt SequentialAgent / ParallelAgent / LoopAgent do?
│
├─ YES ──────────────────────────────► use it; stop here
│
└─ NO — I need routing, a join, or non-agent nodes
│
Can you draw the workflow before the input arrives?
│
├─ YES ───────────────────────────► Pillar 1 · Graph workflow (L2a/L2b)
│
└─ NO
├─ Known team, request picks the subset? ─► Pillar 2 · Collaborative (L3a/L3b)
└─ Does the shape depend on the input? ──► Pillar 3 · Dynamic (L4a/L4b)

Die ehrliche Gegenüberstellung von Version 1.x und Version 2
Das ist nicht „2.0 kann Dinge, die 1.x nicht konnte“ – 1.x konnte alles erstellen. Der Unterschied besteht darin, dass 2.0 jeder Form einen direkteren Ausgangspunkt gibt. Der bekannte Kontrollfluss verlässt also den Prompt und wird zu einer Struktur, die Sie sehen und testen können.
Muster | Kosten für Version 1.x | Startseite des ADK 2 |
Graph | 4 LLM-Aufrufe im gemeinsamen Build; Routing in einem Prompt verborgen | Funktions- und Agentenknoten als Peers → 1 Aufruf, |
Zusammenarbeit | über | Ein deklariertes Team: |
Dynamisch | Durch Rekursion wird das Framework verlassen. |
|
Die gesamte App und was ein Diagramm nicht zeigen kann
Sie haben nun alle unten aufgeführten Teile erstellt. Workflow macht seine Struktur unter graph.edges verfügbar. Dieses Bild wird also aus dem Code generiert und nicht von Hand gezeichnet. Die Introspektion findet die Zusammenfassung dieses Labs:
Säule | Inhalt von | Warum |
1. Grafik (L2b) | 10 Kanten, Routen und alles | Sie haben es gezeichnet, bevor eine Eingabe erfolgte. |
2 · Collaborative (L3a) | 0 Kanten: Nur | Das LLM wählt die Teilmenge pro Anfrage aus. |
3. Dynamisch (L4a/L4b) | 3 Kanten – in beiden identisch | Die Rekursion ist in Python geschrieben und nicht im Diagramm enthalten. |
Die letzte Zeile ist der Beweis für die Frage, die in L4b beantwortet wird: L4a und L4b haben dasselbe Diagramm und nur eines von beiden wird rekursiv aufgerufen.
Was Sie jetzt erstellen können
Jedes Muster, das Sie gerade ausgeführt haben, ist eine echte Produktform:
Sie haben | In der Praxis sieht das so aus: | Start |
Diagramm + Router (L2a/L2b) | Dokumentpipelines, ETL-mit-LLM-Schritten, Überprüfungs-/Genehmigungsketten, Evaluierungstools | L2b dieses Repositorys |
Koordinator + | ein Support-Copilot mit Spezialistenteams, Triage-Schreibtischen und Multi-Lens-Überprüfung | Marathon-Demo, Modus 2 |
| Aufnahmeformulare, Buchungsabläufe, Onboarding, KYC – alle „collect then act“-Prozesse | |
Dynamische Breite/Tiefe (L4a/L4b) | Research Agents, Berichtsgeneratoren, Audit-Sweeps für Eingaben unbekannter Größe | Marathon-Demo, Modus 3 |
Sie komponieren
Die drei Muster schließen sich nicht gegenseitig aus. Ein Grafknoten kann einen Collaborative Coordinator aufrufen und ein Spezialist kann einen dynamischen Workflow starten. Wählen Sie das richtige Muster für jeden Teil des Problems aus. So vermeiden Sie, dass jedes Agentensystem zu einem riesigen Prompt wird.

💡 Selbst ausprobieren:Das Script, mit dem dieses Bild erstellt wurde, ist scripts/graph_dump.py. Richten Sie es auf ein beliebiges Workflow und es werden die tatsächlichen Kanten gedruckt – ein kostenloses Strukturschema für alles, was Sie bauen.
14. Glückwunsch

Sie haben einen Marathon Race Day Coach und dabei alle drei Orchestrierungsmuster von ADK 2 erstellt.
Das haben Sie gelernt
- Prolog: Der Mega-Prompt, der sein eigenes Wetter erfunden hat – warum Struktur überhaupt existiert.
- L0–L1:
Agent,Runner, ein echtes Tool, das das Modell aufruft, und Ihr ersterWorkflow(Funktionsknoten + Agent-Knoten als Peers). - L2a / L2b: Graph-Workflows: parallele Fan-Out-Funktion +
JoinNode, dann deterministisches Routing – ein LLM-Aufruf. - L3a: Collaborative Agents: Das gleiche Team wird in
chat(isoliert) und dann insingle_turn(parallele Teilmenge + Synthese) ausgeführt – ein Flag, zwei Welten. - L3b –
task-Modus: eine pausierte klärende Frage, eine geskriptete Fortsetzung,finish_task, die ein validiertes Objekt zurückgibt. - L4a / L4b: Dynamische Workflows: Laufzeitbreite (Fan-out), dann Laufzeittiefe (Rekursion) mit Grenzen im Code.
- L5: Der Entscheidungsbaum und die Zusammensetzung der Muster.
Zeilen, die beibehalten werden sollten
Funktionen bereiten den Kontext vor. Kanten definieren den Workflow. Der Router wählt den Pfad aus. Das Modell schreibt die Antwort.
LLM die Arbeit gestalten lassen, aber die Grenzen im Code beibehalten:
Muster an die Form Ihres Problems anpassen:
Nächste Schritte
- Sie können die vollständige App ausführen, aus der diese Ebenen abgeleitet wurden: den Marathon Race Day Coach, der mit FastAPI + SSE erstellt wurde und eine Browser-Benutzeroberfläche hat, auf der alle drei Modi live angezeigt werden: github.com/cuppibla/adk-2-marathon-demo.
- Weitere Informationen: adk-workflows-compared – alle 23 offiziellen ADK2-Workflowbeispiele, jeweils mit einem 1.x-Port und einer Anleitung zur Verwendung. Beginnen Sie mit
docs/three-pillars.mdund dann mit den Themen, die in diesem Codelab ausgelassen wurden:07_loop,17_request_input,22_agent_in_workflow. - Übertrage dein eigenes Problem: Welche Teile sind bekannt (L2), bekanntes Team (L3a/L3b) und unbekannte Form (L4)?
- Code ansehen: github.com/cuppibla/adk2-tutorial.
- Wurde das Gerät im Rahmen eines Workshops repariert? Ihr Guthaben und das damit erstellte Projekt sind nicht unbegrenzt gültig. Wenn Sie diese Levels weiterhin kostenlos ausführen möchten, führen Sie stattdessen den Schritt Einrichtung für zu Hause aus: ein kostenloser AI Studio-Schlüssel, kein Cloud-Projekt, keine Abrechnung. Das Austauschen dieser einen Zelle ist die einzige Änderung.