[Spring] chatGPT API 설정 및 사용하기

Spring 2025. 8. 11.

 

  목  차

  • API key 준비하기 
  • OpenAI 설정하기
  • OpenAI API 사용하기

 

 


 

  API key 준비하기

 

가장 먼저 결제를 해주어야 합니다. 그렇지 않으면 요청이 가지를 않아요.

5$ 이상부터 결제 가능합니다.

 

 

결제 완료하였다면 `API keys` 탭에 들어가줍니다.

오른쪽 위 `+ Create new secret key` 를 눌러줍니다.

 

 

만들어지고 최초 1회만 노출이 되니 잘 복사하여줍니다.

 

 


 

  OpenAI 설정하기

 

application.yml 에 다음 코드를 추가해줍니다.

주의 할 점은 들여쓰기 단계가 spring 이랑 같은 단계입니다.

openai:
  apiKey: {여기에 API key 붙여넣기}
  connect-timeout: 10s
  read-timeout: 30s

 

 

그리고 build.gradle 에 다음 의존성을 추가해줍니다.

 

implementation "com.openai:openai-java:2.20.1"

 

 

OpenAiConfig 클래스 파일을 하나 만들고 다음과 같이 작성해줍니다.

그럼 이렇게 설정은 끝나게 됩니다.

 

@Configuration
public class OpenAIConfig {

    @Bean
    public OpenAIClient openAIClient(
            @Value("${openai.apiKey:${OPENAI_API_KEY}}") String apiKey) {

        return OpenAIOkHttpClient.builder()
                .apiKey(apiKey)
                .timeout(Duration.ofSeconds(30))
                .build();
    }
}

 

 


 

  OpenAI API 사용하기

 

먼저 systemMessage 를 정해줍니다.

이 텍스트는 chatGPT '지침' 같은 부분입니다.

 

String system = """
        너는 금융 전문가다. 다음 규칙을 지켜서만 답한다.
        - 반드시 JSON 객체 하나만 출력한다.
        - 키 이름은 정확히 "score" 하나만 허용한다.
        - 값은 0 이상 100 이하의 정수.
        - JSON 외 텍스트/설명/코드블록/추가 키 금지.
        """;

 

 

 

그리고 userMessage 를 커스텀하거나 입력 받습니다.

이 부분은 chatGPT '본문' 의 역할을 합니다.

 

본격적으로 AI API 를 사용하기 전에 의존성 주입을 해줍니다.

 

private final OpenAIClient openAI;

 

 

이제 파라미터를 만들어 줄 겁니다. `ChatCompletionCreateParams` 클래스의 인스턴스를 만들 건데 여러 설정을 해줄 수 있습니다.

 

이 객체에는 요청에 필요한 모든 파라미터가 담깁니다.

- .model("gpt-5-nano"): 모델을 정하는 건데 현 시점에서 gpt-5-nano 모델이 값도 정말 싸고 성능이 나쁘지 않습니다.

- .addSystemMessage(system): 아까 정의했던 '지침' 역할을 하는 system 을 인자로 넣어줍니다.

- .addUserMessage(userJson): 유저의 프롬프트를 인자로 넣어줍니다.

- .temperature(1): gpt-5-nano 의 경우 1이 고정값입니다.

 

        ChatCompletionCreateParams params = ChatCompletionCreateParams.builder()
                .model("gpt-5-nano")
                .addSystemMessage(system)
                .addUserMessage(userJson)
                .temperature(1)
                .build();

 

 

 

파라미터를 만들었으니 요청을 보내야겠죠? 그 요청을 보내고 응답을 받는 클래스가 `ChatCompletion` 입니다.

 

/* ② 호출 */
        ChatCompletion completion = openAI.chat()
                .completions()
                .create(params);

 

openAI -> Open API 클라이언트 객체

.chat() -> 채팅 관련 API로 이동

.completions() -> 채팅 완료(응답 생성) 기능 선택

.create(파라미터) -> 실제 요청을 생성하고 API를 호출

 

여기서 create() 에 들어가는 `파라미터`는 앞서 빌드했던 `ChatCompletionCreateParams` 의 인스턴스를 인자로 넣어야 합니다.

 

그리고 create() 메소드를 실행하면 ChatCompletion 객체를 반환합니다. 

이 객체에는 API 응답이 들어있습니다.

- 생성된 텍스트

- 사용 토큰 수

- 모델 정보

등등

 

 

 

ChatGPT API  응답(ChatCompletion)에는 여러 개의 choice(응답 후보)가 들어갈 수 있습니다.

choices() 는 List<ChatCompletion.Choice> 를 반환합니다. 보통 하나의 요청에서는 첫 번째 choice 만 사용한다고 합니다.

 

completion.choices()

 

 

응답 리스트를 java stream 으로 변환합니다.

 

.stream()

 

 

첫 번째 choice만 가져옵니다.

반환 타입은 Optional<ChatCompletion.Choice> 입니다.

.findFirst()

 

 

choice.message() -> 모델이 생성한 메시지 객체

.content() -> 메시지의 실제 텍스트

.flatMap 을 사용하는 이유는 그냥 .map() 을 사용하면 이미 Optional 이 있는데 Optional<Optional<String>>이 됩니다.

 

.flatMap(choice -> choice.message().content())

 

 

마지막으로 예외를 처리합니다.

 

.orElseThrow(() -> new BusinessException(ErrorCode.GPT_EMPTY_RESPONSE))

 

 

지금까지 내용을 체이닝으로 묶으면 아래와 같이 됩니다.

/* ③ content 추출 — README 권장 방식 (Optional 처리) */
        String content = completion.choices().stream()
                .findFirst()
                .flatMap(choice -> choice.message().content())  // Optional<String>
                .orElseThrow(() ->
                        new BusinessException(ErrorCode.GPT_EMPTY_RESPONSE));

 

 

 

 

깃허브 openai/openai-java 의 README 를 읽어보시면 위와 같은 내용 확인하실 수 있습니다.