코딩 해파리

스프링 환경에서 ChatGPT-4o API로 이미지 분석 요청하기(2) 본문

Development/AI

스프링 환경에서 ChatGPT-4o API로 이미지 분석 요청하기(2)

haepalea 2024. 6. 28. 15:12
클래스 작성을 시작해 보자!

 

이번에 알려드릴 Open AI 쪽에 요청을 보내기 위한 Request 구조와

요청에 대한 답을 받기 위한 Response 구조의 아주 간략화된 DTO 클래스 구조를 작성할 겁니다!

 

일단,

https://platform.openai.com/docs/api-reference/chat

이 API Reference를 보면 Request 쪽과 Response 쪽에 구조를 보면,,,

뭐가 너~~~ 무 많습니다...

 

그러니까, 오늘은 모든 기능과 모든 상황을 처리할 수 있는

범용성이 높은 클래스 구조를 작성하기보다는

처음 입문하는 느낌으로다가 messages에 User Message만 담아서 보내보도록 할게요!

그리고 "Required"만 사용하면 보낼 수는 있으니까, 이것들만 작성을 해보겠습니다!

 

이후에 다른 기능들, 예를 들어 messages에 System Message를 보내서

ChatGPT의 대답 범위 혹은 콘셉트를 바꾸는 식으로 하는 등의 여러 방법에 대해서도 다뤄보고 할게요!

 

일단... 입문이니까! 바로 해보겠습니다!

 

1. ImageUrl(request 패키지)

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
@AllArgsConstructor
public class ImageUrl {
    private String url;
}

 

2. Content(request 패키지, 가상 클래스로 구현)

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

@Getter @Setter
@AllArgsConstructor
@NoArgsConstructor
public abstract class Content {
    private String type;
}

 

3. TextContent(request 패키지)

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
@AllArgsConstructor
public class TextContent extends Content {
    private String text;

    public TextContent(String type, String text) {
        super(type);
        this.text = text;
    }
}

 

4. ImageContent(request 패키지)

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
@AllArgsConstructor
public class ImageContent extends Content {
    private ImageUrl image_url;

    public ImageContent(String type, ImageUrl image_url) {
        super(type);
        this.image_url = image_url;
    }
}

 

5. Message(공통 dto 패키지, 가상 클래스로 구현)

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public abstract class Message {
    private String role;
}

 

6. TextMessage(공통 dto 패키지)

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class TextMessage extends Message {
    private String content;

    public TextMessage(String role, String content) {
        super(role);
        this.content = content;
    }
}

 

7. ImageMessage(request 패키지)

import java.util.List;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import org.example.chatgptimageanalysis.dto.Message;

@Getter
@Setter
@AllArgsConstructor
public class ImageMessage extends Message {
    private List<Content> content;

    public ImageMessage(String role, List<Content> content) {
        super(role);
        this.content = content;
    }
}

 

8. Choice(response 패키지)

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.example.chatgptimageanalysis.dto.TextMessage;

@Getter
@NoArgsConstructor
@AllArgsConstructor
public class Choice {
    private int index;
    private TextMessage message;
}

 

9. ChatGPTRequest(request 패키지) -> Builder 패턴 사용

 

import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.Collections;
import java.util.List;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.example.chatgptimageanalysis.dto.Message;
import org.example.chatgptimageanalysis.dto.TextMessage;

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class ChatGPTRequest {
    @JsonProperty("model")
    private String model;
    @JsonProperty("messages")
    private List<Message> messages;
    @JsonProperty("max_tokens")
    private int maxTokens;

    public static ChatGPTRequest createImageRequest(String model, int maxTokens, String role, String requestText, String imageUrl) {
        TextContent textContent = new TextContent("text", requestText);
        ImageContent imageContent = new ImageContent("image_url", new ImageUrl(imageUrl));
        Message message = new ImageMessage(role, List.of(textContent, imageContent));
        return createChatGPTRequest(model, maxTokens, Collections.singletonList(message));
    }

    public static ChatGPTRequest createTextRequest(String model, int maxTokens, String role, String requestText) {
        Message message = new TextMessage(role, requestText);
        return createChatGPTRequest(model, maxTokens, Collections.singletonList(message));
    }

    private static ChatGPTRequest createChatGPTRequest(String model, int maxTokens, List<Message> messages) {
        return ChatGPTRequest.builder()
                .model(model)
                .maxTokens(maxTokens)
                .messages(messages)
                .build();
    }
}

 

10. ChatGPTResponse(response 패키지)

import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.List;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@NoArgsConstructor
@AllArgsConstructor
public class ChatGPTResponse {
    @JsonProperty("choices")
    private List<Choice> choices;
}

 

이 클래스 구조는 OpenAI API Reference를 참고하여 작성하였습니다.
이 코드는 Text를 이용한 평범한 요청과 Image File을 이용한 요청까지도 가능합니다!

 

전체 클래스 구조는 아래와 같습니다!

 

나머지 Service, Controller, Config 클래스는 다음 포스팅에서 소개할게요!
Config와 Service 부분에서 꼭 짚고 넘어가야 할 게 있으니... 

확인해 주세요!