Tutorial: So geht Spring AI
Macht Java mit Spring AI bei KI-Entwicklungsprojekten bald Python Konkurrenz? aerogondo2 | shutterstock.com
Geht’s um Programmiersprachen für künstliche Intelligenz (KI) ist Python bislang der unangefochtene Spitzenreiter. Andere Sprachen standen diesbezüglich bislang ein wenig im Abseits – zum Beispiel Java. Inzwischen ist allerdings eine neue Ära angebrochen, in der KI-Modelle eine Schlüsselkomponente für Machine Learning (ML) darstellen. Dabei ist die entscheidende Frage, wie deren Funktionalität in größere Systeme integriert werden kann. Diese Art der Integration ist eine Spezialität von Java.
Da trifft es sich besonders gut, dass die Macher hinter Spring vor kurzem eine KI-Version ihres Java-Frameworks veröffentlicht haben. Die verspricht, die Programmierarbeit für eine Vielzahl von KI-Projekten zu vereinheitlichen. Entwickler sollen mit Spring AI ihr gesamtes Wissen über die Spring-Semantik und Enterprise-Infrastrukturen auf Machine Learning anwenden können.
In diesem Tutorial lesen Sie, wie das funktioniert.
Was ist Spring AI?
Spring AI fasst eine Vielzahl von KI-Tools verschiedener Anbieter zusammen, darunter verschiedene Bibliotheken und Frameworks. Zum Beispiel in den Bereichen:
Natural Language Processing (NLP),
Computer Vision,
Spracherkennung und -synthese,
Empfehlungssysteme,
Generative AI oder
ETL.
Darüber hinaus umfasst Spring AI auch einige spezialisierte Tools, beispielsweise für Anomalieerkennung, Zeitreihen-Analysen und Reinforcement Learning. Diese Liste soll künftig erweitert werden. Eine vollständige Übersicht finden Sie hier.
Aktuell liegt der Fokus von Spring auf dem LLM-Use-Case. Das Framework unterstützt ChatGPT – sowohl von OpenAI als auch als Azure Service. Support gibt es zudem für die KI-Modelle von Google, Hugging Face und Amazon.
Die zugrundeliegende Idee: Spring AI will künftig eine möglichst breite Palette von KI-Tools in ein konsistentes, Spring-ähnliches Komponentensystem integrieren.
Ein Spring-Projekt aufsetzen
Ein Weg, Spring AI zu nutzen, besteht darin, eine neue Boot-App dafür einzurichten. Dazu füttern Sie Ihre Kommandozeile mit:
spring boot new --from ai --name myProject
Falls Sie bereits über ein bestehendes Projekt verfügen, können Sie dieses mit folgendem Befehl um die spring-ai-bom-Abhängigkeit erweitern.
spring boot add ai
Die API von Spring AI
Die Spring-AI-Schnittstelle besteht aus mehreren Branches – die umfassendste ist das Model-Interface. Dieses bietet eine generische Komponente, mit der Entwickler nahezu jede Art von KI-Funktionalität in Anwendungen integrieren können. Das Interface dient außerdem dazu, die Plattformen verschiedener KI-Anbieter innerhalb des Spring-Ökosystems verfügbar zu machen.
In Spring AI werden diverse KI-Typen als Implementierungen der Model-Schnittstelle erweitert, darunter ChatModel, EmbeddingModel, ImageModel und SpeechModel. Auch eine Streaming-Version namens StreamingModel existiert. Diese Modellimplementierungen kapseln die vom Anbieter geleistete Arbeit, die von der ChatClient-Implementierung genutzt wird.
Spring AI unterstützt auch Function Calling. Das ermöglicht, eine API über benutzerdefinierten Anwendungscode bereitzustellen, mit der die KI interagieren kann, um ihre Antworten zu formulieren. Bislang unterstützt Spring AI:
Anthropic Claude,
Azure OpenAI,
Google VertexAI Gemini,
Groq,
Mistral AI,
Ollama und
OpenAI.
Wie bereits erwähnt, bietet Spring AI auch ETL-Support für Vektordatenbanken. Das wird als Document Reader, Transformer und Writer modelliert. Alle großen Anbieter werden abgedeckt. Darüber hinaus bringt Spring AI auch umfassenden Embedding-Support mit: Das EmbeddingModel-Interface abstrahiert die Umwandlung von Text in ein numerisches Format für eine Vielzahl von Anbietern.
Ein weiterer komplexer Bereich, den Spring AI in Angriff nimmt, ist die Multimodalität. Das ermöglicht es, Text und Bilder zu mischen. Im Folgenden ein Beispiel aus der Spring-AI-Dokumentation:
byte[] imageData = new ClassPathResource("/multimodal.test.png").getContentAsByteArray();
var userMessage = new UserMessage(
"Explain what do you see in this picture?", // content
List.of(new Media(MimeTypeUtils.IMAGE_PNG, imageData))); // media
ChatResponse response = chatModel.call(new Prompt(List.of(userMessage)));
Prompts helfen dabei, den User Input zu strukturieren. Sie wirken allerdings nur auf den ersten Blick simpel und können mitunter ziemlich komplex ausfallen. Geht es darum, den Output von KI-Modellen zu strukturieren, unterstützt das StructuredOutput-Interface. Das ist besonders wichtig, wenn der Output zum Input für ein anderes System wird. Ein weiterer interessanter Aspekt der KI-Entwicklung ist das Testing. Auch an dieser Stelle bietet Spring AI Unterstützung.
Eine Spring-AI-Beispielanwendung
Die Funktionsweise von Spring AI betrachten wir nun anhand eines einfachen Beispiels aus dem Spring AI Azure Workshop. Dabei handelt es sich um ein Projekt in einem Maven-Layout. Dabei ist vor allem die application.resources-Datei zu beachten, die folgende Code-Zeile enthält:
// src/main/resources/application.resources
spring.ai.azure.openai.chat.options.deployment-name=gpt-35-turbo-16k
Das erstellt eine Property mit dem Value gpt-turbo-16k. Der spring.ai.azure.openai.chat.options.deployment-name ist wichtig, weil er per Autokonfiguration mit einem Spring-Bean-Konfigurator verknüpft ist, der auf dieser Grundlage einen ChatClient erstellt. Folgende Abhängigkeit in pom.xml stellt diesen Client bereit:
org.springframework.ai
spring-ai-azure-openai-spring-boot-starter
Wenn Spring das Projekt nach einem ChatClient durchsucht, nutzt es die Property, um einen ChatClient unter Verwendung der Namenskonventionen im openai-Starterprojekt zu erstellen. Im folgenden helloworld-Beispiel wird dieser ChatClient vom Controller aufgerufen:
package com.xkcd.ai.helloworld;
import org.springframework.ai.chat.ChatClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.Map;
@RestController
public class SimpleAiController {
private final ChatClient chatClient;
@Autowired
public SimpleAiController(ChatClient chatClient) {
this.chatClient = chatClient;
}
@GetMapping("/ai/simple")
public MapString, generation(
@RequestParam(value = "message", defaultValue = "Tell me a joke") String message) {
return Map.of("generation", chatClient.call(message));
}
}
Hierbei handelt es sich um einen typischen Spring REST Controller, bei dem das chatClient-Member als @Autowired an eine Methode gebunden ist. Dieser ChatClient wird dann verwendet, um die Requests unter /ai/simple zu bearbeiten. Die Endpoint-Methode gibt eine Map mit einem „Generation“-Key zurück, dessen Value der Return Value von chatClient.call(message) entspricht.
Damit all das funktioniert, benötigen Sie einen API-Schlüssel für Azure. Dieser wird als Umgebungsvariable festgelegt:
export SPRING_AI_AZURE_OPENAI_API_KEY=
Anschließend müssen Sie auch der Engine „mitteilen“, wo sich der KI-Endpunkt befindet:
export SPRING_AI_AZURE_OPENAI_ENDPOINT=
Sind alle Elemente vorhanden, können Sie das Projekt mit $ maven spring-boot:run ausführen. Über localhost:8080/ai/simple sollten Sie nun einen KI-generierten Witz abrufen können.
Andere Beispiele im Azure-Repository demonstrieren, wie dieser grundlegende Rahmen um zusätzliche Funktionen erweitert werden kann. Sie können beispielsweise ganz einfach ein Prompt Template zur Beispiel-App hinzufügen:
// src/main/resources/prompts/joke-prompt.st
Tell me a {adjective} joke about {topic}
Das wird im Controller wie folgt verwendet:
@Value("classpath:/prompts/joke-prompt.st")
private Resource jokeResource;
Am Ende könnten Sie noch Folgendes ergänzen:
PromptTemplate promptTemplate = new PromptTemplate(jokeResource);
(fm)
Sie wollen weitere interessante Beiträge zu diversen Themen aus der IT-Welt lesen? Unsere kostenlosen Newsletter liefern Ihnen alles, was IT-Profis wissen sollten – direkt in Ihre Inbox!
Hier finden Sie den kompletten Artikel: