\n\n\n\n Im Troubleshooting meiner Agentic Workflows: So geht's - AgntDev \n

Im Troubleshooting meiner Agentic Workflows: So geht’s

📖 12 min read2,259 wordsUpdated Mar 27, 2026

Hallo zusammen, hier ist Leo von agntdev.com. Ich hoffe, ihr habt alle eine produktive Woche!

Heute möchte ich etwas erforschen, das mich in letzter Zeit sehr beschäftigt, besonders da ich an ein paar persönlichen Projekten arbeite, die komplexere, mehrstufige agentische Workflows beinhalten. Wir sprechen oft über den Aufbau von Agenten, über die LLMs selbst und über die coolen Dinge, die sie tun können. Aber was ist mit dem weniger glamourösen, aber absolut entscheidenden Aspekt, sicherzustellen, dass unsere Agenten tatsächlich zuverlässig und effizient über die Zeit funktionieren?

Konkret spreche ich über Agenten-Beobachtbarkeit. Es geht nicht nur um Protokollierung; es geht darum, wirklich zu verstehen, was dein Agent tut, warum er es tut, und Probleme zu erkennen, bevor sie sich zu größeren Schwierigkeiten entwickeln. In einer Welt, in der Agenten mit externen APIs interagieren, Entscheidungen basierend auf dynamischen Eingaben treffen und möglicherweise über längere Zeiträume laufen, blind zu fliegen, ist eine Rezeptur für Katastrophen. Ich habe das auf die harte Tour gelernt, wie ich gleich erklären werde.

Der „Mystery Bug“, der mir alles beigebracht hat

Vor einigen Monaten entwickelte ich einen persönlichen Assistenten-Agenten. Nennen wir ihn „Projekt Chronos“. Sein Job war es, meinen Kalender, Nachrichten-Feeds und spezifische Slack-Kanäle zu überwachen, dann proaktiv Meetings vorzuschlagen, wichtige Updates zusammenzufassen oder sogar erste Antworten auf häufige Anfragen zu entwerfen. Auf den ersten Blick eigentlich Standardzeug.

Ich baute ihn, testete ihn mit ein paar Szenarien, und es schien gut zu funktionieren. Ich richtete ihn so ein, dass er über Nacht läuft, in der Annahme, ich würde morgens eine perfekt kuratierte Zusammenfassung finden. Stattdessen wachte ich auf und fand… nichts. Oder vielmehr eine teilweise Zusammenfassung, die abrupt endete, gefolgt von einer kryptischen Fehlermeldung in meinen Systemprotokollen, die im Wesentlichen sagte „irgendetwas ist kaputt gegangen.“

Das Debuggen war ein Albtraum. Chronos sollte mehrere Dinge tun: Kalenderereignisse abrufen, eine Nachrichten-API abfragen, eine Slack-API ansteuern, die Daten verarbeiten und dann eine Zusammenfassung erzeugen. Welcher Schritt ist fehlgeschlagen? Warum? Hat er überhaupt alle Schritte versucht? War es eine API-Drosselung? Ein fehlerhafter Prompt? Ein Timeout? Ich hatte keine Ahnung.

Meine anfängliche Protokollierung war grundlegend: „Schritt X gestartet“, „Schritt Y abgeschlossen“ und dann die Endausgabe oder ein Fehler. Das war nicht genug. Es war wie der Versuch, ein Auto-Problem zu diagnostizieren, wenn man nur wusste, dass es gestartet ist und dann angehalten hat, ohne Informationen über die Motortemperatur, den Kraftstoffdruck oder elektrische Fehler.

Diese Erfahrung hat mir klar gemacht: Wenn du es ernst meinst mit der Entwicklung von Agenten, brauchst du ab Tag eins eine solide Beobachtbarkeit. Es ist kein Nachgedanke; es ist ein grundlegendes Element.

Über die grundlegende Protokollierung hinaus: Was bedeutet „Beobachtbarkeit“ für Agenten?

Für mich gliedert sich die Beobachtbarkeit von Agenten in ein paar Schlüsselbereiche, die jeweils einen anderen Blick auf die Funktionsweise deines Agenten ermöglichen:

1. Schritt-für-Schritt-Ausführungsverfolgung

Dies ist das Wichtigste. Du musst genau wissen, was dein Agent in jeder Phase seiner Ausführung tut. Denk daran als einen detaillierten Breadcrumb-Pfad. Für Projekt Chronos musste ich sehen:

  • Wann er angefangen hat, Kalenderereignisse abzurufen.
  • Die Parameter, die er für den API-Aufruf des Kalenders verwendet hat (z.B. Datumsbereich).
  • Die rohe Antwort von der Kalender-API.
  • Wie er diese Antwort verarbeitet hat.
  • Den genauen Prompt, den er an das LLM zur Zusammenfassung von Kalenderinformationen gesendet hat.
  • Die Antwort des LLM.
  • Alle Tools, die er aufgerufen hat, mit ihren Eingaben und Ausgaben.
  • Fehlermeldungen, nicht nur „irgendetwas ist fehlgeschlagen“, sondern einen spezifischen Fehler mit Kontext (z.B. „Kalender-API hat 401 Unauthorized für Benutzer X zurückgegeben“).

Dieses Detailniveau ist unbezahlbar, um Probleme zu reproduzieren und Entscheidungspunkte zu verstehen. Meine ersten Protokolle sagten nur „Kalenderdaten abrufen…“ und dann „Kalenderdaten zusammenfassen…“ ohne dazwischen. Nicht hilfreich, wenn das Datenabrufen selbst lautlos fehlgeschlagen ist.

2. Prompt- und Antwortverfolgung

Das LLM ist das Gehirn deines Agenten. Wenn du nicht weißt, welche Prompts es erhält und welche Antworten es gibt, fliegst du blind. Das umfasst:

  • Den vollständigen Prompt, der an das LLM gesendet wurde (System, Benutzer und alle Funktionsaufrufbeschreibungen).
  • Die Temperatur, top_p und andere Generierungsparameter.
  • Die rohe Antwort des LLM, einschließlich aller Toolaufrufe, die es entschieden hat, zu tätigen.
  • Token-Nutzung (Eingabe, Ausgabe, insgesamt) zur Kostenverfolgung und Leistungsanalyse.

Das ist entscheidend für das Prompt Engineering. Wenn ein Agent unsinnige Antworten gibt, hilft es, den genauen Prompt zu sehen, den er erhalten hat, um zu debuggen, ob der Eingabekontext falsch war oder ob der Prompt selbst schlecht strukturiert war.

3. Toolaufrufüberwachung

Agenten interagieren oft mit externen Tools oder APIs. Jede Interaktion ist ein potenzieller Fehler- oder unerwarteter Verhaltenspunkt. Du musst protokollieren:

  • Welches Tool aufgerufen wurde.
  • Die genauen Argumente, die an das Tool übergeben wurden.
  • Die rohe Ausgabe des Tools.
  • Alle Fehler, die vom Tool zurückgegeben wurden oder während seiner Ausführung aufgetreten sind.

Für Chronos, wenn er versuchte, die Slack-API aufzurufen, um eine Zusammenfassung zu posten, musste ich den Kanal wissen, den er anvisierte, den Inhalt der Nachricht und ob die API beispielsweise einen 403 Forbidden-Fehler zurückgab. Mein vorheriges Setup sagte mir nur „Versuch, in Slack zu posten.“

4. Status-Schnappschüsse

Viele Agenten behalten einen internen Zustand – einen Notizblock, ein Gedächtnis, eine Liste von Fakten, die sie gesammelt haben. Die periodische Erfassung dieses Zustands kann unglaublich nützlich für das Debuggen sein. Wenn ein Agent in einer Schleife feststeckt oder eine falsche Entscheidung trifft, kann es aufschlussreich sein, seine internen „Gedanken“ zu verschiedenen Zeitpunkten zu sehen, um zu erkennen, wo sein Verständnis aus dem Ruder gelaufen ist.

Es geht weniger darum, jede einzelne Variablenänderung zu protokollieren, sondern vielmehr darum, wichtige Entscheidungszustände zu erfassen. Für Chronos könnte das „Aktuelles Verständnis des Zeitplans des Benutzers“ oder „Wichtige Erkenntnisse aus den Nachrichten-Feeds bis jetzt“ sein.

Praktische Ansätze: Beobachtbarkeit einbauen

Okay, wie setzen wir das tatsächlich um, ohne in Protokollen zu ertrinken? Hier sind ein paar praktische Strategien und Code-Snippets.

Strategie 1: Strukturierte Protokollierung mit Kontext

Vergiss `print()`-Anweisungen. Benutze eine ordentliche Protokollierungsbibliothek (wie Pythons `logging`-Modul). Wichtig ist, dass du deine Protokollnachrichten mit strukturierten Daten (JSON, Dictionaries) anreichest, anstatt nur mit einfachen Strings. Das macht Protokolle durchsuchbar, auswertbar und wesentlich nützlicher.

Hier ist ein vereinfachtes Beispiel in Python:


import logging
import json
import uuid
from datetime import datetime

# Grundlegende Logger-Konfiguration (in einer echten Anwendung würdest du das robuster konfigurieren)
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)
handler = logging.StreamHandler()
formatter = logging.Formatter('%(levelname)s: %(message)s')
handler.setFormatter(formatter)
logger.addHandler(handler)

def log_agent_step(agent_id: str, step_name: str, status: str, details: dict = None):
 log_data = {
 "timestamp": datetime.now().isoformat(),
 "agent_id": agent_id,
 "step_name": step_name,
 "status": status, # z.B. "started", "completed", "failed"
 "details": details if details is not None else {}
 }
 logger.info(json.dumps(log_data))

class MyAgent:
 def __init__(self, agent_id: str = None):
 self.agent_id = agent_id if agent_id else str(uuid.uuid4())
 self.memory = [] # Einfache interne Erinnerung

 def _fetch_calendar_events(self, user_id: str, date_range: str):
 log_agent_step(self.agent_id, "fetch_calendar_events", "started", 
 {"user_id": user_id, "date_range": date_range})
 try:
 # Simuliere API-Aufruf
 if "error" in date_range:
 raise ValueError("Simulierter Kalender API-Fehler")
 
 events = [
 {"title": "Team Sync", "time": "10:00 AM"},
 {"title": "Client Meeting", "time": "02:00 PM"}
 ]
 log_agent_step(self.agent_id, "fetch_calendar_events", "completed", 
 {"num_events": len(events), "data_preview": events[0]})
 self.memory.append(f"Kalenderereignisse: {events}")
 return events
 except Exception as e:
 log_agent_step(self.agent_id, "fetch_calendar_events", "failed", 
 {"error": str(e), "traceback": "..."}) # Im echten Leben, Traceback erfassen
 raise

 def _summarize_with_llm(self, prompt_text: str):
 log_agent_step(self.agent_id, "summarize_with_llm", "started", 
 {"prompt_length": len(prompt_text), "prompt_preview": prompt_text[:100]})
 try:
 # Simuliere LLM-Aufruf
 if "fail_llm" in prompt_text:
 raise RuntimeError("Simulierter LLM API-Fehler")
 
 response = f"LLM Zusammenfassung von: {prompt_text[:50]}..."
 token_usage = {"input": len(prompt_text) // 4, "output": len(response) // 4}
 log_agent_step(self.agent_id, "summarize_with_llm", "completed", 
 {"response_length": len(response), "token_usage": token_usage, 
 "llm_response_preview": response[:100]})
 self.memory.append(f"LLM erzeugte Zusammenfassung: {response}")
 return response
 except Exception as e:
 log_agent_step(self.agent_id, "summarize_with_llm", "failed", 
 {"error": str(e), "traceback": "..."})
 raise

 def run_daily_briefing(self, user_id: str):
 log_agent_step(self.agent_id, "run_daily_briefing", "started", {"user_id": user_id})
 try:
 calendar_data = self._fetch_calendar_events(user_id, "today")
 news_summary = self._summarize_with_llm("Fasse die wichtigsten Nachrichten von heute zusammen...")
 
 final_briefing_prompt = (
 f"Erstelle ein tägliches Briefing basierend auf:\n"
 f"Kalender: {json.dumps(calendar_data)}\n"
 f"Nachrichten: {news_summary}"
 )
 final_briefing = self._summarize_with_llm(final_briefing_prompt)
 
 log_agent_step(self.agent_id, "run_daily_briefing", "completed", 
 {"final_briefing_length": len(final_briefing)})
 return final_briefing
 except Exception as e:
 log_agent_step(self.agent_id, "run_daily_briefing", "failed", 
 {"error": str(e), "current_memory": self.memory}) # Erfassung des Gedächtnisses bei Fehler
 raise

# Beispielverwendung
if __name__ == "__main__":
 agent = MyAgent()
 print(f"\n--- Führe Agent {agent.agent_id} (Erfolgsfall) aus ---")
 try:
 briefing = agent.run_daily_briefing("leo_g")
 print(f"Briefing: {briefing[:100]}...")
 except Exception as e:
 print(f"Agentenlauf fehlgeschlagen: {e}")

 agent_fail = MyAgent()
 print(f"\n--- Führe Agent {agent_fail.agent_id} (Kalenderfehlerfall) aus ---")
 try:
 # Simuliere Kalenderfehler, indem "error" im date_range übergeben wird
 agent_fail._fetch_calendar_events("leo_g", "error_today") 
 except Exception as e:
 print(f"Agentenlauf fehlgeschlagen wie erwartet: {e}")

 agent_llm_fail = MyAgent()
 print(f"\n--- Führe Agent {agent_llm_fail.agent_id} (LLM-Fehlerfall) aus ---")
 try:
 # Simuliere LLM-Fehler
 agent_llm_fail._summarize_with_llm("fail_llm_please")
 except Exception as e:
 print(f"Agentenlauf fehlgeschlagen wie erwartet: {e}")

Beachte, wie `log_agent_step` die Agenten-ID, den Schrittname, den Status und ein Wörterbuch relevanter Details erfasst. Das macht es einfach, Protokolle nach Agenten-ID zu filtern, einen einzelnen Lauf nachzuverfolgen oder nach allen „fehlgeschlagenen“ Schritten zu suchen.

Strategie 2: Zentrale Beobachtbarkeit mit einer speziellen Bibliothek/Dienst

Für komplexere Agenten oder Produktionsumgebungen wirst du schnell über einfaches Datei-Logging hinauswachsen. Hier glänzen spezialisierte Werkzeuge. Bibliotheken wie LangChain’s `LangSmith` (oder Ähnliches für andere Frameworks) bieten integrierte Nachverfolgung, Visualisierung und Debugging für LLM-Anwendungen.

Selbst wenn du LangChain nicht verwendest, ist das Konzept übertragbar. Du kannst deinen eigenen Wrapper um die Ausführung deines Agenten bauen, der strukturierte Ereignisse an einen Logging-Dienst (Datadog, Splunk, ELK-Stack oder sogar ein einfaches S3-Bucket mit Lambda-Verarbeitung) sendet. Der Schlüssel ist, das Ereignisschema zu standardisieren.

Mein verbessertes Projekt Chronos verwendet jetzt eine benutzerdefinierte `TraceManager`-Klasse, die kritische Operationen umschließt. Dieser Manager sendet strukturierte Ereignisse an eine lokale Datenbank für die Entwicklung und an einen Cloud-Logging-Dienst in der Produktion. So kann ich eine vollständige „Nachverfolgung“ jedes Agentenlaufs sehen, mit verschachtelten Schritten und allen damit verbundenen Daten (Eingabeaufforderungen, Antworten, Tool-Eingaben/-ausgaben, Fehler).

Strategie 3: Abfangen von LLM- und Tool-Anrufen

Viele LLM-SDKs erlauben es, Rückruf- oder Abfangmethoden für API-Aufrufe einzurichten. Nutze diese! Anstatt manuell vor und nach jeder LLM-Aufforderung zu protokollieren, kannst du einen einzigen Abfangpunkt haben, der automatisch protokolliert:

  • Die genaue angesprochene API-Endpunkt.
  • Request-Header und -Inhalt (insbesondere die Aufforderung).
  • Response-Header und -Inhalt (die Vollständigkeit).
  • Latency.
  • Alle Ausnahmen.

Ebenso kannst du deine Tool-Aufrufe umschließen. Wenn du ein `search_web`-Tool hast, sollte der Wrapper die Suchanfrage, die verwendete Suchmaschine und die obersten N Ergebnisse protokollieren, die zurückgegeben werden, zusammen mit eventuellen Fehlern.

Handlungsfähige Erkenntnisse für dein nächstes Agentenprojekt

  1. Das Design zuerst für Beobachtbarkeit gestalten: Behandle es nicht als Nachgedanke. Denk darüber nach, was du zum Debuggen benötigen würdest, bevor du deinen ersten Agentenschritt schreibst.
  2. Strukturiertes Logging annehmen: Verzichte auf `print()` und `console.log()` für Produktionscode. Verwende eine ordentliche Logging-Bibliothek und gebe strukturierte Daten (JSON) für jedes bedeutende Ereignis aus.
  3. Alles Wichtige nachverfolgen: Protokolliere den Beginn und das Ende jedes wichtigen Schrittes, alle LLM-Aufforderungen und -Antworten (einschließlich Parameter und Token-Anzahlen) und jeden Tool-Aufruf mit seinen Eingaben und Ausgaben.
  4. Zustand bei Fehlern erfassen: Wenn ein Agent fehlschlägt, protokolliere seinen internen Zustand oder Speicher zu diesem Zeitpunkt. Dies bietet wichtigen Kontext, um zu verstehen, warum es fehlgeschlagen ist.
  5. Agentenspezifische IDs verwenden: Weisen jedem Agentenlauf eine eindeutige ID zu (z.B. eine UUID). Dies ermöglicht es dir, einen einzelnen Ausführungspfad durch deine Protokolle einfach zu filtern und nachzuverfolgen.
  6. Deine Nachverfolgungen visualisieren: Wenn möglich, verwende oder baue ein Werkzeug, das diese strukturierten Protokolle als Ereignisfolge visualisieren kann. Den Fluss zu sehen, macht das Debuggen unendlich einfacher, als durch Rohtexte zu sichten. LangSmith macht das wunderbar, aber selbst ein benutzerdefiniertes Skript kann eine einfache HTML-Zeitachse rendern.
  7. Kosten überwachen: Die Verwendung von LLM-Token ist ein direkter Kostenfaktor. Protokolliere es. Dies hilft dir zu verstehen, wohin dein Geld fließt und deine Aufforderungen zu optimieren.

Agenten zu entwickeln ist spannend, aber zuverlässige Agenten zu entwickeln, darin liegt die echte Arbeit (und der echte Wert). Und Zuverlässigkeit beginnt mit dem Wissen, was im Hintergrund vor sich geht. Meine schmerzhafte Erfahrung mit Projekt Chronos hat mir diese Lektion gut beigebracht. Warte nicht auf deinen eigenen „mysteriösen Fehler“, um dich zu überzeugen. Beginne noch heute intelligent zu protokollieren.

Was sind deine bevorzugten Beobachtbarkeitsstrategien für Agenten? Schreib mir in den Kommentaren oder in den sozialen Medien. Ich bin immer daran interessiert zu hören, wie andere diese Herausforderungen angehen!

🕒 Published:

✍️
Written by Jake Chen

AI technology writer and researcher.

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