\n\n\n\n Ich bin der Falle des neuen, brillanten Agentenrahmens entkommen. - AgntDev \n

Ich bin der Falle des neuen, brillanten Agentenrahmens entkommen.

📖 13 min read2,422 wordsUpdated Mar 29, 2026

Okay, Freunde, Leo Grant hier, zurück mit einer weiteren tiefen Erkundung der wilden Welt der Agentenentwicklung. Heute möchte ich über etwas sprechen, das mich beschäftigt, etwas, das ich in Forum nach Forum auftauchen sah, und ehrlich gesagt, etwas, womit ich selbst vor nicht allzu langer Zeit noch zu kämpfen hatte: Die Falle des „Neuen Glänzenden Agentenrahmens“. Wir waren alle schon einmal dort, oder?

Es ist 2026, und es scheint, als würde jede Woche ein neuer SDK oder Agentenrahmen erscheinen. Jeder von ihnen verspricht, schneller, intelligenter, skalierbarer oder einfach einfacher zu sein, um autonome Agenten zu erstellen. Und als jemand, der in diesem Bereich lebt und atmet, ist meine erste Reaktion immer eine Mischung aus Aufregung und FOMO. „Ist das der? Ist das das Tool, das endlich mein Herzensprojekt ohne wochenlange Boilerplate-Codierung Realität werden lässt?“

Ich erinnere mich, dass ich im Oktober an einem persönlichen Finanzassistenten-Agenten arbeitete. Die Idee war einfach: ein Agent, der meine Ausgaben überwacht, Abonnementdienste identifiziert, die ich möglicherweise nicht nutze, und sogar in meinem Namen bessere Tarife aushandelt. Ich hatte ein einfaches Python-Skript am Laufen, das einen benutzerdefinierten Nachrichtenbus und viele `if/else` verwendete. Es war unbeholfen, das steht fest, aber es funktionierte.

Dann sah ich die Ankündigung für „Aether“, einen neuen Agentenrahmen, der auf Rust basierte und eine unglaubliche Konkurrenz sowie eine deklarative Agentendefinitionssprache versprach. Mein Reptiliengehirn schrie sofort: „Schreib es neu! Rust ist die Zukunft! Mein Python-Kram ist eine Schande!“ Also verbrachte ich zwei gute Wochen damit, mein ganzes Projekt auf Aether zu portieren. Und was soll ich sagen? Obwohl Aether in der Tat leistungsfähig und elegant ist, endete ich mit einem Projekt, das funktional identisch mit meiner Python-Version war, aber jetzt musste ich ein ganz neues Ökosystem von Buildwerkzeugen, Abhängigkeitsmanagement und aetherspezifischem Fehlerhandling lernen.

Es war eine wertvolle Lektion, die ich heute mit euch teilen möchte. Das größte Hindernis in der Agentenentwicklung ist nicht immer, den „besten“ Rahmen zu finden; es ist zu verstehen, wann man einen Rahmen verwenden sollte und noch wichtiger, wann es besser ist, bei dem zu bleiben, was man weiß, und auf Basisgrundsätzen aufzubauen. Heute werden wir darüber sprechen, diese „Build“-Mentalität zu übernehmen, insbesondere in Bezug auf die Kommunikation und das grundlegende Zustandsmanagement Ihrer Agenten, anstatt blind den neuesten SDK zu übernehmen.

Das Hauptproblem: Überengineering der Kommunikation

Die meisten Agentenrahmen versuchen im Kern, zwei Hauptprobleme zu lösen:

  1. Inter-Agenten-Kommunikation: Wie kommunizieren die Agenten miteinander? Nachrichtenwarteschlangen, RPC, geteilter Zustand?
  2. Agenten-Zustandsmanagement: Wie verfolgt ein Agent, was er weiß, was er getan hat und was er als Nächstes tun soll?

Und das sind zweifellos kritische Probleme. Aber oft bieten Rahmen eine so umfassende und meinungsstarke Lösung an, dass sie für einfachere Projekte übertrieben wird oder unnötige Komplexität einführt. Mein Finanzagent musste zum Beispiel nur mit einem anderen „Agenten“ (einer fiktiven Bank-API) und seinem eigenen internen Zustand kommunizieren. Ein vollständiger Nachrichtenbus mit komplexem Routing war wie der Einsatz eines Raketenwerfers, um eine Fliege zu treffen.

Also, was wäre, wenn wir es vereinfachen? Was wäre, wenn wir über das absolut Notwendigste nachdenken, was Sie brauchen, um Agenten kommunizieren zu lassen und Erinnerungen zu speichern? Es geht nicht darum, Rahmen für immer abzulehnen, sondern zuerst eine solide Grundlage zu schaffen, die zugrunde liegenden Mechanismen zu verstehen und dann zu entscheiden, ob ein Rahmen wirklich Mehrwert bietet, anstatt nur zusätzliche Lasten aufzubringen.

Einfache Nachrichtenübermittlung: Die Baseline HTTP/JSON

Seien wir brutal ehrlich: Für eine große Anzahl von Anwendungsfällen von Agenten, insbesondere solche, die mit Webdiensten oder anderen externen Systemen interagieren, sind HTTP und JSON Ihre besten Freunde. Sie sind allgegenwärtig, gut verstanden und unglaublich flexibel. Sie brauchen kein benutzerdefiniertes Protokoll oder einen komplexen Nachrichtenbroker, wenn Ihre Agenten hauptsächlich Anfragen senden und Antworten empfangen.

Betrachten wir ein Szenario, in dem Sie einen „Scraper-Agenten“ haben, der Daten von einer Webseite abruft, und einen „Verarbeiter-Agenten“, der diese Daten bereinigt und analysiert. Wie kommunizieren sie?


# scraper_agent.py (vereinfacht)
import requests
import json

def scrape_data(url):
 response = requests.get(url)
 if response.status_code == 200:
 return response.text
 return None

def send_to_processor(data):
 headers = {'Content-Type': 'application/json'}
 payload = {'raw_data': data}
 try:
 response = requests.post('http://localhost:8001/process', headers=headers, data=json.dumps(payload))
 response.raise_for_status() # Wurf einer Ausnahme bei HTTP-Fehlern
 print(f"Daten an den Prozessor gesendet: {response.json()}")
 except requests.exceptions.RequestException as e:
 print(f"Fehler beim Senden der Daten an den Prozessor: {e}")

if __name__ == "__main__":
 url_to_scrape = "https://example.com/some_data" # Durch eine echte URL ersetzen
 raw_content = scrape_data(url_to_scrape)
 if raw_content:
 send_to_processor(raw_content)


# processor_agent.py (vereinfacht unter Verwendung von FastAPI)
from fastapi import FastAPI, Request
from pydantic import BaseModel
import uvicorn

app = FastAPI()

class DataPayload(BaseModel):
 raw_data: str

@app.post("/process")
async def process_data(payload: DataPayload):
 # In einem realen Szenario würden Sie hier eine echte Verarbeitung durchführen
 print(f"Rohe Daten zur Verarbeitung empfangen: {payload.raw_data[:50]}...")
 processed_result = f"Verarbeitet: {payload.raw_data.upper()}" # Beispiel für Verarbeitung
 return {"status": "success", "processed_data": processed_result}

if __name__ == "__main__":
 uvicorn.run(app, host="0.0.0.0", port=8001)

Es ist einfach, ich weiß. Aber es ist auch unglaublich mächtig. Sie haben zwei Agenten, die als separate Dienste fungieren und miteinander kommunizieren. Kein spezieller SDK, kein benutzerdefiniertes Nachrichtenformat. Nur Standards der Webpraktiken. Die Schönheit hierbei ist, dass Sie sie unabhängig skalieren, überall bereitstellen und mit standardmäßigen HTTP-Tools debuggen können. Dieser Ansatz deckt eine überraschend große Menge der Kommunikationsbedürfnisse von Agent zu Agent ab, ohne eine Abhängigkeit von einem Rahmen.

Zustandsmanagement: Die Persistenz annehmen

Der zweite große Punkt ist der Zustand. Ein Agent ist nicht wirklich ein Agent, wenn er alles zwischen Ausführungen vergisst. Viele Rahmen bieten einen In-Memory-Zustand oder komplexe Zustandsmaschinen an. Aber oft brauchen Sie wirklich nur eine einfache und zuverlässige Persistenz.

Für meinen Finanzagenten musste ich Elemente wie folgende speichern:

  • Meine aktuellen Abonnements (Name, Kosten, Erneuerungsdatum)
  • Meine Ausgabenkategorien
  • Historische Verhandlungsversuche

Am Anfang versuchte ich, einige In-Memory-Zustandsmechanismen zu verwenden, die von einem Rahmen angeboten wurden, aber sobald der Agent neu startete (was während des Entwicklungsprozesses passiert, glauben Sie mir), waren all diese wertvollen Daten verschwunden. Frustrierend!

Die Lösung? Eine einfache Datenbank. Für viele persönliche Projekte oder sogar kleinere Produktionssysteme ist SQLite eine ausgezeichnete Wahl. Es basiert auf einer Datei, benötigt keinen separaten Server und Python bietet eine hervorragende integrierte Unterstützung.


# agent_state.py
import sqlite3
import json

class AgentState:
 def __init__(self, db_path='agent_data.db'):
 self.conn = sqlite3.connect(db_path)
 self._create_table()

 def _create_table(self):
 cursor = self.conn.cursor()
 cursor.execute('''
 CREATE TABLE IF NOT EXISTS agent_knowledge (
 key TEXT PRIMARY KEY,
 value TEXT
 )
 ''')
 self.conn.commit()

 def set(self, key, data):
 cursor = self.conn.cursor()
 value = json.dumps(data) # Komplexe Objekte als JSON-Strings speichern
 cursor.execute('INSERT OR REPLACE INTO agent_knowledge (key, value) VALUES (?, ?)', (key, value))
 self.conn.commit()

 def get(self, key):
 cursor = self.conn.cursor()
 cursor.execute('SELECT value FROM agent_knowledge WHERE key = ?', (key,))
 row = cursor.fetchone()
 if row:
 return json.loads(row[0])
 return None

 def close(self):
 self.conn.close()

# Beispielnutzung:
if __name__ == "__main__":
 state = AgentState()

 # Abonnement speichern
 state.set('subscription:netflix', {'name': 'Netflix', 'cost': 15.99, 'renewal': '2026-04-01'})
 state.set('subscription:spotify', {'name': 'Spotify', 'cost': 10.99, 'renewal': '2026-03-25'})

 # Abonnement abrufen
 netflix_sub = state.get('subscription:netflix')
 print(f"Netflix-Abonnement: {netflix_sub}")

 # Abonnement aktualisieren
 if netflix_sub:
 netflix_sub['cost'] = 16.99 # Preiserhöhung!
 state.set('subscription:netflix', netflix_sub)
 
 print(f"Aktualisiertes Netflix-Abonnement: {state.get('subscription:netflix')}")

 # Liste der Ausgabenkategorien speichern
 state.set('spending_categories', ['Einkäufe', 'Unterhaltung', 'Versorgungsleistungen'])
 print(f"Ausgabenkategorien: {state.get('spending_categories')}")

 state.close()

Diese Klasse `AgentState` ist sehr simpel, bietet jedoch einen Speicher für Schlüssel-Wert-Paare, der zwischen den Neustarts des Agents erhalten bleibt. Sie können Wörterbücher, Listen, Strings – alles was in JSON serialisiert werden kann – speichern. Für komplexere Beziehungen würden Sie zusätzliche Tabellen definieren, aber für viele Agents ist ein einfacher Schlüssel-Wert-Speicher alles, was Sie für deren “Gedächtnis” brauchen.

Das Ganze Zusammenbringen: Der “Einfache” Agent

Wenn wir also diese Ideen kombinieren, wie sieht ein “einfacher” Agent aus? Es ist ein Prozess, der:

  1. Kommandos empfangen kann (zum Beispiel über einen HTTP-Endpunkt oder eine einfache Nachrichtenwarteschlange).
  2. Aktionen durchführen kann (zum Beispiel HTTP-Anfragen, lokale Skripte ausführen).
  3. Sich an Dinge erinnern kann (zum Beispiel durch die Verwendung eines persistenten Statusspeichers wie SQLite).
  4. Eine Hauptschleife oder einen Planer hat, um zu entscheiden, was als Nächstes zu tun ist.

Stellen wir uns unseren zuvor erwähnten Scraper-Agent vor, aber jetzt mit ein wenig Gedächtnis. Er sollte sich an die URLs erinnern, die er bereits gescraped hat, und wann, um redundante Arbeiten oder gescheiterte Versuche zu vermeiden.


# smart_scraper_agent.py
import requests
import json
import time
from datetime import datetime, timedelta
from agent_state import AgentState # Angenommen, agent_state.py befindet sich im selben Verzeichnis

# Wir werden FastAPI verwenden, um Kommandos zum Starten des Scrappen zu empfangen
from fastapi import FastAPI, BackgroundTasks
from pydantic import BaseModel
import uvicorn

app = FastAPI()
agent_state = AgentState(db_path='scraper_agent_data.db')

class ScrapeRequest(BaseModel):
 url: str
 target_processor_url: str

def _perform_scrape_and_send(url: str, target_processor_url: str):
 """Interne Funktion zum Scrappen und Senden."""
 last_scraped_info = agent_state.get(f'last_scraped:{url}')
 if last_scraped_info:
 last_scrape_time = datetime.fromisoformat(last_scraped_info['timestamp'])
 # Nur scrappen, wenn mehr als eine Stunde vergangen ist (Beispiel)
 if datetime.now() - last_scrape_time < timedelta(hours=1):
 print(f"Überspringe {url}, zuletzt gescrapet um {last_scrape_time}")
 return

 print(f"Scrappen von {url}...")
 try:
 response = requests.get(url, timeout=10)
 response.raise_for_status()
 raw_content = response.text

 # Senden an den Prozessor
 headers = {'Content-Type': 'application/json'}
 payload = {'raw_data': raw_content}
 processor_response = requests.post(target_processor_url, headers=headers, data=json.dumps(payload))
 processor_response.raise_for_status()
 print(f"Daten von {url} an den Prozessor gesendet: {processor_response.json()}")

 # Status nach erfolgreichem Scrappen aktualisieren
 agent_state.set(f'last_scraped:{url}', {
 'timestamp': datetime.now().isoformat(),
 'status': 'success',
 'processor_response': processor_response.json()
 })

 except requests.exceptions.RequestException as e:
 print(f"Fehler beim Scrappen oder Senden für {url}: {e}")
 # Status bei Fehler aktualisieren
 agent_state.set(f'last_scraped:{url}', {
 'timestamp': datetime.now().isoformat(),
 'status': 'failed',
 'error': str(e)
 })
 finally:
 agent_state.close() # Wichtig, die Verbindung zu schließen, wenn sie nicht global verwaltet wird

@app.post("/scrape")
async def start_scrape(request: ScrapeRequest, background_tasks: BackgroundTasks):
 """Endpunkt zum Auslösen einer Scraping-Aktion."""
 background_tasks.add_task(_perform_scrape_and_send, request.url, request.target_processor_url)
 return {"message": f"Scraping von {request.url} initiiert."}

if __name__ == "__main__":
 # Sie könnten hier auch eine geplante Aufgabe haben, die den Status nach URLs zum Scrappen abfragt
 # Für den Moment werden wir einfach den FastAPI-Server ausführen.
 # Zum Ausführen: uvicorn smart_scraper_agent:app --reload --port 8000
 uvicorn.run(app, host="0.0.0.0", port=8000)

Dieses `smart_scraper_agent.py` kombiniert unsere grundlegende HTTP-Kommunikation mit einem persistenten Status. Es verhindert redundantes Scrappen in einem definierten Zeitfenster und speichert das Ergebnis jedes Scrappens. Es ist immer noch einfach, beginnt jedoch, ein “agentisches” Verhalten zu zeigen – sich erinnern, entscheiden und im Einklang mit seinem internen Zustand und externen Reizen handeln.

Wann man einen Rahmen in Betracht ziehen sollte (und warum)

Ich sage nicht, dass Frameworks schlecht sind. Ganz im Gegenteil. Sie haben ihren Platz. Sie sollten anfangen, sie in Betracht zu ziehen, wenn:

  • Komplexe Koordination: Sie haben Dutzende oder Hunderte von Agents, die komplexe Aufgaben koordinieren, Teams bilden oder dynamisch interagieren müssen. Hier werden ein solider Nachrichtenbus, Service-Discovery und eventuell eine Agenten-Orchestrierungsschicht unbezahlbar.
  • Standardisierte Verhaltensweisen: Ihre Agents müssen gemeinsame Verhaltensweisen wie Planung, Zielsetzung oder fortgeschrittenes Verständnis natürlicher Sprache umsetzen. Frameworks bieten oft Abstraktionen oder Integrationen dafür.
  • Bedarf an Skalierbarkeit: Sie bearbeiten einen sehr hohen Nachrichtenverkehr oder eine große Anzahl an konkurrierenden Agents, und benötigen hochoptimierte Kommunikationsprotokolle oder eine bereitwillige verteilte Statusverwaltung.
  • Gemeinschaft und Ökosystem: Sie möchten eine große Gemeinschaft, bestehende Plugins und bewährte Modelle für spezifische Agentenarchitekturen (z. B. FIPA-konforme Agents) nutzen.

Selbst dann bleiben die Prinzipien einer klaren Kommunikation und einer soliden Statusverwaltung, die wir heute diskutiert haben, grundlegend. Ein gutes Framework stützt sich auf diese Prinzipien, es ersetzt nicht die Notwendigkeit, sie zu verstehen.

Wichtige Punkte

Mein Wunsch für Sie heute ist, dass Sie mit einem neuen Gefühl der Ermächtigung und einem kritischen Blick auf die nächste “revolutionäre” Agenten-SDK-Ankündigung zurückkehren. Hier sind die Punkte, die ich möchte, dass Sie sich merken:

  1. Beginnen Sie einfach: Bevor Sie in ein komplexes Framework eintauchen, definieren Sie die absoluten Kommunikations- und Statusbedürfnisse für Ihren Agenten. Können Sie 80 % davon mit HTTP/JSON und einer einfachen Datenbank wie SQLite lösen? Wahrscheinlich.
  2. Verstehen Sie die Elemente: Auch wenn Sie letztendlich ein Framework verwenden, verbringen Sie etwas Zeit damit, zu verstehen, wie Nachrichtenübergang und Statuspersistenz auf einer grundlegenden Ebene funktionieren. Dieses Wissen wird Sie zu einem besseren Debugger und Architekten machen.
  3. Iterieren, nicht neu schreiben: Entwickeln Sie zuerst die Funktionalität Ihres Agenten. Lassen Sie es funktionieren. Wenn Sie auf eine echte Mauer der Skalierbarkeit oder Komplexität stoßen, die offensichtlich durch ein Framework gelöst werden kann, ziehen Sie dann in Betracht, es zu übernehmen. Vermeiden Sie den Impuls, “alles neu zu schreiben”.
  4. Konzentration auf die Agentenlogik: Der wahre Wert Ihres Agenten liegt in seinen Entscheidungen, vorhandenem Wissen und den einzigartigen Aufgaben, die er ausführt. Lassen Sie sich nicht von infrastrukturellen Bedenken den Fokus auf die Entwicklung dieser Kernlogik rauben.
  5. Wählen Sie die Werkzeuge mit Bedacht: Nur weil ein Framework existiert, bedeutet das nicht, dass es das richtige Werkzeuge für Ihre spezifische Aufgabe ist. Bewerten Sie Kosten gegen Nutzen.

Beim nächsten Mal, wenn Sie ein Agentenprojekt starten, versuchen Sie, die grundlegende Kommunikation und Statusverwaltung selbst zu entwickeln, auch wenn es nur für einen Proof of Concept ist. Sie werden viel lernen, bauen einen resilienteren Agenten und vermeiden wahrscheinlich viele Kopfschmerzen in der Zukunft. Fahren Sie fort zu bauen, experimentieren Sie weiter und scheuen Sie sich nicht, sich mit den Grundlagen die Hände schmutzig zu machen. Leo out.

🕒 Published:

✍️
Written by Jake Chen

AI technology writer and researcher.

Learn more →
Browse Topics: Agent Frameworks | Architecture | Dev Tools | Performance | Tutorials
Scroll to Top