스프링

스프링에서 GPT API로 이미지 전송하기

salmon16 2024. 7. 19. 22:08

 

 

개요

스프링에서 GPT-4o API를 활용해 이미지를 전송하고 답변을 받아보자.

 

 

yml

먼저 GPT 설정을 위해 yml파일을 작성하자 

openai:
  model: gpt-4o
  api:
    key: token
    url: https://api.openai.com/v1/chat/completions

 

model과 gpt 사이트에서 발급받은 key를 token에 넣어 둔 후 API를 요청할 url을 작성한다.

 

 

 

이미지 인코딩하기

GPT에 요청을 하려면 이미지를 base64로 인코딩을 해야 한다. 이를 위해 ImageUtils 클래스를 만들어 MultipartFile이미지를 인코딩 하자

 

public class ImageUtils {
    public static String encodeImageToBase64(MultipartFile imageFile) throws IOException {
        byte[] fileContent = imageFile.getBytes();
        return Base64.getEncoder().encodeToString(fileContent);
    }
}

 

ChatGPTConfig

GPT Config파일을 설정하자

@Configuration
public class ChatGPTConfig {

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

    @Bean(name = "GPTRestTemplate")
    public RestTemplate gptRestTemplate() {
        RestTemplate restTemplate = new RestTemplate();
        restTemplate.getInterceptors().add(((request, body, execution) -> {
            request.getHeaders().add("Authorization", "Bearer " + secretKey);
            return execution.execute(request, body);
        }));
        return restTemplate;
    }
}

 

GPT API를 요청하기 위해 RestTemplate를 등혹한다. 이때 헤더에 Bearer토큰으로 발급받은 scretKey를 넣어서 요청을 보내야 한다.

 

요청에 필요한 Dto 클래스 만들기

 

JSON.stringify({
            model: "gpt-4o",  // 사용할 AI 모델
            messages: [{
                role: "user", // 메시지 역할을 user로 설정
                content: [
                    {"type": "text", "text": "What is this image?"},
                    {"type": "image_url", "image_url": {"url": `data:image/jpeg;base64,${base64_image}`}}
                ]
            }, ]

 

위 제이슨은 GPT API에 이미지와 이미지에 대한 텍스트를 전달하기 위해 필요한 Json이다

이를 담을 Dto를 만들어 보자

 

@Data
public class ChatGPTRequest {
    private String model;
    private List<GptRequestMessage> messages;

    public ChatGPTRequest(String model, String base64image) {
        this.model = model;
        this.messages = new ArrayList<>();
        List<Object> list = List.of(new ImgContent("image_url",new ImgContent.Img("data:image/jpeg;base64," + base64image)), new TextContent("text", "다음 이미지를 설명해 줘"));
        this.messages.add(new GptRequestMessage("user", list));
    }
}

model과 prompt역할을 하는 message를 담아준다. 

 

@Getter
@NoArgsConstructor
@AllArgsConstructor
public class GptRequestMessage {
    private String role;
    private List<Object> content;
}

 

이미지를 담아줄 ImgConent와 텍스트를 담아 줄 TextContent를 만들어 준다.

 

@Getter
@NoArgsConstructor
@AllArgsConstructor
public class ImgContent {
    private String type;
    private Img image_url;


    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public static class Img {
        private String url;
    }
}

 

@Getter
@NoArgsConstructor
@AllArgsConstructor
public class TextContent {
    private String type;
    private String text;
}

 

GPT API 응답에 해당하는 Dto도 말들어 준다.

 

@Getter
public class ChatGPTResponse {
    private String id;
    private String object;
    private int created;
    private String model;
    private List<Choice> choices;
    private Usage usage;

    @Getter
    public static class Choice {
        private int index;
        private Message message;
        private String finish_reason;

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

    }

    public static class Usage {
        private int prompt_tokens;
        private int completion_tokens;
        private int total_tokens;

    }

}

 

 

Controller

 

@RestController
@RequestMapping("/api/v1/gpt")
@RequiredArgsConstructor
public class ChatGPTController {
    @Value("${openai.model}")
    private String model;

    @Value("${openai.api.url}")
    private String apiURL;

    private final RestTemplate restTemplate;


    @PostMapping("/chat")
    public String requestGpt(@RequestPart("image") MultipartFile imageFile) {
        String responseContent = null;
        try {
            String base64Image = ImageUtils.encodeImageToBase64(imageFile);
            ChatGPTRequest request = new ChatGPTRequest(model, base64Image);
            ChatGPTResponse chatGPTResponse = restTemplate.postForObject(apiURL, request, ChatGPTResponse.class);
            responseContent = chatGPTResponse.getChoices().get(0).getMessage().getContent().toString();
        }
        catch (Exception e) {
            e.printStackTrace();
        }

        return responseContent;
    }
}

 

요청으로 이미지를 MultipartFile로 받은 후 Base64로 인코딩을 한 후 CharGPTRequest에 담은 후 RestTemplate를 통해 요청을 한다. 그 후 응답을 받아 반환해 주면 된다.