# Observability & Telemetrie

> Das System sehen: was pro Request erfassen, verteiltes Tracing über die Pipeline, Sampling, Laufzeit-Provenienz und die Metrik-vs-Trace-vs-Log-Entscheidung.

Track: [LLM Production Ops](https://physar.tech/learn/llm-production-ops)  
Kanonische Fassung: https://physar.tech/learn/llm-production-ops/observability-telemetry  
Stand: 2026-07-25  
Interaktiver Teil: 6 Checks (nur im Browser)

## Observability & Telemetrie: das laufende LLM-System sichtbar machen

### Warum ein LLM-System ohne Telemetrie blind läuft

Ein LLM-Dienst in Produktion ist eine **Blackbox mit probabilistischem Kern**: keine Exceptions, keine Stacktraces, kein „geht/geht nicht“. Eine Antwort kann formal ein `200 OK` sein und trotzdem inhaltlich falsch. Wenn du nicht pro Request festhältst, **was** hineinging, **was** herauskam und **womit** es bedient wurde, kannst du einen Incident weder erkennen noch reproduzieren.

Observability ist die Grundlage der ganzen Betriebsschleife: **beobachten → erkennen → ändern → betreiben**. Dieses Modul baut den ersten Schritt — die anderen drei bauen darauf auf. Alles Weitere im Track (Drift erkennen, sicher ausrollen, SLOs halten) setzt voraus, dass das System **sichtbar** ist.

> **Merksatz:** Bei klassischen Diensten debuggst du den Fehler. Bei LLM-Diensten debuggst du die **Antwort** — und die ist ohne Telemetrie nach dem Request unwiederbringlich weg.

### Was pro Request erfassen — Umfang gegen Volumen

Der brauchbare Minimalumfang je Request ist mehr als nur die Antwort. Ohne Input, Versionen und Retrieval-Kontext ist ein Fall nicht reproduzierbar; mit rohem Volltext von allem sprengst du bei hohem Traffic Speicher und Kosten.

|  |  |
| --- | --- |
| Input & Output | Wortlaut oder gekürzt/referenziert — nötig, um den Fall nachzuspielen |
| Token-Zahlen | Prompt- und Completion-Tokens — Basis für Kosten und Latenz-Diagnose |
| Latenz | gesamt UND pro Pipeline-Stufe (siehe Tracing) |
| Kosten | pro Request abgeleitet, für Anomalie-Erkennung |
| Modell- & Prompt-Version | welcher Snapshot/welche Vorlage bediente den Request (siehe Provenienz) |
| Retrieval-Kontext | Referenzen (Doc-IDs, Scores) statt Volltext — spart Volumen, bleibt nachvollziehbar |

> **PII gehört woanders hin:** Inputs/Outputs enthalten oft **personenbezogene Daten**. Das **Redaction- und Secrets-Handling** ist ein eigenes Thema (`llmops/security`) — hier geht es nur um den **Umfang-Trade-off**: erfasse genug zum Reproduzieren, aber referenziere statt zu horten und plane Retention.

### Verteiltes Tracing: eine Latenzzahl reicht nicht

Eine LLM-Antwort durchläuft meist mehrere Stufen. Eine **einzige** aggregierte Latenzzahl sagt dir, dass es langsam ist — aber nicht **wo**.

**Retrieval** → Rerank → LLM → Postprocess

Mit **verteiltem Tracing** wird jede Stufe zu einem **Span** unter einer gemeinsamen **Trace-/Korrelations-ID**. Der Trace zeigt die Zeit pro Stufe und ihre Verschachtelung (parent/child). So sieht man, dass die p95-Regression aus dem **Retrieval** kommt — und kann einen einzelnen langsamen Request durch alle Stufen verfolgen.

> **Merksatz:** Aggregierte Zahlen verstecken **wo** und **welcher Request**. Ein Trace mit korrelierten Spans macht beides sichtbar — besonders bei Tail-Problemen, die nur eine Teilmenge der Requests treffen.

### Sampling: welche Traces vollständig behalten

100 % aller Traces mit vollem Payload zu speichern ist bei hohem Traffic zu teuer und PII-lastig. Sampling entscheidet, **welche** Traces bleiben — und **wann** die Entscheidung fällt:

|  |  |
| --- | --- |
| Head-based | Entscheidung am Trace-**Start**, meist zufällig (z. B. 5 %). Billig, aber **outcome-blind** — der Ausgang ist noch unbekannt, also fallen die meisten Fehler weg. |
| Tail-based | Entscheidung **nachdem** alle Spans da sind. Erlaubt outcome-basierte Regeln, braucht aber einen Puffer für alle laufenden Traces. |
| Error-/latency-biased | eine Tail-Regel: behalte **alle** Fehler und langsamen Traces, plus eine kleine Zufallsbasis normaler Traces. |

> **Merksatz:** „Alle Fehler behalten“ ist mit Head-Sampling unmöglich — beim Trace-Start weißt du noch nicht, ob er fehlschlägt. Fehler-Erhalt braucht **Tail-based**.

### Laufzeit-Provenienz: womit wurde dieser Request bedient?

Ein Nutzer meldet eine schlechte Antwort von vor drei Tagen. Seitdem wurde ein neuer Prompt deployt und der Provider hat sein Modell still aktualisiert. Ohne festgehaltene **Provenienz** ist der Fall nicht reproduzierbar.

Stemple jeden Request mit der **exakten Prompt-Version** (Hash/Tag), der **Modell-Identität inkl. Snapshot/Version** und der **aufgelösten Config** (Temperatur, Retrieval-Parameter, aktive Feature-Flags/Experiment-Zuweisung). Diese Provenienz reist mit dem Trace.

> **Merksatz:** Ein App-Commit pinnt deinen **Code** — nicht das provider-seitige Modell noch die per-Request aufgelöste Config. Provenienz **aufzeichnen** ist robust; sie später aus dem Deploy-Log **rekonstruieren** bricht beim ersten stillen Wechsel.

### Feedback-Signale als Telemetrie

Ohne Labels ist Nutzer-Feedback ein wertvolles Qualitätssignal. **Explizit** ist 👍/👎 — aber freiwilliges Feedback ist **spärlich und verzerrt** (meist nur sehr verärgerte oder begeisterte Nutzer, oft unter wenigen Prozent Klickrate).

**Implizite** Signale aus dem Nutzerverhalten ergänzen das Bild und decken die Mehrheit ab:

- Regenerate / „nochmal“ — die Antwort taugte nicht
- Copy-to-Clipboard — die Antwort war brauchbar (mit Vorsicht: kann auch Eskalation sein)
- Folgefrage als Umformulierung — das Ziel wurde verfehlt
- schneller Abbruch der Sitzung — kein Erfolg

> **Merksatz:** Jedes Signal — explizit wie implizit — muss an die **Trace-/Request-ID** geknüpft werden. Ein loser 👎-Zähler sagt, dass etwas schlecht ist; erst die Verknüpfung sagt, **welche** Prompt-/Modell-Version es war.

### Metrik vs. Trace vs. Log — und die Kardinalitäts-Falle

Nicht jedes Signal gehört in denselben Store. Die richtige Wahl hängt an der **Kardinalität** — der Anzahl unterschiedlicher Werte:

|  |  |
| --- | --- |
| Metrik | aggregierbar, günstig, **niedrige** Kardinalität (Labels wie Modell, Endpoint, Status). Für Dashboards & Alerts. |
| Trace | ein Request über alle Stufen, mit hoher Detailtiefe. Für Ursachensuche eines konkreten Requests. |
| Log | diskrete Ereignisse mit Kontext. Für nachträgliche Detail-Recherche. |

In Zeitreihen-Backends erzeugt **jede** eindeutige Kombination aus Metrik-Name und Label-Werten eine **eigene Zeitreihe**. Hochkardinale Labels wie `user_id` oder `prompt_id` (tausende Werte) multiplizieren sich mit den übrigen Labels und sprengen Speicher und Ingestion — die „Cardinality Bomb“. Solche per-Request-Details gehören in Traces/Logs, nicht in Metrik-Labels.

> **Merksatz:** Signal zum Store passend wählen: **niedrige** Kardinalität → Metrik (aggregieren & alarmieren), **hohe** Kardinalität → Trace/Log (auf Abruf durchsuchen). Hardware löst unbeschränkte Kardinalität nicht — sie wächst multiplikativ.

### Zusammenfassung — gleich entscheidest du

Du kennst jetzt die Achsen, ein LLM-System sichtbar zu machen: **Telemetrie-Umfang**, **Tracing & Spans**, **Trace-Sampling**, **Laufzeit-Provenienz**, **Feedback-Signale** und die **Metrik-vs-Trace-vs-Log**-Entscheidung mit ihrer Kardinalitäts-Falle.

> **Gleich im Check:** In den nächsten sechs Entscheidungen wählst du für konkrete Ops-Szenarien selbst — und siehst pro Option, **warum** sie trägt oder aus welchem benannten Grund sie kippt.

## Quellen

- OpenTelemetry — Concepts: Traces, Spans and Context Propagation (offizielle Dokumentation)
- OpenTelemetry — Semantic Conventions for Generative AI Systems (gen_ai.* Attribute)
- OpenTelemetry — Sampling: Head-based vs. Tail-based (offizielle Dokumentation)
- Prometheus — Metric and Label Naming Best Practices (Kardinalität: jede Label-Kombination ist eine neue Zeitreihe)
- Cindy Sridharan — Distributed Systems Observability (O'Reilly, 2018)
- Google SRE Book — Monitoring Distributed Systems
- Joachims et al. — Accurately Interpreting Clickthrough Data as Implicit Feedback (SIGIR 2005)
- OpenTelemetry — Semantic Conventions for Generative AI Systems (gen_ai.* Attribute pro Request)
- OpenTelemetry Blog — Tail Sampling: why it is useful, how to do it, what to consider
- Sculley et al. — Hidden Technical Debt in Machine Learning Systems (NeurIPS 2015; Configuration Debt, Reproduzierbarkeit)
- OpenTelemetry — Semantic Conventions for Generative AI Systems (Modell-/Request-Attribute auf Spans)
- Hu, Koren, Volinsky — Collaborative Filtering for Implicit Feedback Datasets (ICDM 2008)
- Prometheus — Metric and Label Naming Best Practices (jede Label-Kombination ist eine neue Zeitreihe; keine unbeschränkten Label-Werte wie User-IDs)
- Cindy Sridharan — Distributed Systems Observability (O'Reilly, 2018; Metrics vs. Traces vs. Logs)
