Kurs
Das Agent Development Kit (ADK) von Google: Ein Leitfaden mit Demo-Projekt
In diesem Blog zeige ich dir, wie du mit Googles neuem Open-Source-Agent Development Kit (ADK) einen KI-gesteuerten Reiseassistenten mit mehreren Agenten erstellen kannst. Agent Development Kit (ADK) und dem A2A (Agent-zu-Agent) Protokoll.
Wir verwenden mehrere Agenten, um Flüge, Hotels und Aktivitätsempfehlungen zu verwalten, die über REST-APIs und FastAPI-Server kommunizieren. Am Ende verpacken wir das Ganze in ein sauberes Streamlit-Frontend für ein intuitives Nutzererlebnis.
Wir halten unsere Leserinnen und Leser mit The Median auf dem Laufenden, unserem kostenlosen Freitags-Newsletter, der die wichtigsten Meldungen der Woche aufschlüsselt. Melde dich an und bleibe in nur ein paar Minuten pro Woche auf dem Laufenden:
Was ist das Agent Development Kit (ADK) von Google?
Das ADK von Google ist ein modulares, produktionsreifes Framework für den Aufbau von LLM-gesteuerten Agenten. Es ist das gleiche Toolkit, das auch die Agenten in den Google-Produkten wie Agentspace und Customer Engagement Suite antreibt. Jetzt open-sourcedhilft es Entwicklern, leistungsstarke, flexible und interoperable Multi-Agenten-Anwendungen zu entwickeln.
Warum das Agent Development Kit (ADK) verwenden?
ADK bietet die Flexibilität von Python mit eingebauten Strukturen für Zustandsverwaltung, Rückrufe, Streaming und strukturierte Ein-/Ausgabe. Werfen wir einen Blick auf seine wichtigsten Funktionen:
- Multi-Agent by Design: ADK kann Agenten in parallelen, sequenziellen oder hierarchischen Workflows zusammenstellen.
- Model-agnostic: Es funktioniert mit Gemini, GPT-4o, Claude, Mistral und anderen über
LiteLlm
. - Modular und skalierbar: Der Nutzer kann spezialisierte Agenten definieren und mithilfe der integrierten Orchestrierung intelligent delegieren.
- Streaming-fähig: Es unterstützt Echtzeit-Interaktion, einschließlich bidirektionalem Audio/Video.
- Eingebaute Werkzeuge: Es unterstützt lokale CLI und Web UI für Debugging und Evaluierung.
- Unterstützt den Einsatz: Mit ADK lassen sich Agenten einfach containerisieren und in verschiedenen Umgebungen einsetzen.
Was ist das Agent2Agent (A2A) Protokoll von Google?
Das Agent2Agent (A2A)-Protokoll ist ein offener, herstellerneutraler Standard, der von Google entwickelt wurde, um eine einfache Kommunikation und Zusammenarbeit zwischen KI-Agenten über verschiedene Plattformen und Frameworks hinweg zu ermöglichen.
ADK-Agenten stellen einen Standard-HTTP-Endpunkt /run
und Metadaten über .well-known/agent.json
zur Verfügung. Dies ermöglicht die Erkennung von Agenten und die einfache Kommunikation zwischen Agenten (oder sogar externen Orchestrierern wie LangGraph oder CrewAI).
Das Hinzufügen der A2A-Metadaten-Datei ist zwar optional, macht deine Agenten aber interoperabel mit dem breiteren Ökosystem von Agententools und Orchestrierern.
Projektübersicht: KI-gestützter Reiseplaner mit ADK und A2A
In diesem Projekt wird ein Reiseplaner erstellt, der:
- Nimmt das Ziel, die Daten und das Budget als Eingabe.
- Ruft drei verschiedene Agenten an:
flight_agent
: Empfiehlt Flugoptionen.stay_agent
: Findet Hotels innerhalb des Budgets.activities_agent
: Schlägt ansprechende Aktivitäten vor.- Dann nutzt er eine zentrale
host_agent
, um alle Anfragen zu koordinieren. - Und schließlich verwendet er eine Streamlit UI für die Benutzerinteraktion.
Alle Agenten werden als separate FastAPI-Server gehostet und stellen einen /run
Endpunkt zur Verfügung. Die Kommunikation findet über den gemeinsamen A2A-kompatiblen Client statt.
Hinweis: Dieses Projekt läuft der Einfachheit halber komplett auf deinem lokalen Rechner, aber du kannst jeden Agenten und die Benutzeroberfläche auf Cloud-Plattformen wie Render, Railway oder Google Cloud Run bereitstellen, um einen skalierbaren Zugang zu erhalten.
Schritt 1: Voraussetzungen
Beginnen wir mit der Installation der folgenden Bibliotheken:
pip install google-adk litellm fastapi uvicorn httpx pydantic openai streamlit
Richte dann deinen OpenAI API-Schlüssel ein - du kannst auch einen anderen Modellanbieter verwenden. Um zu erfahren, wie du deinen OpenAI-API-Schlüssel einrichtest, empfehle ich dir dieses einführende Tutorial zur GPT-4o API.
export OPENAI_API_KEY="your_key_here"
Schritt 2: Gemeinsames Schema und Dienstprogramme
Bevor wir intelligente Agenten bauen können, müssen wir eine gemeinsame Sprache definieren, in der sie miteinander sprechen können. In unserem Fall geschieht dies mit Hilfe von:
- Ein gemeinsames Schema für die Eingabe (definiert über Pydantic)
- Ein REST-Client-Dienstprogramm zum Aufrufen von Agenten
- Ein REST-Server-Wrapper, um den
/run
Endpunkt für alle Agenten zu standardisieren
Diese werden in den Ordnern shared/
und common/
abgelegt, damit der Code modular bleibt. Schauen wir uns jede einzelne davon an.
Erstellen einer shared/schemas.py
Datei
Wir definieren ein TravelRequest
Schema mit Pydantic. So wird sichergestellt, dass alle Agenten sich über die Struktur der eingehenden Anfragen einig sind, die das Reiseziel, die Reisedaten und das Budget des Nutzers umfasst.
from pydantic import BaseModel
class TravelRequest(BaseModel):
destination: str
start_date: str
end_date: str
budget: float
Dieser Kurs hilft bei:
- Konsistente Eingaben für alle Agenten.
- Hinzufügen einer automatischen Validierung mit FastAPI.
- Vereinfachung der Wiederverwendung von Code.
Erstellen einer common/a2a_client.py
Datei
Dieses leichtgewichtige asynchrone Dienstprogramm ermöglicht es jedem Agenten (insbesondere dem Host), einen anderen Agenten über das A2A-Protokoll aufzurufen, indem er den Endpunkt /run
aufruft.
import httpx
async def call_agent(url, payload):
async with httpx.AsyncClient() as client:
response = await client.post(url, json=payload, timeout=60.0)
response.raise_for_status()
return response.json()
Dieses Dienstprogramm sendet asynchron eine POST-Anfrage an den /run
Endpunkt eines anderen Agenten mit httpx
. Sie gibt die geparste JSON-Antwort zurück und gibt einen Fehler aus, wenn die Anfrage fehlschlägt.
Wir werden dieses Dienstprogramm in unserem Host-Agenten verwenden, um flight_agent
, stay_agent
und activities_agent
aufzurufen.
Erstellen einer common/a2a_server.py
Datei
Anstatt für jeden Agenten eine eigene FastAPI-Route zu schreiben, verallgemeinern wir sie mit der Funktion create_app(agent)
, die die
- Die Bedienung des Agenten am
/run
- Erhalt eines Reiseantrags
- Rückgabe einer strukturierten Antwort
from fastapi import FastAPI
import uvicorn
def create_app(agent):
app = FastAPI()
@app.post("/run")
async def run(payload: dict):
return await agent.execute(payload)
return app
Dieses Dienstprogramm erstellt eine FastAPI-App mit einer Standardroute /run
, die die Ausführung an den angegebenen Agenten delegiert. Sie gewährleistet eine einheitliche Agent-to-Agent (A2A)-Schnittstelle für alle Dienste, die strukturierte JSON-Eingaben verwenden.
Diese gemeinsamen Komponenten machen unser Multi-Agenten-System wartungsfreundlicher, wiederverwendbar und entsprechen Googles A2A-Philosophie des einfachen, strukturierten Nachrichtenaustauschs zwischen Agenten.
Schritt 3: Aufbau des Multi-Agenten-Systems mit ADK und A2A
Nachdem wir nun die gemeinsamen Verträge und Dienstprogramme eingerichtet haben, können wir mit dem Aufbau der einzelnen Agenten beginnen. Um dies in ein wirklich modulares Multi-Agenten-System zu verwandeln, verwenden wir das A2A-Protokoll von Google - eine einfache HTTP-basierte Schnittstelle, über die Agenten konsistent und interoperabel kommunizieren können.
A2A (Agent-to-Agent) ermöglicht die Plug-and-Play-Koordination zwischen Agenten, egal ob es sich um lokale Python-Funktionen oder um gehostete Agenten in Netzwerken handelt. Jeder Agent stellt einen /run
Endpunkt mit einem gemeinsamen Schema zur Verfügung und fungiert als Dienst.
In unserer Demo haben wir vier Agenten:
host_agent
: Orchestriert alle anderen Agentenflight_agent
: Findet passende Flügestay_agent
: Schlägt Unterkünfte voractivities_agent
: Empfiehlt, sich an lokalen Aktivitäten zu beteiligen
Alle Agenten sind ähnlich strukturiert, mit 3 Dateien und einem Unterordner:
agents/
├── host_agent/
│ │ ├── agent.py # Optional if host logic is minimal
│ │ ├── task_manager.py # Calls other agents and aggregates responses
│ │ ├── __main__.py # Starts FastAPI app via common/a2a_server.py
│ │ └── .well-known/
│ │ └── agent.json # A2A Agent Card metadata
├── flight_agent/
├── stay_agent/
└── activities_agent/
Jeder Agent verwendet google.adk.agents.Agent
, einen LiteLlm
Modell-Wrapper und Runner
zur Ausführung. Beginne damit, die folgenden Dateien im Ordner activities_agent
zu erstellen und wiederhole das Gleiche für flight_agent
und stay_agent
.
Erstellen einer agent.py
Datei
Definieren wir nun die Logik für unsere activities_agent
, die dafür verantwortlich ist, auf der Grundlage der Reiseroute des Nutzers ansprechende lokale Erlebnisse zu generieren.
Schritt 1: Importe
Wir beginnen damit, wichtige Module zu importieren, um unseren Agenten zu konfigurieren und auszuführen.
from google.adk.agents import Agent
from google.adk.models.lite_llm import LiteLlm
from google.adk.runners import Runner
from google.adk.sessions import InMemorySessionService
from google.genai import types
import json
Dieser Agent nutzt die Komponenten von Google ADK wie Agent, '
Runner, ' und LiteLlm
und verwaltet den Status mit InMemorySessionService.
. Die Bibliothek Types
wird für die Erstellung von strukturierten Prompts verwendet.
Schritt 2: Aktivitäten Agent
Jetzt instanziieren wir den Agenten selbst mithilfe der ADK-Agentenklasse.
activities_agent = Agent(
name="activities_agent",
model=LiteLlm("openai/gpt-4o"),
description="Suggests interesting activities for the user at a destination.",
instruction=(
"Given a destination, dates, and budget, suggest 2-3 engaging tourist or cultural activities. "
"For each activity, provide a name, a short description, price estimate, and duration in hours. "
"Respond in plain English. Keep it concise and well-formatted."
)
)
Der Parameter Anweisung definiert die Systemaufforderung, die das Verhalten des LLM steuert. Obwohl in diesem Beispiel einfaches Englisch verwendet wird, kannst du die Anweisung so anpassen, dass sie strukturiertes JSON zurückgibt, um das Parsen zu erleichtern.
Schritt 3: Sitzungsmanagement
Um die Interaktionen der Nutzer/innen zu verfolgen, konfigurieren wir einen Lernpfad (Runner) und die Sitzungsinformationen.
session_service = InMemorySessionService()
runner = Runner(
agent=activities_agent,
app_name="activities_app",
session_service=session_service
)
USER_ID = "user_activities"
SESSION_ID = "session_activities"
Die Runner
verwaltet die Agentenausführung für eine bestimmte App-Sitzung. Während die Klasse InMemorySessionService
den Kontext im Speicher speichert. Dann definieren wir Benutzer- und Sitzungs-IDs. In der Produktion können diese jedoch dynamisch oder benutzerspezifisch sein. Dadurch wird sichergestellt, dass eine neue ADK-Sitzung existiert, bevor Aufforderungen an den LLM-Agenten gesendet werden.
Schritt 4: Ausführen der Agentenlogik
Die Funktion execute()
bearbeitet eingehende Anfragen, erstellt eine Eingabeaufforderung, ruft das Modell auf und analysiert die Ausgabe.
async def execute(request):
session_service.create_session(
app_name="activities_app",
user_id=USER_ID,
session_id=SESSION_ID
)
prompt = (
f"User is flying to {request['destination']} from {request['start_date']} to {request['end_date']}, "
f"with a budget of {request['budget']}. Suggest 2-3 activities, each with name, description, price estimate, and duration. "
f"Respond in JSON format using the key 'activities' with a list of activity objects."
)
message = types.Content(role="user", parts=[types.Part(text=prompt)])
async for event in runner.run_async(user_id=USER_ID, session_id=SESSION_ID, new_message=message):
if event.is_final_response():
response_text = event.content.parts[0].text
try:
parsed = json.loads(response_text)
if "activities" in parsed and isinstance(parsed["activities"], list):
return {"activities": parsed["activities"]}
else:
print("'activities' key missing or not a list in response JSON")
return {"activities": response_text} # fallback to raw text
except json.JSONDecodeError as e:
print("JSON parsing failed:", e)
print("Response content:", response_text)
return {"activities": response_text} # fallback to raw text
Die Funktion execute()
erstellt dynamisch eine Eingabeaufforderung mit den Parametern der eingehenden Anfrage wie Zielort, Daten und Budget. Hier ist, was unter der Haube passiert:
- Die Eingabeaufforderung weist das Modell an, ein strukturiertes JSON-Objekt mit einer Aktivitätenliste zurückzugeben.
- Ein
Content
Objekt wird erstellt und an den ADK Runner übergeben, der asynchron auf die endgültige Antwort des Modells mit einem Streaming-Generator wartet. - Sobald die endgültige Antwort eingegangen ist, extrahiert der Agent die Rohtextausgabe und versucht, sie als JSON zu parsen.
- Wenn das Parsen erfolgreich war und der erwartete Aktivitätsschlüssel existiert, werden die strukturierten Daten zurückgegeben.
- Wenn der Schlüssel fehlt oder fehlerhaft ist, wird als Rückfall die Rohtext-Antwort zurückgegeben, damit die Benutzeroberfläche noch eine brauchbare Ausgabe hat.
- Dieser duale Ansatz sorgt für einen reibungslosen Ablauf, wenn der LLM Klartext statt strukturiertem JSON zurückgibt.
Diese Strategie verbessert die Robustheit und die Benutzerfreundlichkeit, vor allem, wenn die Modellergebnisse aufgrund der Temperatur oder der Interpretation der Eingabeaufforderung leicht variieren.
Erstellen einer task_manager.py
Datei
Nachdem wir die execute()
Logik in agent.py
definiert haben, verbinden wir sie mit dem ADK-kompatiblen Server-Setup unter task_manager.py
.
from .agent import execute
async def run(payload):
return await execute(payload)
Diese Datei dient als dünner Wrapper um die zuvor definierte Funktion execute()
. Sie macht die Methode run()
für externe Module verfügbar, insbesondere für das Serverskript in __main__.py
.
Erstellen einer __main__.py
Datei
Die Datei __main__.py
startet einen FastAPI-Server auf Port 8003, der den Agenten am Endpunkt /run
bedient.
from common.a2a_server import create_app
from .task_manager import run
app = create_app(agent=type("Agent", (), {"execute": run}))
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, port=8003)
Hier ist, was passiert ist:
- Die
create_app()
(aus common/a2a_server.py) wickelt unseren Agenten in eine A2A-kompatible FastAPI-Schnittstelle ein. - Wir konstruieren dynamisch ein Objekt mit einer
execute()
Methode, damit ADKrun()
richtig aufrufen kann. - Diese Trennung ermöglicht es uns, zustandslose API-Schnittstellen beizubehalten und gleichzeitig die zentrale Agentenlogik wiederzuverwenden.
Erstellen einer .well-known/agent.json
Datei
Wir verwenden diese JSON-Datei, um die Identität und den Zweck des Agenten gemäß dem A2A-Protokoll (Agent-to-Agent) zu beschreiben.
{
"name": "activity_agent",
"description": "Agent providing activity details."
}
Hinweis: Die Datei .well-known/agent.json
wird zwar nicht direkt von unseren Agenten in diesem Projekt verwendet, aber sie entspricht der A2A-Spezifikation und ist wichtig für die Entdeckung, die Introspektion und die zukünftige Kompatibilität mit Orchestratoren wie LangGraph, CrewAI oder Googles Agentenregistrierung.
Eine ähnliche Logik wird auch für flight_agent
und stay_agent
verwendet.
Schritt 4: Koordinierung mit host_agent
Die host_agent
fungiert als zentraler Planer für die Demo. Die host_agent
ist ein Beispiel für das Steuerungsmuster in Multi-Agenten-Systemen. Es trennt Entscheidungsfindung und Ausführung, so dass sich jeder nachgelagerte Agent auf seine Nische konzentrieren kann, während die Koordinationslogik zentralisiert wird. Das vereinfacht nicht nur das Testen und Skalieren, sondern spiegelt auch die reale Microservice-Architektur in verteilten Systemen wider.
Er sendet dieselbe Nutzlast an alle drei Agenten über ihre /run
APIs und führt die Ergebnisse zusammen. Fügen wir die folgenden Dateien zum Ordner host_agent
hinzu.
Erstellen einer agent.py
Datei
Beginnen wir mit den Basisimporten.
from google.adk.agents import Agent
from google.adk.models.lite_llm import LiteLlm
from google.adk.runners import Runner
from google.adk.sessions import InMemorySessionService
from google.genai import types
Dieser Importblock enthält alle Kernbausteine, die benötigt werden, um einen LLM-basierten Agenten mit dem Google ADK zu definieren und auszuführen: Agent
Klasse, leichtgewichtiger LLM-Wrapper, Runner
für die Ausführung und In-Memory-Session-Management.
host_agent = Agent(
name="host_agent",
model=LiteLlm("openai/gpt-4o"),
description="Coordinates travel planning by calling flight, stay, and activity agents.",
instruction="You are the host agent responsible for orchestrating trip planning tasks. "
"You call external agents to gather flights, stays, and activities, then return a final result."
)
session_service = InMemorySessionService()
runner = Runner(
agent=host_agent,
app_name="host_app",
session_service=session_service
)
USER_ID = "user_host"
SESSION_ID = "session_host"
Der obige Code definiert einen ADK-Agenten auf oberster Ebene, der für die Koordinierung des gesamten Reiseplans verantwortlich ist. In dieser Implementierung rufen wir zwar keine Unteragenten aus dem LLM auf, aber die Systemaufforderung bereitet die Rolle für eine künftige Erweiterung vor, bei der der LLM möglicherweise die Verwendung von Werkzeugen und Metaüberlegungen übernehmen könnte.
async def execute(request):
# Ensure session exists
session_service.create_session(
app_name="host_app",
user_id=USER_ID,
session_id=SESSION_ID
)
prompt = (
f"Plan a trip to {request['destination']} from {request['start_date']} to {request['end_date']} "
f"within a total budget of {request['budget']}. Call the flights, stays, and activities agents for results."
)
message = types.Content(role="user", parts=[types.Part(text=prompt)])
async for event in runner.run_async(user_id=USER_ID, session_id=SESSION_ID, new_message=message):
if event.is_final_response():
return {"summary": event.content.parts[0].text}
Diese execute()
Funktion dient als Haupteinstiegspunkt in das LLM des Host-Agenten. Es:
- Initialisiert eine Sitzung (für Speicherunterstützung, falls erforderlich)
- Baut dynamisch eine Benutzerführung auf
- Sendet es mit ADKs runner.run_async() an das Modell
method
- Erwartet und extrahiert schließlich die endgültige Antwort
Erstellen einer task_manager.py
Datei
Der Aufgabenmanager führt die Orchestrierungslogik aus, indem er Remote-Agenten aufruft und den gesamten Arbeitsablauf der Reiseplanung abwickelt. Für die praktische Umsetzung definieren wir die Service-URLs für jeden Child-Agent. Diese Endpunkte entsprechen dem A2A /run protocol and expect a shared
TravelRequest` JSON Schema.
from common.a2a_client import call_agent
FLIGHT_URL = "http://localhost:8001/run"
STAY_URL = "http://localhost:8002/run"
ACTIVITIES_URL = "http://localhost:8003/run"
Jetzt definieren wir die Nutzlast.
async def run(payload):
#Print what the host agent is sending
print("Incoming payload:", payload)
flights = await call_agent(FLIGHT_URL, payload)
stay = await call_agent(STAY_URL, payload)
activities = await call_agent(ACTIVITIES_URL, payload)
# Log outputs
print("flights:", flights)
print("stay:", stay)
print("activities:", activities)
# Ensure all are dicts before access
flights = flights if isinstance(flights, dict) else {}
stay = stay if isinstance(stay, dict) else {}
activities = activities if isinstance(activities, dict) else {}
return {
"flights": flights.get("flights", "No flights returned."),
"stay": stay.get("stays", "No stay options returned."),
"activities": activities.get("activities", "No activities found.")
}
Diese Funktion verwendet die Hilfsfunktion call_agent()
, um die Nutzlast an jeden nachgelagerten Dienst zu senden, und protokolliert die Eingaben und Ausgaben, damit sie während der Entwicklung sichtbar sind. In dieser Datei befindet sich die eigentliche Orchestrierungslogik.
Erstellen einer __main__.py
Datei
Die Datei __main__.py
dient als Einstiegspunkt für den FastAPI-Server, der den Host-Agenten umhüllt.
from common.a2a_server import create_app
from .task_manager import run
app = create_app(agent=type("Agent", (), {"execute": run}))
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, port=8000)
Die Hauptdatei macht Folgendes:
- Es verwendet
create_app()
voncommon/a2a_server.py
, um eine FastAPI-Anwendung mit einem standardisierten/run
Endpunkt zu erstellen. - Dann übergibt er ein einfaches agentenähnliches Objekt mit einer
execute()
Methode, die intern an dietask_manager.run()
Funktion delegiert. - Zum Schluss wird der FastAPI-Server über
uvicorn
an einem bestimmten Port (normalerweise 8000) gestartet.
Dadurch wird die Schnittstelle des Host-Agenten mit anderen nachgelagerten Agenten abgeglichen und die Konsistenz im gesamten System gewahrt.
Erstellen einer .well-known/agent.json
Datei
Diese Datei funktioniert wie ein klassisches Multi-Agenten-Muster, bei dem ein zentraler Knotenpunkt Aufgaben delegiert und zusammenstellt.
{
"name": "host_agent",
"description": "Coordinates travel planning among specialized agents."
}
Das ist zwar optional, aber es ist eine gute Praxis, dies in alle Agentenverzeichnisse aufzunehmen, wie bereits erklärt.
Schritt 5: Erstellen der Benutzeroberfläche mit Streamlit
Schließlich wollen wir eine einfache App entwickeln, in der die Nutzer ihre Vorlieben eingeben können und eine strukturierte Reiseroute erhalten. Beginne damit, eine travel_ui.py
Datei im Stammverzeichnis zu erstellen und füge den folgenden Code hinzu.
import streamlit as st
import requests
Wir importieren grundlegende Bibliotheken wie Streamlit und Requests für die UI-Unterstützung.
st.set_page_config(page_title="ADK-Powered Travel Planner", page_icon="✈️")
st.title("🌍 ADK-Powered Travel Planner")
origin = st.text_input("Where are you flying from?", placeholder="e.g., New York")
destination = st.text_input("Destination", placeholder="e.g., Paris")
start_date = st.date_input("Start Date")
end_date = st.date_input("End Date")
budget = st.number_input("Budget (in USD)", min_value=100, step=50)
if st.button("Plan My Trip ✨"):
if not all([origin, destination, start_date, end_date, budget]):
st.warning("Please fill in all the details.")
else:
payload = {
"origin": origin,
"destination": destination,
"start_date": str(start_date),
"end_date": str(end_date),
"budget": budget
}
response = requests.post("http://localhost:8000/run", json=payload)
if response.ok:
data = response.json()
st.subheader("✈️ Flights")
st.markdown(data["flights"])
st.subheader("🏨 Stays")
st.markdown(data["stay"])
st.subheader("🗺️ Activities")
st.markdown(data["activities"])
else:
st.error("Failed to fetch travel plan. Please try again.")
Die Streamlit-App bietet eine benutzerfreundliche Oberfläche für die Interaktion mit dem Multi-Agenten-Reiseplaner, der auf ADK basiert. Hier sind ein paar Dinge, die wir im obigen Code ansprechen.
- Er verwendet
text_input
,date_input
undnumber_input
, um Herkunft, Ziel, Datum und Budget zu erfassen. - Wenn du auf "Meine Reise planen" klickst, werden die Eingaben überprüft, um sicherzustellen, dass kein Feld leer bleibt.
- Wenn er gültig ist, erstellt er einen JSON-Payload und sendet eine POST-Anfrage an die
host_agent
.http://localhost:8000/run.
- Die
host_agent
ruft alle untergeordneten Agenten (Flug, Aufenthalt, Aktivität) auf, fasst deren Antworten zusammen und liefert einen einheitlichen Reiseplan. - Die Antwort wird geparst und mit der Methode
st.markdown()
unter separaten Überschriften für Flüge, Aufenthalte und Aktivitäten angezeigt. - Wenn das Backend fehlschlägt, wird eine Fallback-Fehlermeldung mit
st.error()
angezeigt.
Führe nun den folgenden Befehl in deinem Terminal aus:
uvicorn agents.host_agent.__main__:app --port 8000 &
uvicorn agents.flight_agent.__main__:app --port 8001 &
uvicorn agents.stay_agent.__main__:app --port 8002 &
uvicorn agents.activities_agent.__main__:app --port 8003 &
streamlit run travel_ui.py
Wenn ein Nutzer auf "Meine Reise planen" klickt, übernimmt der Host-Agent die Aufgabe, aktiviert die Agenten und zeigt die Ergebnisse in der Benutzeroberfläche an:
Deine gesamte Dateistruktur würde etwa so aussehen:
ADK_demo/
├── agents/
│ ├── host_agent/
│ │ ├── agent.py
│ │ ├── task_manager.py
│ │ ├── __main__.py
│ │ └── .well-known/
│ │ └── agent.json
│ │
│ ├── flight_agent/
│ │ ├── agent.py
│ │ ├── task_manager.py
│ │ ├── __main__.py
│ │ └── .well-known/
│ │ └── agent.json
│ │
│ ├── stay_agent/
│ │ ├── agent.py
│ │ ├── task_manager.py
│ │ ├── __main__.py
│ │ └── .well-known/
│ │ └── agent.json
│ │
│ └── activities_agent/
│ ├── agent.py
│ ├── task_manager.py
│ ├── __main__.py
│ └── .well-known/
│ └── agent.json
│
├── common/
│ ├── a2a_client.py # Utility to send requests to other agents
│ └── a2a_server.py # Shared FastAPI A2A-compatible server template
│
├── shared/
│ └── schemas.py # Shared Pydantic schema
│
├── streamlit_app.py # Frontend UI for user input and response rendering
├── requirements.txt
└── README.md
Und das war's! Ich habe alles, was wir gebaut haben, in diesem GitHub-Projekt.
Fazit
Mit ein paar FastAPI-Apps und ADK-Agenten haben wir einen kollaborativen Reiseplaner gebaut, der:
- Kommuniziert über das A2A-Protokoll
- Nutzt LLM-Agenten für Flüge, Aufenthalte und Aktivitäten
- Fasst die Ergebnisse zusammen und zeigt sie in einer übersichtlichen Streamlit-Benutzeroberfläche an
Auch wenn alle Agenten unter der Haube dasselbe Modell verwenden, ist dieses System ein Multi-Agenten-System, d.h. die Agenten haben unterschiedliche Rollen, isolierte Verantwortlichkeiten und eine strukturierte Kommunikation.
Hier sind ein paar Ressourcen für den Anfang:

Ich bin ein Google Developers Expert in ML (Gen AI), ein Kaggle 3x Expert und ein Women Techmakers Ambassador mit mehr als 3 Jahren Erfahrung im Tech-Bereich. Ich habe 2020 ein Startup im Bereich Gesundheitstechnologie mitbegründet und mache einen Master in Informatik an der Georgia Tech, der sich auf maschinelles Lernen spezialisiert.
Lerne KI mit diesen Kursen!
Kurs
Entwicklung von KI-Systemen mit der OpenAI API
Kurs
Retrieval Augmented Generation (RAG) mit LangChain
Der Blog
Top 30 Generative KI Interview Fragen und Antworten für 2024

Hesam Sheikh Hassani
15 Min.
Der Blog
Die 50 besten AWS-Interview-Fragen und Antworten für 2025

Der Blog
Lehrer/innen und Schüler/innen erhalten das Premium DataCamp kostenlos für ihre gesamte akademische Laufbahn
Der Blog
Die 20 besten Snowflake-Interview-Fragen für alle Niveaus

Nisha Arya Ahmed
15 Min.
Der Blog
Q2 2023 DataCamp Donates Digest
Der Blog