Hey zusammen, hier ist Nina von agntbox.com! Ich hoffe, ihr habt alle eine produktive Woche. Heute möchte ich mich mit etwas beschäftigen, das in meinem Workflow in letzter Zeit viel diskutiert wurde: KI-Agenten. Genauer gesagt möchte ich darüber sprechen, wie wir diese Agenten nicht nur intelligent, sondern wirklich nützlich gestalten können, sodass sie über eine einzige, isolierte Aufgabe hinausgehen. Wir werden ein Framework erkunden, um mehrstufige, zustandsbehaftete KI-Agenten zu bauen.
Ich weiß, ich weiß. „Framework“ kann etwas trocken klingen, aber bleibt bei mir. Es geht nicht um ein komplexes Enterprise-System. Es geht um einen praktischen Ansatz, den ich verfeinert habe, um meine Agenten dazu zu bringen, mehr zu tun, als nur eine Anfrage zu beantworten oder ein Dokument zusammenzufassen. Ich möchte, dass sie sich erinnern, worüber wir gesprochen haben, Aufgaben nachverfolgen und sogar ihr Verhalten basierend auf laufenden Interaktionen anpassen. Denkt dabei weniger an eine starre Struktur und mehr an ein mentales Modell, um bessere KI-Begleiter zu entwerfen.
Das Problem, mit dem ich bei einfacheren Agenten-Setups immer wieder konfrontiert wurde, war der Kontextverlust. Ich würde einen Agenten bitten, X zu tun, und er würde X tun. Dann habe ich ihn gebeten, Y zu tun, was von X abhängt, und oft tat er so, als hätten wir nie über X gesprochen. Es war, als würde man mit jemandem sprechen, der Gedächtnisverlust hat. Frustrierend, oder?
Die Herausforderung: Über Einmal-Interaktionen hinaus
Meine ersten Versuche beim Bau von KI-Agenten folgten oft einem einfachen Muster: Benutzereingabe -> LLM-Aufruf -> Agentenausgabe. Das funktioniert großartig für einfache Aufgaben, wie das Erstellen eines schnellen E-Mail-Entwurfs oder das Finden eines bestimmten Informationsstücks. Aber was, wenn die Aufgabe mehrere Schritte erfordert, bei denen das Ergebnis jedes Schrittes den nächsten beeinflusst? Was, wenn der Agent Vorlieben, frühere Aktionen oder laufende Gespräche erinnern muss?
Angenommen, ich möchte, dass ein Agent mir hilft, den Inhaltskalender meines Blogs zu verwalten. Ein einfacher Agent könnte eine Idee für einen Blogbeitrag generieren. Aber ich möchte, dass er:
- Themen basierend auf aktuellen Trends vorschlägt (die er recherchieren muss).
- Eine Gliederung für ein gewähltes Thema entwirft.
- Meinen Entwurf anhand spezifischer Richtlinien (z. B. SEO, Tonfall) bewertet.
- Verbesserungsvorschläge macht und dann verfolgt, ob ich sie umgesetzt habe.
- Mich an bevorstehende Fristen erinnert.
Das ist keine einmalige Interaktion. Das ist ein Gespräch, eine Zusammenarbeit. Und hier begann die Idee für einen strukturierten Ansatz zu kristallisieren.
Einführung des „Task-State-Tool“ Frameworks
Nach vielen Versuchen und Irrtümern bin ich zu einem konzeptionellen Rahmen gekommen, den ich „Task-State-Tool“ nenne. Es ist keine Bibliothek oder eine spezifische Software (obwohl man es sicherlich mit bestehenden Werkzeugen bauen kann). Es ist eine Denkweise für das Design von Agenten, die sie fähiger und beständiger macht.
1. Aufgaben: Definition des Zwecks des Agenten
Jeder Agent benötigt einen klaren Zweck. Anstatt nur eines Eingabeaufforderung denke ich daran als „Aufgabenbeschreibung“. Diese definiert, was der Agent über eine potenziell lange Interaktion hinweg erreichen soll. Es ist der Nordstern des Agenten.
Für meinen Inhaltskalender-Agenten könnte eine hochrangige Aufgabe lauten: „Hilf Nina, den Prozess der Inhaltserstellung ihres Blogs zu verwalten, von der Ideenfindung bis zur Veröffentlichung, um Qualität und zeitgerechte Lieferung sicherzustellen.“
Unter dieser Hauptaufgabe gibt es Unteraufgaben. Dies sind kleinere, diskrete Aktionen, die der Agent ausführen kann. Zum Beispiel:
GenerateTopicIdeasOutlineBlogPostReviewDraftTrackProgressSendReminder
Jede Unteraufgabe benötigt ihr eigenes klares Ziel und erwartete Ergebnisse.
2. Zustand: Das Gedächtnis und der Kontext des Agenten
Hier geschieht die Magie der Beständigkeit. Der „Zustand“ ist im Wesentlichen das Arbeitsgedächtnis des Agenten. Es handelt sich um einen strukturierten Datenspeicher, der alle Informationen enthält, an die sich der Agent über Interaktionen hinweg erinnern muss. Das ist nicht nur der rohe Chatverlauf; es ist geordnete, relevante Information, die für die laufende Aufgabe wichtig ist.
Denkt daran wie an ein Wörterbuch oder ein JSON-Objekt, das nach jeder wichtigen Aktion aktualisiert wird. Für unseren Inhaltsagenten könnte der Zustand Folgendes umfassen:
current_blog_post_id: Die ID des Beitrags, an dem gerade gearbeitet wird.topic_suggestions: Eine Liste zuvor vorgeschlagener Themen.selected_topic: Das Thema, das Nina ausgewählt hat.outline_generated: Boolean, wahr, wenn eine Gliederung existiert.draft_status: „ausstehend“, „überprüft“, „Überarbeitungen erforderlich.“deadlines: Ein Wörterbuch der Post-IDs zu ihren Fälligkeitsterminen.user_preferences: Ninas bevorzugter Tonfall, Länge, SEO-Keywords.
Den Zustand zu aktualisieren, bedeutet nicht nur, neue Nachrichten anzuhängen. Es geht oft darum, dass das LLM das Gespräch analysiert und wichtige Entitäten, Entscheidungen oder Statusänderungen extrahiert. Dieser strukturierte Zustand ermöglicht es dem Agenten, genau dort weiterzumachen, wo er aufgehört hat, selbst wenn ich meinen Browser schließe und später zurückkomme.
Hier ist ein vereinfachtes Python-Beispiel, wie ein Zustandsobjekt aussehen und aktualisiert werden könnte:
class AgentState:
def __init__(self):
self.data = {
"current_blog_post_id": None,
"topic_suggestions": [],
"selected_topic": None,
"outline_generated": False,
"draft_status": "not_started", # "not_started", "pending", "reviewed", "revisions_needed", "published"
"deadlines": {}, # {post_id: date_str}
"user_preferences": {
"tone": "conversational",
"length": "1000-1500 words",
"keywords": ["AI tools", "tech blogging"]
}
}
def update(self, key, value):
if key in self.data:
self.data[key] = value
print(f"Zustand aktualisiert: {key} = {value}")
else:
print(f"Warnung: Versuch, nicht vorhandenen Zustandskey zu aktualisieren: {key}")
def get(self, key):
return self.data.get(key)
# Beispielverwendung:
my_state = AgentState()
print(my_state.get("draft_status")) # Ausgabe: not_started
# Stell dir vor, das LLM analysiert "Ich möchte an einem Beitrag über LLM-Frameworks arbeiten" und identifiziert einen neuen Beitrag.
my_state.update("current_blog_post_id", "post_123")
my_state.update("selected_topic", "LLM Frameworks")
my_state.update("draft_status", "pending")
print(my_state.get("selected_topic")) # Ausgabe: LLM Frameworks
3. Werkzeuge: Die Fähigkeiten des Agenten
Werkzeuge sind die Hände und Füße des Agenten. Dabei handelt es sich um diskrete Funktionen oder APIs, die der Agent aufrufen kann, um Aktionen in der realen Welt (oder seiner simulierten Welt) auszuführen. Das LLM fungiert als das Gehirn, das entscheidet, welches Werkzeug wann verwendet wird, basierend auf den aktuellen Benutzereingaben und dem internen Zustand des Agenten.
Für unseren Inhaltsagenten könnten Werkzeuge Folgendes umfassen:
SearchInternet(query): Um aktuelle Trends oder spezifische Fakten zu recherchieren.GenerateOutline(topic, preferences): Nimmt ein Thema und Benutzerpräferenzen und gibt eine Gliederung zurück.CritiqueText(text, guidelines): Nimmt einen Entwurf und Richtlinien und gibt Feedback zurück.SaveDocument(content, post_id): Speichert generierte Inhalte in einer Datenbank oder Datei.SetReminder(post_id, date): Integriert sich mit einer Kalender-API.FetchPostContent(post_id): Ruft vorherige Inhalte ab.
Der entscheidende Punkt hier ist, dass das LLM ausdrücklich über diese Werkzeuge informiert werden muss, einschließlich ihrer Namen, Beschreibungen und erwarteten Parameter. Dies geschieht oft über Funktionsaufrufmechanismen, die in modernen LLMs verfügbar sind (wie OpenAIs Funktionsaufruf oder Googles Gemini-Toolaufruf).
Hier ist ein vereinfachtes Python-Beispiel, wie ein Werkzeug für ein LLM definiert werden könnte:
def get_current_weather(location: str):
"""Get the current weather in a given location.
Args:
location: The city and state, e.g. San Francisco, CA
"""
# In einer realen Situation würde dies eine Wetter-API aufrufen
if "london" in location.lower():
return {"temperature": "10 Celsius", "forecast": "cloudy"}
elif "new york" in location.lower():
return {"temperature": "50 Fahrenheit", "forecast": "sunny"}
else:
return {"temperature": "unknown", "forecast": "unavailable"}
tools = [
{
"type": "function",
"function": {
"name": "get_current_weather",
"description": "Get the current weather in a given location",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "Die Stadt und der Staat, z. B. San Francisco, CA",
}
},
"required": ["location"],
},
},
}
]
# Wenn ein LLM entscheidet, dieses Werkzeug zu verwenden, würde es etwas zurückgeben wie:
# {"name": "get_current_weather", "arguments": {"location": "London, UK"}}
# Ihr Code führt dann get_current_weather("London, UK") aus
Wie es alles zusammenpasst: Die Schleife des Agenten
Wie funktionieren also diese drei Elemente zusammen? Es ist eine kontinuierliche Schleife:
- Benutzereingabe: Nina sendet eine Nachricht an den Agenten.
- Kontextaufbau: Der Agent nimmt die Benutzereingabe, den aktuellen
AgentStateund dieTask Definition. Er kombiniert diese, um eine umfassende Eingabeaufforderung für das LLM zu erstellen. - LLM-Entscheidung: Das LLM verarbeitet die Eingabeaufforderung. Basierend auf der Aufgabe, dem Zustand und den verfügbaren Werkzeugen entscheidet es:
- Was es Nina zurück sagen soll.
- Welche(n) Werkzeug(e) es aufrufen soll (wenn überhaupt) und mit welchen Argumenten.
- Wie der
AgentStateaktualisiert werden soll.
- Toolausführung (Optional): Wenn das LLM beschließt, ein Tool aufzurufen, führt der Agent es aus. Das Ergebnis der Ausführung des Tools wird dann in die Schleife zurückgeführt.
- State-Update: Der
AgentStatewird basierend auf der Entscheidung des LLM und/oder dem Output des Tools aktualisiert. - Agentenausgabe: Der Agent antwortet Nina und bittet möglicherweise um Klarstellung oder bestätigt eine Aktion.
- Wiederholen: Die Schleife geht mit Ninas nächster Eingabe weiter.
Diese Schleife ermöglicht es dem Agenten, den Kontext zu wahren, mehrstufige Operationen durchzuführen und sogar sich selbst zu korrigieren, wenn eine Aktion nicht wie geplant verläuft. Es ist ein viel effektiverer Weg, um wirklich hilfreiche AI-Assistenten zu entwickeln.
Ein praktisches Beispiel: „Umrisse für meinen nächsten Beitrag“
Lassen Sie uns ein einfaches Szenario mit meinem Blog-Inhaltsagenten durchlaufen:
Nina: „Hey, ich brauche eine Gliederung für meinen nächsten Beitrag zum Task-State-Tool-Framework. Halte es bei etwa 1500 Wörtern, mit einem gesprächigen Ton, und stelle sicher, dass praktische Beispiele enthalten sind.“
- Benutzereingabe: „Gliederung für den Beitrag zum Task-State-Tool-Framework…“
- Kontextaufbau: Der Agent sieht den aktuellen
AgentState(dieser kann leer sein oder vorherige Interaktionen enthalten). Er kombiniert dies mit der Anfrage des Benutzers und seiner Hauptaufgabe des Inhaltsmanagements. - LLM-Entscheidung: Das LLM, das den Satz „Umrisse für meinen nächsten Beitrag“ sieht und das
OutlineBlogPost-Tool kennt, beschließt, es aufzurufen. Es extrahiert „Task-State-Tool-Framework“ als Thema, „1500 Wörter“ als Länge, „gesprächig“ als Ton und notiert „praktische Beispiele.“ Außerdem identifiziert es dies als neuen Beitrag und schlägt ein Update fürcurrent_blog_post_idundselected_topicim State vor. - Toolausführung: Der Agent ruft
GenerateOutline(topic="Task-State-Tool framework", length="1500 words", tone="conversational", keywords=["practical examples"])auf. - State-Update: Der Agent aktualisiert seinen Status:
current_blog_post_id: „post_124“ (eine neu generierte ID)selected_topic: „Task-State-Tool framework“outline_generated: Truedraft_status: „pending_outline_review“
Die vom Tool zurückgegebene Gliederung wird ebenfalls gespeichert, möglicherweise in einem separaten Inhaltspeicher, der über
post_124verknüpft ist. - Agentenausgabe: „Okay, Nina. Ich habe eine Gliederung für deinen Beitrag zum ‚Task-State-Tool-Framework‘ erstellt, ziele auf etwa 1500 Wörter und einen gesprächigen Ton mit praktischen Beispielen ab. Ich habe sie als ‚post_124‘ gespeichert. Möchtest du, dass ich sie hier anzeige oder vielleicht einige Unterabschnitte vorschlage?“
Jetzt, wenn ich mit „Zeig mir die Gliederung“ antworte, muss der Agent das Thema oder meine Präferenzen nicht neu verstehen. Er ruft einfach die gespeicherte Gliederung ab, die mit post_124 in seinem Status verknüpft ist und zeigt sie an. Das ist die Stärke von zustandsbehafteten Agenten.
Umsetzbare Erkenntnisse für Ihre eigenen Agenten
Wenn Sie leistungsfähigere und beständigere AI-Agenten entwickeln möchten, empfehle ich basierend auf meinen Erfahrungen mit dem Task-State-Tool-Framework Folgendes:
- Beginnen Sie mit einer klaren Aufgabenbeschreibung: Definieren Sie, bevor Sie irgendwelchen Code schreiben, klar, was Ihr Agent im Laufe seines gesamten Lebenszyklus erreichen soll. Zerlegen Sie es in Unteraufgaben.
- Gestalten Sie Ihr Statusschema früh: Denken Sie an all die Informationen, die Ihr Agent sich merken muss. Was sind die wesentlichen Entitäten, Status und Benutzerpräferenzen? Strukturieren Sie dies als Wörterbuch oder einfache Klasse.
- Identifizieren Sie notwendige Tools: Welche externen Aktionen muss Ihr Agent ausführen? Ordnen Sie diese spezifischen Funktionen oder API-Aufrufen zu. Stellen Sie sicher, dass Ihr LLM versteht, wie man sie aufruft (Beschreibungen und Parameter sind entscheidend).
- Umarmen Sie die Schleife: Verstehen Sie, dass die Interaktion mit dem Agenten keinen einmaligen Aufruf darstellt. Es ist ein kontinuierlicher Prozess von Eingabe, Entscheidung, Aktion und Statusaktualisierung.
- Iterieren und Verfeinern von Status-Updates: Dies ist oft der schwierigste Teil. Wie extrahiert Ihr LLM zuverlässig Informationen aus Benutzereingaben, um den Status zu aktualisieren? Möglicherweise benötigen Sie einen separaten, kleineren LLM-Aufruf nur für die Statusanalyse oder sorgfältige Prompt-Optimierung.
- Nicht über-engineeren: Beginnen Sie einfach. Sie benötigen nicht sofort eine komplexe Datenbank für Ihren Status. Eine JSON-Datei oder ein in-memory Wörterbuch kann für Prototypen funktionieren. Skalieren Sie, wenn die Komplexität Ihres Agenten steigt.
Agenten mit dieser Art von persistentem Gedächtnis und Fähigkeiten zu entwickeln, bringt uns über einfache Chatbots hinaus zu wirklich intelligenten Assistenten. Es ist eine Reise, und es wird Herausforderungen geben, aber die Ergebnisse sind unglaublich lohnend. Probieren Sie es aus und lassen Sie mich wissen, was Sie bauen!
Bis zum nächsten Mal, bleiben Sie experimentierfreudig!
🕒 Published: