Startseite / Artikel / Model-Serving-Architektur: Warum die API nur die Eingangstür ist

Model-Serving-Architektur: Warum die API nur die Eingangstür ist

Ein Leitfaden zur Plattform hinter einem Inferenz-Endpunkt: Routing, Skalierung, Versionierung, Observability, Sicherheit und der Aufruf bereitgestellter Modelle aus Spring AI oder LangChain4j.

2004 Wörter

Denken Sie daran, was ein Gast im Restaurant sieht: Jemand nimmt die Bestellung auf, verschwindet Richtung Küche und kommt mit einem Teller zurück. Der unsichtbare Teil ist wichtiger. Bestellungen werden koordiniert, Vorräte geprüft, Köche bereiten Gerichte zu, viele Tische werden gleichzeitig bedient, und jeder Teller muss vor der richtigen Person landen.

Ein Machine-Learning-Modell bereitzustellen folgt demselben Muster. Von außen sieht eine Anwendung einen HTTP-Endpunkt, der eine Anfrage annimmt und eine Vorhersage zurückgibt. Dahinter können Routing, Authentifizierung, Feature-Abruf, Vorverarbeitung, die Modell-Runtime selbst, Ressourcenverwaltung, Versionswahl, Monitoring und Fehlerbehandlung stecken. Der Endpunkt ist der Kellner. Die Serving-Architektur ist das Restaurant.

Raus aus dem Notebook

Ein Modell kann sich im Notebook tadellos verhalten und trotzdem mühsam zu betreiben sein, sobald andere Systeme davon abhängen. In der Entwicklung lädt eine Data Scientist das Modell, bereitet Eingaben vor, führt die Inferenz aus und prüft die Ergebnisse, alles in einer kontrollierten Umgebung. Die Produktion nimmt jede dieser Annehmlichkeiten weg. Mehrere Anwendungen wollen im selben Moment Vorhersagen, der Traffic steigt und fällt, Versionen müssen getauscht werden, ohne Aufrufer zu unterbrechen, und eine Antwort kann von Daten anderer Services abhängen.

Ab diesem Punkt ist das Modell kein eigenständiges Artefakt mehr, sondern eine Komponente eines verteilten Systems. Die Frage verschiebt sich von „Wie rufe ich es auf?“ zu „Wie biete ich Inferenz als verlässlichen Produktionsdienst an?“.

Die API ist die Eingangstür, mehr nicht

Eine API gibt Anwendungen einen kontrollierten Weg, Vorhersagen anzufordern, ist aber nur ein kleiner Ausschnitt des Ganzen. Stellen Sie sich eine Zahlung vor, die durch eine Online-Banking-App läuft. Bevor eine Entscheidung zurückkommt, muss die Anfrage vielleicht authentifiziert, mit Kundenmerkmalen angereichert, validiert, vorverarbeitet, einer Modellversion zugeordnet, bewertet und anschließend nachverarbeitet werden.

Jeder dieser Schritte kann das Ergebnis verändern. Das Modell antwortet vielleicht in Millisekunden, während der Feature-Abruf hängt. Ein gesundes Modell kann unerreichbar werden, weil die Rechenleistung darunter erschöpft ist. Eine neue Modellversion kann sich anders verhalten, ohne dass sich der API-Vertrag überhaupt ändert.

Betrachten Sie die API also als Einstiegspunkt in ein Serving-System, so wie der Kellner für die sichtbare Seite des Restaurants steht.

Was bei einer einzelnen Inferenz passiert

Eine Produktionsanfrage durchläuft typischerweise mehrere Zuständigkeiten, bevor eine Antwort die Geschäftsanwendung erreicht. Ein Gateway kümmert sich womöglich um Authentifizierung, Autorisierung, Routing und Rate Limits. Die Serving-Schicht holt dann Features oder Kontext, führt die Vorverarbeitung aus, wählt eine Modellversion und ruft die Runtime auf. Danach muss die Ausgabe eventuell nachverarbeitet werden, bevor sie zurückgeht.

Der Weg sieht so aus: Client-Anwendung, dann API oder Gateway, dann die Serving-Schicht, dann Feature- und Kontextabruf, dann die Modell-Runtime, dann Nachverarbeitung, dann die Antwort.

Wer den ganzen Weg sieht, diagnostiziert leichter. Dauert ein Aufruf zwei Sekunden statt zweihundert Millisekunden, ist das Modell womöglich unschuldig. Schuld könnten Feature-Abruf, Netzwerk-Hops, Konkurrenz um Ressourcen oder ein überlasteter Worker sein. Behandeln Sie Serving deshalb als ein System vom Client bis zur Runtime und messen Sie es auch so.

Die Architektur dahinter

Ausgereifte Setups teilen Verantwortlichkeiten auf, statt alles in einen Service zu stopfen. Die Geschäftsanwendung verantwortet die Interaktion mit Kunde oder Prozess. Die Serving-Schicht bearbeitet Inferenzanfragen. Die Modell-Runtime führt das Modell aus. Um sie herum liegen Plattformfähigkeiten für Deployment, Skalierung, Sicherheit, Observability und Ressourcenverwaltung.

Der Kernpunkt: Model Serving gehört zur Plattform, zwischen Anwendungen und Runtimes. Es kann an Feature Stores, Model Registries, Gateways und Infrastruktur andocken, ohne dass eines davon Teil des Modells wird. Wenn Modelle und Konsumenten zahlreicher werden, zahlt sich diese Trennung aus: Plattformteams können Deployment- und Runtime-Details ändern, ohne dass jedes Anwendungsteam sie lernen muss.

Ein Modell reicht selten

Das erste Deployment umfasst vielleicht ein einziges Modell, aber Unternehmensplattformen bleiben selten so übersichtlich. Verschiedene Geschäftsbereiche brauchen verschiedene Modelle, und ein Modell kann in mehreren Versionen existieren, während es evaluiert und ausgerollt wird.

Damit wird Routing zu einer Designfrage. Die Plattform muss entscheiden, welches Modell in welcher Version eine Anfrage beantwortet und wo es läuft, besonders wenn sich Modelle im Ressourcenbedarf unterscheiden oder Hardware teilen.

Eine Model Registry liefert einen verlässlichen Katalog dessen, was existiert und welche Versionen verfügbar sind. Statt Deployment-Details über den Anwendungscode zu verstreuen, liest die Serving-Schicht Lifecycle-Informationen aus der Registry. Das trennt das Bauen von Modellen von ihrer Nutzung, sodass sich ein Modell weiterentwickeln kann, ohne dass Aufrufer bei jedem Release nachziehen müssen.

Inferenz skalieren

Inferenz zu skalieren ist nicht immer wie das Skalieren eines gewöhnlichen Webservices. Eine zustandslose API wächst oft durch zusätzliche Instanzen. Modellserver haben weitere Grenzen, denn Modelle können viel Speicher, GPU-Kapazität oder Startzeit verschlingen.

Ein großes Modell braucht womöglich Spezialhardware, während ein kleines Tausende Anfragen pro Sekunde schafft. Manche Workloads profitieren davon, Anfragen zu bündeln, damit die Hardware ausgelastet bleibt. Andere vertragen nicht einmal eine kleine Erhöhung der Antwortzeit.

Skalierungsentscheidungen müssen daher Modellgröße, Traffic, Parallelität, Hardware, Latenzziele und Kosten gemeinsam abwägen. Mehr Instanzen können einen Engpass beheben und einen anderen schaffen, wenn Ladezeit oder GPU-Verfügbarkeit zur Grenze werden.

Synchron, asynchron und Batch

Nicht jeder Anwendungsfall verlangt eine sofortige Antwort. Eine Betrugsprüfung bei der Zahlungsautorisierung braucht sie jetzt. Dokumentenverarbeitung kann einen Auftrag annehmen und die Ergebnisse später liefern.

Batch-Inferenz ist ein drittes Muster. Millionen Kunden über Nacht zu bewerten ist eine Frage des Durchsatzes, nicht der Latenz einer einzelnen Anfrage.

Jedes Muster hat eigene architektonische Eigenschaften, also starten Sie beim Geschäftsprozess und nicht bei der REST-Gewohnheit. Fragen Sie, wie schnell die Vorhersage gebraucht wird und wo sie in den umgebenden Ablauf passt.

Versionierung ist ein Produktionsthema

Ein Modell auszuliefern ist nicht dasselbe wie ein Anwendungsrelease. Ein neues Modell kann Vorhersagen und Performance verschieben, selbst wenn sich die Serving-Infrastruktur nicht geändert hat, deshalb ist ein kontrollierter Rollout wichtig.

Ein gängiger Ansatz schickt einen kleinen Teil des Traffics an die neue Version, während die alte den Rest übernimmt. Die Plattform beobachtet technische und geschäftliche Signale, erhöht den Anteil Schritt für Schritt und kann zurückrollen, wenn sich die neue Version danebenbenimmt.

Observability

Klassisches Monitoring sagt, ob die Infrastruktur gesund ist. Serving braucht einen weiteren Blick: Inferenzlatenz, Durchsatz, Fehler, Modellversionen, Ressourcennutzung und den Zustand von Abhängigkeiten wie Feature-Services.

Ein System kann technisch gesund aussehen und trotzdem seltsame Ergebnisse liefern, wenn das Modell Eingaben bekommt, die sich von denen unterscheiden, mit denen es gebaut wurde. Observability sollte daher Infrastrukturmetriken mit passenden Signalen auf Modellebene verbinden und dabei die Sensibilität der Daten beachten. Ziel ist die Gewissheit, dass das richtige Modell läuft, und zwar verlässlich innerhalb der erwarteten Grenzen, nicht bloß eine Antwort vom Endpunkt.

Sicherheit und Isolation

Serving-Endpunkte machen wertvolle Geschäftsfunktionen zugänglich und verarbeiten sensible Daten, also gehört Sicherheit von Anfang an ins Design. Authentifizierung, Autorisierung, Request-Validierung, Rate Limiting, Netzwerkgrenzen und Zugriffskontrolle sollten die Inferenz umgeben, statt erst nach dem Deployment dazuzukommen.

Isolation ist genauso wichtig, wenn Modelle Infrastruktur teilen. Ein einzelner Workload mit hohem Volumen darf andere Modelle nicht von Rechenleistung oder Speicher abschneiden, besonders wenn GPUs im Spiel sind. Wer Serving als Plattformfunktion behandelt, kann diese Kontrollen einheitlich anwenden, statt dass jedes Anwendungsteam dieselben Probleme allein löst.

Nutzung aus Java

Aus einer Java-Anwendung heraus kann der Aufruf eines Modells trügerisch einfach wirken. Ein Framework wie Spring AI bietet eine saubere Programmierabstraktion, und Deployment, Skalierung, Routing und Betrieb der Modelle bleiben außerhalb der App. Diese Trennung ist in einem Unternehmen wertvoll, denn Anwendungsteams sollten nicht für die Infrastrukturentscheidungen zuständig sein, die der Betrieb jedes Modells erfordert.

Mit Spring AI nutzt eine App einen ChatClient, um die KI-Funktion aufzurufen, während das Modell selbst von der Serving-Infrastruktur bereitgestellt wird:

@Service
public class RiskAssessmentService {

    private final ChatClient chatClient;

    public RiskAssessmentService(ChatClient chatClient) {
        this.chatClient = chatClient;
    }

    public String assess(String transactionContext) {
        return chatClient.prompt()
                .system("""
                        You are a transaction risk assessment assistant.
                        Analyse the supplied transaction context.
                        """)
                .user(transactionContext)
                .call()
                .content();
    }
}

Der Code weiß nicht, ob das Modell in einem lokalen Container, einem Kubernetes-Cluster, auf einem dedizierten Inferenzserver oder auf GPU-Hardware läuft. Das ist Sache der Plattform. Die Anwendung nutzt die Fähigkeit über die Schnittstelle, die sie bekommt.

Nützlicher wird die Idee, wenn das Modell strukturierten Kontext braucht. Statt jede Anwendung ihre Eingaben selbst holen und zusammensetzen zu lassen, verlagern Sie diese Aufgabe in einen Anwendungs- oder Plattformservice:

public String assess(String customerId, Transaction transaction) {

    String context = featureService
            .getCustomerContext(customerId);

    return chatClient.prompt()
            .system("Assess the transaction using the customer context.")
            .user("""
                    Customer context:
                    %s

                    Transaction:
                    %s
                    """.formatted(context, transaction))
            .call()
            .content();
}

Die Java-Anwendung orchestriert die Geschäftsinteraktion, ein Feature-Service liefert aktuellen Kontext, und die Serving-Schicht bleibt für die Inferenz zuständig. Je mehr Anwendungen dasselbe Modell nutzen, desto wertvoller wird diese Aufteilung.

LangChain4j bietet eine ähnliche Abstraktion auf Anwendungsebene. Die Unternehmensanwendung definiert ein Interface, das die KI-Fähigkeit repräsentiert, und hält so modellspezifische Infrastruktur aus dem Geschäftscode heraus:

public interface RiskAssistant {

    @SystemMessage("""
        Assess the transaction risk using the supplied
        customer and transaction context.
        """)
    String assess(String context);
}

Die App nutzt diese Fähigkeit dann über das Framework, und der Endpunkt dahinter wird unabhängig verwaltet:

String context = featureService
        .getCustomerContext(customerId);

String assessment = riskAssistant.assess(context);

Die entscheidende Grenze verläuft nicht zwischen Spring AI und LangChain4j. Beide können als Integrationsschicht dienen. Wichtig ist die Trennung von Geschäftscode, KI-Orchestrierung und Serving-Infrastruktur. Sie erlaubt es der Plattform, sich eigenständig zu verändern: Ein Modell kann auf eine andere Runtime umziehen, Kapazität kann wachsen, eine neue Version kann ausgerollt werden, und nichts davon erzwingt einen Umbau der Java-Anwendungen, die sie nutzen. Das ist der eigentliche Vorteil, Serving als Plattformfähigkeit zu behandeln und nicht nur als Modell hinter einem HTTP-Endpunkt.

Eine Architektur wählen

Kein einzelnes Design passt zu jedem Workload. Ein kleines Modell in einem internen Tool mit wenig Traffic kann problemlos innerhalb der Anwendung laufen. Ein Modell, das mehrere Geschäftsanwendungen teilen, kann eine eigene Serving-Schicht rechtfertigen.

Container bieten konsistentes Deployment und Skalierung, Kubernetes eine stärkere Orchestrierung für größere Modellportfolios. Spezialisierte Inferenzplattformen lohnen sich, sobald Sie GPUs, sehr hohen Durchsatz, fortgeschrittenes Batching oder feinere Ressourcenkontrolle brauchen.

Wägen Sie Modelleigenschaften, Traffic-Profil, Latenzanforderungen, geschäftliche Kritikalität, betriebliche Reife und Kosten ab. Die schickste Plattform ist nicht automatisch die richtige. Streben Sie die kleinste Architektur an, die die Anforderungen des Workloads verlässlich erfüllt und einen sinnvollen Weg zum Wachsen offenlässt.

Der Endpunkt ist erst der Anfang

Zurück im Restaurant sieht der Gast den Kellner, doch das ist nur ein dünner Teil eines großen Betriebs. Die Bestellung muss korrekt aufgenommen, an die richtige Station geschickt, mit den vorhandenen Ressourcen zubereitet, mit anderen Tischen abgestimmt und serviert werden, ohne die Küche lahmzulegen.

Model Serving funktioniert genauso. Ein Endpunkt macht ein Modell erreichbar, und Erreichbarkeit ist nur der Anfang. Verlässliche Inferenz beruht auf dem, was sie umgibt: Routing, Kontextabruf, Versionen, Rechenleistung, Skalierung, Fehlerbehandlung, Observability, Sicherheit und betriebliche Kontrollen.

Das Modell mag im Zentrum der Fähigkeit bleiben, aber die Serving-Architektur entscheidet, ob diese Fähigkeit echte Geschäftsentscheidungen tragen kann. Beim Serving geht es nicht darum, ein Modell zugänglich zu machen. Es geht darum, das System zu bauen, mit dem ein Modell solche Entscheidungen verlässlich unterstützt.

Zum Weiterlesen

Für die Java-Seite lohnt sich ein Blick in die Dokumentation von LangChain4j und Spring AI. Auf Plattformseite sind die Kubernetes-Dokumentation, KServe und NVIDIAs Triton Inference Server gute Startpunkte.