Spring Java LLM

Spring AI: Java 개발자를 위한 AI 애플리케이션 개발

Spring AI는 Java/Spring 개발자가 익숙한 환경에서 AI 기능을 통합할 수 있게 해주는 프레임워크입니다. ChatClient API, RAG, Tool Calling, Vector Database 통합 등 핵심 기능을 상세히 알아봅니다.

d

devfreshi85

Author

Published

Mar 12, 2026

개요

Spring AI는 AI 엔지니어링을 위한 애플리케이션 프레임워크입니다. Spring 생태계의 설계 원칙인 이식성(Portability)모듈러 설계를 AI 도메인에 적용하며, POJO를 애플리케이션의 빌딩 블록으로 사용하는 것을 장려합니다.

Spring AI의 핵심은 기업의 데이터와 API를 AI 모델에 연결하는 것입니다.

왜 Spring AI를 사용해야 할까?

기존 AI 개발의 한계

많은 Java 백엔드 개발자들이 AI 서비스를 개발할 때 Python 기반의 LangChain을 사용해야 했습니다. 하지만 Java/Spring에 익숙한 개발자들에게는:

  • 새로운 언어 학습 비용: Python과 그 생태계를 익혀야 함
  • 개발 환경 분리: 기존 Spring 프로젝트와 별도의 코드베이스 관리
  • 운영 복잡성 증가: 두 개의 서로 다른 기술 스택 운영

Spring AI의 장점

"이젠 AI 개발도 Spring스럽게!"
  1. 익숙한 개발 환경: Java & Spring 환경에서 그대로 AI 서비스 개발
  2. Spring 생태계 통합: Spring Boot Auto Configuration, DI, AOP 등 기존 기능 활용
  3. 통합된 코드베이스: 하나의 프로젝트에서 비즈니스 로직과 AI 기능 통합
  4. 낮은 학습 곡선: Spring 개발자라면 빠르게 적응 가능

핵심 개념

1. 모델 (Models)

AI 모델은 정보를 처리하고 생성하는 알고리즘입니다. Spring AI는 다양한 입력/출력 유형을 지원합니다:

입력 유형 출력 유형 예시
언어 언어 ChatGPT, Claude, Gemini
언어 이미지 DALL-E, Stable Diffusion
언어 오디오 TTS (Text-to-Speech)
오디오 언어 Whisper (STT)
언어 임베딩 text-embedding-ada-002

2. 프롬프트와 프롬프트 템플릿

프롬프트는 AI 모델을 안내하는 언어 기반 입력입니다. Spring AI에서는 프롬프트 템플릿을 사용하여 동적인 프롬프트를 생성할 수 있습니다:

String answer = ChatClient.create(chatModel).prompt()
    .user(u -> u
            .text("Tell me the names of 5 movies whose soundtrack was composed by {composer}")
            .param("composer", "John Williams"))
    .call()
    .content();

이는 Spring MVC의 View 패턴과 유사하게 동작합니다.

3. 임베딩 (Embeddings)

임베딩은 텍스트, 이미지, 비디오를 숫자 배열(벡터)로 변환한 것입니다. 이 벡터들은 텍스트의 의미를 포착하며, 벡터 간의 거리를 계산하여 유사도를 판단할 수 있습니다.

텍스트 → 임베딩 모델 → [0.123, -0.456, 0.789, ...] (벡터)

이는 RAG(검색 증강 생성) 구현의 핵심입니다.

4. 토큰 (Tokens)

토큰은 AI 모델의 기본 처리 단위입니다:

  • 영어에서 1 토큰 ≈ 0.75 단어
  • 토큰 = 비용: API 호출 비용은 토큰 수에 따라 결정
  • 컨텍스트 윈도우: 모델이 한 번에 처리할 수 있는 토큰 한계 (예: GPT-4는 8K~128K)

5. 구조화된 출력 (Structured Output)

AI 모델의 출력을 POJO로 매핑할 수 있습니다:

record ActorFilms(String actor, List<String> movies) {}

ActorFilms actorFilms = chatClient.prompt()
    .user("Generate the filmography for a random actor.")
    .call()
    .entity(ActorFilms.class);

지원 AI 모델 제공자

Spring AI는 모든 주요 AI 모델 제공자를 지원합니다:

제공자 지원 모델 타입
OpenAI Chat, Embedding, Image, Audio, Moderation
Anthropic Chat (Claude)
Azure OpenAI Chat, Embedding, Image, Audio
Google (Vertex AI) Chat, Embedding
Amazon Bedrock Chat, Embedding
Ollama Chat, Embedding (로컬 모델)
Mistral AI Chat, Embedding
Groq Chat
DeepSeek Chat
NVIDIA Chat

ChatClient API

ChatClient는 AI 모델과 통신하기 위한 Fluent API를 제공합니다. WebClientRestClient 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()
            .content();
    }
}

시스템 프롬프트 설정

@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();
    }
}

스트리밍 응답

Flux<String> output = chatClient.prompt()
    .user("Tell me a joke")
    .stream()
    .content();

다중 모델 사용

@Configuration
public class ChatClientConfig {

    @Bean
    public ChatClient openAiChatClient(OpenAiChatModel chatModel) {
        return ChatClient.create(chatModel);
    }

    @Bean
    public ChatClient anthropicChatClient(AnthropicChatModel chatModel) {
        return ChatClient.create(chatModel);
    }
}

Vector Database 통합

Spring AI는 20개 이상의 벡터 데이터베이스를 지원합니다:

  • 상용: Pinecone, MongoDB Atlas, Azure Vector Search, Oracle
  • 오픈소스: Milvus, Chroma, Weaviate, Qdrant, Redis
  • PostgreSQL 기반: PGVector
  • 그래프 DB: Neo4j
  • 검색 엔진: Elasticsearch, OpenSearch, Typesense

VectorStore 인터페이스

public interface VectorStore extends DocumentWriter, VectorStoreRetriever {

    void add(List<Document> documents);

    void delete(List<String> idList);

    void delete(Filter.Expression filterExpression);

    List<Document> similaritySearch(SearchRequest request);
}

사용 예시

@Autowired
VectorStore vectorStore;

void load(String sourceFile) {
    JsonReader jsonReader = new JsonReader(new FileSystemResource(sourceFile),
            "price", "name", "shortDescription", "description", "tags");
    List<Document> documents = jsonReader.get();
    this.vectorStore.add(documents);
}

List<Document> search(String question) {
    SearchRequest request = SearchRequest.builder()
        .query(question)
        .topK(5)
        .similarityThreshold(0.7)
        .build();

    return vectorStore.similaritySearch(request);
}

메타데이터 필터링

// SQL-like 필터 표현식
SearchRequest request = SearchRequest.builder()
    .query(question)
    .filterExpression("country == 'UK' && year >= 2020 && isActive == true")
    .build();

// 또는 Fluent API
FilterExpressionBuilder b = new FilterExpressionBuilder();
Expression expression = b.and(b.eq("genre", "drama"), b.gte("year", 2020)).build();

Tool Calling (Function Calling)

Tool Calling은 AI 모델이 외부 시스템의 API를 호출할 수 있게 하는 패턴입니다.

정보 검색 예시

class DateTimeTools {

    @Tool(description = "Get the current date and time in the user's timezone")
    String getCurrentDateTime() {
        return LocalDateTime.now()
            .atZone(LocaleContextHolder.getTimeZone().toZoneId())
            .toString();
    }
}

// 사용
String response = ChatClient.create(chatModel)
        .prompt("What day is tomorrow?")
        .tools(new DateTimeTools())
        .call()
        .content();

액션 수행 예시

class DateTimeTools {

    @Tool(description = "Get the current date and time in the user's timezone")
    String getCurrentDateTime() {
        return LocalDateTime.now()
            .atZone(LocaleContextHolder.getTimeZone().toZoneId())
            .toString();
    }

    @Tool(description = "Set a user alarm for the given time, provided in ISO-8601 format")
    void setAlarm(String time) {
        LocalDateTime alarmTime = LocalDateTime.parse(time, DateTimeFormatter.ISO_DATE_TIME);
        System.out.println("Alarm set for " + alarmTime);
    }
}

// 사용
String response = ChatClient.create(chatModel)
        .prompt("Can you set an alarm 10 minutes from now?")
        .tools(new DateTimeTools())
        .call()
        .content();

Function Bean으로 등록

@Configuration
class WeatherTools {

    @Bean
    @Description("Get the weather in location")
    Function<WeatherRequest, WeatherResponse> currentWeather() {
        return request -> new WeatherResponse(30.0, Unit.C);
    }
}

RAG (Retrieval Augmented Generation)

RAG는 AI 모델이 학습하지 않은 데이터를 활용하여 정확한 답변을 생성하는 기법입니다.

ETL 파이프라인

  1. Extract: 문서에서 데이터 추출
  2. Transform: 텍스트를 청크로 분할하고 임베딩 생성
  3. Load: 벡터 데이터베이스에 저장

QuestionAnswerAdvisor 사용

ChatClient.builder(chatModel)
    .build()
    .prompt()
    .advisors(
        MessageChatMemoryAdvisor.builder(chatMemory).build(),
        QuestionAnswerAdvisor.builder(vectorStore).build()
    )
    .user(userText)
    .call()
    .content();

MCP (Model Context Protocol) 지원

Spring AI 2.0부터 MCP(Model Context Protocol)를 지원합니다:

  • MCP Client: 외부 MCP 서버의 도구, 리소스, 프롬프트 사용
  • MCP Server: Spring 애플리케이션의 도구를 MCP 프로토콜로 노출
  • Claude Desktop 등 MCP 호환 클라이언트와 통합 가능

빠른 시작

1. 의존성 추가

<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-openai-spring-boot-starter</artifactId>
</dependency>

2. API 키 설정

spring.ai.openai.api-key=${OPENAI_API_KEY}

3. 코드 작성

@SpringBootApplication
public class SpringAiDemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringAiDemoApplication.class, args);
    }

    @Bean
    public CommandLineRunner runner(ChatClient.Builder builder) {
        return args -> {
            ChatClient chatClient = builder.build();
            String response = chatClient
                .prompt("Tell me a joke")
                .call()
                .content();
            System.out.println(response);
        };
    }
}

4. 실행

./mvnw spring-boot:run

Spring AI로 무엇을 할 수 있나요?

대표적인 사용 사례

  1. “문서와 대화하기” (Chat with your documentation)
    • 회사 내부 문서, 매뉴얼, FAQ를 기반으로 Q&A 시스템 구축
  2. 지능형 챗봇
    • 고객 지원, 상담 봇 개발
  3. 콘텐츠 생성
    • 블로그 글, 이메일, 보고서 자동 생성
  4. 코드 어시스턴트
    • 코드 생성, 리팩토링 제안, 문서화
  5. 데이터 분석
    • 자연어로 데이터 쿼리 및 분석

주요 기능 요약

기능 설명
ChatClient API Fluent API로 AI 모델과 통신
Structured Output AI 응답을 POJO로 매핑
Vector Database 20개 이상의 벡터 DB 지원
Tool Calling 외부 API/함수 호출 기능
RAG 검색 증강 생성 지원
MCP Model Context Protocol 지원
Observability AI 작업 관찰 가능성
Chat Memory 대화 기록 관리
Advisors API 재사용 가능한 AI 패턴 캡슐화
Model Evaluation 환각 응답 방지 및 평가 도구

마치며

Spring AI는 Java/Spring 개발자가 익숙한 환경을 벗어나지 않고 AI 기능을 통합할 수 있게 해주는 강력한 프레임워크입니다. Python 기반 LangChain의 영감을 받았지만, Spring의 철학을 따르며 Java 개발자에게 최적화되어 있습니다.

특히 다음과 같은 경우 Spring AI를 강력히 추천합니다:

  • 이미 Spring 기반 프로젝트를 운영 중인 팀
  • Python 학습 비용을 줄이고 싶은 Java 개발자
  • 하나의 코드베이스에서 비즈니스 로직과 AI 기능을 통합하고 싶은 경우
  • Spring 생태계의 이점(DI, AOP, Auto Configuration)을 AI 개발에도 적용하고 싶은 경우

참고 자료