Alle Notizen

Observability überlebt dein Agent-Framework

Observability überlebt dein Agent-Framework

Das Framework zu wählen, auf dem dein Agent läuft, ist eine Sechs-Monats-Entscheidung, die du rückgängig machen kannst. Das Schema zu wählen, auf dem deine Traces, Evals und Alerts reiten, ist eine Fünf-Jahres-Entscheidung, die du nicht rückgängig machst. Bau das Rückgrat zuerst, lass das Framework darüber dann austauschbares Detail sein.

Kernpunkte

  • Framework-Wahl ist im Quartal reversibel. Observability-Schema-Wahl schreibt jedes Dashboard und jedes Alert um.
  • Instrumentiere einmal auf OpenTelemetry GenAI Semconv plus OTLP, dann lass LangGraph, Agent Framework oder ADK darüber austauschen.
  • Multi-Turn-Scenario-Violation-Rate, nicht Singleton-Score, ist das Shipping-Gate, das einen Framework-Tausch überlebt.
  • SMB-realistischer Stack heute: OTel-SDK plus self-hosted Langfuse oder Arize Phoenix, nicht das Enterprise-only AI Foundry.
  • Zwei ehrliche Kosten: OTel GenAI Semconv hat noch Development-Status, und LangSmiths Zero-Config-DX ist genuin klebrig.

In diesem Artikel

Was "Agents beobachten und steuern" tatsächlich heißt

Bevor ein Akronym fällt, die Klartext-Version. Ein KI-Agent ist ein Programm, das entscheidet, was als nächstes zu tun ist, ein Tool aufruft, das Ergebnis betrachtet und wieder entscheidet. Ihn zu "beobachten" heißt, jede dieser Entscheidungen mit so viel Detail aufzuzeichnen, dass du nachspielen kannst, was passierte, wenn ein Kunde reklamiert, wenn eine Zahl auf einem Dashboard abdriftet oder wenn ein Regulator fragt. Ihn zu "steuern" heißt, Regeln zu ergänzen, die schlechte Entscheidungen blockieren, bevor sie einen Tool-Aufruf erreichen: kein Geldtransfer ohne Approval, keine Sozialversicherungsnummer in das Modell pasten, keine Vorgabe, Mensch zu sein.

Das Trace ist der Beleg. Die Steuerung ist das Schloss. Beide gehören irgendwohin, das den nächsten Framework-Rewrite überlebt. Heute gibt es einen echten Kampf darum, wo dieses "irgendwo" liegt, und die Antwort, auf die sich der Engineering-Markt zubewegt, ist der falsche Ort, um selbstzufrieden zu sein.

💡 Frameworks sind die Klamotten dieses Jahres. Traces sind der Körper darunter. Klamotten kannst du wechseln. Körper kannst du nicht wechseln, ohne die Identität zu wechseln.

Die Fünf-Jahre-vs-sechs-Monate-Asymmetrie

Ich habe in Microsoft 365 liefert Agent-Inventory, nicht Observability argumentiert, dass die Per-Request-Schicht im von M365 ausgelieferten Inventory fehlte. Behandle diesen Beitrag und jenen als Diptychon: Der erste benennt die Lücke, dieser benennt, was ich tatsächlich hineinbauen würde. BRK250 ist Microsofts Antwort auf dieselbe Lücke, und sie bündelt eine klare Botschaft mit einer schweren Forderung: Wähle ein beliebiges Framework, aber vereinheitliche die Trace-Plane. Die Session, veröffentlicht auf dem MicrosoftDeveloper-Kanal im Rahmen der Build-2026-Open-Trust-Stack-Ankündigung, demonstriert Cross-Framework-Controls, die Multi-Turn-Policy-Violations von rund 57% auf etwa 10% drücken, ohne die Over-Refusal-Rate zu erhöhen. Diese Zahl ist der Schlagzeilen-Datenpunkt, und sie existiert nur, weil die Runtime-Telemetrie zuerst verdrahtet war.

Hier ist, was ich mit der Asymmetrie meine. Wenn du dich im Februar für LangGraph entschieden hast und im August zu Microsoft Agent Framework oder Google ADK wechseln willst, ist die Arbeit unangenehm, aber endlich: Graph umschreiben, Tools portieren, neu testen. Sechs Monate Schmerz, Decke. Wenn du dich im Februar auf ein proprietäres Trace-Schema festgelegt hast, ist jedes Dashboard, jedes Alert, jeder Cost-per-Conversation-Report, jeder Regression-Test, jede annotierte Incident-Timeline jetzt in diesem Vokabular geschrieben. Die Migration kostet dich den Audit-Trail selbst, nicht den Code. Das ist die Fünf-Jahres-Entscheidung, die sich hinter etwas verbirgt, das wie eine Tooling-Wahl aussieht.

Was diese Asymmetrie 2026 konkret macht, ist, dass es endlich ein konvergierendes offenes Rückgrat gibt. OpenTelemetrys GenAI Semantic Conventions definieren, wie ein Span aussieht, der von einem LLM-Aufruf, einem Tool-Aufruf oder einem Agent-Schritt emittiert wird. Die neuen Agent-und-Framework-Span-Conventions erweitern das auf Multi-Agent-Topologien. Microsoft trägt zusammen mit Ciscos Outshift-Team die Multi-Agent-Erweiterungen upstream bei, sodass ein einzelnes Trace Agent Framework, Foundry und ein Drittanbieter-Framework auf einer Timeline überspannen kann. Das ist das Rückgrat. Wähle es.

Montagsschritt: Öffne das Projekt, in dem dein einer Production-Agent läuft. Ergänze opentelemetry-instrumentation-* für das Framework, das er heute nutzt, und eine einzige OTLP-Exporter-Env-Var, die auf einen Collector zeigt, den du kontrollierst. Tu das, bevor du das Gespräch beendest, ob du Frameworks migrieren willst.

Das Plain-OTel-Bild für einen Nicht-Azure-SMB

Stell dir den Head of Engineering einer 80-Personen-AI-Native-Beratung vor. Sie haben einen Production-Agent auf LangChain, zwei weitere im Late-Stage internen Prototypen auf LangGraph, und ein Board, das gerade naiv gefragt hat: "Sind wir auf dem richtigen Framework?" Die richtige Antwort ist nicht ja oder nein. Die richtige Antwort ist: "Das Framework ist die billige Frage, hier ist die teure."

Ihr realistischer OSS-Stack:

# docker-compose.yml Fragment für das SMB-Observability-Rückgrat
services:
  otel-collector:
    image: otel/opentelemetry-collector-contrib:0.110.0
    command: ["--config=/etc/otel-config.yaml"]
    volumes:
      - ./otel-config.yaml:/etc/otel-config.yaml
    ports:
      - "4317:4317"   # OTLP gRPC
      - "4318:4318"   # OTLP HTTP
  langfuse:
    image: langfuse/langfuse:3
    environment:
      DATABASE_URL: postgres://langfuse:langfuse@postgres:5432/langfuse
      CLICKHOUSE_URL: http://clickhouse:8123
      NEXTAUTH_SECRET: ${LANGFUSE_SECRET}
    ports:
      - "3000:3000"
  postgres:
    image: postgres:16
  clickhouse:
    image: clickhouse/clickhouse-server:24

Und die Anwendungsseite in Python, mit dem OTel-Exporter, der auf den Collector zeigt:

# agent/observability.py
import os
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter

os.environ["OTEL_SEMCONV_STABILITY_OPT_IN"] = "gen_ai_latest_experimental"

provider = TracerProvider()
provider.add_span_processor(
    BatchSpanProcessor(OTLPSpanExporter(endpoint="otel-collector:4317", insecure=True))
)
trace.set_tracer_provider(provider)

# Dann instrumentiere das Framework, das du heute nutzt.
# Alle emittieren dieselben GenAI-Semconv-Spans in denselben Collector:
from opentelemetry.instrumentation.langchain import LangchainInstrumentor
LangchainInstrumentor().instrument()

Montagsentscheidung für diesen Head of Engineering: Den OTel-GenAI-Exporter in den aktuellen LangChain-Agent verdrahten, ein self-hosted Langfuse auf einer einzelnen VM hinter dem Collector aufstellen und beides darauf zeigen, bevor entschieden wird, ob einer der drei Agents zu Microsoft Agent Framework migriert wird. Messbares Ergebnis: Jeder Trace aus jedem Framework landet binnen einer Woche im selben Store. Jetzt ist die Framework-Entscheidung nur noch Code. Die Auditierbarkeits-Entscheidung ist bereits getroffen.

Dieselbe Form funktioniert für einen 80-Personen-Mittelstands-SaaS-Shop, der Arize Phoenix statt Langfuse fährt, weil sie OpenInferences First-Class-Eval-Primitive wollen. Das Rückgrat überlebt auch die Backend-Wahl. Das ist der ganze Punkt.

Wo die These verliert

Zwei reale Kosten, und so zu tun, als seien sie nicht da, ist, wie dieser Rat schlecht altert.

Erstens haben die OTel-GenAI-Semantic-Conventions Stand Juni 2026 noch Development-Status. Die Spec selbst sagt wörtlich: "Dieser Übergangsplan wird aktualisiert, um eine stabile Version einzuschließen, bevor die GenAI-Conventions als stabil markiert werden", was eine ehrliche Art ist zu sagen, dass sich niemand auf ein Stabildatum festgelegt hat. Die Opt-in-Env-Var OTEL_SEMCONV_STABILITY_OPT_IN=gen_ai_latest_experimental existiert, weil das Schema sich noch verschieben kann, Attribut-Namen umbenannt werden können und deine Dashboards nachziehen müssen. Schema-Churn ist eine reale Kosten. Sie ist kleiner als ein Framework-Rewrite, aber nicht gratis. Wenn du ein Fünf-Personen-Team leitest, das einen Agent ausliefert, und du alles auf ein einzelnes Backend setzt, ist der experimentelle Status ein fairer Grund, ein Quartal zu warten oder parallel auf OpenInference und OTel GenAI dual zu schreiben und später zu migrieren.

Zweitens ist die Developer-Experience-Lücke zwischen LangSmith und einem self-hosted Langfuse plus OTel-Collector real und unterbewertet. LangSmith auf LangChain/LangGraph sind zwei Umgebungsvariablen, und deine Traces erscheinen gestylt, indiziert und replay-bereit. Langfuse und einen Collector aufzustellen ist an einem guten Tag ein halber Tag und eine ganze Woche, wenn dein Team nie ein ClickHouse betrieben hat. Ein Team, von dem ich las, meldete eine LangSmith-Rechnung von 1.200 Dollar pro Monat nach einem Traffic-Surge, was die kanonische "Vendor-Lock-in hat endlich zugebissen"-Anekdote ist und eine faire Warnung, aber die Kehrseite ist auch ehrlich: Zero-Config-DX ist echtes Geld wert für ein Team, das noch keinen Platform-Engineer eingestellt hat. Die Rückgrat-zuerst-These muss diese Lücke anerkennen. Die Antwort lautet nicht "alle sollten am Tag eins self-hosten". Die Antwort lautet: "Wenn dein framework-gekoppeltes Tool der einzige Ort ist, an dem deine Traces leben, zahlst du mit Optionalität."

Montagsschritt auf der Kostenseite: Ich deckle meine bei einer Zahl, die ich nicht überschreiten werde, ohne die Entscheidung neu zu öffnen, und schreibe sie in dieselbe Zeile wie die Framework-Wahl. Wenn LangSmith dein Team in diesem Quartal in Produktion bringt und die Rechnung unter dem Deckel liegt, shipp es. In dem Moment, in dem die Kosten den Deckel überschreiten, oder in dem Moment, in dem ein zweites Framework in Produktion landet, tausche ich den Exporter auf OTLP und route zu Langfuse oder Phoenix. Die Instrumentierung ändert sich nicht. Nur das Ziel.

Multi-Turn-Violation-Rate ist das eigentliche Ship-Gate

Die leise wichtigste Zahl im BRK250-Walkthrough ist nicht 10%. Sie ist 57%. Die Banking-Agent-Demo, gebaut auf LangGraph und mit sechs internen Tools via MCP verbunden, zeigte eine 28%-Violation-Rate bei Single-Prompt-Evals und eine 57%- bis 58%-Violation-Rate bei Multi-Turn-Szenarien, bevor irgendwelche Controls angewendet wurden. Ein defensiver System-Prompt drückte die Singleton-Zahl auf 15% und bewegte die Multi-Turn-Zahl gar nicht. Dann drückten deterministische Guardrails in der Agent Control Specification Multi-Turn-Violations auf etwa 10%, ohne die Over-Refusal-Rate zu erhöhen, was der Schlagzeilen-Befund im BRK250-Walkthrough auf dem MicrosoftDeveloper-Kanal ist.

Hier ist die Umrahmung. Die Multi-Turn-Zahl ist die einzige, die auf einen echten Kunden in einer echten Session mappt. Die Singleton-Zahl ist das, was jeder öffentliche Benchmark und jeder "wir haben unseren Agent getestet"-Tweet zitiert. Wenn dein Observability-Rückgrat kein vollständiges Multi-Turn-Szenario mit Tool-Aufrufen darin aufzeichnen kann, ist die einzige Zahl, die du produzieren kannst, die falsche. Frameworks kommen und gehen. Das Ship-Gate, wenn du dich festlegst, ist das, wogegen deine CI/CD für immer läuft.

Montagsschritt auf der Eval-Seite: Ich nehme ein production-geformtes Multi-Turn-Szenario aus meinen echten Logs (10 bis 20 Turns, enthält einen Tool-Aufruf, enthält eine umstrittene Entscheidung), mache daraus eine Test-Fixture, und lasse CI fehlschlagen, wenn die Violation-Rate auf diesem einen Szenario eine schriftlich festgelegte Schwelle überschreitet. Der Replay des BRK250-Walkthroughs zeigte, dass das die Fälle fängt, die Prompts verstecken. Es zu tun erfordert, dass die Trace-Plane zuerst da ist.

Die Control Plane gehört über das Rückgrat, nicht ins Framework

Die andere Microsoft-Ankündigung auf BRK250 war Agent Control Specification (ACS), eine Open-Source-Middleware-Schicht, die zwischen Agent-Runtime und Policy-Engine sitzt, mit Rego als einer der unterstützten Policy-Sprachen und YAML für die Deklaration. Die relevante Eigenschaft ist nicht, dass ACS existiert. Sie ist, dass ACS, wie das OTel-Rückgrat, so positioniert ist, dass es das Framework darunter überlebt. Acht Interventionspunkte (Input, Output, Tool, Pre-Tool, Post-Tool und so weiter) werden einmal in einem Manifest deklariert und zur Laufzeit angewendet, egal ob das Framework LangGraph, Semantic Kernel, AutoGen, Microsoft Agent Framework oder Google ADK ist.

Die Control Plane hat denselben Fünf-Jahre-vs-sechs-Monate-Charakter wie die Trace-Plane. Wo du eine Policy ausdrückst ("keine Sozialversicherungsnummer ins Modell geben"), ist eine langlebige Entscheidung. Das Framework, um das die Policy gelegt wird, ist kurzlebig. Die SSN-Regel in einen LangGraph-System-Prompt zu legen heißt, dass sie an dem Tag stirbt, an dem du auf Agent Framework wechselst. Sie in eine Rego-Datei in einem ACS-Manifest zu legen heißt, dass sie jeden Framework-Tausch darunter überlebt. Dieselbe Logik gilt für Telemetrie.

💡 Wenn deine Safety-Logik über einen Prompt, einen Classifier und einen Tool-Wrapper verstreut ist, ist deine Framework-Wahl jetzt tragend für deine Audit-Story. Das ist die falsche Abhängigkeit.

Für die 80-Personen-Beratung ist der praktische Schritt bescheidener, als ACS heute auszurollen. Es ist, das Pattern anzuerkennen und den Policy-Ausdruck auf eine Schicht außerhalb des Frameworks zu verschieben. Konkret: Behalte die prompt-basierten defensiven Regeln vorerst (billig, brüchig, für ein Quartal in Ordnung), aber schreibe die deterministischen als ein kleines Middleware-Modul in deinem eigenen Code, das jeden Tool-Aufruf und jeden Output umhüllt. Dieses Modul, nicht das Framework, ist das, was zu ACS oder zu einer äquivalenten OSS-Control-Spec portiert wird, wenn eine davon gewinnt.

Montagsschritt auf der Steuerungsseite: Liste die drei Policies auf, die du aktuell in einem System-Prompt kodierst und die du peinlich fändest, wenn ein Regulator sie als einzige Enforcement-Schicht vorfände ("kein Geldtransfer ohne Approval", "keine SSN in einer Antwort", "nicht als Mensch ausgeben"). Reimplementiere jede als deterministischen Check im Code, aus deinem eigenen Tool-Call-Wrapper aufgerufen, mit einem geloggten Span bei jedem Check. Du hast jetzt begonnen, eine Control Plane zu bauen, die das Framework überlebt, ohne dich auf die Spec irgendeines Vendors festzulegen.

Die "Any Framework"-Tracing-Realität, geprüft

Die Behauptung, die BRK250 zu Cross-Framework-Tracing macht, ist konkret und prüfenswert. Microsoft Agent Framework propagiert Trace-Context an MCP-Server über das params._meta-Feld der tools/call-Requests, was die Standard-MCP-_meta-Erweiterung ist. Azure AI Foundry hat Out-of-the-Box-Tracing für Microsoft Agent Framework, Semantic Kernel, LangChain, LangGraph und das OpenAI Agents SDK, gebaut auf OpenTelemetry. LangChain, LangGraph, AutoGen, Semantic Kernel, das OpenAI Agents SDK und Google ADK emittieren heute alle OTel-GenAI-Spans. Die "Any Framework"-Behauptung ist 2026 kein Marketing. Sie wird wörtlich.

Der ehrliche Contrarian-Faden ist die OpenInference-versus-OTel-GenAI-Conventions-Debatte. OpenInference ist Arizes Schema, ausgeliefert in Phoenix und in vielen der Framework-Integrationen. OTel GenAI Semconv ist der SIG-getriebene offene Standard, aber neuer. Sie überlappen sich, sie sind sich bei manchen Attribut-Namen uneinig, und beide fließen über OTLP, sodass Backend-Ingestion selten das Problem ist. Der pragmatische Schritt für einen SMB ist, einen zu wählen und dual zu instrumentieren, wenn die Kosten klein sind (sie sind es meist, da beide auf OTLP reiten), oder im Zweifelsfall OTel GenAI zu wählen, weil die Spec sich auf Stable zubewegt und die Multi-Agent-Schicht offen mit Cisco und der OTel-Community co-entwickelt wird. Die Entscheidung zählt weniger als die Disziplin, sie aufzuschreiben und nicht jedes Framework heimlich sein natives Trace-Format einschmuggeln zu lassen.

Beim Overhead sind die relevanten Primärquellen-Zahlen beruhigend. OpenTelemetry fügt unter 1ms Overhead pro LLM-Aufruf hinzu, wobei LLM-API-Latenz im Bereich 100ms bis 30s vollständig dominiert, was die einzige Zahl ist, die für einen LLM-Workload zählt. Dieselbe Quelle zitiert eine synthetische 265,9%-Overhead-Zahl für einen SDK-Benchmark und eine 41,7%-Overhead-Zahl für Jaeger mit aggressivem Tail-Sampling, beide nützlich zum Sizing der Collector-Tier, keine relevant für die Per-Call-Latenz in einer GenAI-Pipeline. Behandle Per-Call-Overhead als Nicht-Problem. Behandle Collector-Sizing als reale Capacity-Planning-Frage.

Montagsschritt auf der Schema-Seite: Schreibe in das README deines Repos, exakt welches Schema du emittierst. Zwei Zeilen. "Wir emittieren OTel GenAI Semconv. Wir fließen über OTLP." Das ist das kleinste mögliche Artefakt, das eine implizite Entscheidung in eine gepflegte verwandelt.

Was das für die SMB-Agentur heißt, die das hier liest

Die meisten Leser dieses Beitrags sind nicht Microsoft. Die meisten leiten ein kleines Team, einen bis drei Production-Agents, und ein Tooling-Budget, das gegen Fehlwetten empfindlich ist. Die Framework-Debatte, gerade dieses Jahr, kann sich wie die wichtigste Entscheidung im Gebäude anfühlen. Sie ist es nicht. Sie ist die sichtbarste, was nicht dasselbe ist.

Die Reihenfolge der Operationen, die die nächsten 18 Monate überlebt, sieht so aus. Erstens: Verpflichte dich schriftlich auf ein offenes Trace-Schema und einen OTLP-Transport. Zweitens: Wähle ein self-hostbares oder günstiges OSS-Backend (Langfuse, Phoenix, OpenLLMetry, Honeycomb, SigNoz, Grafana Tempo) und betreibe es dort, wo du die Daten kontrollierst. Drittens: Schreibe deine wichtigsten Multi-Turn-Szenarien als Fixtures und gate CI an der Violation-Rate. Viertens: Beginne, deterministische Policies aus System-Prompts in ein Steuerungsmodul zu verlagern, das du auf eine offene Control-Spec tauschen kannst, wenn eine davon gewinnt. Fünftens, und erst fünftens: Entscheide, welches Framework du dieses Quartal nutzt.

💡 Das Framework ist die sichtbarste Entscheidung im Gebäude. Die Trace- und Control-Planes sind die tragenden. Die meisten Teams drehen die Reihenfolge um. Drehe sie zurück.

Der Talk-Titel für BRK250 war "any framework". Das Argument, das ich dir mitgeben will, ist das Duale dazu: Der einzige Grund, dass "any framework" ein kohärentes Versprechen ist, ist, dass das Rückgrat darunter endlich stabil genug ist, es zu stützen. Wenn du dich nicht auf das Rückgrat festlegst, verwandelt sich "any framework" zurück in "das Framework, mit dem ich feststecke".

Ich habe in 12 Monaten Agents auf drei Frameworks ausgeliefert. Die einzigen Artefakte, die alle drei Migrationen überlebten, waren die Traces, die dagegen geschriebenen Evals und die Policy-Module, die außerhalb des Frameworks lebten. Die Frameworks selbst waren der billige Teil. Das Rückgrat war der teure Teil und der Teil, der jede Migration aus "alles neu schreiben" in "die Orchestrierung neu schreiben" verwandelte.

Wenn du mitten in einer Migration, mitten in einer Framework-Entscheidung oder einfach mitten in einer Wette steckst, würde ich Notizen vergleichen. Wie sieht deine Trace-Plane aus? Wo leben deine Policies? Wenn deine ehrliche Antwort "innerhalb des Frameworks" ist, ist das das Gespräch, das es wert ist, vor dem nächsten Quartal zu führen. Erreich mich auf LinkedIn oder unter marcus-duwe.de. Ich pflege eine kleine Liste von OSS-Observability-Stacks, die in Produktion einen Framework-Tausch überlebt haben, und ich tausche meine gegen deine.