Spezialisierte Agenten und einen Router erstellen
Auf dieser Seite
Von der Theorie zur Praxis
Die vorherige Lektion hat das Konzept der Übergabe (Handoffs) eingeführt. Nun bauen Sie das vollständige System in der tatsächlichen Reihenfolge der Konstruktion: zuerst die Spezialisten, dann den Router, anschließend die Verbindung zwischen ihnen und schließlich die Konversation, die alles in Gang setzt. Diese Reihenfolge ist nicht willkürlich: Der Router kann nur auf Agenten verweisen, die bereits existieren.
Schritt 1: Erstellen der Spezialisten-Agenten
Jeder Agent erhält einen präzisen Bereich der Expertise und nichts anderes.
from mistralai.client import Mistral
from mistralai.client.models import CompletionArgs, ResponseFormat, JSONSchema
import os
client = Mistral(api_key=os.environ["MISTRAL_API_KEY"])
# Web-Such-Agent
web_agent = client.beta.agents.create(
model="mistral-large-latest",
name="web-search-agent",
description="Agent, der online nach Informationen sucht.",
instructions="Führen Sie präzise Websuchen durch. Zitieren Sie Ihre Quellen stets.",
tools=[{"type": "web_search"}]
)
# Finanz-Agent
finance_agent = client.beta.agents.create(
model="mistral-large-latest",
name="finance-agent",
description="Agent, der sich auf finanzielle Fragen spezialisiert hat.",
instructions="""Sie sind ein Finanzexperte.
- Nutzen Sie numerische Daten
- Erklären Sie Konzepte klar
- Markieren Sie Risiken"""
)
# Rechen-Agent
calculator_agent = client.beta.agents.create(
model="mistral-large-latest",
name="calculator-agent",
description="Agent für detaillierte mathematische Berechnungen.",
instructions="Erklären Sie jeden Schritt der Berechnung. Nutzen Sie den Code-Interpreter für komplexe Berechnungen.",
tools=[{"type": "code_interpreter"}]
)
Diese vier Felder spielen sehr unterschiedliche Rollen, und eines verdient besondere Aufmerksamkeit. Der name in Kebab-Case ist für Sie: Er erscheint in Ihren Protokollen und Tests, und ein lesbarer Name spart Ihnen das Vergleichen undurchsichtiger IDs. Die instructions richten sich an das Modell, sobald es zu arbeiten beginnt, sodass sie domänenspezifisch sein müssen: „Risiken markieren” bedeutet etwas für einen Finanzagenten, während „hilfreich sein” für niemanden etwas bedeutet. Die tools folgen dem Prinzip der strengen Notwendigkeit: Der obige Finanzagent verfügt über keine Tools, da er ohne diese zu arbeiten vermag; die Gewährung von Tools würde lediglich Missbrauch einladen. Schließlich ist die description keine Dokumentation: Es ist der Text, den der Router liest, um zu entscheiden, ob er hierhin oder anderswo überweisen soll.
Schritt 2: Erstellen des Router-Agenten
Der Router verfügt über keine Tools. Seine gesamte Aufgabe besteht darin, die Anfrage zu analysieren und den Empfänger auszuwählen.
router_agent = client.beta.agents.create(
model="mistral-large-latest",
name="router-agent",
description="Router-Agent, der Anfragen verteilt.",
instructions="""Sie sind ein Orchesterleiter.
Analysieren Sie jede Anfrage und überweisen Sie an den richtigen Agenten:
- Fragen, die Online-Daten erfordern → web-search-agent
- Finanzielle Fragen → finance-agent
- Berechnungen und numerische Analysen → calculator-agent
Antworten Sie niemals direkt – überweisen Sie stets."""
)
Diese letzte Zeile verhindert, dass das System zusammenbricht. Ohne sie würde ein Router, der auf einem großen Modell basiert, Fragen beantworten, die ihm einfach erscheinen, Ihre Spezialisten umgehen und Antworten produzieren, ohne die Tools zu nutzen, die diese verwendet hätten. Sie landen mit einer Multi-Agent-Architektur, in der die Hälfte der Agenten niemals genutzt wird.
Schritt 3: Übergabe-Ziele definieren
Nun müssen Sie dem Router mitteilen, an welche Agenten er überweisen darf.
router_agent = client.beta.agents.update(
agent_id=router_agent.id,
handoffs=[web_agent.id, finance_agent.id, calculator_agent.id]
)
Der Parameter handoffs nimmt eine Liste von Agenten-IDs entgegen, und der Router kann an einen beliebigen davon überweisen. Dies ist kein Privileg, das nur dem Router vorbehalten ist: Spezialisten können auch ihre eigenen Ziele deklarieren.
# Der Finanz-Agent kann an die Websuche und den Rechen-Agenten überweisen
finance_agent = client.beta.agents.update(
agent_id=finance_agent.id,
handoffs=[web_agent.id, calculator_agent.id]
)
Eine Kette wie Router → Finanz → Websuche → Rechen wird dann möglich. Wenn der Finanz-Agent einer Frage gegenübersteht, die einen aktuellen Zinssatz erfordert, überweist er nicht zurück an den Router: Er geht direkt zum Spezialisten, den er benötigt, genau wie ein Berater, der einen Kollegen anruft, statt durch die Rezeption zu gehen.
Schritt 4: Konversation starten
response = client.beta.conversations.start(
agent_id=router_agent.id,
inputs="Finden Sie den aktuellen EZB-Zins und berechnen Sie die Zinseszinsen über 10 Jahre für 100.000 €."
)
# Den Fluss analysieren
for entry in response.outputs:
if entry.type == "agent.handoff":
print(f"[ÜBERWEISUNG] → {entry.next_agent_id}")
elif entry.type == "tool.execution":
print(f"[TOOL] {entry.tool_name}")
elif entry.type == "message.output":
print(f"[ANTWORT] {entry.content[:200]}...")
Führen Sie diese Anfrage aus und beobachten Sie die Spur, bevor Sie die Antwort betrachten. Sie sollten zwei Übergaben und mindestens eine Tool-Ausführung sehen; wenn Sie keine sehen, hat Ihr Router eigenständig geantwortet, und es ist Zeit, seine Anweisungen zu verschärfen.
Der Haupthebel: die Beschreibung
Wenn das Routing fehlschlägt, ist die Beschreibung fast immer schuld. Der Router kennt Ihre Absichten nicht; er liest nur diesen Text für jeden Kandidaten-Agenten.
# Schlecht — zu vage
description="Ein nützlicher Agent."
# Gut — der Router weiß, wann er überweisen soll
description="Agent, der aktuelle Informationen im Internet sucht und seine Quellen zitiert."
Schreiben Sie jede Beschreibung als Antwort auf die Frage „In welchem Fall sollte ich diesen Agenten anrufen?” und nicht als Zusammenfassung dessen, was er ist. Das zweite Beispiel benennt die Situation – aktuelle Informationen, im Internet – während das erste den Router raten lässt. Überprüfen Sie auch, dass sich keine Beschreibungspaar überschneiden: Zwei Agenten, die in ähnlichen Begriffen beschrieben werden, führen zu einem instabilen Routing von einer Ausführung zur nächsten.
Vollständiges Beispiel
Hier ist die zusammengefasste Version, bei der handoffs direkt während der Router-Erstellung übergeben werden, da die Spezialisten zu diesem Zeitpunkt bereits existieren.
from mistralai.client import Mistral
import os
client = Mistral(api_key=os.environ["MISTRAL_API_KEY"])
# 1. Spezialisten-Agenten
research = client.beta.agents.create(
model="mistral-large-latest",
name="research-agent",
description="Online-Informationsuche mit Quellen.",
tools=[{"type": "web_search"}]
)
analyst = client.beta.agents.create(
model="mistral-large-latest",
name="analyst-agent",
description="Datenanalyse und Berechnungen mit Python.",
tools=[{"type": "code_interpreter"}]
)
writer = client.beta.agents.create(
model="mistral-large-latest",
name="writer-agent",
description="Entwurf strukturierter und professioneller Berichte.",
instructions="Schreiben Sie klare Berichte mit einer Einleitung, einer Analyse und Empfehlungen."
)
# 2. Router mit Übergaben
router = client.beta.agents.create(
model="mistral-large-latest",
name="router",
description="Orchestriert komplexe Anfragen.",
instructions="Analysieren Sie die Anfrage und überweisen Sie an den entsprechenden Spezialisten.",
handoffs=[research.id, analyst.id, writer.id]
)
# 3. Starten
response = client.beta.conversations.start(
agent_id=router.id,
inputs="Analysieren Sie den europäischen Cloud-Computing-Markt im Jahr 2026: Größe, Akteure, Trends."
)
Wichtige Erkenntnisse
- Erstellen Sie Spezialisten-Agenten mit präzisen, aufgabenorientierten Beschreibungen
- Der Router verwendet Beschreibungen, um den Ziel-Agenten auszuwählen
client.beta.agents.update(handoffs=[...])definiert Übergabe-Ziele- Übergaben können verschachtelt sein (Agent A → Agent B → Agent C)
- Die Beschreibung jedes Agenten ist der primäre Hebel für die Routing-Qualität