카테고리 없음

[Spring AI] OpenAI 연결하기 (최종프로젝트 37일차)

sooyeoneo 2025. 2. 7. 23:25

Spring AI 없이 OpenAI API 직접 연결하기

📌 개요

Spring AI를 사용하지 않고 RestTemplate 또는 WebClient를 이용해 OpenAI API를 직접 호출하는 방법입니다.


1️⃣ OpenAI API 키 발급

OpenAI API 사이트에서 API 키를 발급받습니다.

❕ Spring AI 기술 사용 시에도 반드시 발급


2️⃣ application.yml 설정

OpenAI API 키를 application.yml 또는 application.properties에 저장합니다.

openai:
  api-key: sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxx
  model: gpt-3.5-turbo

⚠ 주의:

API 키는 Github에 올리지 않도록 .gitignore 설정을 확인하세요!


3️⃣ OpenAI API 요청 및 응답 DTO 정의

☑️ 요청 DTO (OpenAIRequest.java)

package com.example.openai.dto;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class OpenAIRequest {
    private String model;
    private List<Message> messages;
    private double temperature;

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public static class Message {
        private String role;
        private String content;
    }
}

☑️ 응답 DTO (OpenAIResponse.java)

package com.example.openai.dto;

import lombok.Data;
import java.util.List;

@Data
public class OpenAIResponse {
    private List<Choice> choices;

    @Data
    public static class Choice {
        private Message message;
    }

    @Data
    public static class Message {
        private String role;
        private String content;
    }
}


4️⃣ OpenAI API 호출 서비스 구현

☑️ RestTemplate을 이용한 API 호출 (OpenAIService.java)

package com.example.openai.service;

import com.example.openai.dto.OpenAIRequest;
import com.example.openai.dto.OpenAIResponse;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.Collections;

@Service
public class OpenAIService {

    private final RestTemplate restTemplate;
    private final String apiUrl = "<https://api.openai.com/v1/chat/completions>";

    @Value("${openai.api-key}")
    private String apiKey;

    @Value("${openai.model}")
    private String model;

    public OpenAIService(RestTemplate restTemplate) {
        this.restTemplate = restTemplate;
    }

    public String chatWithOpenAI(String userMessage) {
        OpenAIRequest.Message message = new OpenAIRequest.Message("user", userMessage);
        OpenAIRequest request = new OpenAIRequest(model, Collections.singletonList(message), 0.7);

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.setBearerAuth(apiKey);

        HttpEntity requestEntity = new HttpEntity<>(request, headers);
        ResponseEntity response = restTemplate.exchange(
                apiUrl, HttpMethod.POST, requestEntity, OpenAIResponse.class
        );

        return response.getBody().getChoices().get(0).getMessage().getContent();
    }
}


5️⃣ OpenAI API 컨트롤러 구현

☑️ API 요청을 처리하는 컨트롤러 (OpenAIController.java)

package com.example.openai.controller;

import com.example.openai.service.OpenAIService;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/api/openai")
public class OpenAIController {

    private final OpenAIService openAIService;

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

    @GetMapping("/chat")
    public String chatWithAI(@RequestParam String message) {
        return openAIService.chatWithOpenAI(message);
    }
}


6️⃣ 실행 및 테스트

서버 실행

./gradlew bootRun

☑️ API 호출

curl "<http://localhost:8080/api/openai/chat?message=안녕하세요>"

☑️ 응답 예시

{
  "response": "안녕하세요! 어떻게 도와드릴까요?"
}

 

 

Spring AI를 사용하여 OpenAI API 연결하기

📌 개요

Spring AI를 사용하여 OpenAI API를 쉽게 연동하는 방법을 설명합니다.

Spring AI는 OpenAI API 호출을 위한 자동 설정(Spring Boot Auto Configuration) 을 제공하여,

번거로운 API 요청/응답 처리를 간소화할 수 있습니다.


1️⃣ Spring AI 의존성 추가

☑️ build.gradle에 추가

Spring AI를 사용하기 위해 spring-ai-openai 라이브러리를 추가합니다.

repositories {
    mavenCentral()
    maven { url '<https://repo.spring.io/milestone>' }
    maven { url '<https://repo.spring.io/snapshot>' }
}

dependencies {
    // OpenAI API 연동을 위한 Spring AI
    implementation "org.springframework.ai:spring-ai-openai-spring-boot-starter"
    implementation 'org.springframework.ai:spring-ai-openai'
    implementation "org.springframework.boot:spring-boot-starter-webflux"
    implementation platform("org.springframework.ai:spring-ai-bom:1.0.0-SNAPSHOT")
}

🔹 BOM(Bill of Materials)이란?

BOM은 Spring AI의 권장 종속성 버전을 선언하는 역할을 합니다.

이를 통해 각 라이브러리의 버전을 직접 관리할 필요 없이, BOM에 의해 자동으로 조정됩니다.


2️⃣ OpenAI API 키 설정

☑️ application.properties에 API 키 추가

# OpenAI API 설정
spring.ai.openai.api-key=${OPENAI_API_KEY}
spring.ai.openai.chat.options.model=gpt-3.5-turbo

⚠ 주의: API 키는 .gitignore에 추가하여 Git에 노출되지 않도록 주의하세요!


3️⃣ Spring AI의 ChatClient 설정

Spring AI에서는 ChatClient라는 인터페이스를 사용해 OpenAI API와 통신합니다.

자동 설정을 이용해 ChatClient를 쉽게 주입받을 수 있습니다.

☑️ ChatClient 빈 등록 (AiConfig.java)

@Configuration
public class AiConfig {

    @Bean
    ChatClient chatClient(ChatClient.Builder builder) {
        return builder.build();
    }
}

위 설정을 통해 ChatClient 객체가 Spring 빈으로 등록됩니다.


4️⃣ AI와 대화하는 서비스 구현

☑️ AI에게 질문을 보내고 응답을 받는 서비스 (AiChatServiceImpl.java)

@Service
@RequiredArgsConstructor
public class AiChatServiceImpl implements AiChatService {

    private final ChatClient chatClient;
    private final ObjectMapper objectMapper;
    private final AiChatHistoryService aiChatHistoryService;

    @Override
    public AiChatResponseDto getAiRecommendation(Long memberId, String sessionId, String prompt) {
        // ChatClient를 사용해 AI에게 요청
        String response = chatClient.prompt().user(prompt).call().content();

        // JSON 응답 파싱
        String recommendation;
        try {
            Map<String, String> responseMap = objectMapper.readValue(response, Map.class);
            recommendation = Optional.ofNullable(responseMap.get("recommendation"))
                    .orElse("추천할 메뉴가 없습니다.").trim();
        } catch (Exception exception) {
            recommendation = "추천할 메뉴를 파싱하는 데 실패했습니다.";
        }

        // AI 추천 히스토리 MySQL + Redis에 저장
        aiChatHistoryService.saveChatHistory(memberId, sessionId, recommendation);

        return new AiChatResponseDto(recommendation);
    }
}

🔹 설명:

  • chatClient.prompt().user(prompt).call().content();
    • AI에게 요청을 보내고 응답을 받아오는 핵심 코드입니다.
  • 응답이 JSON 형태일 경우, ObjectMapper를 사용해 파싱합니다.
  • AI 추천 결과를 MySQL + Redis에 저장하여 캐싱합니다.

5️⃣ ChatClient의 동작 방식

Spring AI의 ChatClient는 OpenAI API와 통신하기 위한 유창한 API(Fluent API) 를 제공합니다.

이 API를 사용하면 프롬프트를 쉽게 구성할 수 있습니다.

☑️ ChatClient 요청 흐름

  1. 사용자 메시지를 생성
  2. chatClient.prompt().user("추천할 점심 메뉴 알려줘")
  3. OpenAI API에 요청을 보냄
  4. call();
  5. AI의 응답을 받아 문자열로 반환
  6. content();

🔹 ChatClient를 사용하면?

  • RestTemplate이나 WebClient를 직접 사용할 필요 없이 간결한 코드로 AI API를 호출할 수 있습니다.

6️⃣ AI 응답 처리

☑️ ChatResponse 객체로 상세한 응답 받기

OpenAI의 응답을 더욱 상세하게 받고 싶다면 chatResponse() 메서드를 사용할 수 있습니다.

ChatResponse response = chatClient.prompt()
        .user("이 AI가 사용할 수 있는 기능을 설명해줘")
        .call()
        .chatResponse();

System.out.println(response.getMetadata()); // 메타데이터 출력
System.out.println(response.getGenerations().get(0).getText()); // 첫 번째 응답 출력

🔹 ChatResponse 객체에는?

  • 토큰 사용량 정보 (비용 절감에 도움)
  • 다중 응답 (여러 개의 결과를 받아볼 수 있음)
  • 세부적인 메타데이터 (요청당 사용된 AI 리소스)

7️⃣ 실행 및 테스트

☑️ 서버 실행

./gradlew bootRun

☑️ API 호출

curl "<http://localhost:8080/api/openai/chat?message=점심> 추천해줘"

☑️ 응답 예시

{
  "response": "김치찌개, 된장찌개, 비빔밥을 추천합니다!"
}


✨ 정리

☑️ Spring AI를 사용하면 OpenAI API 연동이 더욱 간편해집니다.

☑️ ChatClient를 활용하면 RestTemplate/WebClient 없이 AI API를 호출할 수 있습니다.

☑️ Fluent API 지원으로 더 직관적인 코드 작성이 가능합니다.

☑️ MySQL + Redis 캐싱을 활용하여 AI 응답을 효율적으로 저장할 수 있습니다.


📚 참고 문서

📌 Spring AI 공식 문서

📌 Spring AI Getting Started

📌 Spring AI ChatClient API

 

Chat Client API :: Spring AI Reference

Creating a ChatClient with a default system text in an @Configuration class simplifies runtime code. By setting defaults, you only need to specify the user text when calling ChatClient, eliminating the need to set a system text for each request in your run

docs.spring.io

 

 

1. Spring AI를 활용한 AI 연동 방식

☑️ Spring AI를 활용하는 방식

  • WebClient 기반 ChatClient 사용: Spring AI가 OpenAI API와의 연결을 대신 수행하여 개발자가 직접 API 요청을 처리할 필요가 없습니다.
  • Spring Boot와의 손쉬운 통합: 기존의 Spring 생태계와 쉽게 연동 가능하며, 설정만으로 OpenAI와 통신이 가능합니다.
  • 비동기 처리 지원: WebClient를 통해 비동기 요청을 쉽게 구현할 수 있어 성능 최적화 가능합니다.

☑️ Spring AI를 사용하지 않는 경우 (직접 외부 API 연결)

  • RestTemplate 또는 WebClient를 직접 사용: 개발자가 OpenAI API와 직접 통신하는 로직을 작성해야 합니다.
  • 인증 및 요청 포맷 관리 필요: OpenAI의 API 키를 직접 관리하고, 요청 및 응답을 직접 파싱해야 합니다.
  • 비동기 처리 직접 구현 필요: WebClient를 직접 활용해 비동기 요청을 구현해야 합니다.

2. Spring AI의 장점

  • 코드 단순화: OpenAI API와 직접 통신하는 코드 작성 부담이 줄어들고, Spring AI가 이를 추상화하여 더욱 직관적인 코드 작성이 가능합니다.
  • 유지보수성 향상: Spring Boot와의 네이티브 통합 덕분에 유지보수가 쉬워지고, 최신 Spring 업데이트를 그대로 반영 가능합니다.
  • 성능 최적화: WebClient 기반으로 설계되어 비동기 처리와 성능 최적화가 가능합니다.

3. GPT-3.5 Turbo의 장점

  • 향상된 성능: 기존 모델 대비 빠르고 저렴한 비용으로 더 나은 응답을 제공합니다.
  • 대용량 컨텍스트 지원: 이전 버전보다 긴 대화 이력을 기억할 수 있어 더욱 자연스러운 대화가 가능합니다.
  • 다양한 활용 가능성: 코드 생성, 문서 요약, 챗봇 구현 등 다양한 영역에서 활용 가능합니다.

 

 

 

Spring AI 기술

 

 

 

 

Spring AI는 AI 애플리케이션을 개발하기 위한 기반이 되는 추상화를 제공합니다. 이러한 추상화에는 여러 구현이 있어 최소한의 코드 변경으로 쉽게 구성 요소를 교체할 수 있습니다.

Spring AI는 다음과 같은 기능을 제공합니다.

  • 채팅, 텍스트-이미지, 임베딩 모델을 위한 AI 제공자 전반의 휴대용 API 지원. 동기식 및 스트리밍 API 옵션이 모두 지원됩니다. 모델별 기능에 대한 액세스도 가능합니다.
  • Anthropic, OpenAI, Microsoft, Amazon, Google, Ollama 등 모든 주요 AI 모델 제공업체 지원. 지원되는 모델 유형은 다음과 같습니다.
    • 채팅 완료
    • 임베딩
    • 텍스트를 이미지로
    • 오디오 전사
    • 텍스트 음성 변환
    • 절도
    • 구조화된 출력 - AI 모델 출력을 POJO에 매핑합니다.
    • Apache Cassandra, Azure Cosmos DB, Azure Vector Search, Chroma, Elasticsearch, GemFire, MariaDB, Milvus, MongoDB Atlas, Neo4j, OpenSearch, Oracle, PostgreSQL/PGVector, PineCone, Qdrant, Redis, SAP Hana, Typesense 및 Weaviate 등 모든 주요 벡터 데이터베이스 공급자를 지원합니다.
    • SQL과 유사한 새로운 메타데이터 필터 API를 포함하여 Vector Store 공급자 전반의 이식 가능한 API입니다.
    • 도구/함수 호출 - 모델이 클라이언트 측 도구 및 기능의 실행을 요청하여 필요에 따라 필요한 실시간 정보에 액세스할 수 있도록 허용합니다.
    • 관찰성 - AI 관련 작업에 대한 통찰력을 제공합니다.
    • 데이터 엔지니어링을 위한 문서 주입 ETL 프레임워크 .
    • AI 모델 평가 - 생성된 콘텐츠를 평가하고 환각 반응으로부터 보호하는 데 도움이 되는 유틸리티입니다.
    • AI 모델과 벡터 저장소를 위한 Spring Boot 자동 구성 및 스타터.
    • ChatClient API - AI 채팅 모델과 통신하기 위한 Fluent API로, WebClient 및 RestClient API와 관용적으로 유사합니다.
    • Advisors API - 반복적인 생성 AI 패턴을 캡슐화하고, 언어 모델(LLM)로 송수신되는 데이터를 변환하고, 다양한 모델과 사용 사례 간에 이식성을 제공합니다.
    • 채팅 대화 메모리 및 검색 증강 생성(RAG) 지원 .
    이 기능 세트를 사용하면 "문서에 대한 Q&A" 또는 "문서와 채팅"과 같은 일반적인 사용 사례를 구현할 수 있습니다.시작하기 섹션 에서는 첫 번째 AI 애플리케이션을 만드는 방법을 보여줍니다. 이후 섹션에서는 코드 중심 접근 방식으로 각 구성 요소와 일반적인 사용 사례를 자세히 살펴봅니다.
  • 개념 섹션에서는 AI 개념과 Spring AI에서의 표현 방식에 대한 전반적인 개요를 제공합니다.

 

 

 

 

 

 

 

TIL 2월 7일