Zum Inhalt springen
Michael Schwarz
Anfrage

KI nachrüsten, ohne das System neu zu bauen.

Java · LLM · Dresden · remote Ich baue LLM-Funktionen in gewachsene Java-Systeme. Als eigenes Modul oder direkt in die Fachlogik, auf Wunsch vollständig auf eigener Hardware.

Verfügbarkeit
offen für neue Projekte
Schwerpunkt
LLM-Integration in Java-Systeme
Kontakt
Nachricht oder Telefon

Derselbe Stack, neues Werkzeug.

Ich komme aus der Java-Enterprise-Entwicklung und bin dort geblieben. Die KI-Themen sind dazugekommen, nicht an ihre Stelle getreten. Deshalb kann ich beides im selben System zusammenbringen.

Womit ich arbeite

  • Jakarta EE, WildFly
  • JSF / React
  • DB2 / MSSQL
  • Handel, E-Commerce, Finanzen

seit 2009

Was ich dazu baue

  • MCP-Server (Quarkus)
  • LangChain4j
  • llama.cpp, lokal
  • lokal oder per API

seit 2023

Links die Technologien, mit denen ich seit 2009 arbeite. Rechts die, die seit 2023 dazugekommen sind.

Der Vorstand will KI. Das System ist von 2011.

Deshalb endet die Anforderung meistens bei „geht nicht ohne Neubau“ und bleibt liegen. Jakarta EE, ein Applikationsserver, eine Datenbank, über Jahre gewachsene Fachlogik: wer daran etwas Grundsätzliches ändert, hat ein Migrationsprojekt statt einer KI-Funktion.

Ich setze da an, wo es am wenigsten kostet: an den Schnittstellen. Ein eigenes Modul, eine definierte Schnittstelle, ein abschaltbarer Zustand. Und wo das sinnvoller ist, direkt im Bestandscode. Das Bestandssystem merkt davon so wenig wie möglich. Im besten Fall nur, dass es gelesen wird.

Und wenn die Daten das Haus nicht verlassen dürfen, läuft das Modell auf eigener Hardware. Quantisiert, passend dimensioniert, ohne externen Anbieter im Datenpfad. Auch in regulierten Umgebungen.

Konkret: was ich baue.

Sechs Dinge, die in gewachsenen Java-Systemen immer wieder gebraucht werden.

MCP-Server für die eigenen Java-Services

Ihr Bestandssystem kann längst alles: Auftrag suchen, Bestand prüfen, Retoure anlegen. Ein MCP-Server macht genau diese Methoden für einen Assistenten aufrufbar, jede einzeln freigegeben. Der Support fragt dann „Wo steht Auftrag 4711?“, statt sich durch drei Masken zu klicken. Was nicht freigegeben ist, existiert für das Modell nicht.

Bausteine

  • Quarkus-Service mit MCP-Endpunkt
  • Werkzeuge auf bestehende EJB- oder REST-Methoden
  • Rechte und Limits je Werkzeug
  • Protokoll über jeden Aufruf

Skills und KI-Agenten aufsetzen

Ein Werkzeug freizugeben reicht nicht. Das Modell muss wissen, dass es bei einer Reklamation erst den Auftrag lädt, dann die Lieferung prüft und bei fehlendem Beleg nachfragt, statt zu raten. Genau das steht in einem Skill: Reihenfolge, Abbruchbedingungen, Ton der Antwort.

Bausteine

  • Skills: Ablauf, Reihenfolge, Abbruchbedingungen
  • Werkzeugbeschreibungen, die das Modell versteht
  • Agent mit klarem Auftrag statt Allzweck-Chat
  • Tests gegen typische Fälle aus dem Fachbereich

RAG: Antworten aus dem eigenen Bestand

Betriebshandbücher, Confluence-Seiten, Jira-Tickets, Verträge, Produktstammdaten aus der Datenbank: was verstreut liegt, kommt in einen Index. Auf „Welche Kündigungsfrist gilt für Vertragsart B?“ kommt die Antwort aus diesen Quellen, mit Dokument und Abschnitt dazu. Und wenn nichts gefunden wird, heißt die Antwort „nicht gefunden“ statt einer erfundenen Frist.

Bausteine

  • Anbindung der Quellen: Dateiablage, Confluence, Datenbank
  • Embeddings und Vektor-Index
  • Antwort mit Dokument- und Abschnittsangabe
  • Nachindexierung bei Änderungen

Lokales LLM auf eigener Hardware

Wenn Kundendaten das Haus nicht verlassen dürfen, läuft ein offenes Modell auf Ihrer eigenen Maschine: Llama, Mistral oder Qwen, quantisiert auf die Größe, die Ihre GPU trägt. Kein Anbieter im Datenpfad. Vorher messe ich, welches Modell in welcher Quantisierung die nötige Antwortzeit schafft, und ich sage es, wenn die vorhandene Hardware dafür nicht reicht.

Bausteine

  • Modellauswahl und Quantisierung mit llama.cpp
  • Messung: Antwortzeit, Speicherbedarf, parallele Anfragen
  • Betrieb als Dienst im eigenen Netz
  • Modellwechsel ohne Codeänderung

LLM-Anbindung im Java-Code mit LangChain4j

Statt HTTP-Aufrufe von Hand zu bauen, bekommt die Anwendung ein Java-Interface, das sich wie jeder andere Service injizieren lässt. Dahinter steckt LangChain4j; welcher Anbieter antwortet, ist eine Zeile Konfiguration. Wird einer teurer oder fällt aus der Richtlinie, wechselt man auf einen anderen oder auf das lokale Modell, ohne die Fachlogik anzufassen.

Bausteine

  • Java-Interface statt handgeschriebener HTTP-Aufrufe
  • LangChain4j als Integrationsschicht
  • Anbieterwechsel per Konfiguration
  • Tests gegen ein Fake statt gegen die API

Java-Modernisierung, wenn sie vorher nötig ist

Manchmal geht es vorher nicht: Java 8 auf einem Applikationsserver von 2016, Fachlogik in JSF-Backing-Beans, keine Schnittstelle, an der ein neuer Service andocken könnte. Dann wird zuerst entflochten. Versionssprung, Fachlogik aus der Oberfläche ziehen, REST-Schnittstellen schneiden. In Schritten, die einzeln produktiv gehen können.

Bausteine

  • Versionssprung: Java, Jakarta EE, Applikationsserver
  • Fachlogik aus JSF-Backing-Beans lösen
  • REST-Schnittstellen schneiden und dokumentieren
  • Jeder Schritt einzeln produktiv setzbar

Wie ich mit KI arbeite

Transformer selbst trainiert, nicht nur verwendet
Mit PyTorch von Hand aufgebaut, um die Mechanik zu verstehen: Tokenisierung, Attention, was beim Training tatsächlich passiert. Deshalb kann ich einschätzen, was ein Modell leisten kann und wo die Grenze liegt. Dazu kleinere eigene Modelle: Klassifizierer, ein Agent, der Snake spielen lernt, und das Basistraining eines kleinen Sprachmodells in begrenztem Umfang.
Fine-Tuning statt Training von Grund auf
Ein eigenes LLM von null zu trainieren kostet mehr, als es in fast jedem Fall einbringt. Sinnvoll ist der Weg darunter: ein offenes Modell nehmen und auf Ihre Fälle, Ihre Sprache, Ihr Format feinjustieren. Kleine eigene Modelle trainiere ich nur da, wo sie hingehören, etwa zur Klassifizierung mit einem normalen Feed-Forward-Netz.
Werkzeuge allein machen noch keinen Agenten
Die meisten Agenten scheitern nicht am Modell, sondern daran, dass niemand beschrieben hat, wann welches Werkzeug dran ist. Ohne Anleitung wählt ein Modell plausibel, nicht richtig. Deshalb gehört zu jedem Werkzeug eine Anleitung, und beides gehört zusammen entwickelt.

Seit 2009 Java

Michael Schwarz, Java- und KI-Entwickler aus Dresden

Seit 09/2009 entwickle ich Java-Enterprise-Anwendungen, schwerpunktmäßig für Handel und E-Commerce sowie für den Finanz- und Versicherungsbereich. Ich arbeite von Dresden aus, remote für Projekte in Deutschland, Österreich und der Schweiz. Technischer Kern: Jakarta EE mit CDI, EJB, JPA/Hibernate und JAX-RS, dazu JBoss/WildFly und Quarkus, React und JSF im Frontend, Kotlin für Android.

Dass ich heute LLMs in solche Systeme baue, ist keine Umschulung, sondern derselbe Job mit einem neuen Werkzeug: Ich weiß, wo in einer gewachsenen Landschaft eine Schnittstelle hingehört und wo sie Schaden anrichtet.

Woran ich zuletzt gearbeitet habe

  • Architektur

    Architektur und Teamleitung für eine Plattform zur Absatzfinanzierung bei Banken, von der Angebotserstellung bis zur Antragsbearbeitung. Jakarta EE, Quarkus, React.

  • KI im Produkt

    KI-Funktionen in derselben Plattform: Zusammenfassungen und eine KI-geführte Antragsstrecke, eingebaut in die bestehende Fachlogik.

  • KI im Haus

    Mitverantwortlich für den KI-Einsatz in einem Softwarehaus. Dazu ein interner MCP-Server, der GitLab-Repositories als Graph in Neo4j für Assistenten abfragbar macht (GraphRAG): Wer ruft wen auf, was hängt an welcher Schnittstelle.

  • Eigenes Labor

    Qwen-Modelle (3.6 und 3.8) mit llama.cpp, so quantisiert, dass sie auf einer RTX 3060 mit 12 GB flüssig laufen. Dazu ein „Second Brain“ als MCP-Server mit Quarkus und Neo4j. Eigene Projekte, keine Kundenprojekte.

Sprachen und Frameworks
Java 8-25, Kotlin, JavaScript/TypeScript, Python, SQL, Jakarta EE, Hibernate, Quarkus, JSF/PrimeFaces, REST, JSON, XML
KI und LLM
LangChain4j, MCP, RAG, Embeddings, Vektordatenbanken, Prompt Engineering, llama.cpp, Ollama, Quantisierung, PyTorch, Transformer, Fine-Tuning, OpenAI API, Anthropic API, lokale LLMs, On-Premise-KI
Architektur
Microservices, Monolith-Modernisierung, Domain-Driven Design, Clean Architecture, Event-Driven, API-Design, Legacy-Migration
Datenbanken
DB2, MSSQL
Build, CI/CD und Betrieb
Maven, Gradle, Git, Docker, Kubernetes, Jenkins, Linux
Testen
JUnit, Mockito, TestContainers, Integrationstests
Methodik
Scrum, Kanban, Code Reviews, technische Konzeption, Aufwandsschätzung

Offen für neue Projekte

Eine Nachricht oder ein Anruf genügt. Alles Weitere klären wir im Gespräch.

Verfügbarkeit
offen für neue Projekte
Start
kurzfristig
Auslastung
10-15 Stunden pro Woche
Einsatzort
remote, vor Ort im Raum Dresden nach Absprache
Form
freiberuflich
Sprachen
Deutsch, Englisch
Kontakt
Nachricht oder Telefon

Häufige Fragen

Was ist ein MCP-Server?

Ein MCP-Server stellt Werkzeuge nach dem Model Context Protocol bereit, einem offenen Standard für die Anbindung von KI-Assistenten. Der Assistent sieht, welche Werkzeuge es gibt, und ruft sie bei Bedarf auf. Die eigentliche Arbeit erledigt Ihr bestehender Java-Code, etwa ein REST-Endpunkt oder eine EJB-Methode.

Muss unser Java-System für KI umgebaut werden?

In der Regel nicht. Die KI-Funktion läuft als eigenes Modul oder eigener Quarkus-Service und nutzt Schnittstellen, die es schon gibt. Das Bestandssystem bleibt auf seiner Java- und Jakarta-EE-Version. Nur wenn es keine Stelle gibt, an der ein neuer Service andocken kann, wird vorher entflochten.

Kann das Modell dann alles in unserem System tun?

Nein. Das Modell nutzt nur Werkzeuge, die einzeln freigegeben sind, mit eigenen Rechten und Limits je Werkzeug. Jeder Aufruf wird protokolliert. Was nicht freigegeben ist, existiert für das Modell nicht.

Was bedeutet RAG?

RAG steht für Retrieval Augmented Generation. Vor jeder Antwort werden passende Abschnitte aus Ihren eigenen Quellen gesucht, etwa Handbüchern, Confluence oder der Datenbank, und das Modell antwortet nur aus diesen Abschnitten, mit Dokument und Abschnitt als Beleg. Steht nichts dazu in den Quellen, lautet die Antwort „nicht gefunden“.

Verlassen unsere Daten bei einem lokalen Modell das Haus?

Nein. Ein offenes Modell wie Qwen, Llama oder Mistral läuft mit llama.cpp auf Ihrer eigenen Hardware im eigenen Netz. Kein externer Anbieter ist im Datenpfad, auch nicht für die Protokolle.

Welche Hardware braucht ein lokales Sprachmodell?

Das hängt von Aufgabe und Modellgröße ab. Für klar umrissene Aufgaben wie Zusammenfassen, Klassifizieren oder Antworten aus eigenen Dokumenten reicht oft eine einzelne Grafikkarte, wenn das Modell passend quantisiert ist. Vor einer Anschaffung wird auf Ihrer Hardware gemessen, nicht geschätzt.

Sind wir danach an einen KI-Anbieter gebunden?

Nein. Die Anwendung spricht das Modell über LangChain4j an. Ein Wechsel zu einem anderen Anbieter oder zu einem lokalen Modell ist eine Frage der Konfiguration, die Fachlogik bleibt unverändert.

Arbeiten Sie auch remote?

Ja. Ich arbeite von Dresden aus, remote für Projekte in Deutschland, Österreich und der Schweiz. Termine vor Ort sind nach Absprache möglich.

Anfrage

Schreiben Sie mir oder rufen Sie an: was das System ist, was es können soll und ab wann. Sie bekommen eine Einschätzung, ob sich das als abgegrenztes Modul umsetzen lässt. Und wenn nicht, sage ich das auch.

info@michael-schwarz.dev