Installation
Instrumentierung
session_id und agent_id weglassen. Die Scopes binden die Identität auf Kontextvariablen, und jeder Event-Aufruf liest sie zurück – du musst IDs nie durch deine Funktionen durchreichen.
Alle drei funktionieren sowohl mit async with als auch mit with.
Verschachtelte Agenten bilden den Baum. parent_id und Tiefe werden aus dem Stack berechnet:
Wie ein Scope schließt
agent() behandelt Exceptions für dich:
agent_end gesendet, weil das Dashboard den Span bei agent_end schließt und alles danach keinem Span mehr zugeordnet wird. Eine Stornierung ist kein Fehler, daher verschmutzen abgebrochene Durchläufe die Fehlerübersicht nicht. Die Exception wird immer erneut ausgelöst: Ein Scope verschluckt sie nie.
Die Event-Methoden
Fünfzehn Methoden in sechs Familien. Die meisten kommen paarweise – du sendest den Öffner, dann den Schließer, und das SDK misst den Span dazwischen.Beispiel
Eine Tool-Calling-Schleife gegen die OpenAI API, ohne Agent-Framework:docs/manual/examples/.
Threads und Async
Kontextvariablen werden automatisch in asyncio-Tasks übertragen. In neue Threads werden sie nicht übertragen, da ein Thread mit einem leeren Kontext startet.propagate() wirft das Worker-Event einen TypeError, der den Fix benennt, anstatt auf keiner Session zu landen. Das ist beabsichtigt: Ein Event ohne Session wird beim Ingest übersprungen und mit 200 beantwortet – das ist genau der stille Fehler, den die Identitätsschicht verhindern soll.
Ein Framework ohne Adapter instrumentieren
Jedes Agent-Framework gibt dir dieselben drei Nahtpunkte. Mappe sie und du hast eine vollständige Trace – die vier mitgelieferten Adapter tun nichts anderes.Den Durchlauf einrahmen
Jedes Tool einrahmen
Jeden Modellaufruf paaren
Warum es keinen AutoGen-Adapter gibt
Warum es keinen AutoGen-Adapter gibt
autogen-corewird seit September 2025 nicht mehr gepflegt.- AG2 bietet keinen prozessweiten Registrierungspunkt, der dem Hook-System der anderen Frameworks entspricht – die Instrumentierung erfordert daher das Einwickeln jedes Agenten an jeder Konstruktionsstelle.
Tiefer eintauchen
Wie die Aufzeichnung tatsächlich funktioniert. Nichts davon ist nötig, um loszulegen.Wie eine Aufzeichnung pro Framework aussieht
Wie eine Aufzeichnung pro Framework aussieht
- LangGraph
- CrewAI
- LlamaIndex
- Pydantic AI
- Custom agents
Wie eine Session startet und endet
Wie eine Session startet und endet
session_id teilen.Der Status wird aus der Form der Trace abgeleitet:agent_end für dich, und beim Teardown schließen sie alles noch Offene und markieren es als unvollständig – ein abgestürzter Durchlauf wird als done mit einer sichtbaren Lücke abgeschlossen, statt hängen zu bleiben.interrupt() pausiert den Durchlauf, der Root-Span bleibt absichtlich offen, und der fortsetzende Aufruf schließt ihn. Beide Aufrufe gehören zu einer Session.Identität: session_id, agent_id und wer sie vergibt
Identität: session_id, agent_id und wer sie vergibt
session_id und agent_id sind bei jeder Event-Methode optional. Werden sie weggelassen, werden sie aus dem umschließenden Scope aufgelöst:TypeError, der den Fix benennt, anstatt ein Event ohne Session zu senden, das beim Ingest übersprungen und mit 200 beantwortet werden würde.Scopes binden die Identität auf Kontextvariablen. Diese werden automatisch in asyncio-Tasks übertragen, aber nicht in neue Threads – wickle einen Worker in failproofai_sdk.propagate() ein.Wer welche ID vergibt
Wie Adapter session_id auflösen
Der erste Treffer gewinnt:- Eine explizite
session_id-Option - Metadaten pro Aufruf
- Der umschließende
session()-Scope - Framework-Metadaten
- Die eigene Run-ID des Frameworks
agent_id niedrig halten
Sie ist die primäre Facette auf jeder Dashboard-Ansicht und eine LowCardinality(String)-Spalte. Ein Wert pro Durchlauf degradiert die Spalte und füllt das Filter-Dropdown mit einem Eintrag pro Durchlauf.Adapter schützen diese Spalte für dich:fw_agent_id / fw_run_id behalten, wo sie abfragbar bleibt, ohne eine Facette zu sein.Event-Typen, gruppiert – und welches Framework was aufzeichnet
Event-Typen, gruppiert – und welches Framework was aufzeichnet
human_pause und human_interrupt beschreiben eine Person, die auf den Agenten einwirkt – das signalisiert kein Framework. Diese musst du selbst senden.Paare, Korrelation und Dauer
Paare, Korrelation und Dauer
Korrelationsregeln
- Verwende dieselbe
tool_call_id,hook_id,pause_idoderinput_idfür das passende Abschlussevent. - Das SDK berechnet
duration_msfürtool_result,hook_completed,agent_resumeundhuman_input. Es an diese Methoden zu übergeben wirft einenValueError. duration_mswird beimodel_responseakzeptiert, weil nur der Aufrufer die echte Provider-Latenz kennt. Es muss ein Integer sein – ein Float wirft am Aufrufpunkt einenValueError, da der Server die Spalte als vorzeichenlosen 32-Bit-Integer liest und sonst NULL speichern würde.- Korrelationsschlüssel sind nach Art und Session begrenzt, sodass ein Tool-Aufruf und ein Hook sicher dieselbe ID teilen dürfen, und zwei parallele Sessions dieselben IDs wiederverwenden können, ohne zu kollidieren. Sie sind nicht nach Agent begrenzt: Ein Paar, das unter einem Agenten geöffnet und unter einem anderen geschlossen wird, korreliert trotzdem – das ist der Normalfall in Multi-Agent-Frameworks.
request_idpaartmodel_requestmitmodel_response. Ohne sie werden Model-Events in Reihenfolge pro Agent gepaart, sodass parallele Aufrufe falsch gepaart werden.- Ein über Prozesse hinweg aufgeteiltes Paar korreliert noch auf der Serverseite, aber das SDK kann seine In-Process-Dauer nicht berechnen.
- Die Pending-Map hält maximal 10.000 Starts und entfernt den ältesten Eintrag, wenn sie voll ist.
Was im Paket steckt und wie instrument() dein Framework findet
Was im Paket steckt und wie instrument() dein Framework findet
failproofai-sdk installiert alles, alle vier Adapter inklusive. Die Extras ziehen das Framework nach, nicht den Adapter.import failproofai_sdk ist vertraglich abhängigkeitsfrei, erzwungen durch einen Test, der das gebaute Wheel mit --no-deps installiert, und einen weiteren, der beweist, dass kein Framework sys.modules erreicht.sys.modules, nicht die Liste installierter Pakete – ein installiertes, aber nie importiertes Framework wird nicht instrumentiert und nie in deinem Namen importiert. Um zu sehen, was verdrahtet ist:instrument("crewai") auf einer Maschine ohne CrewAI wirft keine Exception. Es loggt eine Warnung und gibt () zurück, sodass ein fehlendes Framework nie einen Prozess zum Absturz bringt, der auch andere instrumentiert.Die Warnung enthält den zugrunde liegenden ImportError, und diese Meldung nennt den genauen Installationsbefehl – die Lösung steht also in deinen Logs, nicht versteckt.FAILPROOFAI_SDK_STRICT=1, damit stattdessen eine Exception ausgelöst wird. Dieses Flag wird einmal gelesen und gecacht, also exportiere es vor dem Start deines Prozesses, statt es mittendrin zu setzen.Wie Events die Cloud erreichen
Wie Events die Cloud erreichen
.tmp, dann fsync, dann ein atomares Umbenennen:.jsonl, kann also nie eine halb geschriebene Datei lesen. Der Dateiname trägt Timestamp, Prozess-ID und Sequenznummer, sodass zwei Prozesse, die in derselben Millisekunde flushen, nicht kollidieren können. Die Queue ist auf 10.000 Events begrenzt; darüber hinaus werden die ältesten gelöscht und geloggt.Der Daemon versendet deine Batches. Er öffnet oder überschreibt sie nicht.ls mit dem Collector um die Wette läuft und nur einen Bruchteil der gesendeten Events zeigt – nicht zu unterscheiden von einem SDK, das nichts aufgezeichnet hat.Um zu bestätigen, dass Events tatsächlich angekommen sind, prüfe das Dashboard. Um den Spool beim Füllen zu beobachten, stoppe den Daemon zuerst.Wenn die Instrumentierung fehlschlägt
Wenn die Instrumentierung fehlschlägt
try, und alles, was das SDK tut, geschieht außerhalb davon.FAILPROOFAI_SDK_STRICT=1, um einen verschluckten Fehler laut zu machen.Häufige Probleme
Ein Span endet nie
Ein Span endet nie
model_request ohne model_response oder ein tool_use ohne tool_result. Verwende die Scopes, die das Paar auch dann garantieren, wenn der Body eine Exception wirft. Wenn du die Event-Methoden direkt aufrufst, verwende try und finally.duration_ms übergeben wirft einen ValueError
duration_ms übergeben wirft einen ValueError
tool_result, hook_completed, agent_resume und human_input abgelehnt. Bei model_response wird es akzeptiert, weil nur du die echte Provider-Latenz kennst, und es muss ein Integer sein.Events aus einem Worker-Thread werfen einen TypeError
Events aus einem Worker-Thread werfen einen TypeError
failproofai_sdk.propagate() ein. Siehe Threads und Async.Ein zusätzliches Feld ist verschwunden oder hat etwas überschrieben
Ein zusätzliches Feld ist verschwunden oder hat etwas überschrieben
model oder outcome dieses überschreiben und eine gespeicherte Spalte verändern würde. Verwende einen Namespace; die Adapter nutzen das Präfix fw_.Der Agenten-Filter hat Tausende von Einträgen
Der Agenten-Filter hat Tausende von Einträgen
agent_id ist eine Facette mit niedriger Kardinalität, und du hast eine Run-ID hineingespeichert. Verwende eine Rolle oder einen Node-Namen und leg die echte ID in ein Payload-Feld.
