참고 - Spring AI 공식문서
snapshot ver.repositories {
mavenCentral()
maven { url 'https://repo.spring.io/milestone' }
maven { url 'https://repo.spring.io/snapshot' }
}
dependencies {
implementation platform("org.springframework.ai:spring-ai-bom:1.0.0-SNAPSHOT")
implementation 'org.springframework.ai:spring-ai-openai-spring-boot-starter'
}
application.properties for OpenAIhttps://docs.spring.io/spring-ai/reference/api/chat/openai-chat.html
// API KEY 설정
spring.ai.openai.api-key=SECRET_KEY
// 기타 옵션 설정
spring.ai.openai.chat.options.model
spring.ai.openai.chat.options.temperature
spring.ai.openai.chat.options.frequencyPenalty
...
fluent API를 제공한다.fluent API란 메소드 체이닝에 기반한 객체 지향 API 설계 메소드@RestController
class MyController {
private final ChatClient chatClient;
public MyController(ChatClient.Builder chatClientBuilder) {
this.chatClient = chatClientBuilder.build();
}
@GetMapping("/ai")
String generation(String userInput) {
return this.chatClient.prompt()
.user(userInput)
.call() // AI 모델에게 request룰 보낸다
.content(); // AI 모델의 response를 String으로 리턴한다
}
}
spring.ai.chat.client.enabled=false 추가ChatModel myChatModel = ... // usually autowired
ChatClient.Builder builder = ChatClient.builder(myChatModel);
// or create a ChatClient with the default builder settings:
ChatClient chatClient = ChatClient.create(myChatModel);
.call()로 응답받기
content를 String으로 반환받음ChatResponse 객체로 응답받기
ChatResponse chatResponse = chatClient.prompt()
.user("Tell me a joke")
.call()
.chatResponse()
// 하나의 프롬프트에서 생성된 1개 이상의 output을 포함한 Generation 인스턴스들로 이루어짐
// 또한 AI 모델의 reponse의 ChatResponseMetadata를 포함하고 있음 (예: 생성된 토큰 수)
public class ChatResponse implements ModelResponse<Generation> {
private final ChatResponseMetadata chatResponseMetadata;
private final List<Generation> generations;
@Override
public ChatResponseMetadata getMetadata() {...}
@Override
public List<Generation> getResults() {...}
// other methods omitted
}
// assistant message와 metadata를 가지고 있음
public class Generation implements ModelResult<AssistantMessage> {
private AssistantMessage assistantMessage;
private ChatGenerationMetadata chatGenerationMetadata;
@Override
public AssistantMessage getOutput() {...}
@Override
public ChatGenerationMetadata getMetadata() {...}
// other methods omitted
}
record ActorFilms(String actor, List<String> movies) {
}
ActorFilms actorFilms = chatClient.prompt()
.user("Generate the filmography for a random actor.")
.call()
.entity(ActorFilms.class);
@Configuration
class Config {
@Bean
ChatClient chatClient(ChatClient.Builder builder) {
return builder.defaultSystem("You are a friendly chat bot that answers question in the voice of a Pirate")
.build();
}
}
defaultOptions - ChatOptions 설정Prompt for inputChatResponse for outputpublic interface ChatModel extends Model<Prompt, ChatResponse> {
default String call(String message) {// implementation omitted
}
@Override
ChatResponse call(Prompt prompt);
}

ChatResponse response = chatModel.call(
new Prompt(
"Generate the names of 5 famous pirates.",
OpenAiChatOptions.builder()
.withModel("gpt-4-o")
.withTemperature(0.4)
.build()
));