Spring Boot 3.5 + Spring AI 1.0 + 자바 21 기반으로
OpenAI Chat Completion API를 가장 간단한 코드로 호출하는 방법을 정리했다.
Spring AI를 사용하면서 가장 편리했던 점은 핵심 구성요소들이 대부분 인터페이스 기반으로 설계되어 있다는 것이다.
ChatModel, EmbeddingModel, ImageModel 등 주요 기능들은 모두 공통된 인터페이스를 중심으로 동작하기 때문에, 개발자는 구체적인 구현 클래스를 신경 쓰지 않고 인터페이스만 의존하면 된다.
테스트 환경에서는 실제 OpenAI 서버를 호출하지 않고도 Mock 객체로 쉽게 대체할 수 있고, 서비스 로직을 거의 수정하지 않은 채로 OpenAI에서 Azure OpenAI, HuggingFace, Mistral 같은 다른 모델 제공자로 옮겨가는 것도 가능하다.
단순히 설정 파일만 변경하면 되고 비즈니스 로직은 그대로 유지되는 형태라 유지보수가 훨씬 수월하다. 또한 ChatClient나 ChatModel 같은 API들도 인터페이스 기반으로 추상화되어 있어, 복잡한 WebClient 설정이나 HTTP 요청 코드를 직접 작성할 필요가 없다는 점도 매우 편리하다.
변수 이름: OPENAI_API_KEY
변수 값: sk-XXXXXXXXXXXXXXXXXXXXXXXX
⚠️ 환경변수 추가 후 반드시 IDE(STS/IntelliJ)를 재시작해야 적용된다.
IDE는 실행될 때 환경변수를 읽기 때문에,
재시작하지 않으면 ${OPENAI_API_KEY}를 문자열 그대로 읽는다.
plugins {
id 'java'
id 'org.springframework.boot' version '3.5.7'
id 'io.spring.dependency-management' version '1.1.7'
}
group = 'com.example'
version = '0.0.1-SNAPSHOT'
java {
toolchain {
languageVersion = JavaLanguageVersion.of(21)
}
}
repositories {
mavenCentral()
}
ext {
set('springAiVersion', "1.0.3")
}
dependencies {
// Spring Web (Tomcat 포함)
implementation 'org.springframework.boot:spring-boot-starter-web'
// Spring AI
implementation 'org.springframework.ai:spring-ai-starter-model-openai'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}
dependencyManagement {
imports {
mavenBom "org.springframework.ai:spring-ai-bom:${springAiVersion}"
}
}
포인트
spring.application.name=spring_AI_1
server.port=8090
spring.ai.openai.api-key=${OPENAI_API_KEY}
여기서 ${OPENAI_API_KEY}는 시스템 환경변수에서 자동으로 읽는다.
환경 변수없이 바로 키를 넣어도 잘 동작하지만 키가 노출되면 큰일날 수 있으니까 번거로워도 환경 변수를 사용하기를 권장한다.
Spring AI는 기존 WebClient로 헤더 설정하고 JSON 구조 만들던 방식보다 훨씬 간단하게
OpenAI API를 사용할 수 있도록 도와준다.
특히 ChatClient로
chatClient.prompt("질문").call().content();
이렇게 한 줄만으로 응답을 받을 수 있다.
package com.example.demo.service;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.model.ChatModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class ChatService {
@Autowired
private ChatModel chatModel;
public void run() {
ChatClient chatClient = ChatClient.builder(chatModel).build();
String response = chatClient.prompt("스티븐 잡스의 명언 3개 알려줘")
.call()
.content();
System.out.println("결과:\n" + response);
}
}
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import com.example.demo.service.ChatService;
@SpringBootApplication
public class SpringAi1Application {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(SpringAi1Application.class, args);
ChatService chatService = context.getBean(ChatService.class);
chatService.run();
}
}

스프링 콘솔에 OpenAI 응답이 정상적으로 출력된다.