Hallo zusammen, Leo hier von agntdev.com! Heute möchte ich über etwas sprechen, das meine Herangehensweise an die Erstellung von Agenten heimlich verändert hat: den Aufstieg spezialisierter SDKs. Nicht irgendeine SDKs, sondern solche, die dafür entwickelt wurden, die Orchestrierung komplexer Agentenverhalten weniger schmerzhaft und flüssiger zu gestalten.
Für lange Zeit schien mein Arbeitsablauf in der Agentenentwicklung mich ständig dazu zu zwingen, das Rad neu zu erfinden. Ich hatte eine brillante Idee für einen Agenten, der mit mehreren APIs kommunizieren, Entscheidungen treffen und vielleicht sogar aus seinen Interaktionen lernen sollte. Und dann verbrachte ich Tage, manchmal Wochen, nur damit, das grundlegende Gerüst aufzubauen: Statusverwaltung, Toolaufrufe, Speicher, parallele Ausführung. Es war erschöpfend. Ich hatte das Gefühl, 80 % meiner Zeit mit der Infrastruktur zu verbringen und nur 20 % mit der tatsächlichen Intelligenz, die ich aufbauen wollte.
All das änderte sich vor ungefähr anderthalb Jahren, als die ersten wirklich soliden agentenspezifischen SDKs begannen, an Bedeutung zu gewinnen. Ich spreche nicht nur von Hüllen um LLMs; ich meine Werkzeuge, die grundlegend die Art und Weise verändern, wie Sie intelligente Agenten konzipieren, erstellen und bereitstellen. Und heute möchte ich mich auf einen bestimmten Aspekt davon konzentrieren: wie moderne Agenten-SDKs komplexe Interaktionen zwischen mehreren Agenten und gemeinsamem Zustand vereinfachen und was einst ein Albtraum war, in ein handhabbares Entwurfsmuster verwandeln.
Die Alte Methode: Spaghetti-Code und Verteilte Kopfschmerzen
Gehen wir etwas zurück. Bevor diese SDKs reif wurden, wenn Sie wollten, dass Agenten zusammenarbeiten, mussten Sie auf einige gängige Muster zurückgreifen, von denen keines besonders unterhaltsam war. Sie könnten einen zentralen “Koordinator”-Agenten haben, der als Regulator fungierte und Nachrichten zwischen den anderen vermittelte. Oder Sie hatten ein Pub/Sub-System, das ideal zum Entkoppeln war, aber die Verwaltung des gemeinsamen Zustands oder sequentieller Abhängigkeiten wurde zu einer ganz anderen Angelegenheit.
Ich erinnere mich an ein Projekt, bei dem ich ein Kundenservice-Agentensystem aufbaute. Wir hatten einen Agenten, der eingehende Tickets sortierte, einen anderen, der in der Wissensdatenbank suchte, und einen dritten, der bei Bedarf an einen Menschen eskalierte. Das klingt einfach, oder? Die Realität war, dass der “Sortier”-Agent die Fähigkeiten des “Such”-Agenten kennen musste, und der “Such”-Agent musste wissen, wie er die Ergebnisse an den “Sortier”-Agenten zurückgeben konnte, der dann entschied, den “Eskalations”-Agenten auszulösen. Jeder Agent hatte seine eigene kleine Zustandsmaschine, und sie zu synchronisieren war ein Albtraum. Das Debuggen war wie das Ausfindigmachen einer bestimmten Spaghetti in einer Schüssel voller Spaghetti – jede Änderung in einem Agenten schien uns unerwartet auf die anderen auszuwirken.
Gemeinsame Speicherung? Vergessen Sie das. Wir übermittelten JSON-Blobs und hofften, dass alle auf der gleichen Wellenlänge bezüglich des Schemas waren. Das Versionieren war ein ständiger Kampf. Es funktionierte letztendlich, aber es war fragil. Und das ist das Schlüsselwort: fragil. In dem Moment, in dem Sie einen vierten Agenten hinzufügen oder den Ablauf ändern wollten, standen Sie vor einer erheblichen Neugestaltung.
Die Neue Methode: Orchestrierung als erstklassiges Bürger
Moderne Agenten-SDKs verändern dieses Paradigma grundlegend, indem sie die Orchestrierung und den gemeinsamen Kontext als zentrale Funktionen behandeln und nicht als nebensächliche Überlegungen. Sie bieten Abstraktionen, die es Ihnen ermöglichen, die Rollen der Agenten, ihre Fähigkeiten (Werkzeuge) und vor allem, wie sie in einem gemeinsamen Umfeld oder einem “Ausführungsstrang” interagieren, zu definieren. Es geht nicht nur darum, Nachrichten zu übermitteln; es geht darum, einen gemeinsamen Arbeitsbereich, ein gemeinsames Verständnis der Aufgabe und strukturierte Mittel für die Agenten zu definieren, um zu einem gemeinsamen Ziel beizutragen.
Für mich kam der größte “Aha!”-Moment, als ich begann, SDKs zu verwenden, die ein Konzept von “Graphen” oder “Workflows” für Agenten anboten. Anstatt einfach Nachrichten zu senden, konnten die Agenten in einem vordefinierten Fluss arbeiten, und das SDK verwaltete die Zustandsübergänge, Toolaufrufe und sogar die Fehlerbehandlung untereinander. Es fühlte sich an, als würde man von Assembly-Sprache auf ein hochrangiges Framework wechseln.
Beispiel 1: Kollaborative Suche mit gemeinsamem Kontext
Lassen Sie uns ein praktisches Beispiel betrachten. Stellen Sie sich vor, Sie möchten einen Recherche-Assistenten erstellen. Nicht nur einen Agenten, der sucht, sondern einen, der eine komplexe Anfrage analysieren, Teile delegieren, die Ergebnisse synthetisieren und dann eine Zusammenfassung erstellen kann. So könnten Sie das mit einem modernen SDK angehen (ich werde eine konzeptionelle Python-ähnliche Syntax verwenden, die spezifischen SDKs variieren, aber die Prinzipien sind allgemein anwendbar):
from agent_sdk import Agent, Workflow, Tool, SharedState
# Einige Werkzeuge definieren
def search_web(query: str):
# Eine Suche im Web simulieren
return f"Suchergebnisse für '{query}': ..."
def summarize_text(text: str):
# Eine Zusammenfassung simulieren
return f"Zusammenfassung von : {text[:50]}..."
# Werkzeuge registrieren
search_tool = Tool("web_search", search_web, "Sucht Informationen im Internet.")
summarize_tool = Tool("text_summarizer", summarize_text, "Fasst den gegebenen Text zusammen.")
# Agenten definieren
research_planner = Agent(
name="Planer",
description="Zerlegt komplexe Suchanfragen in Teilaufgaben.",
tools=[] # Der Planer verwendet keine Werkzeuge direkt, er delegiert
)
information_gatherer = Agent(
name="Sammelagent",
description="Führt Websuchen basierend auf Teilaufgaben durch.",
tools=[search_tool]
)
synthesizer = Agent(
name="Synthesizer",
description="Synthetisiert die gesammelten Informationen in kohärente Punkte.",
tools=[summarize_tool]
)
# Den Workflow definieren
research_workflow = Workflow(
name="Komplexe Recherche-Aufgabe",
initial_state={"query": "", "sub_tasks": [], "raw_data": [], "synthesized_data": "", "final_report": ""},
agents=[research_planner, information_gatherer, synthesizer]
)
@research_workflow.step(agent=research_planner)
def plan_research(state: SharedState):
# LLM-Aufruf oder regelbasierte Logik zur Zerlegung der Anfrage
state["sub_tasks"] = ["suche X", "suche Y", "suche Z"]
print(f"Planer: Die Anfrage '{state['query']}' wurde in {state['sub_tasks']} zerlegt.")
return "gather_information" # Übergang zum nächsten Schritt
@research_workflow.step(agent=information_gatherer, loop_over="sub_tasks")
def gather_information(state: SharedState, sub_task: str):
result = state.call_tool("web_search", query=sub_task)
state["raw_data"].append({"task": sub_task, "result": result})
print(f"Sammelagent: '{sub_task}' erledigt, {len(result)} Zeichen erhalten.")
return "synthesize_results" # Nach Abschluss aller Teilaufgaben zum nächsten Schritt übergehen
@research_workflow.step(agent=synthesizer)
def synthesize_results(state: SharedState):
all_raw_text = "\n".join([d["result"] for d in state["raw_data"]])
summary = state.call_tool("text_summarizer", text=all_raw_text)
state["synthesized_data"] = summary
print(f"Synthesizer: Eine Zusammenfassung von {len(state['raw_data'])} Elementen erstellt.")
return "draft_report" # Letzter Schritt
@research_workflow.step(name="draft_report")
def draft_report(state: SharedState):
# LLM-Aufruf für den endgültigen Bericht basierend auf synthesized_data
state["final_report"] = f"Endbericht zu '{state['query']}':\n{state['synthesized_data']}"
print(f"Endbericht:\n{state['final_report']}")
return "finished"
# Ausführung des Workflows
initial_query = "Die Auswirkungen der Quanteninformatik auf die Kryptographie im nächsten Jahrzehnt."
result_state = research_workflow.run(query=initial_query)
print(f"\nWorkflow abgeschlossen. Endbericht erstellt: {result_state['final_report'] != ''}")
Was passiert hier? Der `Workflow` verwaltet den `SharedState`. Die Agenten kommunizieren nicht direkt miteinander; sie lesen und schreiben in diesen gemeinsamen Zustand. Der Dekorator `research_workflow.step` gibt an, welcher Agent zu welchem Zeitpunkt aktiv ist und welche Übergänge stattfinden. Das SDK kümmert sich darum, das Objekt `SharedState` zu übermitteln und die Konsistenz sicherzustellen. Wenn `gather_information` bei einer Teilaufgabe fehlschlägt, kann das SDK so konfiguriert werden, dass es erneut versucht oder alarmiert, ohne die gesamte Kette zu brechen.
Das ist eine massive Verbesserung im Vergleich zur manuellen Nachrichtenübermittlung. Die Struktur ist explizit. Der Zustand ist zentralisiert, aber zugänglich. Und vor allem liefert das SDK den Rahmen für diese Koordination, wodurch der Standardcode reduziert wird.
Gemeinsamer Speicher und Dynamische Zustandsverwaltung
Über die expliziten Workflow-Grafen hinaus bieten viele SDKs ausgeklügelte Shared-Memory-Modelle. Es geht nicht nur um ein Wörterbuch von Werten; es handelt sich um Kontexte, die von jedem Agenten, der an einer Sitzung beteiligt ist, zugegriffen und aktualisiert werden können. Dieser gemeinsame Kontext kann Folgendes umfassen:
- Konversationsverlauf: Die vollständige Transkription der Interaktionen, entscheidend für LLM-gestützte Agenten.
- Ergebnisse von Toolaufrufen: Die Ausgaben früherer Toolausführungen, die die folgenden Agenten benötigen könnten.
- Benutzerpräferenzen/-profil: Persistente Informationen über den Endbenutzer.
- Domänenspezifisches Wissen: Relevante Fakten oder Regeln für die aktuelle Aufgabe.
Die Schönheit dieser Modelle des gemeinsamen Gedächtnisses liegt oft in ihrer Fähigkeit, automatisch zu serialisieren und zu deserialisieren, über Sitzungen hinweg persistent zu sein und manchmal sogar gleichzeitig anstehenden Aktualisierungen problemlos zu begegnen. Hier erweist sich das SDK als unverzichtbar – es verwaltet die Komplexität des verteilten Zustands, ohne dass Sie jedes Lock und Mutex selbst schreiben müssen.
Beispiel 2: Dynamische Kettenbildung von Tools mit gemeinsamem Kontext
Betrachten Sie einen Agenten, der bei der Reiseplanung hilft. Dies könnte einen Agenten „Flugbuchung“ und einen Agenten „Hotelbuchung“ beinhalten. Beide arbeiten auf einem in dem Speicher geteilten Objekt `TripPlan`.
from agent_sdk import Agent, Session, Tool, SharedContext
# Vereinfachte Definitionen der Tools
def find_flights(origin: str, destination: str, date: str):
return {"flight_id": "FL123", "price": 350, "departure_time": "10:00"}
def find_hotels(city: str, check_in: str, check_out: str):
return {"hotel_id": "H456", "name": "Grand Hotel", "price_per_night": 120}
flight_tool = Tool("find_flights", find_flights, "Findet Flüge zwischen Städten.")
hotel_tool = Tool("find_hotels", find_hotels, "Findet Hotels in einer Stadt.")
# Agenten
flight_agent = Agent(name="FlightAgent", description="Verwaltet die Flugbuchungen.", tools=[flight_tool])
hotel_agent = Agent(name="HotelAgent", description="Verwaltet die Hotelbuchungen.", tools=[hotel_tool])
coordinator_agent = Agent(name="Coordinator", description="Orchestiert die Reiseplanung.", tools=[]) # LLM könnte hier sein
# Gemeinsamer Kontext für die Sitzung
class TripPlan(SharedContext):
origin: str = ""
destination: str = ""
travel_date: str = ""
check_in_date: str = ""
check_out_date: str = ""
booked_flight: dict = {}
booked_hotel: dict = {}
status: str = "planung"
# Eine Sitzung zur Verwaltung der Interaktion
trip_session = Session(
agents=[flight_agent, hotel_agent, coordinator_agent],
context_model=TripPlan
)
# Simulieren Sie eine Benutzerinteraktion und Agentenantworten
# In einem realen Szenario würde der Koordinatoragent (LLM) dies steuern
# basierend auf der Benutzereingabe und seinem eigenen Denken.
# Initiale Benutzeranfrage
trip_session.context.origin = "NYC"
trip_session.context.destination = "LAX"
trip_session.context.travel_date = "2026-06-15"
trip_session.context.check_in_date = "2026-06-15"
trip_session.context.check_out_date = "2026-06-18"
print(f"Anfänglicher Plan: {trip_session.context.dict()}")
# Der Koordinator entscheidet, den Flugagenten aufzurufen
# In einer realen Konfiguration wäre dies ein Toolaufruf des LLM
print("\nKoordinator: Fragt FlightAgent, ob er Flüge findet...")
flight_result = flight_agent.call_tool(
"find_flights",
origin=trip_session.context.origin,
destination=trip_session.context.destination,
date=trip_session.context.travel_date
)
trip_session.context.booked_flight = flight_result
print(f"FlightAgent hat gefunden: {trip_session.context.booked_flight}")
# Der Koordinator entscheidet, den Hotelagenten aufzurufen, unter Verwendung des aktualisierten Kontexts
print("\nKoordinator: Fragt HotelAgent, ob er Hotels findet...")
hotel_result = hotel_agent.call_tool(
"find_hotels",
city=trip_session.context.destination, # Verwendet die Zielstadt aus dem Kontext
check_in=trip_session.context.check_in_date,
check_out=trip_session.context.check_out_date
)
trip_session.context.booked_hotel = hotel_result
trip_session.context.status = "gebucht"
print(f"HotelAgent hat gefunden: {trip_session.context.booked_hotel}")
print(f"\nEndstatus des Reiseplans: {trip_session.context.status}")
print(f"Vollständiger Kontext: {trip_session.context.dict()}")
Hier fungiert das Objekt `TripPlan` als die einzige Wahrheitquelle für die Sitzung. Die Agenten können darauf lesen und schreiben. Die `Session` orchestriert, welcher Agent aktiviert wird, möglicherweise basierend auf der LLM-Ausgabe des `Coordinator`-Agenten. Wenn `flight_agent` `booked_flight` aktualisiert, kann `hotel_agent` diese Änderung sofort sehen und seine Handlungen anpassen. Dies ist leistungsstark, um reaktive und kontextbewusste Multi-Agenten-Systeme aufzubauen.
Praktische Tipps für Ihr nächstes Agentenprojekt
- Bewerten Sie SDKs nach ihren Orchestrierungsfähigkeiten: Suchen Sie nicht nur nach LLM-Wrappers. Priorisieren Sie SDKs, die ausdrücklich Multi-Agenten-Workflows, gemeinsamen Zustand und strukturierte Kommunikationsmodelle unterstützen. Achten Sie auf Funktionen wie `Workflow`-Graphen, `SharedContext`-Modelle und eine gute Integration von Tools.
- Gestalten Sie zuerst Ihren gemeinsamen Zustand: Überlegen Sie bereits, bevor Sie die Logik des Agenten schreiben, welche Informationen *alle* betroffenen Agenten haben oder ändern müssen. Definieren Sie ein klares Schema für Ihren gemeinsamen Kontext. Dies wird Ihre Agentenkonstruktionen leiten und Inkonsistenzen bei den Daten vermeiden.
- Adoptieren Sie ein „Koordinator“- oder „Router“-Agentenmodell: Selbst mit fortschrittlichen SDKs kann es hilfreich sein, einen bestimmten Agenten (der oft von einem LLM unterstützt wird) zu haben, um zu entscheiden, *welcher* andere Agent als nächstes handeln oder *welches* Tool aufgerufen werden soll. Dies kann Ihr Design vereinfachen. Das SDK verwaltet die Mechanismen; Ihr Koordinator verwaltet die Intelligenz.
- Umarmen Sie ein toolzentriertes Denken: Die Agenten interagieren hauptsächlich mit der Welt (und miteinander) über Tools. Definieren Sie Ihre Tools klar und stellen Sie sicher, dass sie auf Daten arbeiten oder Daten produzieren, die gut in Ihren gemeinsamen Kontext integriert werden.
- Fangen Sie einfach an, iterieren Sie: Versuchen Sie nicht, sofort ein monolithisches Multi-Agenten-System aufzubauen. Beginnen Sie mit zwei Agenten, die an einer einfachen Aufgabe mit gemeinsamem Zustand arbeiten, und führen Sie schrittweise mehr Komplexität und Agenten ein.
Die Tage, an denen man manuell Nachrichtenwarteschlangen und maßgeschneiderte Zustandsmaschinen für jede Multi-Agenten-Interaktion koppeln musste, sind glücklicherweise vorbei. Moderne Agenten-SDKs bieten die erforderlichen Abstraktionen, um ausgeklügelte und kollaborative Systeme zu bauen, die nicht nur funktionsfähig, sondern auch wartbar und skalierbar sind. Wenn Sie noch mit fragilen und chaotischen Agentenarchitekturen kämpfen, ist es an der Zeit, ernsthaft zu überlegen, was diese neuen SDKs zu bieten haben. Sie haben mein Leben definitiv viel einfacher gemacht, und ich denke, sie können auch Ihres erleichtern.
Das wäre alles! Lassen Sie mich in den Kommentaren wissen, welche SDKs Sie für die Multi-Agenten-Orchestrierung verwenden und welche Herausforderungen Sie noch haben. Viel Spaß beim Entwickeln!
🕒 Published: