Direkt zum Inhalt

Das Agent Development Kit (ADK) von Google: Ein Leitfaden mit Demo-Projekt

Lerne, wie du mit dem Agent Development Kit (ADK) von Google und dem Agent2Agent (A2A)-Protokoll einen Multi-Agenten-Reiseassistenten erstellst.
Aktualisierte 14. Apr. 2025  · 12 Min. Lesezeit

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 Agenten
  • flight_agent: Findet passende Flüge
  • stay_agent: Schlägt Unterkünfte vor
  • activities_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 ADK run() 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() von common/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 die task_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 und number_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:

Streamlit-Schnittstelle für ein Multi-Agenten-System, das mit dem Agent Development Kit (ADK) von Google entwickelt wurde

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                    

Streamlit-Schnittstelle für ein Multi-Agenten-System, das mit dem Agent Development Kit (ADK) von Google entwickelt wurde

Streamlit-Schnittstelle für ein Multi-Agenten-System, das mit dem Agent Development Kit (ADK) von Google entwickelt wurde

Streamlit-Schnittstelle für ein Multi-Agenten-System, das mit dem Agent Development Kit (ADK) von Google entwickelt wurde

Streamlit-Schnittstelle für ein Multi-Agenten-System, das mit dem Agent Development Kit (ADK) von Google entwickelt wurde

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:


Aashi Dutt's photo
Author
Aashi Dutt
LinkedIn
Twitter

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.

Themen

Lerne KI mit diesen Kursen!

Zertifizierung verfügbar

Kurs

Entwicklung von LLM-Anwendungen mit LangChain

3 hr
20.1K
Entdecke, wie du mit LLMs, Prompts, Ketten und Agenten in LangChain KI-gestützte Anwendungen erstellen kannst.
Siehe DetailsRight Arrow
Kurs starten
Mehr anzeigenRight Arrow
Verwandt

Der Blog

Top 30 Generative KI Interview Fragen und Antworten für 2024

Dieser Blog bietet eine umfassende Sammlung von Fragen und Antworten zu generativen KI-Interviews, die von grundlegenden Konzepten bis hin zu fortgeschrittenen Themen reichen.
Hesam Sheikh Hassani's photo

Hesam Sheikh Hassani

15 Min.

Der Blog

Die 50 besten AWS-Interview-Fragen und Antworten für 2025

Ein kompletter Leitfaden zur Erkundung der grundlegenden, mittleren und fortgeschrittenen AWS-Interviewfragen, zusammen mit Fragen, die auf realen Situationen basieren.
Zoumana Keita 's photo

Zoumana Keita

15 Min.

Der Blog

Lehrer/innen und Schüler/innen erhalten das Premium DataCamp kostenlos für ihre gesamte akademische Laufbahn

Keine Hacks, keine Tricks. Schüler/innen und Lehrer/innen, lest weiter, um zu erfahren, wie ihr die Datenerziehung, die euch zusteht, kostenlos bekommen könnt.
Nathaniel Taylor-Leach's photo

Nathaniel Taylor-Leach

4 Min.

Der Blog

Die 20 besten Snowflake-Interview-Fragen für alle Niveaus

Bist du gerade auf der Suche nach einem Job, der Snowflake nutzt? Bereite dich mit diesen 20 besten Snowflake-Interview-Fragen vor, damit du den Job bekommst!
Nisha Arya Ahmed's photo

Nisha Arya Ahmed

15 Min.

Der Blog

Q2 2023 DataCamp Donates Digest

DataCamp Donates hat im zweiten Quartal 2023 über 20.000 Stipendien an unsere gemeinnützigen Partner vergeben. Erfahre, wie fleißige benachteiligte Lernende diese Chancen in lebensverändernde berufliche Erfolge verwandelt haben.
Nathaniel Taylor-Leach's photo

Nathaniel Taylor-Leach

Der Blog

2022-2023 DataCamp Classrooms Jahresbericht

Zu Beginn des neuen Schuljahres ist DataCamp Classrooms motivierter denn je, das Lernen mit Daten zu demokratisieren. In den letzten 12 Monaten sind über 7.650 neue Klassenzimmer hinzugekommen.
Nathaniel Taylor-Leach's photo

Nathaniel Taylor-Leach

8 Min.

Mehr anzeigenMehr anzeigen