Idee in 30 Sekunden
Debugging von Agent-Runs hilft, vom Symptom zur Ursache zu kommen: was genau kaputt ist, in welchem Schritt, und warum.
DafĂŒr mĂŒssen Tracing, Logs und Metriken eines problematischen Runs zusammengefĂŒhrt werden.
Ohne das sieht das Team oft nur den finalen Fehler, aber nicht den gesamten Weg dorthin.
Das Hauptproblem
In Agent-Systemen hat ein Incident selten nur eine offensichtliche Ursache.
Der finale Fehler kann nur eine Folge sein: Das eigentliche Problem kann frĂŒher begonnen haben, zum Beispiel durch einen langsamen tool call, ein fehlerhaftes retry oder eine Regression nach dem Release. Ohne systematisches debugging ist das schwer schnell zu lokalisieren.
Als NĂ€chstes schauen wir, wie man diese Signale liest und stabil root cause findet.
In Production sieht das oft so aus:
- in Logs gibt es viele Events, aber keine klare Reihenfolge;
- die Ursache vermischt sich mit Begleitfehlern;
- der Incident wurde "gefixt", kommt aber nach dem Release zurĂŒck;
- MTTR steigt, weil das Team den Incident-Kontext jedes Mal neu aufbauen muss.
Genau deshalb sollte debugging eines Runs ein eigener operativer Prozess sein und keine manuelle Suche nach dem "ersten error".
So funktioniert es
Ein praktischer debugging run besteht meist aus drei Ebenen:
- Run-Kontext (
run_id,trace_id,release,workflow); - Evidence -> Analyse (
spans,logs,metrics,stop_reason); - Entscheidung (Hypothese -> Fix -> Verifikation via replay und Tests).
Diese Ebenen beantworten: wo das Problem liegt, warum es entstanden ist und ob der Fix es wirklich entfernt. Tracing zeigt den Pfad, Logs zeigen Ereignisse, und Metriken zeigen AusmaĂ und Trend.
Viele Logs != schnelles debugging. Geschwindigkeit entsteht nicht aus Datenmenge, sondern aus Korrelation rund um einen Run.
Typische Production-Signale fĂŒr debugging runs
| Signal | Wo prĂŒfen | Warum es wichtig ist |
|---|---|---|
| first_error_span | Tracing | Punkt finden, an dem der Fehler zuerst erschien |
| slowest_span | Tracing + Metriken | Bottleneck-Kandidat (muss verifiziert werden) |
| stop_reason | Log run_finished | verstehen, wie der Run beendet wurde |
| error_class | tool_result / llm_result Logs | Timeout von Logikfehler trennen |
| repeated_tool_calls | tool_call Logs + tool metrics | wiederholte Aufrufe erkennen (loops, retries, tool spam) |
| run_latency_p95 | Metriken | prĂŒfen, ob Incident bereits systemisch ist |
| release_diff | Release-Vergleichsdashboard | Regression nach Ănderungen erkennen |
| synthetic_run_status | health checks | Auswirkung auf kritischen workflow prĂŒfen |
Damit debugging stabil bleibt, werden diese Signale typischerweise nach release, workflow, model und tool segmentiert.
Wichtig: keine high-cardinality Labels (run_id, request_id, user_id) in Metriken aufnehmen. DafĂŒr sind Logs und Tracing besser geeignet.
Wie man den Debugging-Layer liest
Welcher Run ist fehlgeschlagen -> in welchem Schritt -> warum genau. Diese drei Ebenen sollte man immer gemeinsam betrachten.
Wichtig ist, auf Trends und Release-Deltas zu schauen, nicht nur auf ein einzelnes Notfall-Event.
Typische Signalkombinationen:
first_error_span=tool_call+tool_error_rateâ -> Problem in einem konkreten tool-layer;run_latency_p95â +tool_latency_p95stabil -> wahrscheinlich Problem in LLM oder runtime-Logik;repeated_tool_callsâ +stop_reason=max_steps-> Agent steckt in einer Schleife;error_rateâ nach Release + positivesrelease_diff-> Ănderungsregression, kein einmaliger Incident;synthetic_run_status=fail+health_scoreâ -> Problem beeinflusst bereits kritischen workflow.
Wann verwenden
Ein formaler debugging-flow ist nicht immer nötig.
FĂŒr ein einfaches single-shot Szenario ohne tools reichen manchmal Basis-Logging und manuelle FehlerprĂŒfung.
Ein systematischer debugging-Ansatz wird aber kritisch, wenn:
- Runs mehrere reasoning-Schritte und tool calls enthalten;
- Incidents Latenz, Kosten oder SLO beeinflussen;
- Releases hĂ€ufig kommen und Regressionen frĂŒh erkannt werden mĂŒssen;
- es einen on-call Prozess gibt und ein planbares MTTR nötig ist.
Implementierungsbeispiel
Unten ist eine vereinfachte Funktion, die Evidence fĂŒr einen Run sammelt und eine Basis-Hypothese bildet. Das ersetzt kein vollstĂ€ndiges incident tooling, zeigt aber einen praktischen debugging-Prozess.
from collections import Counter
def debug_run(run_id, trace_events, log_events, debug_metrics_snapshot):
run_spans = sorted(
[s for s in trace_events if s.get("run_id") == run_id],
key=lambda s: s.get("started_at_ms", 0),
)
run_logs = [e for e in log_events if e.get("run_id") == run_id]
first_error_span = next((s for s in run_spans if s.get("status") == "error"), None)
# slowest_span kann None sein, wenn der Run keine spans enthÀlt
slowest_span = max(run_spans, key=lambda s: s.get("latency_ms", 0), default=None)
stop_reason = "unknown"
for event in reversed(run_logs):
if event.get("event") == "run_finished":
stop_reason = event.get("stop_reason", "unknown")
break
seen_signatures = set()
repeated_tools = Counter()
for event in run_logs:
if event.get("event") != "tool_call":
continue
signature = (event.get("tool"), event.get("args_hash"))
if signature in seen_signatures:
repeated_tools[event.get("tool")] += 1
else:
seen_signatures.add(signature)
hypotheses = []
if first_error_span and first_error_span.get("step_type") == "tool_call":
hypotheses.append("Wahrscheinlicher Ausfall im tool-layer: Tool-VerfĂŒgbarkeit und timeout policy prĂŒfen.")
if repeated_tools:
hypotheses.append("Wiederholte tool calls erkannt: dedupe/cache und stop conditions prĂŒfen.")
if slowest_span and debug_metrics_snapshot.get("run_latency_p95_ms", 0) > debug_metrics_snapshot.get("slo_latency_ms", 2500):
hypotheses.append("p95 latency liegt ĂŒber SLO: Bottleneck ĂŒber slowest_span lokalisieren.")
if debug_metrics_snapshot.get("release_error_rate_delta", 0) > 0:
hypotheses.append("error_rate ist nach Release gestiegen: Ănderungen in prompt/runtime/tool routing prĂŒfen.")
return {
"run_id": run_id,
"first_error_span": first_error_span,
"slowest_span": slowest_span,
"stop_reason": stop_reason,
"repeated_tools": dict(repeated_tools),
"hypotheses": hypotheses,
}
Debugging gilt erst als abgeschlossen, wenn das Problem reproduzierbar ist (replay) und bestÀtigt ist, dass der Fix es stabil entfernt. Wenn sich das Problem nicht reproduzieren lÀsst, wechselt debugging in den Modus von Hypothesen statt Beweisen.
Replay != optional.
Ohne replay ist es eine Annahme.
Mit replay ist es ein Beweis.
So kann ein kurzer debugging snapshot aussehen:
| Run | first_error_span | slowest_span | stop_reason | Fazit |
|---|---|---|---|---|
| run_9fd2 | tool_call: search_docs | tool_call: search_docs (1.8s) | tool_error | tool degradiert + retries |
| run_a113 | llm_generate | llm_generate (2.4s) | step_error | Modellfehler nach Release |
| run_d77c | â | reasoning (3.1s) | max_steps | Loop ohne expliziten Fehler |
Investigation
Wenn ein Incident-Signal auslöst:
run_id,trace_id,releaseund betroffenen workflow festhalten;- im Tracing
first_error_spanundslowest_spanfinden; - in Logs
stop_reason,error_class,repeated_tool_callsprĂŒfen; - in Metriken AusmaĂ bestĂ€tigen (Spike oder Trend) und Release-Deltas vergleichen.
Typische Fehler
Auch mit observability scheitert debugging oft an typischen Fehlern.
Analyse beginnt bei irgendeinem Log-Fehler
Ohne Bindung an eine konkrete run_id mischt das Team Symptome aus verschiedenen Incidents.
So wird es schwer, lokales Problem von kaskadierendem Ausfall zu trennen.
Keine Korrelation von trace + logs + metrics
Wenn Tracing, Logs und Metriken getrennt betrachtet werden, widersprechen sich Hypothesen oft. Dadurch steigt MTTR selbst bei einfachen Tool-AusfÀllen.
repeated calls und stop_reason werden ignoriert
Ohne diese Signale ĂŒbersieht man leicht loops und retry storms. Das verdeckt oft die frĂŒhe Phase von Tool-Spam.
Kein Vergleich mit vorherigem Release
Ohne release_diff sieht das Team nicht, ob das Problem nach Ănderungen aufgetreten ist.
Dadurch bleibt Regression lÀnger in Production.
Incident wird ohne replay und Verifikation geschlossen
Ein Fix kann nur das Symptom entfernen, nicht die Ursache. Das erhöht das Risiko einer wiederholten teilweisen Störung.
Selbst-Check
Unten ist eine kurze Baseline-Checkliste fĂŒr debugging-flow vor dem Release.
Fortschritt: 0/9
â Grundlegende Observability fehlt
Das System wird in production schwer zu debuggen sein. Starten Sie mit run_id, structured logs und tracing von tool calls.
FAQ
Q: Womit beginnt debugging eines problematischen Runs?
A: Starte mit run_id und trace_id: finde first_error_span, prĂŒfe stop_reason und bestĂ€tige dann das AusmaĂ in den Metriken. first_error_span ist der schnellste Weg zum Fehlerpunkt.
Q: Was ist wichtiger fĂŒr debugging: Tracing oder Logs?
A: Beides zusammen: Tracing zeigt den Schrittpfad, Logs liefern Event-Details (error_class, args_hash, policy decision).
Q: Wie erkenne ich Release-Regression statt einmaligem Ausfall?
A: Vergleiche error_rate, latency_p95, repeated_tool_calls zwischen Releases. Wenn das Signal nach dem Release stabil schlechter ist, ist es Regression.
Q: Was ist das Minimum an Daten fĂŒr Debugging in 10-15 Minuten?
A: Minimum: run_id, trace_id, first_error_span, stop_reason, error_class, latency_p95 und Release-Kontext.
Verwandte Seiten
Weiter zum Thema:
- Agent-Tracing â wie man den Pfad eines Runs Schritt fĂŒr Schritt sieht.
- Agent-Logging â welche Events fĂŒr Incident-Analyse nötig sind.
- Agent-Metriken â wie man einmaligen Ausfall von Trend trennt.
- Agent Health Checks â frĂŒhe Degradationssignale vor dem Incident.
- Fehler-Alerting fĂŒr KI-Agenten â wie Investigation rechtzeitig gestartet wird.