In den bisherigen Posts haben wir einen Agenten von Grund auf gebaut, ihm ein Fundament gegeben, Multi-Agent-Koordination untersucht, Evaluation und Guardrails implementiert und den Agenten als lokalen Service exponiert.

Jetzt der letzte Schritt: Alles auf eigene Infrastruktur. Kein API-Call verlässt das Netzwerk.

Das Szenario: Ein MLflow-Agent im Cluster

Der Agent, den wir in dieser Phase bauen, hat einen konkreten Zweck: Er greift direkt auf MLflow zu — Experimente vergleichen, Modell-Deployments prüfen, Alias-Strategien abfragen. Ohne UI-Navigation, ohne manuelle API-Calls. Stattdessen natürliche Sprache: “Welche Modelle sind im Status Live?” — und der Agent ruft die richtigen Tools auf.

Das ist kein hypothetisches Beispiel. Wer ein MLOps-Setup betreibt — mit Experiment-Tracking, Model Registry, Promotion-Strategien — kennt das: Informationen sind da, aber verteilt über verschiedene Oberflächen und APIs. Ein Agent, der diese Informationen aggregiert und in Kontext setzt, spart Zeit.

Fünf Schritte zur Datensouveränität

Der Weg vom lokalen Prototyp zum souveränen Cluster-Deployment besteht aus fünf Schritten. Jeder baut auf dem vorherigen auf.

Schritt 1: MCP-Server als Tool-Schicht. Der Agent kennt keine MLflow-URLs, keine API-Versionen, keine Authentifizierung. Ein MCP-Server abstrahiert das — acht Tools für Tracking und Model Registry. Wenn sich die MLflow-API ändert, ändert sich der Server, nicht der Agent.

Schritt 2: ReAct-Agent mit LangGraph. Der Agent entscheidet selbst, welche Tools er braucht, ruft sie auf, interpretiert die Ergebnisse und führt bei Bedarf Folgeanfragen durch. Multi-Turn-Konversationen über persistente Sessions — die Frage “Zeig mir die Runs vom ersten Experiment” nutzt den Kontext der vorherigen Frage.

Schritt 3: Deployment im Kubernetes-Cluster. FastAPI-Service mit persistenten Sessions (SQLite auf EBS). Der MCP-Server läuft als Subprocess im selben Pod. Ab jetzt kann das Team den Agenten nutzen — nicht nur der Entwickler auf seinem Laptop.

Schritt 4: Tracing mit Langfuse. Self-hosted Langfuse als Tracing-Backend, deployt via ArgoCD. Integration über das Callback-Pattern — zwei Zeilen Code, kein Node und kein Prompt geändert. Jeder Tool-Call, jeder LLM-Call, jede Latenz ist sichtbar. Und die Traces bleiben im eigenen Cluster.

Schritt 5: Self-Hosted LLM mit vLLM. Der entscheidende Schritt für Datensouveränität. Qwen 2.5 7B (AWQ-quantisiert) läuft als eigener Pod im Cluster. Der Wechsel von Claude zu Qwen erfordert fünf Zeilen Code-Änderung — ChatAnthropic wird zu ChatOpenAI (vLLM ist OpenAI-kompatibel). Die eigentliche Arbeit liegt nicht im Code, sondern in der GPU-Infrastruktur: Node-Labels, Tolerations, VRAM-Budgetierung, Modell-Download-Zeiten.

Was “datensouverän” konkret bedeutet

Nach Schritt 5 sieht die Architektur so aus:

                          Kubernetes-Cluster
  ┌─────────────────────────────────────────────────────────────┐
  │                                                             │
  │  Service          Agent Pod               vLLM Pod          │
  │  ┌────────┐      ┌──────────────┐        ┌──────────────┐   │
  │  │ :8080  │─────→│ FastAPI      │───────→│ Qwen 2.5 7B  │   │
  │  └────────┘      │ Agent Code   │        │ GPU          │   │
  │                  │ MCP Client   │        └──────────────┘   │
  │                  │  ↕ stdio     │        ┌──────────────┐   │
  │                  │ MCP Server   │───────→│ Langfuse     │   │
  │                  └──┬────────┬──┘        │ (Tracing)    │   │
  │                     │        │           └──────────────┘   │
  │                     │        │           ┌──────────────┐   │
  │                     │        └──────────→│ EBS Volume   │   │
  │                     │                    │ (Sessions)   │   │
  │                     │ HTTP               └──────────────┘   │
  │                     │                    ┌──────────────┐   │
  │                     └───────────────────→│ MLflow       │   │
  │                                          │ (Tracking)   │   │
  │                                          └──────────────┘   │
  │                                                             │
  └─────────────────────────────────────────────────────────────┘

Alle Kommunikation bleibt cluster-intern. Kein Prompt geht an einen externen LLM-Provider. Kein Trace verlässt das Netzwerk. Die Sessions liegen auf einem persistenten Volume. Das ist kein theoretisches Versprechen — es ist messbar: Die Langfuse-Traces zeigen ausschließlich cluster-interne Endpunkte.

Was man dabei lernt

Self-hosted LLM ist ein Infrastruktur-Entscheid, kein Code-Entscheid. Fünf Zeilen Code ändern sich. Die eigentliche Arbeit liegt in GPU-Nodes, VRAM-Planung und Modell-Serving. Wer Kubernetes und GPU-Infrastruktur beherrscht, hat den schwierigsten Teil bereits hinter sich.

“Funktioniert lokal” und “funktioniert im Container” sind zwei verschiedene Aussagen. Subprocesses erben Umgebungsvariablen nicht automatisch in Kubernetes. StorageClass muss explizit gesetzt werden. Pfade, die lokal relativ funktionieren, brechen im Container. Das sind keine großen Probleme — aber sie kosten Zeit, wenn man sie nicht erwartet.

Cluster-interne Latenz ist ein spürbarer Vorteil. Der Agent mit Qwen 2.5 7B im Cluster ist schneller als mit Claude über das Internet — trotz eines deutlich kleineren Modells. Alle Calls (LLM, MLflow, Langfuse) bleiben im Cluster, ohne Internet-Roundtrips.

Separation of Concerns zahlt sich am Ende aus. Der Agent-Code bleibt von Schritt 1 bis Schritt 5 nahezu unverändert. Deployment, Tracing, LLM-Backend — alles wird von außen konfiguriert, nicht hineingebaut. Das ist derselbe Grundsatz, der sich durch die gesamte Serie zieht: Fachlogik und Betriebslogik gehören in getrennte Schichten.

Rückblick auf die Serie

Sieben Posts, ein Bogen:

In Post 1 haben wir verstanden, was einen Agenten ausmacht — vier Komponenten, eine Konfiguration. In Post 2 haben wir ihm ein Fundament gegeben — LangGraph für Struktur, MCP für standardisierte Tools. Post 3 hat gezeigt, wann mehrere Agenten sinnvoll sind und wie man sie koordiniert. Post 4 hat gemessen, ob der Agent gut arbeitet. Post 5 hat ihn abgesichert. Post 6 hat ihn als Service exponiert. Und dieser Post hat den gesamten Stack auf eigene Infrastruktur gebracht.

Der rote Faden: Jeder Schritt hat den Agenten nicht intelligenter gemacht, sondern robuster, sichtbarer und kontrollierbarer. Und am Ende steht ein System, das vollständig unter eigener Kontrolle läuft — vom Code über das Modell bis zum Tracing.


Code und Details: Alle fünf Blöcke — MCP-Server, ReAct-Agent, Kubernetes-Deployment, Langfuse-Tracing, Self-Hosted LLM mit vLLM — sind auf GitHub dokumentiert: → agentic-ai / Phase 5: Agentic MLOps


Ich bin ML Engineer mit Fokus auf Self-Hosted AI und Datensouveränität. Ich helfe Unternehmen im DACH-Raum, ML- und AI-Systeme auf eigener Infrastruktur zu betreiben. Offen für Austausch und spannende Projekte — schreib mir auf LinkedIn.