Überspringen Sie zu Inhalten

aaron.de

Primäres Menü
  • Über mich
  • Heim
  • 2024
  • Dezember
  • J
  • Spring AI / OpenAI Tutorial
  • Allgemein

Spring AI / OpenAI Tutorial

aaron 1. Dezember 2024

Table of Contents

Toggle
  • Frage via Spring AI an OpenAI senden und die Antwort anzeigen
  • REST-Controller verwenden
  • Prompt-Template verwenden
  • System-Prompt verwenden
    • Über den Autor
        • aaron

Frage via Spring AI an OpenAI senden und die Antwort anzeigen

OpenAI Key erstellen
https://platform.openai.com/settings/organization/api-keys

Anschließend den Key als Umgebungsvariable setzen: OPENAI_API_KEY

Neues Spring Boot Projekt erstellen:
https://start.spring.io/

Innerhalb der Spring Boot Anwendung bzw. der „application.properties“ Datei den OpenAI Key bzw. Umgebungsvariable (OPENAI_API_KEY) referenzieren.

spring.application.name=springai
spring.ai.openai.api-key=${OPENAI_API_KEY}
application.properties
package de.aaron.springai.services;

public interface OpenAIService {

String getAnswer(String question);
}
OpenAIService.java
package de.aaron.springai.services;

import org.springframework.ai.chat.model.ChatModel;
import org.springframework.ai.chat.model.ChatResponse;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.chat.prompt.PromptTemplate;
import org.springframework.stereotype.Service;

@Service
public class OpenAIServiceImpl implements OpenAIService {

private final ChatModel chatModel;

public OpenAIServiceImpl(ChatModel chatModel) {
this.chatModel = chatModel;
}

@Override
public String getAnswer(String question) {

PromptTemplate promptTemplate = new PromptTemplate(question);
Prompt prompt = promptTemplate.create();
ChatResponse chatResponse = chatModel.call(prompt);

return chatResponse.getResult().getOutput().getContent();
}

}
OpenAIServiceImpl.java
package de.aaron.springai.services;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class OpenAIServiceImplTest {

@Autowired
OpenAIService openAIService;

@Test
void getAnswer() {
String answer = openAIService.getAnswer("Who would win in a fight between Superman and Chuck Norris?");
System.out.println("Answer: " answer);
}

}
OpenAIServiceImplTest.java

Nachdem wir das Interface und die Klassen erstellt haben, sollte die Projektstruktur wie folgt aussehen:

Nachdem Ausführen des Unit-Tests, sollte auf die Frage „Who would win in a fight between Superman and Chuck Norris?“ die Antwort angezeigt werden. In diesem Fall:

„Answer: In a hypothetical fight between Superman and Chuck Norris, it’s important to consider their respective attributes. Superman, being a fictional character from DC Comics, possesses superhuman strength, speed, flight, invulnerability, and various other powers, including heat vision and freezing breath. These abilities make him one of the most powerful superheroes.

Chuck Norris, on the other hand, is a real person known for his martial arts expertise and roles in action films. While he has a legendary status in popular culture, often exaggerated through jokes and memes about his toughness, he is still human and lacks the superhuman abilities that Superman has.

In a purely fictional context, Superman’s array of superpowers would likely give him the upper hand in a physical confrontation. However, the outcome of such a fight would ultimately depend on the context and the rules set within that fictional scenario.“

REST-Controller verwenden

REST-Controller erstellen.
Der Endpoint ist z.B. via Postman unter der folgenden URL localhost:8080/ask zu erreichen.

package de.aaron.springai.controllers;

import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import de.aaron.springai.models.Answer;
import de.aaron.springai.models.Question;
import de.aaron.springai.services.OpenAIService;

@RestController
public class QuestionController {

private final OpenAIService openAIService;

public QuestionController(OpenAIService openAIService) {
this.openAIService = openAIService;
}

@PostMapping("/ask")
public Answer answerQuestion(@RequestBody Question question) {
return openAIService.getAnswer(question);
}

}
QuestionController.java
package de.aaron.springai.services;

import de.aaron.springai.models.Answer;
import de.aaron.springai.models.Question;

public interface OpenAIService {

// String getAnswer(String question);
Answer getAnswer(Question question);

}
OpenAIService.java
package de.aaron.springai.services;

import org.springframework.ai.chat.model.ChatModel;
import org.springframework.ai.chat.model.ChatResponse;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.chat.prompt.PromptTemplate;
import org.springframework.stereotype.Service;

import de.aaron.springai.models.Answer;
import de.aaron.springai.models.Question;

@Service
public class OpenAIServiceImpl implements OpenAIService {

private final ChatModel chatModel;

public OpenAIServiceImpl(ChatModel chatModel) {
this.chatModel = chatModel;
}

@Override
public Answer getAnswer(Question question) {

PromptTemplate promptTemplate = new PromptTemplate(question.question());
Prompt prompt = promptTemplate.create();
ChatResponse chatResponse = chatModel.call(prompt);

return new Answer(chatResponse.getResult().getOutput().getContent());
}

}
OpenAIServiceImpl.java
package de.aaron.springai.models;

public record Answer(String answer) {

}
Answer.java
package de.aaron.springai.models;

public record Question(String question) {

}
Question.java

Die Projektstruktur sollte wie folgt aussehen:

Endpoint via Postman aufrufen:

Prompt-Template verwenden

Ein Prompt-Template in Spring AI ist eine Vorlage, die Platzhalter für dynamische Eingaben enthält, um strukturierte Prompts für KI-Modelle zu erstellen. Es ermöglicht die flexible Generierung von Anfragen, indem Variablen wie Benutzereingaben oder Kontextinformationen eingefügt werden.

In diesem Fall möchte ich via Postman lediglich den Namen „Superman“ an den neuen Endpoint „template“ übertragen. Im Hintergrund wird das Wort „Superman“ in dem folgenden Sazt/Frage/Template eingesetzt und beantwortet: „What is the real name of {value}?“.

What is the real name of {value}?
prompt-template.st
package de.aaron.springai.controllers;

import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import de.aaron.springai.models.Answer;
import de.aaron.springai.models.Question;
import de.aaron.springai.models.TemplateRequest;
import de.aaron.springai.services.OpenAIService;

@RestController
public class QuestionController {

private final OpenAIService openAIService;

public QuestionController(OpenAIService openAIService) {
this.openAIService = openAIService;
}

@PostMapping("/ask")
public Answer answerQuestion(@RequestBody Question question) {
return openAIService.getAnswer(question);
}

@PostMapping("/template")
public Answer answerQuestionTemplate(@RequestBody TemplateRequest request) {
return openAIService.getTemplateAnswer(request);
}

}
QuestionController.java
package de.aaron.springai.models;

public record TemplateRequest(String value) {

}
TemplateRequest.java (Model)
package de.aaron.springai.services;

import de.aaron.springai.models.Answer;
import de.aaron.springai.models.Question;
import de.aaron.springai.models.TemplateRequest;

public interface OpenAIService {

// String getAnswer(String question);
Answer getAnswer(Question question);

Answer getTemplateAnswer(TemplateRequest request);

}
OpenAIService.java
package de.aaron.springai.services;

import java.util.Map;

import org.springframework.ai.chat.model.ChatModel;
import org.springframework.ai.chat.model.ChatResponse;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.chat.prompt.PromptTemplate;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Service;

import de.aaron.springai.models.Answer;
import de.aaron.springai.models.Question;
import de.aaron.springai.models.TemplateRequest;

@Service
public class OpenAIServiceImpl implements OpenAIService {

private final ChatModel chatModel;

public OpenAIServiceImpl(ChatModel chatModel) {
this.chatModel = chatModel;
}

/*/
@Override
public String getAnswer(String question) {

PromptTemplate promptTemplate = new PromptTemplate(question);
Prompt prompt = promptTemplate.create();
ChatResponse chatResponse = chatModel.call(prompt);

return chatResponse.getResult().getOutput().getContent();
}
//*/

@Override
public Answer getAnswer(Question question) {

PromptTemplate promptTemplate = new PromptTemplate(question.question());
Prompt prompt = promptTemplate.create();
ChatResponse chatResponse = chatModel.call(prompt);

return new Answer(chatResponse.getResult().getOutput().getContent());
}


@Value("classpath:templates/prompt-template.st")
private Resource getPromptTemplate;

@Override
public Answer getTemplateAnswer(TemplateRequest request) {

PromptTemplate promptTemplate = new PromptTemplate(getPromptTemplate);
Prompt prompt = promptTemplate.create(Map.of("value", request.value()));

ChatResponse chatResponse = chatModel.call(prompt);

return new Answer(chatResponse.getResult().getOutput().getContent());
}
}
OpenAIServiceImpl.java

Die Projektstruktur sollte wie folgt aussehen:

What is the real name of {value}?

His name on earth '''name'''.
His name on krypton '''name'''.
His mother's name '''name'''.
His adoptive mother's name '''name'''.
His father's name '''name'''.
His adoptive father's name '''name'''.
His age '''age'''
prompt-template.st (Template Erweiterung)

System-Prompt verwenden

package de.aaron.springai.services;

import de.aaron.springai.models.Answer;
import de.aaron.springai.models.Question;
import de.aaron.springai.models.TemplateRequest;

public interface OpenAIService {

....

Answer getSystemPromptAnswer(Question request);

}
OpenAIService.java
	@Override
public Answer getSystemPromptAnswer(Question question) {

String systemPrompt = "Translate the answer into German language.";
SystemPromptTemplate systemPromptTemplate = new SystemPromptTemplate(systemPrompt);
Message systemMessage = systemPromptTemplate.createMessage();


PromptTemplate promptTemplate = new PromptTemplate(question.question());
Message userMessage = promptTemplate.createMessage();

List<Message> messages = List.of(systemMessage, userMessage);

Prompt prompt = new Prompt(messages);

ChatResponse chatResponse = chatModel.call(prompt);

return new Answer(chatResponse.getResult().getOutput().getContent());
}
OpenAIServiceImpl.java
@PostMapping("/systemAnswer")
public Answer answerQuestionSystemPrompt(@RequestBody Question question) {
return openAIService.getSystemPromptAnswer(question);
}
QuestionController.java

Über den Autor

Avatar-Foto

aaron

Administrator

Besuchen Sie die Website Alle Beiträge anzeigen

Post navigation

Previous: Whisper: Automatische Transkription von Videos in Text
Next: Ollama mit llama3.2/3.3/DeepSeekv3 lokal verwenden + REST Aufruf.

Verwandte Geschichten

BotFather_BG_Aaron_Kreis
  • Allgemein

Telegram Bot API Tutorial

aaron 15. September 2025
kameras
  • Allgemein

Web Application Firewall (WAF): Ein praktischer Leitfaden

aaron 8. September 2025
AsciiDoc_005
  • Allgemein

AsciiDoc & Kroki: eine bewährte Kombination für klare Softwaredokumentation

aaron 6. September 2025

Sie haben vielleicht verpasst

BotFather_BG_Aaron_Kreis
  • Allgemein

Telegram Bot API Tutorial

aaron 15. September 2025
kameras
  • Allgemein

Web Application Firewall (WAF): Ein praktischer Leitfaden

aaron 8. September 2025
AsciiDoc_005
  • Allgemein

AsciiDoc & Kroki: eine bewährte Kombination für klare Softwaredokumentation

aaron 6. September 2025
Data
  • Allgemein

Datensouveränität als Schlüssel für erfolgreiche KI

aaron 3. September 2025
Impressum & Datenschutz
Copyright © All rights reserved. | MoreNews von AF themes.
Diese Website benutzt Cookies. Wenn du die Website weiter nutzt, gehen wir von deinem Einverständnis aus.