\n\n\n\n Meine Strategie zur Fehlersuche bei meinem KI-Agenten: Licht in die Black Box bringen - AgntAI Meine Strategie zur Fehlersuche bei meinem KI-Agenten: Licht in die Black Box bringen - AgntAI \n

Meine Strategie zur Fehlersuche bei meinem KI-Agenten: Licht in die Black Box bringen

📖 12 min read2,255 wordsUpdated Mar 30, 2026

Alright, Leute, Alex Petrov hier, ich melde mich von agntai.net. Es ist Ende März 2026, und ich habe mit etwas zu kämpfen, das mich schon eine Weile stört: das “Black Box”-Problem bei KI-Agenten. Nicht nur das Modell selbst, sondern der gesamte agentische Loop. Wir bauen diese unglaublichen Systeme, die Entscheidungen treffen, planen und ausführen, aber oft, wenn etwas schiefgeht, herauszufinden *warum* sich anfühlt, als würde man versuchen, ein Gespräch in einem dunklen Raum zu debuggen.

Heute möchte ich über etwas sprechen, das in meiner eigenen Arbeit absolut entscheidend geworden ist: die Beobachtbarkeit in die Architektur von KI-Agenten von Grund auf zu integrieren. Nicht als nachträglicher Gedanke, nicht als aufgesetztes Überwachungstool, sondern als intrinsischen Teil davon, wie wir diese komplexen Systeme gestalten und implementieren. Denn seien wir ehrlich, wenn du nicht sehen kannst, was dein Agent tut, denkt und womit er kämpft, fliegst du blind, und das ist ein Rezept für eine Katastrophe in jeder Produktionsumgebung.

Der unsichtbare Agent: Meine eigenen Debugging-Albträume

Ich erinnere mich an ein spezielles Projekt aus dem letzten Jahr. Wir hatten einen Agenten, der dazu entworfen wurde, eine komplexe Datenpipeline zu verwalten, Anomalien zu identifizieren, Lösungen vorzuschlagen und sogar einige davon nach menschlicher Genehmigung auszuführen. Auf dem Papier war es brillant. In der Praxis war es ein Albtraum zu debuggen. Manchmal hing er in einer Schleife fest oder traf eine scheinbar unlogische Entscheidung, die zu größeren Problemen führte. Unser erster Ansatz war, nur die letzte Aktion und den gelegentlichen internen Zustand zu protokollieren. Das war nicht genug.

Wenn er feststeckte, sahen wir in den Protokollen nur eine sich wiederholende Sequenz von “Status überprüfen,” “Daten abrufen,” “Status überprüfen.” Warum? Wonach suchte er? An welchem Entscheidungspunkt scheiterte er? Wir hatten keine Ahnung. Es war, als würde man versuchen, ein Auto-Problem zu diagnostizieren, indem man nur auf den Kilometerzähler und das ‘Motor prüfen’-Licht schaut. Wir haben Tage, manchmal Wochen, damit verbracht, spezifische Szenarien zu reproduzieren, mehr Print-Anweisungen hinzuzufügen und Tests erneut auszuführen. Es war langsam, schmerzhaft und unglaublich ineffizient.

Diese Erfahrung hat eine einfache Wahrheit deutlich gemacht: Wenn du zuverlässige KI-Agenten aufbauen willst, musst du in ihren Köpfen oder zumindest in ihrem Prozessfluss sehen können. Du musst ihr Denken, ihre internen Zustandsänderungen, ihre Nutzung von Werkzeugen und ihre Entscheidungsfindungen verstehen. Es geht dabei nicht nur um Protokollierung; es geht um strukturierte, kontextuelle und zugängliche Beobachtbarkeit.

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

Wenn ich über Beobachtbarkeit spreche, denke ich an drei Hauptpfeiler: Protokolle, Metriken und Traces. Wir sind alle mit diesen in traditioneller Software vertraut, aber für KI-Agenten nehmen sie eine etwas andere Form an.

Protokolle: Detaillierte Erzählungen agentischer Schritte

Es geht hier nicht nur um `print(“Agent hat X gemacht”)`. Es geht um strukturierte Protokollierung, die Kontext erfasst. Betrachte es als den Agenten, der ein Tagebuch über seinen Denkprozess und seine Aktionen führt. Jeder Protokolleintrag sollte eine Geschichte erzählen:

  • Was war der Input? (z.B. Benutzeraufforderung, Sensordaten, internes Ereignis)
  • Was war der aktuelle Zustand? (z.B. Inhalt des Speichers, aktives Ziel, Ergebnis der vorherigen Aktion)
  • Welcher interne Denk-Schritt ist aufgetreten? (z.B. “Planungsphase initiiert,” “Werkzeugauswahl basierend auf X,” “Kritik am Plan Y”)
  • Was war der genaue Werkzeugaufruf, einschließlich der Argumente?
  • Was war die rohe Ausgabe des Werkzeugs?
  • Wie hat der Agent diese Ausgabe interpretiert?
  • Welche nächste Entscheidung wurde getroffen und warum? (z.B. “beschlossen, den Plan aufgrund eines Fehlers in der Werkzeugausgabe zu verfeinern,” “nächste Aktion A basierend auf Ziel B ausgewählt”)

Ein einfacher Weg, dies umzusetzen, ist die Verwendung einer strukturierten Protokollierungsbibliothek (wie Pythons `logging`-Modul mit JSON-Formatierern oder `structlog`). Jedes Mal, wenn dein Agent eine signifikante interne Zustandsänderung vornimmt, ein Werkzeug aufruft oder eine Entscheidung bewertet, protokolliere es mit relevantem Kontext.


import logging
import json
from datetime import datetime

# Setup des strukturierten Loggers
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)

class JsonFormatter(logging.Formatter):
 def format(self, record):
 log_entry = {
 "timestamp": datetime.fromtimestamp(record.created).isoformat(),
 "level": record.levelname,
 "message": record.getMessage(),
 "agent_id": getattr(record, 'agent_id', 'unknown'),
 "context": getattr(record, 'context', {}),
 "step_type": getattr(record, 'step_type', 'generic'),
 "details": getattr(record, 'details', {})
 }
 return json.dumps(log_entry)

handler = logging.StreamHandler()
handler.setFormatter(JsonFormatter())
logger.addHandler(handler)

class MyAgent:
 def __init__(self, agent_id):
 self.agent_id = agent_id
 self.memory = []
 self.current_goal = None

 def perceive(self, input_data):
 logger.info("Agent hat neue Eingabe wahrgenommen.", 
 extra={"agent_id": self.agent_id, 
 "step_type": "perception",
 "details": {"input": input_data}})
 self.memory.append(f"Wahrgenommen: {input_data}")
 # ... Eingabe verarbeiten ...

 def plan(self):
 # Planung simulieren
 plan_steps = ["status_prüfen", "daten_abholen", "daten_analysieren"]
 self.current_goal = "Daten verarbeiten"
 logger.info("Agent hat neuen Plan erstellt.", 
 extra={"agent_id": self.agent_id, 
 "step_type": "planning",
 "context": {"goal": self.current_goal},
 "details": {"plan": plan_steps}})
 return plan_steps

 def execute_tool(self, tool_name, args):
 logger.info(f"Agent führt Werkzeug aus: {tool_name} mit Argumenten {args}",
 extra={"agent_id": self.agent_id,
 "step_type": "tool_execution",
 "context": {"current_goal": self.current_goal},
 "details": {"tool": tool_name, "arguments": args}})
 # Werkzeugausführung simulieren
 if tool_name == "daten_abholen":
 result = {"status": "success", "data": "some_data"}
 else:
 result = {"status": "error", "message": "Unbekanntes Werkzeug"}

 logger.info(f"Werkzeug {tool_name} hat zurückgegeben: {result}",
 extra={"agent_id": self.agent_id,
 "step_type": "tool_result",
 "context": {"current_goal": self.current_goal},
 "details": {"tool": tool_name, "result": result}})
 return result

 def run(self, input_data):
 self.perceive(input_data)
 plan_steps = self.plan()
 for step in plan_steps:
 if step == "daten_abholen":
 self.execute_tool("daten_abholen", {"source": "api"})
 logger.info("Agent hat aktuellen Durchlauf beendet.",
 extra={"agent_id": self.agent_id,
 "step_type": "cycle_end",
 "details": {"memory_size": len(self.memory)}})

# Beispielverwendung
agent = MyAgent(agent_id="data_processor_001")
agent.run("Neuer Bericht muss verarbeitet werden.")

Metriken: Quantifizierung der Gesundheit und Leistung von Agenten

Protokolle geben uns die Erzählung, aber Metriken geben uns den Puls. Dies sind numerische Werte, die die Leistung des Agenten, die Ressourcennutzung und interne Zustände über die Zeit verfolgen. Denk darüber nach:

  • Latenz der Entscheidungsfindung: Wie lange dauert es, bis der Agent von der Wahrnehmung eines Inputs zur Ausführung einer Aktion übergeht?
  • Häufigkeit der Werkzeugnutzung: Welche Werkzeuge werden am häufigsten aufgerufen? Werden einige nie verwendet?
  • Anzahl der Planungsiterationen: Wie oft verfeinert der Agent seinen Plan, bevor er handelt? Eine hohe Zahl könnte auf Komplexität oder Schwierigkeiten hinweisen.
  • Speicherauslastung: Wie viel Speicher verbraucht der Agent? Wächst es unkontrolliert?
  • Erfolgs-/Misserfolgsraten von Aktionen: Scheitern bestimmte Werkzeuge häufiger?
  • Token-Nutzung: Kritisch für LLM-basierte Agenten – wie viele Tokens werden pro Interaktion oder pro Zielabschluss verbraucht?

Du kannst Bibliotheken wie Prometheus-Clientbibliotheken verwenden oder einfach Zähler in deinem Code erhöhen und sie in eine Zeitreihendatenbank pushen. Der Schlüssel ist, diese Metriken *vor* dem Deployment zu definieren und dabei zu überlegen, welche Informationen hilfreich wären, falls etwas schiefgeht.


from prometheus_client import Counter, Histogram, generate_latest
import time

# Definiere Prometheus-Metriken
AGENT_ACTIONS_TOTAL = Counter('agent_actions_total', 'Gesamtzahl der Aktionen, die vom Agenten durchgeführt wurden', ['agent_id', 'action_type', 'status'])
PLANNING_DURATION_SECONDS = Histogram('planning_duration_seconds', 'Dauer der Planungsphase in Sekunden', ['agent_id'])
TOOL_CALLS_TOTAL = Counter('tool_calls_total', 'Gesamtzahl der Toolaufrufe', ['agent_id', 'tool_name'])
TOOL_CALL_DURATION_SECONDS = Histogram('tool_call_duration_seconds', 'Dauer der Toolaufrufe in Sekunden', ['agent_id', 'tool_name'])

class MyAgentWithMetrics(MyAgent): # Erbe von unserem vorherigen Agenten
 def __init__(self, agent_id):
 super().__init__(agent_id)
 self.agent_id = agent_id

 def plan(self):
 start_time = time.time()
 plan_steps = super().plan() # Rufe die ursprüngliche Planmethode auf
 PLANNING_DURATION_SECONDS.labels(agent_id=self.agent_id).observe(time.time() - start_time)
 AGENT_ACTIONS_TOTAL.labels(agent_id=self.agent_id, action_type="plan", status="success").inc()
 return plan_steps

 def execute_tool(self, tool_name, args):
 TOOL_CALLS_TOTAL.labels(agent_id=self.agent_id, tool_name=tool_name).inc()
 start_time = time.time()
 result = super().execute_tool(tool_name, args) # Rufe die ursprüngliche execute_tool auf
 TOOL_CALL_DURATION_SECONDS.labels(agent_id=self.agent_id, tool_name=tool_name).observe(time.time() - start_time)
 
 status = "success" if result.get("status") == "success" else "failure"
 AGENT_ACTIONS_TOTAL.labels(agent_id=self.agent_id, action_type=f"tool_{tool_name}", status=status).inc()
 return result

# Um Metriken bereitzustellen, würdest du typischerweise einen kleinen HTTP-Server ausführen:
# from http.server import BaseHTTPRequestHandler, HTTPServer
# class MetricsHandler(BaseHTTPRequestHandler):
# def do_GET(self):
# self.send_response(200)
# self.send_header('Content-Type', 'text/plain; version=0.0.4; charset=utf-8')
# self.end_headers()
# self.wfile.write(generate_latest())
#
# if __name__ == '__main__':
# # Beispielverwendung
# agent_metric = MyAgentWithMetrics(agent_id="data_processor_002")
# agent_metric.run("Einen weiteren Bericht verarbeiten.")
# # Du würdest dann http://localhost:8000/metrics abfragen (oder einen anderen Port, auf dem du läuft)
# # print(generate_latest().decode('utf-8')) # Für direkte Ausgabe in die Konsole

Spuren: Den Weg des Agenten verfolgen

Spuren bieten eine End-to-End-Sicht auf eine einzelne Anfrage oder Zielerfüllung und zeigen die Abfolge von Ereignissen und deren Beziehungen über verschiedene Komponenten hinweg. Für einen KI-Agenten könnte eine „Spur“ den gesamten Lebenszyklus der Verarbeitung eines einzelnen Benutzerbefehls darstellen, von der Wahrnehmung bis zur endgültigen Aktion, und alle internen Planungen, Toolaufrufe und Denkprozesse aufzeigen.

Stell dir ein Wasserfalldiagramm vor, in dem jede Balkenoperation eine distincte Operation darstellt: „Benutzerabsicht analysieren“, „Ursprünglichen Plan generieren“, „Tool X aufrufen“, „Toolausgabe bewerten“, „Plan verfeinern“, „Endgültige Aktion ausführen“. Jede dieser „Spannen“ hätte ihre eigene Start-/Endzeit, Dauer und zugehörige Metadaten (wie den verwendeten LLM-Befehl, die Antwort oder die Tool-Argumente).

Hier glänzen Tools wie OpenTelemetry. Du instrumentierst deinen Code, um Spannen für jeden signifikanten agentischen Schritt zu erstellen. Diese Spannen werden dann korreliert, sodass du den gesamten Fluss visualisieren kannst. Wenn dein Agent stecken bleibt oder eine schlechte Entscheidung trifft, kann eine Spur dir genau zeigen, *wo* in der Abfolge das Problem auftrat, wie lange dieser spezielle Schritt dauerte und welche Eingaben/Ausgaben beteiligt waren.

Für Agenten ist das Tracing besonders mächtig, weil es uns ermöglicht, die *denkerische Kette* zu visualisieren. Du kannst den ursprünglichen Befehl, den Denkprozess des LLMs, das Tool, das es entschieden hat aufzurufen, die Ausgabe des Tools und wie das LLM diese Ausgabe dann interpretierte, um seinen nächsten Schritt zu formulieren, sehen. Dies ist von unschätzbarem Wert für das Debugging und das Verständnis von neu auftretenden Verhaltensweisen.

Design für Beobachtbarkeit: Keine nachträgliche Überlegung

Die größte Lektion, die ich gelernt habe, ist, dass Beobachtbarkeit ein zentrales Gestaltungsprinzip sein muss, kein Aspekt, den man in letzter Minute anbringen möchte. Wenn du die Architektur deines Agenten skizzierst, stelle dir folgende Fragen:

  • Was sind die kritischen Entscheidungspunkte? Diese sind ideale Kandidaten für strukturierte Protokolle.
  • Welche Informationen benötige ich, um zu verstehen, warum ein Agent eine bestimmte Aktion durchgeführt hat? Stelle sicher, dass deine Protokolle diese erfassen.
  • Was sind die wichtigsten Leistungskennzahlen für diesen Agenten? Definiere Metriken dafür.
  • Wie fließt ein einzelnes Ziel oder eine Anfrage durch die verschiedenen Komponenten des Agenten? Dies ist deine Tracing-Möglichkeit.
  • Wie werde ich Informationen über verschiedene Agenteninstanzen oder über verschiedene Teile eines verteilten Agentensystems korrelieren? Einzigartige `agent_id` und `request_id`-Felder in Protokollen/Spuren sind hilfreich.

Denk darüber nach, eine „Beobachtbarkeitsschicht“ in dein Agenten-Framework einzubauen. Diese Schicht fängt wichtige Ereignisse (Toolaufrufe, LLM-Interaktionen, Zustandsänderungen) ab und gibt automatisch strukturierte Protokolle, Metriken und Spuren aus, ohne die Kernlogik deines Agenten zu überladen.

Handlungsorientierte Erkenntnisse für dein nächstes Agentenprojekt

  1. Nutze strukturierte Protokollierung: Verabschiede dich von einfachen Druckanweisungen. Verwende eine Protokollbibliothek, die es dir ermöglicht, Schlüssel-Wert-Paare zu deinen Protokolleinträgen hinzuzufügen. Füge immer `agent_id`, `request_id` (falls zutreffend), `step_type` und relevanten `context` in deinen Protokollen hinzu.
  2. Instrumentiere für wichtige Metriken: Identifiziere 3-5 kritische Metriken, die die Gesundheit und Leistung deines Agenten definieren (z.B. Entscheidungsverzögerung, Erfolgsquote der Tools, Token-Nutzung). Implementiere Prometheus oder ähnliche Client-Bibliotheken, um diese bereitzustellen.
  3. Plane für Tracing: Auch wenn du nicht sofort vollständiges OpenTelemetry implementierst, skizziere mental die „Spannen“ im Lebenszyklus deines Agenten. Überlege, wie du sie verbinden würdest. Dies erleichtert die zukünftige Implementierung von Tracing erheblich.
  4. Zentralisiere deine Daten: Protokolliere nicht nur in eine Datei. Schiebe deine Protokolle und Metriken in ein zentrales System (z.B. ELK-Stack, Grafana Loki, Prometheus + Grafana). Dies ist entscheidend für aggregierte Ansichten und historische Analysen.
  5. Visualisiere alles: Rohprotokolle und Metriken sind nützlich, aber Dashboards und Trace-Visualisierungen machen sie umsetzbar. Verbringe Zeit damit, aussagekräftige Grafana-Dashboards zu erstellen oder Tracing-UIs zu verwenden, um das Verhalten deines Agenten zu verstehen.
  6. Übe „beobachtungsgetriebene Entwicklung“: Bevor du eine komplexe agentische Schleife schreibst, überlege dir, wie du sein Verhalten beobachten wirst. Dieses vorweggenommene Denken spart später viel Debugging-Zeit.

Es ist schwierig, zuverlässige, produktionsbereite KI-Agenten zu erstellen. Sie sind von Natur aus komplexe, nicht deterministische Systeme. Aber indem wir von Anfang an Beobachtbarkeit einbauen, können wir diese schwarzen Kästen in durchsichtige verwandeln, was es uns ermöglicht, unsere Agenten besser zu verstehen, zu debuggen und letztendlich mehr Vertrauen in sie zu haben. Es ist nicht nur eine gute Praxis; es ist eine Notwendigkeit für jeden, der ernsthaft daran interessiert ist, diese Systeme in der realen Welt einzusetzen.

Baue weiter, beobachte weiter, und ich sehe dich beim nächsten Mal hier auf agntai.net!

🕒 Published:

🧬
Written by Jake Chen

Deep tech researcher specializing in LLM architectures, agent reasoning, and autonomous systems. MS in Computer Science.

Learn more →
Browse Topics: AI/ML | Applications | Architecture | Machine Learning | Operations

Recommended Resources

AgntzenBotsecAgntdevBotclaw
Scroll to Top