Production-Agents brauchen Runtime-Scorer, nicht nur Pre-Ship-Evals
Production-Agents brauchen Runtime-Scorer, nicht nur Pre-Ship-Evals
Du hast den Agent geshippt. Die CI-Suite war grün. Eine Woche später paste jemand ein echtes User-Transkript in Slack, und es ist auf eine Weise falsch, die keiner deiner Testfälle vorhergesagt hat. Das ist die Prototype-to-Production-Klippe, und sie wird nicht gelöst, indem du mehr Zeilen zur Pre-Ship-Suite hinzufügst. Die Suite, die das fängt, muss innerhalb des Request-Pfades leben, echten Traffic samplen, Scores zurück in Traces schreiben und Rollouts gaten, bevor Nutzer die Regression spüren.
Kernaussagen
- Pre-Ship-Eval-Suites frieren eine Verteilung ein; Production-Traffic driftet innerhalb von Tagen nach Launch von dieser Verteilung weg.
- Runtime Evals sind ein eigenes Artefakt: Online-Scorer, Shadow-Traffic und Regression-Gates, verdrahtet in den Deploy-Pfad.
- Ein LLM-Judge, der schwächer ist als das Modell, das er bewertet, produziert selbstbewusstes Rauschen und dekoriert Regressionen, statt sie zu fangen.
- Observability antwortet auf "lief es"; Runtime Evals antworten auf "war es richtig"; das zu verwechseln ist der teuerste Fehler im Stack.
- Ein 1-Prozent-Haiku-Judge-Sample auf einer Million Traces pro Monat kostet nahe 1.000 USD: keine wirtschaftliche Ausrede, blind zu shippen.
In diesem Artikel
- Die Prototype-to-Production-Klippe in Klartext
- Warum die CI-Suite in dem Moment aufhört zu funktionieren, in dem Nutzer eintreffen
- Was ein Runtime-Eval tatsächlich ist
- Das Vier-Oberflächen-Modell, auf das Production-Teams konvergieren
- Ein KMU-Stack, den der Plattform-Lead am Montag shippen kann
- Wo Runtime-Evals verlieren: Latenz, Kosten, Judge-Kalibrierung
- Regression-Gates in den Deploy-Pfad verdrahten, nicht in den PR-Pfad
- Das BRK241-Walkthrough als einen Datenpunkt nachspielen
- Was ich zuerst bauen würde
Die Prototype-to-Production-Klippe in Klartext
Vor dem Deploy kontrollierst du die Inputs. Du hast die Testfälle geschrieben. Du hast die Prompts gewählt. Der Agent läuft gegen eine gefrorene Verteilung und eine gefrorene Rubrik, und ein grüner CI-Build heißt, dass der Agent den Test besteht, den du dir vorgestellt hast.
Nach dem Deploy kontrollierst du die Inputs nicht. Echte Nutzer fragen Dinge, die deine Test-Bank nie antizipiert hat. Der Retrieval-Korpus driftet, während Dokumente sich ändern. Der Vendor patcht das Modell hinter der API, und deine Prompts antworten über Nacht anders. Die Failure-Verteilung verschiebt sich schneller, als eine statische Test-Suite enkodieren kann, und die ausgelieferte Test-Suite scort jetzt einen Agent, zu dem sie nicht mehr passt.
Der Fix ist nicht "schreib mehr Tests". Der Fix ist ein zweites Artefakt, das in Production läuft: Scorer, die Live-Traces lesen, sie auf derselben Rubrik wie deine CI-Suite bewerten und Drift sichtbar machen, bevor das nächste Release rausgeht. Das ist, was ich mit Runtime Evals meine. Mein Schwesterbeitrag Models depreciate, eval suites compound deckte die Pre-Ship-Hälfte dieses Vertrags ab: wie man die Bank baut, den Judge kalibriert und die CI-Suite lauffähig hält. Dieser Beitrag ist die Post-Ship-Hälfte, das andere Panel des Diptychons.
Warum die CI-Suite in dem Moment aufhört zu funktionieren, in dem Nutzer eintreffen
Eine CI-Suite ist ein Snapshot. Du hast 200 Inputs gewählt, die richtigen Antworten gelabelt, und die Suite sagt dir, ob der heutige Prompt den gestrigen Prompt gegen diesen Snapshot schlägt. Der Snapshot ist nur so lange ehrlich, wie Production-Traffic ihm ähnelt.
Drei Kräfte bewegen Production weg vom Snapshot:
- User-Drift. Echte Nutzer schreiben nicht so, wie PMs sich das vorstellen. Die Top-Failure-Modes nach einem Monat live sind fast immer Klassen von Inputs, für die du nie einen Test geschrieben hast.
- Korpus-Drift. RAG-Systeme retrieven aus einem Korpus, der von anderen Menschen aktualisiert wird. Derselbe Prompt gegen dasselbe Modell kann Antworten ändern, weil die zugrundeliegenden Dokumente sich geändert haben.
- Vendor-Drift. Frontier-Modell-Snapshots werden gepatcht. Derselbe API-Endpoint verhält sich Monat für Monat anders, manchmal still, manchmal in einer Release Note dokumentiert, die niemand im Team abonniert hat.
💡 Die Eval-Suite, die echte Drift fängt, ist aus echten Production-Failures gebaut, nicht aus Prompts, die ein PM sich letztes Quartal vorgestellt hat. Die CI-Bank altert in dem Moment aus, in dem Production beginnt, Failures zu emittieren, die die Bank nie gesehen hat.
Die Foundry-Concept-Seite zur Agent-Observability benennt die Production-Hälfte direkt: "Continuous evaluation: Quality and safety evaluation of production traffic at a sampled rate" und "Scheduled evaluation: Scheduled quality and safety evaluation using test datasets to detect system drift." Das sind zwei andere Oberflächen als CI. Siehe Microsofts Observability-Concept-Seite für die wortwörtliche Formulierung.
Was ein Runtime-Eval tatsächlich ist
Ein Runtime Eval ist ein Scorer, der gegen Live-Production-Traces läuft, auf einem gesampelten Subset, und den Score zurück in den Trace-Store schreibt, sodass du ihn so abfragen kannst wie Latenz und Token-Counts.
Drei konkrete Formen tauchen auf:
- Inline-Scorer. Der Judge läuft im Request-Pfad, blockt auf dem Score, und der Agent kann darauf verzweigen (Retry, an Mensch eskalieren, Fallback zurückgeben). Hoher Signalgehalt, hohe Kosten, nur auf kleinen Traffic-Anteilen sinnvoll.
- Async-Scorer. Der Trace geht in eine Queue, der Judge bewertet ihn, nachdem die User-Response gesendet ist, und der Score wird zurück in den Trace geschrieben. Der Nutzer sieht nichts Zusätzliches; das Team sieht Drift-Dashboards. Die meisten Teams sollten hier starten.
- Scheduled Re-Run. Ein Golden Set läuft auf einer Cron gegen das aktuelle Production-Modell und den aktuellen Prompt, und jede Regression jenseits eines Schwellenwerts paged den On-Call. Das ist die Production-Erweiterung deiner CI-Bank.
Das Async-Muster ist, was Langfuse Model-Based Evaluations und Braintrust Online Evals standardmäßig liefern. Beide lassen dich einen Judge-Prompt auf einen gesampelten Stream von Production-Traces zeigen und Scores zurückschreiben. CI-Vendor und Runtime-Vendor sind für die meisten Teams ins selbe Produkt kollabiert.
Montagszug: wähl einen Trace-Store (Langfuse oder Braintrust, falls du managed willst, Arize Phoenix, falls du MIT-lizenzierten Self-Host brauchst), aktiviere Trace-Export auf deinem Agent und schreib einen einzigen Judge-Prompt für den Failure Mode, der dich zuletzt in Production gebissen hat.
Das Vier-Oberflächen-Modell, auf das Production-Teams konvergieren
Ich habe genug Teams die Klippe überqueren sehen, um den Stack auf vier Oberflächen konvergieren zu sehen. Keine ersetzt die anderen.
- Offline- / CI-Evals. Inspect AI für das Agent-Execution-Harness, OpenAI Evals für das kanonische Task-Format, Promptfoo für adversariales Probing. Die Pre-Flight-Checkliste.
- Online-Evals. Gesampelter LLM-as-Judge auf Live-Traces. Langfuse, Braintrust, Arize Phoenix, LangSmith Online Evaluators, Humanloop. Die Cockpit-Instrumente.
- Observability. OpenTelemetry-Traces, Latenz, Token-Kosten, Error Rate. Sagt dir, dass der Agent lief. Sagt dir nicht, dass er richtig war.
- Drift-Detection. Scheduled Re-Runs des Golden Sets gegen den aktuellen Production-Stack. Fängt Vendor-Patches, bevor Nutzer sie fangen.
Observability mit Evals zu verwechseln ist der teuerste Einzelfehler, den ich Teams machen sehe. Ein sauberes Latenz-Dashboard mit einer 99-Prozent-Uptime-Zahl sagt dir nichts darüber, ob die Antworten gut waren. Der Trace-Store ist notwendig, nicht hinreichend.
Ein KMU-Stack, den der Plattform-Lead am Montag shippen kann
Konkretes Szenario, weil Abstraktionen einen Montagmorgen nicht überleben. Du bist Plattform-Lead in einer 90-Personen-SaaS-Bude. Du hast vor sechs Wochen einen Support-Triage-Agent geshippt. CI ist grün. Customer Success forwardet Screenshots falscher Antworten. Du hast kein Observability-Budget-Approval.
Hier ist der Stack, den ich vor dem Mittagessen aufstellen würde:
- Trace-Store. Self-Host Langfuse auf dem billigsten VPS, den du schon hast. Kostenlos, OSS, Langfuse Self-Host Docs decken docker-compose in unter einer Stunde ab.
- Judge-Modell. Claude Haiku 4.5 bei rund 0,001 USD pro Judge-Call bei typischen Eval-Prompt-Größen. Bei 1 Prozent Sampling auf einer Million Traces pro Monat landest du bei rund 1.000 USD Judge-Spend pro Monat, der KMU-Schwellenwert, über dem Sampling Pflicht wird.
- Golden Set. Ein 50-Zeilen-Google-Sheet. Der Plattform-Lead und ein Customer-Success-Mitarbeiter labeln Inputs und ideale Outputs aus den Transkripten des letzten Monats. Das ist das Regression-Set.
- CI-Gate. GitHub Actions, das Inspect AI gegen das 50-Zeilen-Set auf jedem PR fährt, der das Prompt-Verzeichnis berührt. Merge bei Regression über zwei Zeilen blocken.
- Drift-Cron. Ein nächtlicher GitHub-Actions-Cron lässt dasselbe 50-Zeilen-Set gegen den Live-Production-Stack laufen. Sinkt der Score um mehr als 5 Prozent gegen eine 7-Tage-Baseline, im Team-Slack posten.
Montags-Output: ein Slack-Kanal, der pingt, wenn der Agent regrediert. Messbares Outcome: Time-to-Detect einer Regression sinkt von "ein Customer-Success-Forward, Tage später" auf "morgen früh, vor dem Standup". Das ist die einzige Metrik, die für die erste Iteration zählt.
# Bootstrap the Monday stack
git clone https://github.com/langfuse/langfuse
cd langfuse && docker compose up -d # trace store, port 3000
# CI gate, .github/workflows/evals.yml
inspect eval golden_set.py --model anthropic/claude-haiku-4.5 \
--max-samples 50 --log-dir ./eval-logs
# Drift cron, runs at 02:00 UTC
0 2 * * * inspect eval golden_set.py \
--model anthropic/claude-haiku-4.5 \
--tags drift,prod \
--fail-on-error
Wo Runtime-Evals verlieren: Latenz, Kosten, Judge-Kalibrierung
Ich tue nicht so, als wären Runtime Evals gratis. Drei ehrliche Tradeoffs entscheiden, ob sie sich auf deinem Stack rechnen.
Latenz. Ein Inline-Judge addiert die volle Round-Trip-Zeit des Judge-Modells zu deinem nutzerseitigen Pfad. Auf einem Haiku-Class-Judge sind das ein paar hundert Millisekunden, auf einem Frontier-Judge können das mehrere Sekunden sein. Meine Faustregel: bei Sub-Second-SLAs oder Chat-Streaming sind Inline-Judges ein No-Go; Async-Scoring ist die einzig viable Form.
Kosten. Sampling fixt die Stückkosten, nicht die Audit-Kosten. Bei niedrigem QPS ist die Mathematik trivial. Die Zahl, die ich im Kopf behalte: über grob 10 QPS sustained mit einem Frontier-Class-Judge kann die Judge-Rechnung die Modell-Rechnung, die sie bewertet, übersteigen. Der Hebel ist die Sample-Rate, aber je niedriger du sampelst, desto länger dauert es, ein Drift-Event mit statistischer Konfidenz zu detektieren. Unter 100 gesampelten Traces pro Tag pro Failure Mode schluckt das Rauschniveau echtes Signal.
Judge-Kalibrierung. Ein LLM-Judge, der schwächer ist als das Modell, das er bewertet, produziert selbstbewusstes Rauschen. Hamel Husains Critique-Shadowing-Methodologie setzt die Latte beim Iterieren des Judge-Prompts, bis die Human-Judge-Übereinstimmung rund 90 Prozent erreicht. Das Position-Bias-Paper Judging the Judges: A Systematic Study of Position Bias in LLM-as-a-Judge dokumentiert, dass "position bias is not due to random chance and varies significantly across judges and tasks." Unterhalb der Modellparität dekoriert der Judge Regressionen, statt sie zu fangen, was schlimmer ist als kein Judge, weil es falsches Vertrauen weckt.
Die ehrliche Antwort: Runtime Evals zahlen sich nicht bei jedem QPS und jeder Marge zurück. Unterhalb von vielleicht 1 QPS und kleiner Nutzerbasis reicht ein täglicher Scheduled Re-Run des Golden Sets; du brauchst kein Online-Sampling. Darüber ist Async-Sampling die richtige Form, Inline ist für den einen kritischen Hop reserviert, an dem du es dir leisten kannst, auf dem Score zu verzweigen.
Regression-Gates in den Deploy-Pfad verdrahten, nicht in den PR-Pfad
Das CI-Eval-Gate blockt Pull Requests. Das Runtime-Regression-Gate blockt Rollouts. Das sind nicht dieselben Gates, und die meisten Teams shippen nur das erste.
Ein Rollout-Gate sieht so aus:
- Neuer Prompt oder Modell-Variante deployt zu einem Canary-Slice. Standard-SRE-Canary-Ramp: 1 Prozent, 5 Prozent, 25 Prozent, 100 Prozent.
- Bei jedem Ramp-Schritt sampeln Async-Scorer die Canary-Traces und die Baseline-Traces auf demselben Judge-Prompt.
- Sinkt der Mean Score der Canary um mehr als einen Schwellenwert (meiner startet bei 3 Prozent absolut, pro Oberfläche getunt), hält die Ramp und rollt automatisch zurück.
- Hält die Canary für die Ramp-Dwell-Time, geht der Promoter zum nächsten Ramp-Schritt.
# rollout-gate.yml
canary:
ramp: [1, 5, 25, 100]
dwell_per_step: 30m
gate:
scorer: haiku-4.5-judge-v3
sample_rate: 0.05
metric: mean_score
threshold_abs_drop: 0.03
baseline_window: 24h
on_fail: rollback
Das ist das Muster, auf das Microsofts Foundry Monitor Agents How-To mit Alerting und Continuous-Evaluation-Oberflächen zeigt, und das Muster, das Braintrust unter Online Evals dokumentiert. Die Form ist unabhängig vom Vendor; was sich unterscheidet, ist, ob das Rollout-Gate im selben Produkt wie der Trace-Store liegt oder eine Glue-Schicht, die du schreibst.
Montagszug: wähl die kleinste Oberfläche in deinem Agent-Stack (einen Tool-Call, einen Retrieval-Schritt) und setz einen gesampelten Scorer darauf, bevor du irgendetwas anderes instrumentierst. Du musst nicht den ganzen Agent am ersten Tag scoren, um zu lernen, ob das Gate-Konzept zu deinem Team passt.
Das BRK241-Walkthrough als einen Datenpunkt nachspielen
Die Microsoft Build BRK241-Session auf dem Microsoft Developer YouTube Channel ist ein bestätigender Datenpunkt für die These, kein Recap. Beim Nachspielen des BRK241-Walkthroughs ist der relevante Zug azd ai agent eval init, der ein Benchmark-Dataset aus historischen Production-Traces bootstrappt, wenn kein Golden Set existiert, und azd ai agent optimize, das eine automatisierte Schleife fährt, die Kandidaten-Varianten über System-Prompts, Tool-Beschreibungen, Skills und Target-Modelle hinweg rankt. Im Walkthrough hat der Optimizer einen 11-Prozent-Evaluator-Score-Gain auf einer voice-enabled Agent-Variante zutage gefördert, was das Framing des Talks motivierte.
Die Zahl selbst ist nicht der Punkt. Das Muster ist: derselbe Trace-Store, der dir Observability gibt, bootstrappt das Eval-Set, und das Eval-Set füttert den Optimizer. Der Runtime-Trace, der Runtime-Score und das Rollout-Gate sind eine geschlossene Schleife. Microsoft pitcht diese Schleife innerhalb von Foundry; dieselbe Schleife existiert innerhalb von Langfuse plus Inspect AI plus einem Custom-Rollout-Script, wenn dein Stack OSS ist. Der Vendor wechselt; die Schleife nicht.
Die Schwester-Build-Sessions sind zwei Skim-Links wert: BRK231 zu Reinforcement Learning für Production-Agents und BRK250 zu Open-Source-Observability über Frameworks hinweg. Zusammen triangulieren sie, wohin der Vendor-Konsens läuft: Runtime Evals plus Rollout-Gates plus geschlossene-Schleife-Tuning, keine statische CI-Suite.
Was ich zuerst bauen würde
Wenn ich in ein Team geworfen würde, das CI-Evals und null Runtime Evals hat, ist hier die Reihenfolge, in der ich bauen würde. Jeder Schritt hat ein messbares Outcome, bevor der nächste startet.
- Trace-Store. OpenTelemetry-Export vom Agent zu Langfuse oder Phoenix aktivieren. Outcome: jeder Production-Request ist per ID abfragbar mit vollen Inputs, Outputs, Latenz und Kosten. Zeit: ein halber Tag.
- Manueller Labeling-Sprint. Zwei Engineers verbringen zwei Tage damit, 100 Production-Traces für den Top-Failure-Mode zu labeln. Outcome: ein gelabeltes Set in Hamel Husains "100+ labeled examples"-Kalibrierungsboden.
- Judge-Prompt v1. Eine Rubrik für diesen Failure Mode schreiben. Gegen das gelabelte Set iterieren, bis Human-Judge-Übereinstimmung 90 Prozent überschreitet. Outcome: ein kalibrierter Judge, der wert ist, auf Live-Traffic gezeigt zu werden.
- Async-Runtime-Scoring. Den Judge auf 5 Prozent der Live-Traces laufen lassen. Scores zurück in den Trace-Store schreiben. Outcome: ein tägliches Drift-Dashboard für einen Failure Mode, end-to-end.
- Rollout-Gate. Denselben Judge in ein Canary-Rollout-Script verdrahten. Outcome: Prompts und Modellwechsel können nicht shippen, ohne die Score-Schwelle auf dem Canary-Slice zu halten.
- Scheduled Drift-Cron. Nächtlicher Re-Run des gelabelten Sets gegen das Live-Modell. Outcome: Vendor-Patches und Korpus-Drift werden am Morgen nach dem Vorfall gefangen.
Schritte 1 bis 3 sind das Fundament; das Team bewegt sich messbar von blind zu instrumentiert. Schritte 4 bis 6 sind die geschlossene Schleife; das Team bewegt sich messbar von instrumentiert zu selbstkorrigierend. Die ganze Sequenz passt in einen Zweiwochen-Sprint für ein Vier-Personen-Plattform-Team. Ich habe sie in drei Wochen mit einem Zweier-Team gefahren; der Kalibrierungsschritt ist der Teil, der sich am schlechtesten komprimieren lässt.
Hast du eine Version dieser Schleife gefahren und bist beim Ordering anderer Meinung, oder ist die KMU-Judge-Mathematik für dich oberhalb eines bestimmten QPS gebrochen, dann will ich Notizen vergleichen. Der Runtime-Eval-Stack ist der jüngste Teil der Production-Agent-Toolchain, und der erste Build jedes Teams sieht leicht anders aus als der erste Build jedes anderen Teams. Da liegen die Lektionen.