
개요
생성형 AI 기술이 빠르게 확산되면서, Java 기반 백엔드에 LLM(Large Language Model)을 통합하려는 수요가 급증하고 있습니다. 하지만 OpenAI나 Anthropic의 REST API를 직접 호출하면 인증 처리, 스트리밍, 프롬프트 템플릿 관리 등 반복적인 코드가 늘어난다는 문제가 있습니다.
Spring AI는 이 문제를 해결하기 위해 등장한 Spring 공식 프레임워크입니다. Spring의 친숙한 프로그래밍 모델(DI, Auto-configuration, Starter)을 그대로 유지하면서 OpenAI, Azure OpenAI, Anthropic, Ollama 등 다양한 AI 모델을 추상화된 인터페이스로 연동할 수 있습니다. 이 글에서는 Spring AI를 프로젝트에 적용하고, ChatClient를 통해 LLM과 대화하는 과정을 단계별로 살펴봅니다.
Spring AI 프로젝트 설정
Spring AI를 사용하려면 먼저 BOM(Bill of Materials)과 의존성을 추가해야 합니다. Spring Initializr(start.spring.io)에서 "Spring AI" 스타터를 선택하거나, 아래처럼 pom.xml을 직접 수정합니다.
현재 안정 버전은 1.0.0-M6 이상이며, Spring Boot 3.3+ 환경이 필요합니다.
<!-- pom.xml -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-bom</artifactId>
<version>1.0.0-M6</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- OpenAI 연동 스타터 -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-openai-spring-boot-starter</artifactId>
</dependency>
</dependencies>이어서 application.yml에 API 키와 모델 설정을 추가합니다. 환경 변수를 통해 키를 주입하는 것이 권장 방식입니다.
# application.yml
spring:
ai:
openai:
api-key: ${OPENAI_API_KEY} # 환경 변수로 주입
chat:
options:
model: gpt-4o
temperature: 0.7 # 창의성 조절 (0.0 ~ 1.0)ChatClient로 LLM 호출하기
Spring AI의 핵심은 ChatClient 인터페이스입니다. 마치 Spring의 RestTemplate이나 JdbcTemplate처럼, 복잡한 HTTP 통신을 추상화해 단순한 메서드 호출로 LLM 응답을 받을 수 있습니다.
아래 예시는 사용자의 질문을 받아 AI 답변을 반환하는 서비스 레이어입니다.
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.stereotype.Service;
@Service
public class AiAssistantService {
private final ChatClient chatClient;
// Spring AI가 ChatClient.Builder를 자동 빈으로 등록
public AiAssistantService(ChatClient.Builder builder) {
this.chatClient = builder
.defaultSystem("당신은 친절한 Java 기술 전문가입니다. 간결하게 답변하세요.")
.build();
}
/**
* 단순 질의응답 (동기 방식)
*/
public String ask(String userMessage) {
return chatClient.prompt()
.user(userMessage) // 사용자 메시지 설정
.call() // LLM 호출
.content(); // 응답 텍스트 추출
}
}// 실행 결과 예시 (ask("Java record와 class의 차이를 설명해줘") 호출 시)
"Java 14에서 도입된 record는 불변 데이터 객체를 간결하게 선언하기 위한 특수 클래스입니다.
생성자, getter, equals, hashCode, toString을 자동 생성하므로 DTO 정의 시 코드량을 크게 줄일 수 있습니다.
반면 일반 class는 가변 상태와 복잡한 상속 구조를 표현할 때 적합합니다."defaultSystem()으로 시스템 프롬프트를 한 번만 설정해두면, 이후 모든 호출에 자동으로 적용됩니다. 이를 통해 AI의 역할과 응답 스타일을 일관되게 관리할 수 있습니다.
프롬프트 템플릿과 구조화된 출력 활용
단순 텍스트 응답을 넘어, 현업에서는 프롬프트 템플릿으로 동적 변수를 주입하거나 응답을 Java 객체로 직접 파싱하는 패턴을 자주 활용합니다.
아래는 상품 리뷰를 분석해 구조화된 결과를 반환하는 예시입니다. BeanOutputConverter를 사용하면 LLM 응답을 별도 JSON 파싱 없이 바로 Java 레코드로 변환할 수 있습니다.
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.converter.BeanOutputConverter;
import org.springframework.stereotype.Service;
// 분석 결과를 담는 불변 레코드
record ReviewAnalysis(
String sentiment, // "긍정", "부정", "중립"
int score, // 1~10점
String summary // 한 줄 요약
) {}
@Service
public class ReviewAnalyzerService {
private final ChatClient chatClient;
public ReviewAnalyzerService(ChatClient.Builder builder) {
this.chatClient = builder.build();
}
public ReviewAnalysis analyze(String reviewText) {
var converter = new BeanOutputConverter<>(ReviewAnalysis.class);
String prompt = """
다음 상품 리뷰를 분석하고, 아래 JSON 형식으로만 응답하세요.
{format}
리뷰: {review}
""";
return chatClient.prompt()
.user(u -> u.text(prompt)
.param("format", converter.getFormat()) // JSON 스키마 자동 삽입
.param("review", reviewText))
.call()
.convert(converter); // 응답을 ReviewAnalysis 객체로 변환
}
}// 실행 결과 예시
ReviewAnalysis[
sentiment="긍정",
score=8,
summary="배송이 빠르고 품질이 기대 이상이라는 호평"
]BeanOutputConverter는 내부적으로 Jackson 스키마를 생성해 프롬프트에 삽입하고, LLM이 반환한 JSON을 자동으로 역직렬화합니다. 별도 파서를 작성할 필요 없이 타입 안전한 응답 처리가 가능합니다.
맺음말
Spring AI는 LLM 통합에 필요한 반복 코드를 크게 줄이고, Spring 생태계의 DI와 설정 자동화를 그대로 활용할 수 있는 실용적인 선택지입니다. 핵심 이점을 정리하면 다음과 같습니다.
- 멀티 모델 지원:
application.yml설정만 변경하면 OpenAI, Anthropic, Ollama 등으로 전환 가능합니다. - 타입 안전한 출력:
BeanOutputConverter로 JSON 파싱 없이 Java 객체 매핑입니다. - Spring 통합:
@Autowired, 트랜잭션, 캐싱 등 기존 패턴과 자연스럽게 결합합니다.
다음 단계로는 RAG(Retrieval-Augmented Generation) 패턴을 적용해 자체 문서 기반 QA 시스템을 구축하거나, VectorStore 인터페이스를 통해 pgvector, Redis 등과 연동하는 방법을 살펴볼 만합니다. Spring AI 공식 문서(docs.spring.io/spring-ai)에서 최신 마일스톤 릴리즈 노트도 함께 확인하길 권합니다.
참고
'프로그래밍 PROGRAMMING > 자바 JAVA AND FRAMEWORKS' 카테고리의 다른 글
| Java Virtual Threads로 고성능 서버 구현하기 스레드 병목을 해소하는 방법 (0) | 2026.03.06 |
|---|---|
| [JAVA/SPRING] Java Virtual Threads로 고성능 서버 구축하기 스레드 전환 비용 줄이는 방법 (0) | 2026.03.06 |
| [JAVA/SPRING] Java 캐시 전략 총정리: Caffeine부터 Redis 이중 캐시까지 (0) | 2026.03.04 |
| [JAVA/SPRING] Spring Boot Virtual Threads로 처리량 높이기 어떻게 설정하고 언제 써야 할까 (0) | 2026.03.04 |
| [JAVA/SPRING] Java 검색 엔진 구축 로드맵: 전처리부터 인기검색어까지 (0) | 2026.03.03 |