Skip to main content

Installation

Unterstützt: crewai 1.13 bis 2.0. Version 1.13 ist das Release, das started_event_id und normalisierte Token-Nutzung eingeführt hat – beides wird vom Adapter benötigt, um Ereignisse zuzuordnen und Tokens zu erfassen.

Instrumentierung

instrument() registriert einen Listener auf dem modulweiten Ereignis-Bus von CrewAI und abonniert je einen Handler pro Ereignisklasse. An deiner Crew, den Agents, Tasks oder Tools ändert sich nichts.

Was aufgezeichnet wird

Ein Task erzeugt bewusst keine Ereignisse. Ein CrewAI-Task ist ein Teilbereich der Agent-Ausführung, die ihn ausführt – würde man beides erfassen, würde jede Zeile doppelt erscheinen und als Geschwister dargestellt. Die Task-ID und der Name werden stattdessen in den eigenen Ereignissen des Agents mitgeführt. Speicher- und Wissensoperationen werden als Tools aufgezeichnet, benannt nach der betroffenen Oberfläche, damit sie neben deinen echten Tools erscheinen und deren Latenz verglichen werden kann. Bei einer hierarchischen Crew macht die Verschachtelung den Trace lesbar:
CrewAI ordnet eine delegierte Ausführung dem delegate_work_to_coworker-Tool-Ereignis zu, nicht direkt dem Manager – der Adapter folgt diesem Link entsprechend. Ohne ihn würde jeder Agent als Geschwister jedes anderen erscheinen und die Delegierungsstruktur ginge verloren.

Beispiel

Die Übergabe ist im Trace sichtbar: Der analyst-Span schließt sich, der writer-Span öffnet sich, und beide liegen innerhalb eines einzigen crew-Spans.

Spans benennen

agent_id stammt aus Agent(role=...), was ihn zu einer lesbaren Dashboard-Facette macht.
agent_id ist eine Spalte mit geringer Kardinalität. Eine Rolle, die eine Run-ID oder einen Zeitstempel enthält, verschlechtert sie für jede Abfrage. Sieht eine Rolle wie eine ID aus, lehnt der Adapter sie ab und legt den tatsächlichen Wert stattdessen in einem Payload-Feld ab.

Session steuern

Wird in dieser Reihenfolge aufgelöst, erster Treffer gewinnt:
  1. instrument("crewai", session_id=...)
  2. Der umschließende failproofai_sdk.session()-Scope
  3. Eine generierte uuid4().hex, einmal pro Crew oder Flow
Umhülle den Kickoff, um ihn pro Run zu steuern:

Optionen

session_id ist die einzige Option, die dieser Adapter liest. Prompts und Completions werden immer aufgezeichnet, auf das Payload-Budget gekürzt.

Human in the Loop

CrewAI hat zwei Human-in-the-Loop-Oberflächen, und beide werden als dieselben vier Ereignisse aufgezeichnet. @human_feedback auf einer Flow-Methode läuft über den Ereignis-Bus von CrewAI: Die Laufzeit sendet ein Ereignis, bevor sie auf eine Person wartet, und ein weiteres nach der Antwort. Task(human_input=True) hingegen nicht. Es ruft input() im eigenen Input-Provider von CrewAI auf und sendet keinerlei Ereignis – daher umhüllt der Adapter diesen Provider direkt. Ohne diese Maßnahme wäre das gesamte menschliche Warten unsichtbar und würde als aktive Agent-Zeit abgerechnet. In beiden Fällen erhältst du:
agent_pause bis agent_resume ist das einzige Paar, das Pausenzeit erfasst. Ohne es wird ein zehnminütiges menschliches Warten als zehn Minuten aktive Agent-Zeit abgerechnet.
CrewAI setzt keine Korrelations-ID auf einem der beiden Human-Feedback-Ereignisse, sodass der Adapter sie anhand des Flow- und Methodennamens zuordnet und auf die zuletzt geöffnete Pause zurückfällt. Das ist korrekt, da eine Konsoleneingabe blockiert. Wenn du einen nebenläufigen Feedback-Provider baust, setze request_id auf beiden Ereignissen.
Da der Task(human_input=True)-Pfad den Input-Provider von CrewAI umhüllt statt ein Ereignis zu abonnieren, wird er bei uninstrument() wiederhergestellt und gibt jede Ausnahme von input() unverändert weiter – einschließlich KeyboardInterrupt.

Häufige Probleme

Eine role enthält eine UUID, einen Zeitstempel oder ein lauf-spezifisches Suffix. Verwende eine stabile, menschenlesbare Rolle und lege die lauf-spezifische ID stattdessen in der Task-Beschreibung ab.
Der Ereignis-Bus ist asynchron, und kickoff() kehrt zurück, bevor die letzten Handler durchgelaufen sind. Leere ihn zuerst:
Dies ist eine Eigenschaft von CrewAI, nicht des SDK.
agent_end schließt offene Pausen zwangsweise, aber nicht Tools oder Modelle – ein Run, der innerhalb eines Tool-Aufrufs abbricht, lässt diesen Span offen. Ein normaler Teardown schließt alles noch Offene und markiert es als unvollständig. Nur ein SIGKILL lässt es hängen, da dann kein Code mehr ausgeführt werden kann.
Prüfe in dieser Reihenfolge: instrument() wurde vor kickoff() aufgerufen; es gibt ein with failproofai_sdk.session(): darum; crewai ist Version 1.13 oder neuer; FAILPROOFAI_SDK_STRICT=1 ist gesetzt, damit ein fehlerhafter Hook eine Ausnahme auslöst statt stillschweigend ignoriert zu werden.

Weiter

Funktionsweise

Paare, IDs, Session-Lebenszyklus und Übermittlung.

Einen Trace lesen

Verfolge die Kausalität durch die soeben aufgezeichnete Session.

Andere Frameworks

LangGraph, LlamaIndex, Pydantic AI und individuelle Agents.