![LLM-Logging-Best-Practices: 9 Regeln, die wir in der Produktion befolgen [2026]](/_next/image?url=https%3A%2F%2Fmedia.techsy.io%2Ftechsy-io%2Fhero-510-1200x630.webp&w=3840&q=75)
LLM-Logging-Best-Practices: 9 Regeln, die wir in der Produktion befolgen [2026]
Diese neun LLM-Logging-Best-Practices sind die Regeln, nach denen unser Produktions-Stack tatsächlich läuft: Wir loggen 1,2 Millionen LLM-Requests pro Monat über vier Services, und jeder einzelne landet als eine einzige JSON-Zeile mit model, tokens, latency, cost_usd und trace_id in Grafana Loki. structlog 25.4.0 schreibt den Datensatz, Presidio entfernt vorher die PII, und die gesamte Pipeline ist die Logging-Hälfte unseres Observability-Stacks.
Die wichtigsten Punkte
- Loggen Sie jeden LLM-Request als strukturiertes JSON mit 14+ benannten Feldern, niemals als Freitext.
- Maskieren Sie PII vor dem Schreiben des Logs mit Presidio oder einem vergleichbaren Tool, nicht danach.
- Hängen Sie OpenTelemetry-GenAI-Semantic-Convention-Attribute an jeden Trace.
- Bei 1 Million Requests pro Tag kosten dieselben 60 GB 108 $/Monat in Datadog, 30 $ in Loki und 1,20 $ in ClickHouse.
Was LLM-Logging wirklich bedeutet (und warum „einfach alles loggen" scheitert)
LLM-Logging bedeutet, von jedem Modell-Request und jeder Antwort einen strukturierten Datensatz zu erfassen: den Prompt, die Completion, Token-Zahlen, Latenz, Kosten und den Trace, der alles mit einer Nutzersitzung verknüpft. Es ist kein Infrastruktur-Logging. CPU, Speicher und Pod-Restarts gehören in Ihren Metrics-Stack; dieser Beitrag behandelt nur den Request-Level-Datensatz, mit dem Sie Modellverhalten debuggen, bepreisen und prüfen können.
Der Instinkt „einfach alles loggen" ist schwer auszutreiben, und er ist teuer. Volle Prompts und Completions erzeugen bei 1 Million Requests pro Tag rund 60 GB Text pro Monat, und ein Teil dieses Textes sind Kunden-PII, die Sie nun unbefristet speichern. Das Datenminimierungs-Prinzip aus Artikel 5 DSGVO verlangt, dass personenbezogene Daten „dem Zweck angemessen und erheblich sowie auf das notwendige Maß beschränkt" sind, und ein roher Prompt-Dump fällt am ersten Tag durch diesen Test. Alles zu loggen ist keine Strategie; es ist ein Haftungsrisiko mit monatlicher Rechnung.
Was sind die 9 LLM-Logging-Regeln?
Neun Regeln, in der Reihenfolge, in der wir sie umsetzen würden: vollständige Prompts und Antworten mit gehashten Identifiern loggen, strukturiertes JSON ausgeben, Tokens und Kosten pro Request erfassen, OpenTelemetry-Trace-Kontext anhängen, PII vor dem Schreiben maskieren, bei hohem Volumen sampeln, Aufbewahrungsstufen festlegen, Safety-Events separieren und das Ergebnis abfragbar machen. Zu jeder Regel gibt es unten den Code oder die Tabelle, die sie durchsetzt.
Regel 1: Den vollständigen Prompt und die Antwort loggen (mit Hashes, nicht mit rohen PII)
Loggen Sie den kompletten Prompt und die komplette Completion für jeden Request, denn Teil-Logs sind der Grund, warum man am Ende vor einem Vorfall steht, ohne zu wissen, was das Modell tatsächlich gesehen hat. Die eine Ausnahme ist die Identität: Schreiben Sie niemals rohe Nutzer-IDs, E-Mails oder Namen in den Datensatz. Speichern Sie stattdessen einen SHA-256-Hash der Nutzer-ID. Ein Hash lässt Sie die vollständige Sitzungshistorie eines Nutzers per Offline-Lookup rekonstruieren, während die Logzeile selbst für jeden, der sie nicht lesen darf, wertlos bleibt. Dieselbe Logik gilt für System-Prompts: hashen, den Hash loggen und den Klartext in Ihrer Prompt-Registry behalten, wo er bereits versioniert ist.
Regel 2: Strukturiertes JSON verwenden: jedes Feld benannt, nichts als Freitext
Für LLM-Logging-Best-Practices in Python oder jeder anderen Sprache ist strukturiertes Logging in JSON die nicht verhandelbare Regel: jedes Feld benannt, typisiert und abfragbar, nichts als formatierter String abgelegt. Eine Freitextzeile wie INFO called gpt-4o, took 812ms lässt sich nur greppen. Ein JSON-Datensatz lässt sich nach Modell aggregieren, nach Kosten summieren und mit einem Trace verknüpfen. OpenAIs eigene Production Best Practices verfolgen dieselbe Idee: strukturierte Metadaten auf SDK-Ebene erfassen statt mit print-Anweisungen.
Hier ist das Schema, das jeder Techsy-Service ausgibt, vierzehn Felder:
{
"request_id": "req_01J9XK4M7Q",
"timestamp": "2026-07-18T09:24:31.482Z",
"environment": "production",
"model": "claude-sonnet-4-20250514",
"prompt_tokens": 1284,
"completion_tokens": 396,
"latency_ms": 812,
"cost_usd": 0.0098,
"system_prompt_hash": "sha256:9f2c1a4e...",
"user_id_hash": "sha256:b7e4d831...",
"rag_sources": ["kb/pricing-2026.md", "kb/refund-policy.md"],
"guardrail_result": "pass",
"trace_id": "4bf92f3577b34da6a3ce929d0e0e4736",
"span_id": "00f067aa0ba902b7"
}Drei Felder verdienen eine Anmerkung. cost_usd wird zur Request-Zeit aus den Token-Zahlen und dem veröffentlichten Preis des Modells berechnet, niemals nachträglich durch einen nächtlichen Job. Die beiden Hash-Felder sind der Kompromiss aus Regel 1: offline korrelierbar, im Log undurchsichtig. Und trace_id und span_id sind W3C-Trace-Context-Werte, genau darum geht es in Regel 4.
Wenn vier Services, die Provider direkt aufrufen, nach vier Stellen für Instrumentierung klingen: Ein LiteLLM-Proxy zentralisiert das, mit einem Logging-Hook vor jedem Provider.
Regel 3: Token-Zahlen und Kosten pro Request erfassen
Token-Verbrauchs-Tracking gehört in die Logzeile selbst, nicht in einen Warehouse-Job, der morgen läuft. Jeder Provider liefert Input- und Output-Token-Zahlen in der Antwort; multiplizieren Sie sie genau in diesem Moment mit dem Token-Preis des Modells und schreiben Sie cost_usd in den Datensatz. Preise ändern sich und unterscheiden sich für gecachte und frische Input-Tokens, daher schreibt eine nachträgliche Berechnung mit einer statischen Preistabelle die Historie stillschweigend um. Mit Kosten in jeder Zeile wird „Welches Feature ist teuer?" zu einer Ein-Zeilen-Abfrage statt zu einem Finanzprojekt, und es fließt direkt in die Arbeit ein, Ihre LLM-API-Kosten zu senken.
Regel 4: Trace-Kontext anhängen (OpenTelemetry GenAI Semconv)
Eine Logzeile ohne Trace-ID ist ein Waisenkind: Sie können sie lesen, aber nicht erkennen, welcher Retry, welcher RAG-Schritt oder welcher Nutzer-Turn sie erzeugt hat. Die Lösung sind OpenTelemetries GenAI Semantic Conventions, die Standard-Attributnamen für die Instrumentierung von Modellaufrufen. Geben Sie den Log innerhalb eines aktiven Spans aus, hängen sich trace_id und span_id von selbst an, sodass ein Klick in Grafana Sie vom Trace-Wasserfall direkt zum Rohdatensatz führt.
Die Attribute, die sich auf jedem gen_ai-Span lohnen:
| Attribut | Typ | Beispiel | Zweck |
|---|---|---|---|
| gen_ai.system | string | "anthropic" | Name des Providers |
| gen_ai.request.model | string | "claude-sonnet-4-20250514" | Angefragtes Modell |
| gen_ai.response.model | string | "claude-sonnet-4-20250514" | Modell, das tatsächlich geantwortet hat |
| gen_ai.usage.input_tokens | int | 1284 | Größe des Prompts |
| gen_ai.usage.output_tokens | int | 396 | Größe der Completion |
| gen_ai.response.finish_reasons | string[] | ["stop"] | Warum die Generierung endete |
| gen_ai.response.id | string | "msg_01XK9..." | Antwort-ID des Providers |
from opentelemetry import trace
tracer = trace.get_tracer("ai-sdr")
with tracer.start_as_current_span("chat.completion") as span:
span.set_attribute("gen_ai.system", "anthropic")
span.set_attribute("gen_ai.request.model", "claude-sonnet-4-20250514")
response = client.messages.create(**payload)
span.set_attribute("gen_ai.usage.input_tokens", response.usage.input_tokens)
span.set_attribute("gen_ai.usage.output_tokens", response.usage.output_tokens)
span.set_attribute("gen_ai.response.finish_reasons", [response.stop_reason])
log.info("llm.request", cost_usd=cost) # Rule 2 record, trace IDs auto-attachedRegel 5: PII vor dem Schreiben des Logs maskieren
PII-Maskierung muss passieren, bevor der Datensatz geschrieben wird, nicht als nachträgliche Bereinigung. Sobald eine E-Mail-Adresse in Loki ist, ist sie auch in Ihren Objekt-Storage-Backups, und „wir haben sie später gelöscht" ist keine DSGVO-Antwort. In unserem Setup läuft Microsoft Presidio als structlog-Prozessor und fängt 94 % der E-Mails und Telefonnummern ab, bevor sie Loki erreichen; die Durchrutscher sind fast immer ungewöhnliche Formatierungen, die wir in eigene Recognizer überführen, sobald wir sie finden.
Der gesamte Hook ist fünfzehn Zeilen lang:
from presidio_analyzer import AnalyzerEngine
from presidio_anonymizer import AnonymizerEngine
analyzer = AnalyzerEngine()
anonymizer = AnonymizerEngine()
PII_ENTITIES = ["PERSON", "EMAIL_ADDRESS", "PHONE_NUMBER", "CREDIT_CARD", "IBAN_CODE"]
def redact_pii(text: str) -> str:
results = analyzer.analyze(text=text, language="en", entities=PII_ENTITIES)
return anonymizer.anonymize(text=text, analyzer_results=results).text
# In the structlog processor chain, before JSONRenderer:
# event_dict["prompt"] = redact_pii(event_dict["prompt"])Die Maskierung sitzt in derselben Pipeline-Schicht wie Ihre Input- und Output-Filter und sollte genauso getestet werden. Unsere Guardrail-Pipeline behandelt eine geleakte E-Mail in einem Log als fehlgeschlagenen Eval, nicht als Ops-Fußnote.
Regel 6: Bei hohem Volumen intelligent sampeln
Unterhalb von etwa 100.000 Requests pro Tag loggen Sie alles. Darüber ist Voll-Logging eine Speichersteuer auf Daten, die Sie nie lesen werden, und Sampling ist der Weg, die Datensätze zu behalten, die zählen. Der Haken: Zufalls-Sampling ist die schlechteste Option für LLM-Traffic, denn Fehler, Refusals und Fünf-Dollar-Requests sind per Definition selten, also verwirft eine uniforme 10-%-Rate genau die Events, die Sie debuggen. Sampeln Sie nach Ergebnis, nicht nach Münzwurf.
| Strategie | Wann einsetzen | Komplexität |
|---|---|---|
| Zufall (fixe 10 %) | Basis-Volumenmetriken bei stabilem Traffic | Niedrig |
| Regelbasiert | Bestimmte Modelle, Mandanten oder Routen immer behalten | Niedrig |
| Tail-basiert | Langsame, teure oder fehlgeschlagene Requests behalten; normale verwerfen | Mittel |
| Trigger-basiert | Voller Kontext nur, wenn ein Guardrail auslöst oder ein Eval fehlschlägt | Mittel |
| Adaptiv | Sampling-Rate steigt und fällt mit dem Traffic-Volumen | Hoch |
Ein übliches Setup ist regelbasiert an den Rändern (Produktion und Enterprise-Mandanten: immer loggen) plus tail-basiert in der Mitte. Der Logging-spezifische Blick auf dieses Framework: Ihre Felder guardrail_result und cost_usd sind die Sampling-Signale, bereits vorhanden, wenn Sie Regel 2 und 8 befolgt haben.
Regel 7: Eine Aufbewahrungsrichtlinie festlegen, bevor Sie eine brauchen
Eine Log-Aufbewahrungsrichtlinie ist eine Entscheidung, die man in ruhigen Zeiten trifft, denn die Alternative ist, sie während eines Kosten-Reviews beim doppelten Volumen zu treffen. Das Speicherbegrenzungs-Prinzip aus Artikel 5 DSGVO sagt, dass personenbezogene Daten „nicht länger als erforderlich" aufbewahrt werden sollen, was in der Praxis gestufte Aufbewahrung bedeutet:
| Stufe | Aufbewahrung | Speicher | Anwendungsfall |
|---|---|---|---|
| Hot | 7 Tage | Loki / ClickHouse, lokale Festplatte | Live-Debugging, On-Call-Abfragen |
| Warm | 30 Tage | Objekt-Storage-gestützter Index (S3) | Sprint-Kostenanalyse, Vorfalls-Review |
| Cold | 1 Jahr | Komprimiertes S3/GCS-Archiv | Compliance-Anfragen, Jahresaudits |
Hot beantwortet „Was ist vor zehn Minuten passiert?" schnell und teuer; Cold beantwortet „Was haben wir diesem Kunden im März gesagt?" langsam und günstig. Löschen Sie planmäßig und automatisch, sonst sind die Stufen nur ein Diagramm.
Regel 8: Guardrail- und Safety-Events separat loggen
Safety-Events (Guardrail-Blocks, Refusals, Richtlinienverstöße) sind keine Telemetrie; sie sind Audit-Datensätze und gehören in einen eigenen Stream. Drei Gründe. Alarmierung: Ein Anstieg blockierter Prompt-Injections sollte jemanden pagern, und diesen Alarm können Sie nicht gegen 1 Million Routinezeilen kalibrieren. Aufbewahrung: Compliance kann verlangen, dass Safety-Datensätze Debug-Logs um Jahre überleben. Zugriff: Auditoren bekommen den Safety-Stream, nicht Ihren gesamten Firehose. Markieren Sie das Urteil im Hauptdatensatz (guardrail_result: "block") und routen Sie den vollständigen Datensatz in den separaten Stream. Was als Safety-Event zählt, behandelt unser Guide zu Guardrail-Events.
Regel 9: Logs abfragbar machen, nicht nur speichern
Ein Log, das Sie nicht in unter einer Minute abfragen können, ist ein Backup, kein Observability-Signal. Abfragbar heißt: indizierte Felder, eine Abfragesprache, die Ihr On-Call tatsächlich beherrscht, und Dashboards, die vor dem Vorfall gebaut sind. Wir betreiben Loki und fragen es über 30 Mal pro Woche ab, nach Kosten-Anomalien, Latenz-Regressionen und „Zeig mir jede Refusal für Mandant X gestern." Die Grafana-Loki-Docs sind die Referenz für die Syntax; das Muster, das sich bezahlt macht, ist das Filtern direkt auf geparsten JSON-Feldern:
{service="ai-sdr"} |= "llm.request" | json
| model = "claude-sonnet-4-20250514"
| cost_usd > 0.05
| line_format "{{.timestamp}} {{.request_id}} ${{.cost_usd}} {{.latency_ms}}ms"Fünf Zeilen, kein Export in ein Notebook. Wenn Ihr aktueller Speicher das nicht kann, ist er das Problem, das Sie zuerst lösen sollten.
Was wir in der Produktion tatsächlich loggen
Genug Theorie. Hier ist die geschwärzte Konfiguration aus unserer AI-SDR-Pipeline, dem Service hinter der Zahl von 1,2 Millionen Requests pro Monat aus der Einleitung. Sie läuft mit structlog 25.4.0, das JSON rendert, und wird über Promtail an Grafana Cloud Loki geliefert. Das Modell in dieser Pipeline ist claude-sonnet-4-20250514, und jeder Aufruf durchläuft exakt die Prozessor-Kette aus Regel 2 und 5:
import structlog
structlog.configure(
processors=[
structlog.contextvars.merge_contextvars,
structlog.processors.add_log_level,
structlog.processors.TimeStamper(fmt="iso"),
redact_pii, # Rule 5: Presidio, before serialization
add_otel_trace_ids, # Rule 4: trace_id + span_id from the active span
structlog.processors.JSONRenderer(),
],
)
log = structlog.get_logger()Zwei Zahlen aus dem ersten Quartal mit diesem Setup. Der monatliche Ingest pendelte sich bei 47 GB über vier Services ein, und die p95-Log-Schreiblatenz liegt bei 3 ms, was heißt, dass die Pipeline der Request-Zeit nichts Messbares hinzufügt.
Die Konfigurationsänderung, die sich selbst bezahlt hat: Wir haben im März 2026 cost_usd zu jedem Log-Eintrag hinzugefügt. Innerhalb einer Woche fanden wir ein Prompt-Template, das 340 $/Monat in Retry-Schleifen verbrannte. Ein kurzzeitiger API-Fehler löste drei Retries aus, von denen jeder den vollen 4.000-Token-Kontext erneut sendete. Die Logs machten daraus eine Ein-Zeilen-Abfrage; ohne Kosten pro Request wäre es als ungeklärter Posten im nächsten Quartals-Budget-Review aufgetaucht.
Was kostet LLM-Log-Speicher im großen Maßstab?
Bei 1 Million Requests pro Tag kostet LLM-Log-Speicher für dieselben Daten je nach Speicher grob zwischen 1,20 $ und 108 $ pro Monat. Die Rechnung: Ein vollständiger strukturierter Datensatz ist im Schnitt etwa 2 KB groß, also sind 1 Million Requests pro Tag 2 GB pro Tag oder 60 GB pro Monat. Die unten stehenden, von den Anbietern veröffentlichten Preise (Juli 2026) zeigen, was diese 60 GB in drei gängigen Backends kosten.
| Backend | Preismodell (Anbieterangabe, Juli 2026) | 60 GB/Monat | Anmerkungen |
|---|---|---|---|
| Datadog LLM Observability | 0,10 $/GB Ingest + 1,70 $/GB Indexierung | ~108 $ | Indexierung ist der teure Posten |
| Grafana Cloud Loki | ~0,50 $/GB über Objekt-Storage | ~30 $ | Self-hosted noch günstiger |
| ClickHouse (self-hosted, S3) | ~0,02 $/GB komprimierter Speicher | ~1,20 $ + Compute | Compute sind die eigentlichen Kosten |
Quellen: Datadog-Preise, Grafana Loki und die ClickHouse-Observability-Docs.
Zwei Einschränkungen, denn das ist unsere Berechnung aus Anbieterpreisen, kein Benchmark, den wir durchgeführt haben. Erstens setzt die Datadog-Zahl voraus, dass Sie alles indexieren; die meisten Teams indexieren eine Teilmenge und zahlen deutlich weniger, während Loki und ClickHouse vor allem für das berechnen, was Sie speichern. Zweitens verbergen die 1,20 $ von self-hosted ClickHouse eine echte Rechnung: die Compute-Kosten für den Cluster und die Ingenieursstunden für den Betrieb. Bei 60 GB pro Monat ist ein Managed Service fast immer die günstigere Gesamtlösung. Self-Hosting lohnt sich ab grob 1 TB pro Monat, wo die Pro-GB-Lücke den Ops-Overhead überwiegt.
Die Spannbreite ist die Aussage. Bei 1 Million Requests pro Tag beträgt die Lücke zwischen Datadog-indexiert und self-hosted ClickHouse grob das 90-Fache: 108 $ gegenüber 1,20 $ für dieselben 60 GB. Wählen Sie den Speicher zur Architekturzeit, nicht nachdem die Rechnung kommt.
Welches Logging-Tool sollten Sie wählen?
Für die meisten Teams läuft die Wahl auf vier Optionen hinaus: eine LLM-native Plattform (Langfuse oder LangSmith), ein Proxy-Layer-Tool (Helicone) oder eine schlichte OpenTelemetry-Pipeline in Infrastruktur, die Sie bereits betreiben. Die Tabelle deckt die Entscheidungspunkte ab, die sich tatsächlich unterscheiden; Dashboards, Playback und Prompt-Versionierung sind in allen vier selbstverständlich.
| Langfuse | LangSmith | Helicone | OTel-nativ (Loki/ClickHouse) | |
|---|---|---|---|---|
| Self-hostbar | Ja (Open-Source-Kern) | Nein (SaaS) | Ja (Open Source) | Vollständig |
| OTel-kompatibel | Ja (OTLP-Ingest) | Teilweise (OTLP-Export) | Teilweise | Nativ |
| Kosten-Tracking | Ja | Ja | Ja | DIY (cost_usd selbst berechnen) |
| Eingebaute PII-Maskierung | Nein (Vorverarbeitung) | Nein | Nein | Nein (Presidio, nach Regel 5) |
| Kostenloser Tarif | Ja (Cloud + Self-Host) | Ja (limitiert) | Ja | Kostenlose Software; Infrastruktur zahlen Sie |
Unsere Meinung, offen gesagt: Wir fahren OTel-nativ plus Loki, weil wir den Grafana-Stack bereits für alles andere hatten und eine weitere Datenquelle hinzuzufügen besser war als einen vierten Anbieter einzuführen. Wenn Sie bei null anfangen, ganz ohne Observability-Stack, sind Langfuses Tracing-Modell und der kostenlose Tarif der schnellste Weg zu brauchbaren Ergebnissen, und die Self-Host-Option hält die Exit-Tür offen. Wenn Sie zwischen den beiden LLM-nativen Marktführern wählen, fährt unser Langfuse-vs.-LangSmith-Vergleich den vollständigen Vergleich auf. Und wenn Logging ein Teil einer größeren Monitoring-Entscheidung ist, deckt der vollständige Plattform-Vergleich das breitere Feld ab.
Was sind die häufigsten LLM-Logging-Fehler?
Sechs Fehler machen den Großteil der kaputten LLM-Logging-Setups aus, die wir gesehen haben. Jeder davon ist billig zu vermeiden, wenn Sie ihn erwischen, bevor das Log-Volumen es tut:
- Rohe PII ohne Maskierung loggen. Der häufigste und der teuerste Fehler. Ein Support-Export oder ein geleakter Bucket macht aus Prompt-Logs einen Datenschutzvorfall. Maskieren Sie vor dem Schreiben (Regel 5), nicht beim Lesen.
- Keine Aufbewahrungsrichtlinie. Unbegrenzte Speicherung ist überall der Standard, und sie verdoppelt still Ihre Rechnung jedes Jahr. Wenn Sie nie löschen, haben Sie kein Logging-System; Sie haben ein Archiv mit Größenwahn.
- Unstrukturierte Text-Logs. Print-Output, den Sie nur greppen können, funktioniert im Demo-Maßstab und bricht bei 100.000 Requests pro Tag zusammen, wenn „Finde jeden fehlgeschlagenen Request für Modell X" zu einem Shell-Skript-Nachmittag statt zu einer Abfrage wird.
- Nur Fehler loggen. Erfolgreiche Requests sind die Baseline, gegen die Sie Drift erkennen, und sie sind das Rohmaterial Ihrer Evaluierungspipeline. Loggen Sie auch die Erfolge, notfalls gesampelt, wenn das Volumen es erzwingt.
- Kostenfelder ignorieren. Kein cost_usd pro Request heißt keine Kosten-Alerts, keine Feature-Zuordnung, und die 340-$/Monat-Retry-Schleife aus dem Produktionsabschnitt oben bleibt unsichtbar bis zur Quartalsrechnung.
- Keine Trace-Korrelation. Logs ohne Verbindung zu Spans machen Multi-Step-Agenten-Debugging zum Ratespiel. Wenn Ihrer Logzeile eine trace_id fehlt, ist Regel 4 die Lösung.
Über den Autor
Mert Batur ist Co-Founder von Techsy.io, wo das Team KI-Agenten, Automatisierungssysteme und Voice-/SDR-Pipelines für B2B-Kunden baut. Er schreibt über den LLM-Tooling-Stack, den das Techsy-Team tatsächlich in der Produktion einsetzt. Vernetzen Sie sich auf LinkedIn.
Häufig gestellte Fragen
Was sollten Sie für jeden LLM-Request loggen?
Mindestens: den vollständigen Prompt und die Completion mit maskierten PII, den Modellnamen, Input- und Output-Token-Zahlen, Latenz, Kosten in USD, einen gehashten Nutzer-Identifier sowie die OpenTelemetry-Trace- und Span-IDs. Ergänzen Sie RAG-Quell-IDs und das Guardrail-Urteil, wenn Ihre Pipeline diese Stufen hat. Vierzehn benannte Felder, eine JSON-Zeile pro Request.
Was ist das beste Format für LLM-Logs?
Strukturiertes JSON, ein Objekt pro Request, mit jedem Feld explizit benannt. Freitext-Logs lassen sich nur greppen; JSON-Datensätze lassen sich nach Modell aggregieren, nach Kosten summieren und mit Traces verknüpfen. Geben Sie den Datensatz mit einem strukturierten Logger wie structlog in Python oder pino in Node aus und rendern Sie ihn mit einem JSON-Serializer, niemals mit String-Formatierung.
Wie gehen Sie mit PII in LLM-Logs um?
Maskieren Sie vor dem Schreiben des Logs, nicht danach. Führen Sie Prompt und Completion durch einen Detektor wie Microsoft Presidio innerhalb Ihrer Logging-Pipeline und ersetzen Sie Namen, E-Mails und Telefonnummern durch Tokens wie <EMAIL_ADDRESS>. Sobald rohe PII Ihren Log-Speicher erreichen, sind sie auch in Ihren Backups, und nachträgliches Löschen besteht den DSGVO-Minimierungstest selten.
Was kostet LLM-Log-Speicher im großen Maßstab?
Für 1 Million Requests pro Tag, etwa 60 GB pro Monat bei 2 KB pro Datensatz, rechnen Sie mit grob 108 $/Monat nach Datadogs indexiertem LLM-Observability-Preis, 30 $/Monat bei Grafana Cloud Loki oder etwa 1,20 $/Monat für komprimierten S3-Speicher bei self-hosted ClickHouse plus Compute. Das sind die von den Anbietern veröffentlichten Preise Stand Juli 2026; Self-Hosting addiert Ingenieurszeit obendrauf.
Was sind OpenTelemetry GenAI Semantic Conventions?
Das sind OpenTelemetries Standard-Attributnamen für die Instrumentierung von LLM-Aufrufen: gen_ai.system für den Provider, gen_ai.request.model für das Modell, gen_ai.usage.input_tokens und output_tokens für die Token-Zahlen und gen_ai.response.finish_reasons dafür, warum die Generierung endete. Wer sie nutzt, dessen Traces liest jedes OTel-kompatible Backend, von Jaeger über Tempo bis Langfuse, ohne eigene Parser.
Wie sampelt man LLM-Logs bei hohem Traffic?
Behalten Sie jeden Fehler, jeden Guardrail-Block und jeden Request oberhalb einer Kostenschwelle, dann sampeln Sie den Rest. Dieser tail-basierte Ansatz bewahrt die seltenen Events, die Sie tatsächlich debuggen, während uniformes Zufalls-Sampling sie mit derselben Rate verwirft wie langweiligen Traffic. Unter 100.000 Requests pro Tag lassen Sie Sampling ganz weg und loggen alles.
Wie lange sollten Sie LLM-Logs aufbewahren?
Stufen Sie es: 7 Tage hot für Live-Debugging, 30 Tage warm für Vorfalls-Review und Kostenanalyse und bis zu 1 Jahr cold in komprimiertem Objekt-Storage für Compliance und Audits. Das Speicherbegrenzungs-Prinzip der DSGVO verbietet, personenbezogene Daten länger als erforderlich aufzubewahren, also koppeln Sie jede Stufe mit automatischem Löschen statt mit manuellem Aufräumen.
Was ist der Unterschied zwischen LLM-Logging und LLM-Tracing?
Ein Log ist ein flacher Datensatz eines Events: Dieser Request ist passiert, mit diesen Feldern. Ein Trace ist ein kausaler Baum aus Spans über einen ganzen Request-Pfad, etwa Retrieval, dann der Modellaufruf, dann zwei Tool-Aufrufe. Logs sagen Ihnen was; Traces sagen Ihnen wo und warum. Produktions-Setups geben beides aus, verknüpft über die trace_id.
Fazit
Zusammenfassung: Loggen Sie jeden Request als JSON mit benannten Feldern, berechnen Sie Kosten zur Request-Zeit, hängen Sie OTel-Trace-Kontext an, maskieren Sie PII vor dem Schreiben, sampeln Sie nach Ergebnis, sobald Sie 100.000 Requests pro Tag überschreiten, und wählen Sie einen Speicher, den Sie tatsächlich abfragen können. Die neun Regeln sind so geordnet, dass Sie eine pro Sprint einführen können, und Regel 2, 4 und 5 sind die drei, die sich am schnellsten auszahlen. Wenn Sie den breiteren Monitoring-Stack um die Logs herum wählen, starten Sie mit unserer Übersicht der besten KI-Observability-Plattformen. Und wenn Sie Hilfe beim Aufbau von strukturiertem Logging für Ihren LLM-Stack brauchen, sichern Sie sich eine kostenlose Beratung.