> ## Documentation Index
> Fetch the complete documentation index at: https://docs.befailproof.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Benutzerdefinierte Agenten

> Instrumentiere Traces von benutzerdefinierten Agenten, damit Failproof AI Ausführungen rekonstruieren und Fehler finden kann.

Instrumentiere Traces eines benutzerdefinierten Agenten mit `failproofai-sdk`, damit Failproof AI jeden Lauf rekonstruieren, sein Verhalten prüfen und belegbare Fehler finden kann. Das SDK schreibt strukturierte Ereignisse, die der Failproof-Daemon an Cloud weiterleitet. Es setzt Python 3.10 oder neuer voraus.

Tracing macht benutzerdefinierte Agenten beobachtbar und auditierbar. Um eine unsichere Aktion vor ihrer Ausführung zu verhindern, ist zusätzlich ein Enforcement-Hook in deiner Laufzeitumgebung erforderlich.

<Info>
  Um Richtlinien in einer benutzerdefinierten Agenten-Umgebung durchzusetzen, [kontaktiere Failproof AI](mailto:support@befailproof.ai). Wir helfen dabei, die Modell-, Tool- und Lifecycle-Grenzen deiner Laufzeitumgebung auf Policy-Hooks abzubilden.
</Info>

<div style={{ position: "relative", width: "100%", paddingBottom: "56.25%", height: 0, overflow: "hidden", borderRadius: "12px", margin: "1.5rem 0" }}>
  <iframe src="https://www.youtube.com/embed/VWxukZc5k7s?rel=0&playsinline=1" title="Agent tracing with the Failproof AI Python SDK" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture; fullscreen" allowFullScreen style={{ position: "absolute", top: 0, left: 0, width: "100%", height: "100%", border: 0 }} />
</div>

## `failproofai-sdk` installieren

Das SDK wird derzeit als privates Wheel vertrieben. Wende dich an deinen Failproof AI-Ansprechpartner, um die aktuelle Version und Zugang zum Download zu erhalten.

```bash theme={null}
VERSION=<sdk-version>
pip install "./failproofai_sdk-${VERSION}-py3-none-any.whl"
python -c "import failproofai; print(failproofai.__version__)"
```

Mit `uv` lade das Wheel zunächst herunter und führe `uv add ./failproofai_sdk-${VERSION}-py3-none-any.whl` aus. Fixiere das Wheel in einem privaten Artefakt-Repository oder einer Dependency-Lock-Datei.

Das Paket wird als `failproofai-sdk` installiert und in Python als `failproofai` importiert.

## Failproof-Daemon verbinden

<Tabs>
  <Tab title="Dashboard">
    1. Gehe zu **Admin → Keys** und erstelle einen Schlüssel mit `events:add`.
    2. [Verbinde den Failproof-Daemon mit Cloud](/de/start/setup#connect-a-machine-to-cloud) auf der Agenten-Maschine.
    3. Führe eine instrumentierte Sitzung aus und suche dann deren genaue ID unter **Observe → Events**.
    4. Gehe zu **Observe → Sessions**, wähle dieselbe Umgebung und öffne den rekonstruierten Trace.

           <img src="https://mintcdn.com/exosphere/WgPwQzedeDNwJBTy/images/dashboard/session-detail.png?fit=max&auto=format&n=WgPwQzedeDNwJBTy&q=85&s=7b5f022dd5c485565a8cd92b2e936235" alt="Eine benutzerdefinierte Python-Agenten-Sitzung, rekonstruiert als Ausführungsgraph und geordneter Ereignis-Trace." width="3200" height="2000" data-path="images/dashboard/session-detail.png" />
  </Tab>

  <Tab title="CLI">
    ```bash theme={null}
    failproofai config \
      --connect https://app.befailproof.ai \
      --token <events-add-key>
    failproofai config --status
    ```
  </Tab>
</Tabs>

## Einen vollständigen Lauf instrumentieren

Rufe `configure()` einmal beim Prozessstart auf. Jeder Ereignisaufruf ist keyword-only und erfordert eine stabile `session_id` und `agent_id`.

```python theme={null}
import traceback
import uuid

import failproofai

failproofai.configure(environment="production")

session_id = uuid.uuid4().hex
agent_id = "checkout-agent"

failproofai.event.agent_start(
    session_id=session_id,
    agent_id=agent_id,
    goal="Resolve a failed checkout",
)

try:
    tool_call_id = uuid.uuid4().hex
    failproofai.event.tool_use(
        session_id=session_id,
        agent_id=agent_id,
        tool_name="lookup_order",
        tool_call_id=tool_call_id,
        input={"order_id": "ord_8421"},
    )
    result = {"status": "payment_failed"}
    failproofai.event.tool_result(
        session_id=session_id,
        agent_id=agent_id,
        tool_name="lookup_order",
        tool_call_id=tool_call_id,
        output=result,
    )
except Exception as exc:
    failproofai.event.error(
        session_id=session_id,
        agent_id=agent_id,
        error_type=type(exc).__name__,
        message=str(exc),
        traceback=traceback.format_exc(),
    )
    failproofai.event.agent_end(
        session_id=session_id,
        agent_id=agent_id,
        outcome="failed",
    )
    raise
else:
    failproofai.event.agent_end(
        session_id=session_id,
        agent_id=agent_id,
        outcome="success",
        summary="Escalated the failed payment",
    )
```

Sende `agent_start` einmal pro Akteur. Für Sub-Agenten verwende die `session_id` des Elternagenten erneut, weise jedem Akteur eine eigene `agent_id` zu und setze `parent_id` auf die **Agent-ID** des Elternagenten – nicht auf die Session-ID.

## Konfigurationsreferenz

```python theme={null}
failproofai.configure(
    base_dir=None,
    flush_interval=0.5,
    environment="production",
)
```

| Einstellung        | Verhalten                                                                                 |
| ------------------ | ----------------------------------------------------------------------------------------- |
| `base_dir`         | Explizites Spool-Verzeichnis. Hat Vorrang vor allen Umgebungsvariablen.                   |
| `flush_interval`   | Sekunden zwischen Hintergrundschreibvorgängen aus dem Speicher in JSONL. Standard: `0.5`. |
| `environment`      | Deployment-Label für jedes Ereignis. Standard: `dev`.                                     |
| `FAILPROOFAI_HOME` | Ändert das Failproof AI-Stammverzeichnis, das den `custom-agents`-Spool enthält.          |

Das SDK schreibt in das explizite `base_dir`, falls gesetzt. Andernfalls verwendet es den `custom-agents`-Spool des Failproof-Daemons unter `FAILPROOFAI_HOME` oder `~/.failproofai`.

Das SDK reiht Aufrufe im Speicher ein und schreibt Batches in einem Hintergrund-Thread. Es versucht außerdem einen abschließenden Flush über Pythons `atexit`-Mechanismus. Für kurzlebige Worker sollte ein normales Interpreter-Shutdown ermöglicht werden; ein harter Prozessabbruch kann Ereignisse verlieren, die sich noch im Speicher befinden.

## Ereigniskatalog

Alle Methoden geben `None` zurück. Felder, die als `None` belassen werden, werden weggelassen statt als JSON `null` geschrieben.

| Methode           | Pflichtfelder (über Identität hinaus) | Optionale Felder                                                           |
| ----------------- | ------------------------------------- | -------------------------------------------------------------------------- |
| `agent_start`     | —                                     | `goal`, `parent_id`                                                        |
| `agent_end`       | —                                     | `outcome`, `summary`                                                       |
| `agent_pause`     | `pause_id`                            | `reason`, `user_id`                                                        |
| `agent_resume`    | `pause_id`                            | `reason`, `user_id`                                                        |
| `model_request`   | —                                     | `model`, `messages`, `system`, `tools`                                     |
| `model_response`  | —                                     | `model`, `stop_reason`, `input_tokens`, `output_tokens`, `content`, `role` |
| `tool_use`        | `tool_name`, `tool_call_id`           | `input`                                                                    |
| `tool_result`     | `tool_name`, `tool_call_id`           | `output`, `error`                                                          |
| `hook_triggered`  | `hook_name`, `hook_id`                | `trigger_event`, `input`                                                   |
| `hook_completed`  | `hook_name`, `hook_id`                | `outcome`, `output`, `error`                                               |
| `error`           | `error_type`, `message`               | `traceback`                                                                |
| `human_wait`      | `input_id`                            | `prompt`, `options`, `reason`                                              |
| `human_input`     | `input_id`                            | `response`                                                                 |
| `human_pause`     | —                                     | `reason`, `user_id`                                                        |
| `human_interrupt` | —                                     | `reason`, `user_id`, `at_step`                                             |

Verwende `outcome="failed"`, `"error"`, `"timeout"` oder `"rejected"`, wenn eine Ausführung als Fehler gewertet werden soll. Andere Werte, einschließlich `"failure"`, werden vom aktuellen Backend nicht als Fehler klassifiziert.

## Korrelations- und Dauerregeln

* Verwende dieselbe `tool_call_id`, `hook_id`, `pause_id` oder `input_id` für das zugehörige Abschlussereignis.
* Das SDK berechnet `duration_ms` für `tool_result`, `hook_completed`, `agent_resume` und `human_input`. Wenn du diesen Wert selbst an diese Methoden übergibst, wird ein `ValueError` ausgelöst.
* Tool- und Hook-IDs teilen sich eine prozessweite Pending-Map. Mache sie global eindeutig – über gleichzeitige Sitzungen hinweg und über beide Namespaces; Provider-IDs oder UUIDs sind die sicherste Wahl.
* Ein Paar, das über Prozesse hinweg aufgeteilt ist, korreliert trotzdem nachgelagert, aber das SDK kann seine prozessinterne Dauer nicht berechnen.
* Die Pending-Map hält maximal 10.000 Einträge und verdrängt den ältesten Eintrag, wenn sie voll ist.

## Benutzerdefinierte Felder und Nutzdaten

Jedes Ereignis akzeptiert zusätzliche Keyword-Felder. Verwende JSON-kompatible Werte, wenn nachgelagerte Abfragen Struktur benötigen. Nicht unterstützte Typen wie UUIDs, Datetimes, Decimals, Sets, Bytes und Modellobjekte werden vom Writer in Strings umgewandelt.

Reservierte benutzerdefinierte Namen sind `timestamp`, `session_id`, `agent_id`, `type` und `environment`. Tippfehler bei optionalen Feldern werden als neue benutzerdefinierte Felder akzeptiert – überprüfe daher das ausgegebene JSON, wenn ein Standardfeld nicht in Cloud erscheint.

## Zustellen und überprüfen

<Tabs>
  <Tab title="Dashboard">
    Überprüfe unter **Observe → Events**, ob `agent_start` als erstes und `agent_end` als letztes Ereignis vorhanden ist. Öffne dann **Observe → Sessions** und bestätige, dass Modell-, Tool-, Human-, Hook- und Fehlerereignisse in der vorgesehenen Reihenfolge erscheinen. Verwende die Session-ID als primären Schlüssel bei der Fehlersuche.
  </Tab>

  <Tab title="CLI">
    ```bash theme={null}
    failproofai flush --wait --timeout 60
    failproofai config --status
    fp sessions --since 1h --env production --session-id <session-id>
    fp events --since 1h --session-id <session-id> --full
    ```
  </Tab>
</Tabs>

Wenn Cloud leer ist, überprüfe `$FAILPROOFAI_HOME/custom-agents/events`, andernfalls `~/.failproofai/custom-agents/events`. JSONL-Dateien belegen die SDK-Ausgabe; ein wachsender Spool deutet auf ein Problem mit der Daemon-Konfiguration oder Zustellung hin, während ein leerer Spool auf ein Problem mit der Instrumentierung oder der Prozesslebensdauer hindeutet.

## Fehler in einer benutzerdefinierten Laufzeitumgebung verhindern

Nutze Audit-Ergebnisse und verknüpfte Traces, um die unsichere Aktion, die erforderlichen Belege und die beabsichtigte Reaktion zu definieren. Eine benutzerdefinierte Enforcement-Integration muss die Aktion vor ihrer Ausführung offenlegen, ihre strukturierten Eingaben an die Policy-Engine übergeben und die resultierende allow-, instruct- oder deny-Entscheidung anwenden.

Schreibe an [support@befailproof.ai](mailto:support@befailproof.ai), um diese Integration für deine Laufzeitumgebung zu entwerfen und zu validieren.
