Ein Fünf-Agenten-Support-Desk auf Gemini 3.1 und ADK: Triage, Recherche, Handlung, QA und Orchestrator
Erstellen Sie ein mehragentenbasiertes Kundensupport-System mit Google ADK und Gemini 3.1: typbasierte Weiterleitungen, QA-Korrekturläufe, Agent Engine oder Cloud Run, Sitzungen und Kosten.
Stellen Sie sich eine fehlerhafte Bestellung vor. Ein Kunde schreibt, dass das falsche Produkt angekommen ist, bittet um Rückerstattung und möchte außerdem das richtige Produkt noch am selben Tag versandt bekommen. Hinter diesem einen Satz stecken drei Aufgaben: Die Bestellung überprüfen, die Rückgabe bearbeiten und einen Ersatz schnell versenden. Jede Aufgabe benötigt eigene Daten, eigene Richtlinien und eigene Handlungen. Ein einzelner Support-Bot mit einer einzigen umfangreichen Anweisung kann nur eine einfache Frage bewältigen und stolpert oft, wenn mehrere Aufgaben miteinander verknüpft sind. Er wird langsam, anfällig und fehleranfällig.
Die Lösung besteht in einem mehragentigen Design: mehrere Spezialisten, von denen jeder für einen Teil des Workflows verantwortlich ist, wobei ein Orchesterator den Ablauf steuert. Im Folgenden wird gezeigt, wie man dies auf Google Cloud mit den Gemini 3.1-Modellen sowie dem Google Agent Development Kit (ADK) umsetzt. Es wird erläutert, wie man Agentenrollen mit klaren Grenzen festlegt, wie ein Orchesterator Aufgaben verteilt, Delegierungen vornimmt und Ergebnisse zusammenführt, wie Agenten den Zustand untereinander weitergeben – sowie, was genauso wichtig ist, wann ein einzelner Agent immer noch die bessere Wahl ist.
Was schiefgeht bei einem großen Prompt
Stellen Sie sich einen Support-Agenten vor, der mit einfachen Aufgaben begann und stetig neue Fähigkeiten erwarb: das Abrufen von Informationen aus einer Wissensdatenbank, ein sanfterer Tonfall bei verärgerten Kunden sowie die Möglichkeit zur Selbstüberprüfung. Sein Systemprompt wächst auf über 3.000 Token an, und jede Ergänzung stört etwas, das bereits vorhanden ist. Daraus ergeben sich vier Symptome:
- Begrenzungen durch Mehrfachanwendung. Die Rückerstattungsregeln gelten plötzlich auch für Fragen, die nichts mit Rückerstattungen zu tun haben, wodurch auf einfache Produktanfragen ebenfalls Logik zur Rückgabe angewandt wird.
- Geringere Aufmerksamkeitsspanne. Die Aufmerksamkeit eines Modells ist begrenzt. Wenn sie auf Dutzende von Anweisungen verteilt wird, von denen die meisten für die jeweilige Anfrage irrelevant sind, erhält jede weniger Gewicht.
- Unmögliche Fehlersuche. Wenn die Antwort falsch ist, ist unklar, welche der vielen Anweisungen dazu geführt hat.
- Nur ein Prozessweg für alles. Jede Anfrage durchläuft unabhängig von ihrer Schwierigkeit denselben Ablauf.
Durch Aufteilung der Arbeit erhält jedes Modell sein gesamtes Aufmerksamkeitsbudget für die vorliegende Aufgabe. Es denkt nur während der Verarbeitung von Rückerstattungen an die Rückerstattungsrichtlinien und nur beim Überprüfen eines Entwurfs an den Ton.
ADK ist nach diesem Konzept entworfen. Sein AutoFlow-Mechanismus steuert die Abstimmung zwischen Spezialisten: Wenn ein Orchesterer Sub-Agenten hat, fügt ADK ein transfer_to_agent()-Tool hinzu und schreibt Beschreibungen aller verfügbaren Spezialisten in seinen Kontext. Der Orchesterer weiß somit, wer zu seinem Team gehört und wofür jedes Mitglied geeignet ist.
Struktur des Systems
Anstelle einer einzigen Anfrage steht ein zentraler Orchesterer über einer Reihe von spezialisierten Sub-Agenten. Die Modelle müssen nicht identisch sein. Der stärkste Denker übernimmt Aufgaben, bei denen Urteilsvermögen wichtig ist (Orchestrierung und Qualitätsprüfung), während der schnellste und günstigste für Aufgaben eingesetzt wird, bei denen Geschwindigkeit entscheidend ist (Triage):
- Orchesterer: plant und delegiert. Gemini 3.1 Pro. Seine Tools sind die Spezialisten-Agenten.
- Triage-Agent: liest Stimmung und Absicht ein und leitet weiter. Gemini 3.1 Flash-Lite, unterstützt durch NLP-Klassifikatoren.
Gemini 2.5 Flash bleibt ein guter Allrounder für Prozesse mit einem einzigen Agenten. Wenn jedoch die Qualität der Argumentation Entscheidungen über den Ablauf bestimmt, eignet sich die Gemini 3.1-Serie (grundsätzlich seit Anfang 2026 verfügbar) besser, insbesondere für die Rollen des Orchestriers und der Qualitätskontrolle.
Die beteiligten Google Cloud-Produkte sind:
- Gemini 3.1-Modelle als Kern für die Argumentation, angepasst für den Einsatz von Tools.
- Agent Development Kit als Framework, das Übertragungen über AutoFlow abwickelt.
- Vertex AI Agent Engine als verwalteter Laufzeitumgebung zur Bereitstellung und Skalierung von Agenten.
- Firestore als gemeinsamer Sitzungszustand, in dem Agenten Gesprächsdaten lesen und schreiben können.
- Vertex AI Vector Search zur Suche in der Wissensdatenbank.
Einrichtung von ADK
ADK stellt die notwendige Infrastruktur bereit, einschließlich des Übergabemusters, mit dem ein Agent den Anruf effektiv an einen anderen übertragen kann. Die Installation erfolgt in nur einer Zeile:
pip install google-adk google-generativeai google-cloud-firestore pydantic
Pydantic wird ausdrücklich aufgelistet, weil ADK darauf angewiesen ist, um Schemata für Eingaben und Ausgaben der Agenten zu erstellen, und seine Angabe sorgt für kompatible Versionen.
Über die Struktur des Projekts sollte man frühzeitig nachdenken. Mehr-Agentensysteme versagen am häufigsten an den Schnittstellen: Ein Agent sendet einen refund_id als Integer, während ein anderer einen String erwartet. Eine einfache Struktur mit gemeinsamen Schemata verhindert solche Fehler:
support_agents/
├── main.py # Entry point for Cloud Run
├── common/
│ ├── __init__.py
│ └── schemas.py # Shared Pydantic models (the "handshake")
├── agents/
│ ├── __init__.py
│ ├── orchestrator.py
│ ├── triage.py
│ ├── research.py
│ ├── action.py
│ └── qa.py
└── config.py # Environment & project IDs
Ein Krankenhaus ist eine passende Analogie. Der Orchesterleiter ist das Triage-Pflegepersonal, der Forschungsagent ist der Labortechniker und der Handlungsagent ist der Chirurg. Keiner von ihnen spricht gleichzeitig mit dem Patienten. Sie lesen und aktualisieren die Krankenakte des Patienten, die hier Firestore ist, und schemas.py ist das Format der Akte, auf dem sich alle einigen.
Der Triage-Agent
Triage fungiert wie die Flugverkehrsleitstelle. Sie löst nichts selbst, sondern sorgt lediglich dafür, dass jede Anfrage mit der richtigen Priorität zum richtigen Spezialisten gelangt.
Das Übergeben von Rohstrings zwischen den Agenten führt zu Fehlern. Ein strenges Pydantic-Schema bedeutet, dass der Orchesterleiter ein validiertes Python-Objekt erhält und niemals freien Text analysieren muss. Zuerst kommt das Schema:
# common/schemas.py
from pydantic import BaseModel, Field
class TriageResult(BaseModel):
intents: list[str] = Field(description="List of detected customer goals")
urgency: str = Field(pattern="^(low|medium|high|critical)quot;)
sentiment: str = Field(description="Current emotional state of the user")
required_agents: list[str] = Field(
description="List of sub-agents needed (research, action, etc.)"
)
Dann der Agent, der es erzeugt:
# agents/triage.py
from google.adk.agents import LlmAgent
from common.schemas import TriageResult
triage_agent = LlmAgent(
name="triage_agent",
model="gemini-3.1-flash-lite", # Fast and cheap for classification
instruction="""You are a triage specialist. Analyze the customer's
message and categorize it accurately.
Urgency rules:
- critical: Active outages or safety threats
- high: Frustrated users or financial issues > $100
- medium: Standard requests needing action
- low: General info/feedback
You must NOT attempt to solve the problem. Only classify it.""",
output_schema=TriageResult, # Force structured JSON output
output_key="triage_data"
)
Vier Gestaltungsentscheidungen sind in dieser Definition wichtig:
- Eine Aufgabe. Der Agent beantwortet niemals Fragen oder führt Aktionen aus, sondern klassifiziert nur. Dadurch bleibt die Anfrage kurz und die Genauigkeit hoch.
- Gestrukturierte Ausgabe.
output_schemaerzwingt gültiges JSON, dasTriageResultentspricht, und ADK überprüft es automatisch mithilfe von Pydantic. - Mehrere Absichten gleichzeitig. Da
intentseine Liste von Zeichenketten ist, funktioniert eine Nachricht, die darum bittet, eine Adresse zu aktualisieren und gleichzeitig die neueste Rechnung zu prüfen, während ein Einzel-Label-Klassifikator versagen würde. - Übertragung des Zustands.
output_key="triage_data"speichert das Ergebnis im Sitzungszustand, sodass der Orchestrierer es übersession.state['triage_data']abruft.
Der Forschungsagent
Der Forschungsagent ist der Ermittler. Er holt Rohdaten aus Firestore und dem Abrufprozess ab und fasst sie anschließend zu einem strukturierten Bericht für den Handlungsagenten zusammen. Das Schema dieses Berichts stellt den Vertrag zwischen diesen beiden Rollen dar:
# common/schemas.py (add to existing file)
class ResearchBrief(BaseModel):
order_status: str = Field(description="Current order state")
customer_tier: str = Field(description="e.g. Gold, Standard")
applicable_policy: str = Field(description="Relevant policy text")
can_refund: bool = Field(description="Whether a refund is allowed")
reasoning: str = Field(description="Why this conclusion was reached")
Danach folgen seine Tools und die Definition des Agents:
# agents/research.py
from google.adk.agents import LlmAgent
from google.cloud import firestore
from common.schemas import ResearchBrief
db = firestore.Client()
def lookup_order(order_id: str) -> dict:
"""Fetch real-time shipping status and line items for an order ID."""
doc = db.collection('orders').document(order_id).get()
if doc.exists:
return doc.to_dict()
return {"error": f"Order {order_id} not found"}
def lookup_customer(customer_id: str) -> dict:
"""Retrieve customer profile, tier, and interaction history."""
doc = db.collection('customers').document(customer_id).get()
if doc.exists:
return doc.to_dict()
return {"error": f"Customer {customer_id} not found"}
def search_knowledge_base(query: str) -> list:
"""Search product docs and company policies via RAG pipeline."""
# Uses the RAG pipeline from our previous article
from rag_pipeline import pipeline
result = pipeline.query(query, top_k=5)
return result['sources']
research_agent = LlmAgent(
name="research_agent",
model="gemini-3.1-flash",
instruction="""You are a research specialist.
1. Extract identifiers (Order ID, Customer ID) from the triage data.
2. Use tools to gather order history and relevant company policies.
3. If policy info is missing, use search_knowledge_base.
CRITICAL: Do not answer the customer. Output a formal ResearchBrief.""",
tools=[lookup_order, lookup_customer, search_knowledge_base],
output_schema=ResearchBrief,
output_key="research_brief"
)
Der State wird ohne zusätzlichen Code übertragen. Wenn der Forschungsagent gestartet wird, injiziert ADK triage_data aus dem vorherigen Schritt in seinen Kontext, sodass er bereits weiß, dass er nach der Bestellung mit der Nummer 12345 suchen muss, da die Triage diese Absicht erkannt hat. Jeder Agent baut auf der Arbeit des vorherigen auf, und nichts wird zweimal erledigt. Ein kleiner Produktions-Tipp: ADK umhüllt einfache Funktionen automatisch als FunctionTool-Objekte, doch ihre explizite Umhüllung mit from google.adk.tools import FunctionTool führt zu einer besseren Latenzverfolgung sowie zum Protokollieren der Tokennutzung im Vertex AI Agent Engine.
Der Aktion-Agent
Nur dieser Spezialist hat Schreibzugriff auf die Geschäfts-APIs. Da er hochriskante Operationen durchführt, gelten für ihn strenge Schemata sowie klare Richtlinien. Zunächst das Ausgabeschema:
# common/schemas.py (add to existing file)
class ActionSummary(BaseModel):
actions_taken: list[str] = Field(description="List of actions executed")
refund_id: str | None = Field(default=None, description="Refund ID if issued")
escalated: bool = Field(default=False)
escalation_reason: str | None = Field(default=None)
Dann das Agent selbst, das bei wertvollen Transaktionen eine menschliche Bestätigung anfordert:
# agents/action.py
from google.adk.agents import LlmAgent
from google.adk.tools import FunctionTool
from common.schemas import ResearchBrief, ActionSummary
def process_refund(order_id: str, amount: float, reason: str) -> dict:
"""Process a financial refund. Required: valid order_id and amount."""
# In production: call your payment API
return {
"status": "processed",
"refund_id": f"REF-{order_id}",
"amount": amount
}
def create_replacement_order(
order_id: str,
item_id: str,
shipping_speed: str
) -> dict:
"""Create a replacement order with specified shipping speed."""
# In production: call your order management API
return {
"status": "created",
"new_order_id": f"REPL-{order_id}",
"estimated_delivery": "2 business days"
}
def escalate_to_human(reason: str, priority: str) -> dict:
"""Escalate to a human agent with full context."""
return {
"status": "escalated",
"queue": "priority" if priority == "high" else "standard"
}
# Wrap refund tool with human confirmation for high-value transactions
refund_tool = FunctionTool(
func=process_refund,
require_confirmation=True # Pauses for human approval before executing
)
action_agent = LlmAgent(
name="action_agent",
model="gemini-3.1-flash",
instruction="""You are an action specialist.
Review the 'research_brief' in the session state.
CRITICAL RULES:
1. Only refund if 'can_refund' is True in the research brief
2. If amount > $500, you MUST use escalate_to_human
3. You must call tools for every action — do not just tell the user
it happened
4. If information is missing from the brief, escalate""",
tools=[refund_tool, create_replacement_order, escalate_to_human],
input_schema=ResearchBrief, # Only sees research data, not raw chat
output_schema=ActionSummary,
output_key="action_result"
)
Zwei Einstellungen tragen den größten Teil zur Sicherheit bei. require_confirmation existiert, weil ein Produktivsystem selten einem Agenten erlaubt, allein aufgrund von Anweisungen im Prompt einen Rückerstattungsvorgang durchzuführen. ADKs Tool zur Bestätigung hält die Ausführung bis zu einer menschlichen Genehmigung an und zeigt dem Orchestrierer einen „pending“-Status, den er auf ein Mitarbeiter-Dashboard weiterleiten kann. input_schema ist wichtig, da der Agent ohne es den gesamten Dialog inklusive veralteter Nachrichten sehen würde. Die Einschränkung der Eingaben auf ResearchBrief verhindert, dass veralteter Kontext eindringt, und stellt sicher, dass Entscheidungen auf den aktuellsten Daten beruhen.
Bemerken Sie außerdem, dass escalate_to_human eine bewusste Geschäftsregel und kein Fehlerzustand ist. Der Orchestrierer kann genau erkennen, warum der Agent aufgehört hat, und das Ticket zusammen mit dem vollständigen Research Brief an eine Person weiterleiten.
Der QA-Agent
QA ist die letzte Kontrollstufe. Neben der Überprüfung der Formulierungen vergleicht sie das, was der Handlungsagent getan hat, mit dem Inhalt des Forschungsauftrags, damit Handeln mit Wissen übereinstimmt.
Diese Funktion läuft auf Gemini 3.1 Pro, da sie den gesamten Gesprächsverlauf im Gedächtnis behalten und feine Widersprüche erkennen muss – Aufgaben, bei denen Pro konsequent besser abschneidet als Flash. ADK ermöglicht es außerdem, den Denkmodus zur tieferen Selbstreflexion vor der Freigabe einer Antwort zu nutzen. Das Überprüfungs Schema:
# common/schemas.py (add to existing file)
class QAReview(BaseModel):
is_approved: bool = Field(description="True if the response meets all criteria")
feedback: str = Field(description="Specific corrections if not approved")
final_text: str = Field(description="The customer-facing message")
Und die Agent-Konfiguration:
# agents/qa.py
from google.adk.agents import LlmAgent
from google.adk.planners import BuiltInPlanner
from google.genai.types import ThinkingConfig
from common.schemas import QAReview
qa_agent = LlmAgent(
name="qa_agent",
model="gemini-3.1-pro",
instruction="""You are a senior QA auditor. Compare the 'action_result'
against the 'research_brief' in the session state.
CRITICAL CHECKS:
1. Did the Action Agent refund the EXACT amount listed in the brief?
2. Does the response cite the policy found during research?
3. Is the tone empathetic but professional?
4. Are ALL intents from the triage classification addressed?
5. No unauthorized promises, discounts, or policy exceptions
If any check fails, set is_approved to False with specific feedback.""",
output_schema=QAReview,
output_key="qa_review",
# MEDIUM for routine QA; switch to HIGH for edge cases or audits
planner=BuiltInPlanner(
thinking_config=ThinkingConfig(thinking_level="MEDIUM")
)
)
Die Ablehnung beendet den Prozess nicht. Wenn qa_review.is_approved falsch ist, liest der Orchesterer das feedback-Feld und leitet die Anfrage mit konkreten Korrekturen zurück an den jeweiligen Agenten oder Forschungsagenten. Dieser Korrekturzyklus ist es, der einen Produktionsagenten von einem Demo-Skript unterscheidet. Er ist auf zwei Überarbeitungsrunden beschränkt, danach wird der Fall an einen Menschen weitergeleitet.
Der Orchesterer
Der Orchesterer führt weder Forschungen durch noch handelt er selbst. Er verwaltet den Zustand und sorgt dafür, dass die Spezialisten in einer sinnvollen Reihenfolge arbeiten. Unter Verwendung von sub_agents fügt ADKs AutoFlow das Tool transfer_to_agent() hinzu, und der LLM des Orchesterers wählt den nächsten Spezialisten anhand seiner Anweisungen sowie des aktuellen Sitzungszustands aus:
# agents/orchestrator.py
from google.adk.agents import LlmAgent
from agents.triage import triage_agent
from agents.research import research_agent
from agents.action import action_agent
from agents.qa import qa_agent
orchestrator = LlmAgent(
name="support_orchestrator",
model="gemini-3.1-pro", # Best reasoning for delegation decisions
instruction="""You are the lead coordinator of a customer support team.
Use the following specialists in order:
1. triage_agent: to classify the intent and urgency
2. research_agent: to gather order data and relevant policies
3. action_agent: to execute the required operations
4. qa_agent: to verify the final response
Special cases:
- If triage classifies as 'critical': bypass the chain and escalate
- If QA returns is_approved=False: re-route to the responsible agent
with the feedback (maximum 2 revision cycles, then escalate)
- If any agent fails: escalate to human with full context
You must never respond to the customer directly.
Always route through the specialist pipeline.""",
sub_agents=[triage_agent, research_agent, action_agent, qa_agent]
)
Ausführen
ADK führt Agenten über einen Runner aus, der die Ausführung pausiert, sobald ein Agent ein Tool aufruft, und den Agenten anschließend wieder startet, sobald das Ergebnis zurückgekehrt ist:
# main.py
from google.adk.runners import Runner
from google.adk.sessions import InMemorySessionService
from agents.orchestrator import orchestrator
APP_NAME = "customer_support"
USER_ID = "system"
# For production, replace with a Firestore-backed session service
session_service = InMemorySessionService()
runner = Runner(
agent=orchestrator,
app_name=APP_NAME,
session_service=session_service
)
async def handle_customer_message(customer_id: str, message: str):
"""
Entry point for customer messages.
"""
session_id = f"support-{customer_id}"
# Ensure session exists
session = await session_service.get_session(
app_name=APP_NAME, user_id=USER_ID, session_id=session_id
)
if not session:
session = await session_service.create_session(
app_name=APP_NAME, user_id=USER_ID, session_id=session_id
)
# run_async yields events as agents execute
final_response = None
async for event in runner.run_async(
user_id=USER_ID,
session_id=session_id,
new_message=message
):
if event.is_final_response():
final_response = event
return {
"response": final_response.content.parts[0].text if final_response else None,
"session_id": session_id
}
Warum nicht die Agenten direkt anrufen? Der Runner übernimmt den gesamten Ablauf. Er speichert Sessions, verfolgt den aktiven Agenten, verarbeitet Toolaufrufe und protokolliert jeden Schritt. Da jeder Agent seine Ausgabe unter einem output_key speichert, garantiert der Runner, dass das Forschungsprofil bereitsteht, wenn es vom Handlungsagenten benötigt wird – ohne manuelle Anpassungen. Die Nachvollziehbarkeit ist außerdem inklusive: Jeder Agentenaufruf, jede Toolnutzung sowie jeder Übergabeprozess wird als Ereignis protokolliert, was die zuvor geäußerte Problematik bei der Fehlersuche löst. Wenn etwas schiefgeht, zeigt die Spur an, welcher Agent was und warum entschieden hat.
Implementierungswege
Es gibt zwei Möglichkeiten, es einzusetzen. Vertex AI Agent Engine bietet eine verwaltete Laufzeitumgebung, bei der fast nichts bedient werden muss, während Cloud Run volle Kontrolle über den Container bietet.
Agent Engine
Das ist der wartungsarme Ansatz, der für die meisten ADK-eigenen Konfigurationen empfohlen wird. Legen Sie zwei Variablen fest:
PROJECT_ID=your-project-id
LOCATION_ID=us-central1
Dann führen Sie mit einem Befehl den Deploy durch:
adk deploy agent_engine \
--project=$PROJECT_ID \
--region=$LOCATION_ID \
--display_name="Customer Support Team" \
support_agents
Agent Engine kümmert sich um Skalierung, Session-Persistenz sowie tracebasiertes Logging, das die Eigenschaften der Agenten berücksichtigt. Es gibt keinen Dockerfile, keinen Session-Code und keine Infrastruktur, die betreut werden muss.
Cloud Run
Wählen Sie diese Option, wenn benutzerdefinierte Systembibliotheken, spezielle Netzwerklösungen wie VPC Service Controls oder Komponenten außerhalb des ADK erforderlich sind. Im Beispiel wird statt Flask Quart verwendet. Die Syntax ist nahezu identisch, doch Quart handhabt async/await nativ, wodurch das Anti-Muster asyncio.run() vermieden wird – bei dem für jede Anfrage ein neuer Event-Loop gestartet wird:
# server.py
from quart import Quart, request, jsonify
from main import handle_customer_message
app = Quart(__name__)
@app.route("/support", methods=["POST"])
async def support():
data = await request.get_json()
# No asyncio.run needed — Quart handles the event loop
result = await handle_customer_message(
data["customer_id"],
data["message"]
)
return jsonify(result)
@app.route("/health", methods=["GET"])
async def health():
return jsonify({"status": "healthy"})
if __name__ == "__main__":
app.run(host="0.0.0.0", port=8080)
Die Container-Definition:
# Dockerfile
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 8080
CMD ["python", "server.py"]
Und der Deploy-Befehl:
gcloud run deploy support-agents \
--source . \
--region us-central1 \
--memory 4Gi \
--cpu 2 \
--allow-unauthenticated
Kurz gesagt erfordert Cloud Run eine mittlere Menge an Einrichtungsaufwand (einen Dockerfile und eine API), benötigt eine manuelle Zustandsverwaltung mit Firestore oder Redis, protokolliert in das Standard-Cloud Logging und eignet sich für benutzerdefinierte Laufzeiten sowie Frameworks. Agent Engine benötigt nur einen Befehl, verfügt über integrierte Sessions, erzeugt agentenspezifische Spuren und eignet sich für ADK-native Agenten, die schnell skaliert werden müssen.
Aufrechterhaltung von Konversationen
Das Orchestrator-Beispiel nutzte InMemorySessionService, was für Tests in Ordnung ist, aber alles verliert, wenn der Prozess neu gestartet wird. In der Produktion ist ein dauerhafter Service erforderlich. ADK bietet zwei solcher Dienste.
Mit Agent Engine werden Sessions über den Vertex AI Session Service für Sie verwaltet:
# config.py
from google.adk.sessions import VertexAiSessionService
session_service = VertexAiSessionService(
project="your-project-id",
location="us-central1",
agent_engine_id="your-agent-engine-id" # From adk deploy output
)
Agent Engine fasst außerdem lange Historien zusammen und kümmert sich selbst um die Aufbereitung, sodass kein Firestore-Code erforderlich ist.
Für Cloud Run funktioniert DatabaseSessionService mit einem PostgreSQL- oder SQLite-Backend:
# config.py
from google.adk.sessions import DatabaseSessionService
# PostgreSQL for production
session_service = DatabaseSessionService(
db_url="postgresql+asyncpg://user:pass@host:5432/agents"
)
# Or SQLite for development
session_service = DatabaseSessionService(
db_url="sqlite+aiosqlite:///sessions.db"
)
Es erstellt seine Tabellen beim ersten Start. Wenn es in den Runner eingebettet wird, bleibt der Sitzungszustand auch nach Neustarts erhalten.
Wie der Zustand zwischen Agenten übertragen wird
Es sind keine manuellen get()- und set()-Aufrufe erforderlich. Jeder Agent schreibt automatisch mit seinem output_key in den Sitzungszustand, und späteren Agenten steht dieser dort zur Verfügung:
triage_agent (output_key="triage_data")
↓ writes to session.state["triage_data"]
research_agent (reads triage_data, output_key="research_brief")
↓ writes to session.state["research_brief"]
action_agent (input_schema=ResearchBrief, output_key="action_result")
↓ writes to session.state["action_result"]
qa_agent (reads action_result + research_brief, output_key="qa_review")
Der Runner speichert diesen gesamten Zustand bei dem konfigurierten Backend – egal ob Firestore, PostgreSQL oder Agent Engine.
Drei Gewohnheiten halten den Speicher gesund:
- Zusammenfassen. Speichern Sie gekürzte Ergebnisse anstelle von rohen API-Antworten, sonst füllt sich das Kontextfenster mit Überflussdaten.
- Sessions ablaufen lassen. Support-Sessions sollten eine Gültigkeitsdauer von 24 bis 48 Stunden haben, damit die Datenbank kleiner und sicherer bleibt.
- Persönliche Daten schützen. Rohdaten wie Personalausweisnummern oder Passwörter gehören nicht in den gemeinsamen Zustand; sie sollten daher maskiert werden, bevor etwas in die Session geschrieben wird.
Wann ein einzelner Agent immer noch die bessere Lösung ist
Mehr-Agenten-Systeme sind nicht automatisch überlegen. Eine praktische Entscheidungshilfe:
- Einfache FAQ oder Statusüberprüfung: Einzelagent. Geringste Latenz und Kosten, kein komplexes Denken erforderlich.
- Datenerweiterung durch drei bis fünf Abfragen: Einzelagent. Ein einziger Aufruf des LLM reicht aus, um die grundlegende Nutzung der Tools zu bewältigen.
- Geregelte Arbeitsabläufe: Mehrere Agenten. Die Isolierung hält die Ablauflogik von den Benutzereingaben getrennt, was eine Eingabe von Manipulationsbefehlen erschwert.
- Unklare Routen: Mehrere Agenten. Ein spezieller Triage-Agent, der sich auf die Zuordnung von Absichten spezialisiert hat, verringert die Auswirkungen von Einschränkungen.
- Wichtige Aktionen im Wert von über 500 Dollar: Mehrere Agenten. Es wird eine doppelte Überprüfung durch einen QA-Agenten vor jedem API-Aufruf ermöglicht.
- Auditspezifikationen: Mehrere Agenten. Die Eingaben und Ausgaben jedes Agenten werden getrennt protokolliert.
Eine Faustregel: Wenn ein Prompt für einen einzelnen Agenten bei etwa 3.000 Tokens ankommt – dem Punkt, an dem Einschränkungen zu Problemen führen und die Aufmerksamkeit des Modells nachlässt – oder wenn verschiedene Teile des Arbeitsablaufs unterschiedliche Tools erfordern, ist es an der Zeit, den Agenten aufzuteilen.
Häufige Fallstricke
- Der „Alleskönner-Agent“. Die Leistung sinkt, sobald ein Agent zehn oder mehr Tools besitzt, da die Modelle ihre Energie stattdessen darauf verwenden, ein Tool auszuwählen, anstatt die Anfrage zu verstehen. Teilen Sie den Agenten nach Funktionen auf: Ein Agent, der Rückzahlungen, Versand und rechtliche Aspekte handhaben muss, wird in drei Spezialisten aufgeteilt.
- Ausufernder Kontext. Wenn jeder Agent die gesamte zehn-Schritte umfassende Konversation sieht, steigen die Tokenkosten enorm an. Komprimieren Sie den Zustand, sodass nur die erkannte Absicht weitergeleitet wird und nicht die gesamte Konversation.
input_schema- und output_schema-Verträge ohne überschneidende Aufgaben.ParallelAgent verteilt die Arbeit unabhängig voneinander, und das Parallelausführen von Forschungs- sowie Konformitätsprüfungen kann 30 bis 40 Prozent der Gesamtlatenz reduzieren.Was man davon erwarten kann
Mehr-Agenten-Systeme tauschen Latenz gegen Zuverlässigkeit bei komplexen Aufgaben ein. Veröffentlichte Benchmarks sowie Branchenerfahrungen weisen auf diese Stärken hin:
- Genauigkeit bei komplexen Aufgaben. Das Zerlegen mehrschrittiger Probleme in fokussierte Unteraufgaben bringt in der Regel bessere Ergebnisse als monolithische Anfragen, und die Dokumentation von ADK weist auf höhere Abschlussraten hin, wenn Agenten spezifische Aufgaben haben.
- Eingegrenzte Fehler. Wenn ein Komponente versagt, bleibt der Schaden auf diesem Agent beschränkt und zerstört nicht die gesamte Antwort.
- Auditorierbarkeit. Getrennte Protokolle pro Agent erleichtern das Debuggen sowie die Einhaltung von Vorgaben.
Auch die Kosten sind real:
- Verzögerung. Ein vollständiger Prozess mit fünf Agenten dauert in der Regel 3 bis 8 Sekunden, während ein einzelner Agent nur 1 bis 2 Sekunden benötigt. Sequenzielle Aufrufe stellen das Hauptengpass dar.
thinking_level="HIGH") kann etwa 20.000 Token hinzufügen, wofür ein Entgelt von 12 US-Dollar pro Million Ausgabe-Token anfällt. Eine umfassende QA-Überprüfung kostet daher allein für das Denken etwa 0,24 US-Dollar. Verwenden Sie „HIGH“ selektiv, da die meisten QA-Prüfungen mit „MEDIUM“ ausreichen.Für eine ungefähre monatliche Rechnung bei 100.000 komplexen Abfragen:
- Orchestrator-Routing auf Gemini 3.1 Pro: etwa 80 Dollar
- Triage mit Flash-Lite: etwa 20 Dollar
- Forschung zu Flash: etwa 40 Dollar
- Aktionen mit Flash: etwa 40 Dollar
- QA mit MEDIUM-Thinking auf Pro: etwa 100 Dollar
- Cloud Run mit 2 vCPU und 2 GiB: etwa 120 Dollar
- PostgreSQL-Sessions: etwa 30 Dollar
- Vector Search in Kombination mit einer Ein-Agenten-Einrichtung: etwa 100 Dollar
- Gesamt: etwa 530 Dollar pro Monat
Die Kombination von Modellen ist der eigentliche Kostenfaktor. Nur etwa 30 Prozent der Anfragen (Orchestrator und QA) fallen unter die Pro-Preise, während der Rest auf Flash oder Flash-Lite läuft – zu einem Achtel bis Fünfzigstel des Preises pro Token. Die Einheitskosten für eine komplexe Interaktion betragen etwa einen halben Cent. Diese Zahlen stammen aus den veröffentlichten Preisen von Google Cloud; tatsächliche Rechnungen variieren je nach Komplexität der Abfragen, dem Denklevel sowie der Tiefe der Agentenanrufe.
Reihenfolge der Einführung
Die sinnvolle Reihenfolge besteht darin, mit einem einzelnen Agenten zu beginnen, seine Logik anzupassen, ihn durch Informationsabruf zu stützen und erst dann in Spezialisten aufzuteilen, wenn der Systemprompt zu lang wird oder die Aufgaben zu vielfältig sind, um von einem einzigen Modell zuverlässig bewältigt zu werden. Jede Schicht baut auf der darunterliegenden auf.
Der Zeitpunkt für Microservices bei Agenten
Das Mehr-Agenten-Design macht KI nicht komplizierter. Es macht komplexe Arbeitsabläufe vorhersehbar – genauso wie Microservices den Monolithen ersetzt haben: Ein Prompt wird zu einer verteilten Ansammlung von Komponenten, von denen jede eine bestimmte Aufgabe erledigt. Von einem einzelnen Agenten zu verlangen, gleichzeitig zu sortieren, zu recherchieren, zu handeln und zu prüfen, ist wie von einer Person zu verlangen, gleichzeitig Empfangsdame, leitende Analystin, Technikerin und Prüferin zu sein. Das funktioniert in einem Ein-Mann-Unternehmen, scheitert aber in einem großen Unternehmen.
Geben Sie jedem Agenten eine fokussierte Aufgabe, spezialisierte Tools sowie eine gemeinsame Speicherschicht – das Ergebnis ist präzise, denn fokussierte Anweisungen verursachen weniger Abweichungen bei unzusammenhängenden Aufgaben; es lässt sich debuggen, da der fehlerhafte Spezialist sichtbar ist; und es ist kostengünstig, denn ein Einsatz von fünf Agenten auf Gemini 3.1 kostet etwa einen halben Cent pro komplexer Interaktion, was weit unter einer Minute der Arbeitszeit eines menschlichen Agenten liegt.
Das Design bietet außerdem Raum für weitere Entwicklungen. Mit dem Agent-to-Agent (A2A)-Protokoll, einem offenen Standard unter der Verwaltung der Linux Foundation, könnte ein solches System letztendlich mit von Anbietern oder Partnern betriebenen Agenten verhandeln – beispielsweise könnte ein Support-Agent direkt mit dem Agenten eines Versanddienstleisters kommunizieren, um ein verlorenes Paket ohne menschliche Beteiligung zu lösen.
Für den Moment lautet der Rat einfach: Bauen Sie zunächst einen Agenten und zerlegen Sie das System, wenn die Anweisungen zu lang oder die Aufgaben zu vielfältig werden.